Táimid ag scríobh matchmaking do Dota 2014

Dia duit gach duine.

An earrach seo tháinig mé trasna ar thionscadal inar fhoghlaim na guys conas an leagan freastalaí Dota 2 2014 a reáchtáil agus, dá réir sin, imirt air. Is lucht leanúna mór den chluiche seo mé, agus ní raibh mé in ann an deis uathúil seo a fháil chun mé féin a thumadh i m'óige.

Dordaigh mé go domhain, agus tharla sé mar sin gur scríobh mé bot Discord atá freagrach as beagnach gach feidhmiúlacht nach dtacaítear leis sa seanleagan den chluiche, eadhon cleamhnas.
Roimh na nuálaíochtaí go léir leis an bot, cruthaíodh an stocaireacht de láimh. Bhailíomar 10 bhfreagra ar theachtaireacht agus chuireamar freastalaí le chéile de láimh, nó rinneamar óstáil ar stocaireacht áitiúil.

Táimid ag scríobh matchmaking do Dota 2014

Níorbh fhéidir le mo nádúr mar ríomhchláraitheoir an oiread sin oibre láimhe a sheasamh, agus thar oíche sceitse mé amach an leagan is simplí den bot, rud a d'ardaigh an freastalaí go huathoibríoch nuair a bhí 10 duine ann.

Chinn mé láithreach scríobh i nódejs, mar ní maith liom Python i ndáiríre, agus mothaím níos compordaí sa timpeallacht seo.

Is é seo mo chéad taithí ag scríobh bot do Discord, ach d'éirigh sé amach a bheith an-simplí. Soláthraíonn an modúl npm oifigiúil discord.js comhéadan áisiúil chun oibriú le teachtaireachtaí, imoibrithe a bhailiú, etc.

Séanadh: Tá na samplaí cód go léir “reatha”, rud a chiallaíonn go bhfuil siad tar éis dul trí roinnt atriallta athscríobh istoíche.

Is é bunús na cleamhnais ná “scuaine” ina gcuirtear imreoirí atá ag iarraidh imirt isteach agus nuair nach mbíonn siad ag iarraidh cluiche a dhéanamh nó a aimsiú.

Seo mar a bhreathnaíonn croílár “imreoir”. I dtús báire ní raibh ann ach aitheantas úsáideora in Discord, ach tá pleananna ann cluichí a sheoladh / cuardach a dhéanamh ón suíomh, ach rudaí ar dtús.

export enum Realm {
  DISCORD,
  EXTERNAL,
}

export default class QueuePlayer {
  constructor(public readonly realm: Realm, public readonly id: string) {}

  public is(qp: QueuePlayer): boolean {
    return this.realm === qp.realm && this.id === qp.id;
  }

  static Discord(id: string) {
    return new QueuePlayer(Realm.DISCORD, id);
  }

  static External(id: string) {
    return new QueuePlayer(Realm.EXTERNAL, id);
  }
}

Agus seo é an comhéadan scuaine. Anseo, in ionad “imreoirí,” úsáidtear astarraingt i bhfoirm “grúpa”. I gcás imreoir amháin, is éard atá sa ghrúpa é féin, agus d'imreoirí i ngrúpa, faoi seach, na himreoirí go léir sa ghrúpa.

export default interface IQueue extends EventEmitter {
  inQueue: QueuePlayer[]
  put(uid: Party): boolean;
  remove(uid: Party): boolean;
  removeAll(ids: Party[]): void;

  mode: MatchmakingMode
  roomSize: number;
  clear(): void
}

Chinn mé imeachtaí a úsáid chun comhthéacs a mhalartú. Bhí sé oiriúnach do chásanna - ar an imeacht "fuarthas cluiche do 10 duine", is féidir leat an teachtaireacht riachtanach a sheoladh chuig na himreoirí i dteachtaireachtaí príobháideacha, agus an loighic bhunúsach gnó a dhéanamh - tasc a sheoladh chun ullmhacht a sheiceáil, ullmhaigh an stocaireacht. le haghaidh seoladh, agus mar sin de.

Le haghaidh IOC úsáidim InversifyJS. Tá taithí taitneamhach agam ag obair leis an leabharlann seo. Fast agus éasca!

Tá roinnt scuainí againn ar ár bhfreastalaí - tá 1 × 1, gnáth / rátáil, agus cúpla modh saincheaptha curtha leis againn. Dá bhrí sin, tá RoomService singleton suite idir an t-úsáideoir agus an cuardach cluiche.

constructor(
    @inject(GameServers) private gameServers: GameServers,
    @inject(MatchStatsService) private stats: MatchStatsService,
    @inject(PartyService) private partyService: PartyService
  ) {
    super();
    this.initQueue(MatchmakingMode.RANKED);
    this.initQueue(MatchmakingMode.UNRANKED);
    this.initQueue(MatchmakingMode.SOLOMID);
    this.initQueue(MatchmakingMode.DIRETIDE);
    this.initQueue(MatchmakingMode.GREEVILING);
    this.partyService.addListener(
      "party-update",
      (event: PartyUpdatedEvent) => {
        this.queues.forEach((q) => {
          if (has(q.queue, (t) => t.is(event.party))) {
            // if queue has this party, we re-add party
            this.leaveQueue(event.qp, q.mode)
            this.enterQueue(event.qp, q.mode)
          }
        });
      }
    );

    this.partyService.addListener(
      "party-removed",
      (event: PartyUpdatedEvent) => {
        this.queues.forEach((q) => {
          if (has(q.queue, (t) => t.is(event.party))) {
            // if queue has this party, we re-add party
            q.remove(event.party)
          }
        });
      }
    );
  }

(Cód núdail chun smaoineamh a thabhairt ar an chuma atá ar na próisis go garbh)

Anseo tosaigh mé an scuaine do gach ceann de na modhanna cluiche a cuireadh i bhfeidhm, agus freisin éisteacht le haghaidh athruithe i “grúpaí” chun na scuainí a choigeartú agus roinnt coinbhleachtaí a sheachaint.

Mar sin, go maith, chuir mé isteach píosaí de chód nach bhfuil aon bhaint acu leis an ábhar, agus anois a ligean ar bogadh ar aghaidh go díreach chuig cleamhnais.

Déanaimis an cás a mheas:

1) Ba mhaith leis an úsáideoir a imirt.

2) Chun an cuardach a thosú, úsáideann sé Gateway=Discord, is é sin, freagraíonn sé an teachtaireacht:

Táimid ag scríobh matchmaking do Dota 2014

3) Téann an geata seo chuig RoomService agus deir “Tá úsáideoir ó easaontas ag iarraidh dul isteach sa scuaine, mód: cluiche gan rátáil.”

4) Glacann RoomService iarratas an gheata agus brú ar an úsáideoir (níos cruinne, an grúpa úsáideoirí) isteach sa scuaine atá ag teastáil.

5) Seiceálann an scuaine gach uair a bhíonn go leor imreoirí le himirt. Más féidir, scaoil imeacht:

private onRoomFound(players: Party[]) {
    this.emit("room-found", {
      players,
    });
  }

6) Is léir go bhfuil RoomService sásta éisteacht le gach scuaine in oirchill imníoch don imeacht seo. Faighimid liosta imreoirí mar ionchur, cruthaítear “seomra” fíorúil uathu, agus, ar ndóigh, eisimid imeacht:

queue.addListener("room-found", (event: RoomFoundEvent) => {
      console.log(
        `Room found mode: [${mode}]. Time to get free room for these guys`
      );
      const room = this.getFreeRoom(mode);
      room.fill(event.players);

      this.onRoomFormed(room);
    });

7) Mar sin shroicheamar an t-údarás “is airde” - an rang Bot. Go ginearálta, déileálann sé leis an gceangal idir geataí (ní féidir liom a thuiscint cé chomh greannmhar is atá sé i Rúisis) agus loighic ghnó na cleamhnais. Éisteann an bot leis an imeacht agus ordaíonn sé do DiscordGateway seiceáil ullmhachta a sheoladh chuig gach úsáideoir.

Táimid ag scríobh matchmaking do Dota 2014

8) Má dhiúltaíonn nó má dhiúltaíonn duine an cluiche laistigh de 3 nóiméad, ansin NÁ muid ar ais go dtí an scuaine iad. Fillimid gach duine eile sa scuaine agus fanaimid go dtí go mbeidh 10 nduine ann arís. Má ghlac na himreoirí go léir leis an gcluiche, tosaíonn an chuid suimiúil.

Cumraíocht fhreastalaí tiomnaithe

Déantar ár gcluichí a óstáil ar VDS le freastalaí Windows 2012. As seo is féidir linn roinnt conclúidí a tharraingt:

  1. Níl aon docker air, a bhuail mé sa chroí
  2. Sábhálann muid ar chíos

Is é an tasc ná próiseas a reáchtáil ar VDS ó VPS ar Linux. Scríobh mé freastalaí simplí i bhFleascán. Sea, ní maith liom Python, ach cad is féidir liom a dhéanamh? Tá sé níos tapúla agus níos éasca an freastalaí seo a scríobh air.

Comhlíonann sé 3 fheidhm:

  1. Freastalaí a thosú le cumraíocht - roghnú léarscáil, líon na n-imreoirí chun an cluiche a thosú, agus sraith breiseán. Ní scríobhfaidh mé faoi bhreiseáin anois - sin scéal difriúil le lítear caife san oíche measctha le deora agus gruaig stróicthe.
  2. An freastalaí a stopadh/atosú i gcás naisc nár éirigh leo, nach féidir linn a láimhseáil ach de láimh.

Tá gach rud simplí anseo, níl samplaí cód oiriúnach fiú. Script 100 líne

Mar sin, nuair a tháinig 10 duine le chéile agus ghlac siad leis an gcluiche, seoladh an freastalaí agus bhí gach duine fonn a imirt, cuireadh nasc chun ceangal leis an gcluiche i dteachtaireachtaí príobháideacha.

Táimid ag scríobh matchmaking do Dota 2014

Trí chliceáil ar an nasc, nascann an t-imreoir leis an bhfreastalaí cluiche, agus ansin sin é. Tar éis ~25 nóiméad, glantar an “seomra” fíorúil le himreoirí.

Gabhaim mo leithscéal roimh ré as awkwardness an ailt, níl mé scríofa anseo le fada an lá, agus tá an iomarca cód chun aird a tharraingt ar ailt tábhachtacha. Núdail, i mbeagán focal.

Má fheiceann mé spéis san ábhar, beidh an dara cuid - beidh mo chrá ann le forlíontáin do srcds (freastalaí tiomnaithe Foinse), agus, is dócha, córas rátála agus mion-dotabuff, suíomh le staitisticí cluiche.

Roinnt nasc:

  1. Ár suíomh Gréasáin (staitisticí, clár ceannairí, leathanach tuirlingthe beag agus íoslódáil cliant)
  2. Freastalaí discord

Foinse: will.com

Add a comment