Megapack: Kiel Factorio Solvis la 200-Ludantan Plurludantan Problemon

Megapack: Kiel Factorio Solvis la 200-Ludantan Plurludantan Problemon
En majo de ĉi tiu jaro mi partoprenis kiel ludanto en MMO-okazaĵoj KatherineOfSky. Mi rimarkis, ke kiam la nombro da ludantoj atingas certan nombron, ĉiujn kelkajn minutojn iuj el ili "falas". Feliĉe por vi (sed ne por mi), mi estis unu el tiuj ludantoj, kiuj malkonektis ĉiufoje, eĉ kun bona konekto. Mi prenis ĉi tion kiel personan defion kaj komencis serĉi la kaŭzojn de la problemo. Post tri semajnoj da sencimigo, testado kaj korektado, la cimo estis finfine riparita, sed la vojaĝo ne estis tiom facila.

Problemoj kun plurludantaj ludoj estas tre malfacile spureblaj. Ili kutime okazas sub tre specifaj retaj parametroj kaj tre specifaj ludkondiĉoj (en ĉi tiu kazo, havante pli ol 200 ludantojn). Kaj eĉ kiam la problemo povas esti reproduktita, ĝi ne povas esti konvene elpurigita ĉar enmetado de rompopunktoj haltigas la ludon, konfuzas tempigilojn, kaj kutime kaŭzas la konekton al tempo. Sed danke al persisto kaj mirinda ilo nomita mallerta Mi sukcesis ekscii, kio okazas.

Mallonge, pro cimo kaj nekompleta efektivigo de la latenteca statosimulado, la kliento foje troviĝus en situacio kie ĝi devis sendi retpakaĵeton konsistantan el la eniga elektagado de la ludanto de proksimume 400 ludunuoj en unu horloĝciklo ( ni nomas tion "mega-pako"). La servilo tiam devas ne nur ricevi ĉiujn ĉi tiujn enigajn agojn ĝuste, sed ankaŭ sendi ilin al ĉiuj aliaj klientoj. Se vi havas 200 klientojn, ĉi tio rapide fariĝas problemo. La ligo al la servilo rapide ŝtopiĝas, kaŭzante pakaĵetperdon kaj kaskadon de repetitaj pakaĵetoj. Prokrasti la enig-ago tiam igas eĉ pli da klientoj sendi megapakaĵojn, igante la lavangon iĝi eĉ pli granda. Bonŝancaj klientoj sukcesas resaniĝi; ĉiuj aliaj defalas.

Megapack: Kiel Factorio Solvis la 200-Ludantan Plurludantan Problemon
La problemo estis sufiĉe fundamenta kaj mi prenis 2 semajnojn por ripari ĝin. Ĝi estas sufiĉe teknika, do mi klarigos la sukajn teknikajn detalojn sube. Sed unue, vi devas scii, ke ekde la versio 0.17.54, publikigita la 4-an de junio, antaŭ provizoraj konektoproblemoj, plurludanto fariĝis pli stabila, kaj kaŝi prokrastojn fariĝis multe malpli fuŝa (malpli malrapidiĝo kaj teleportado). Mi ankaŭ ŝanĝis la manieron kiel batalmalfruo estas kaŝita kaj mi esperas, ke ĉi tio faros ĝin iom pli glata.

Multiplayer Mega Pack - Teknikaj Detaloj

Simple, plurludanta en ludo funkcias tiel: ĉiuj klientoj simulas la staton de la ludo, ricevante kaj sendante nur ludanto-enigo (nomita "eniga agoj", Enigo-Agoj). La ĉefa tasko de la servilo estas transdoni Enigo-Agoj kaj kontroli ke ĉiuj klientoj plenumas la samajn agojn en la sama horloĝa ciklo. Vi povas legi pli pri tio en la afiŝo FFF-149.

Ĉar la servilo devas fari decidojn pri kiaj agoj fari, la agoj de la ludanto moviĝas proksimume laŭ tiu ĉi vojo: ludanta ago -> ludkliento -> reto -> servilo -> reto -> ludkliento. Ĉi tio signifas, ke la ago de ĉiu ludanto estas farita nur post rondveturo tra la reto. Pro tio, la ludo ŝajnus terure malrapida, do preskaŭ tuj post la enkonduko de multiludanto en la ludo, mekanismo estis lanĉita por kaŝi prokrastojn. Kaŝi prokraston simulas ludantan enigon sen konsideri la agojn de aliaj ludantoj kaj la decidojn de la servilo.

Megapack: Kiel Factorio Solvis la 200-Ludantan Plurludantan Problemon
Factorio havas ludstato Ludo Ŝtato estas la kompleta stato de la karto, ludanto, estaĵoj kaj ĉio alia. Ĝi estas determinisme simulita en ĉiuj klientoj surbaze de la agoj ricevitaj de la servilo. Ludstato estas sankta, kaj se ĝi iam komencas diferenci de la servilo aŭ iu ajn alia kliento, tiam malsinkroniĝo okazas.

krom Ludo Ŝtato ni havas staton de prokrastoj Latenta ŝtato. Ĝi enhavas malgrandan subaron de la bazstato. Latenta ŝtato ne sankta kaj simple reprezentas bildon de kia aspektos la ludstato estonte surbaze de ludantenigaĵoj Enigo-Agoj.

Tiucele ni konservas kopion de la kreita Enigo-Agoj en la prokrastvico.

Megapack: Kiel Factorio Solvis la 200-Ludantan Plurludantan Problemon
Tio estas, ĉe la fino de la procezo ĉe la klienta flanko, la bildo aspektas kiel ĉi tio:

  1. Ni aplikas Enigo-Agoj ĉiuj ludantoj al Ludo Ŝtato la maniero kiel tiuj enigagoj estis ricevitaj de la servilo.
  2. Ni forigas ĉion el la prokrasta vico Enigo-Agoj, al kiuj, laŭ la servilo, jam estis aplikitaj Ludo Ŝtato.
  3. Forigi Latenta ŝtato kaj restarigi ĝin, por ke ĝi aspektu ĝuste same kiel Ludo Ŝtato.
  4. Ni aplikas ĉiujn agojn de la prokrasta vico al Latenta ŝtato.
  5. Surbaze de datumoj Ludo Ŝtato и Latenta ŝtato Ni transdonas la ludon al la ludanto.

Ĉio ĉi estas ripetita en ĉiu mezuro.

Tro malfacila? Ne malstreĉu, ĉi tio ne estas ĉio. Por kompensi por nefidindaj interretaj konektoj, ni kreis du mekanismojn:

  • Perditaj tiktakoj: kiam la servilo decidas tion Enigo-Agoj estos ekzekutita ĉe la takto de la ludo, tiam se li ne ricevis Enigo-Agoj iu ludanto (ekzemple, pro pliigita prokrasto), li ne atendos, sed informos ĉi tiun klienton "Mi ne konsideris vian Enigo-Agoj, mi provos aldoni ilin en la sekva trinkejo." Ĉi tio estas farita por ke pro problemoj kun la konekto (aŭ komputilo) de unu ludanto, la mapĝisdatigo ne malrapidiĝas por ĉiuj aliaj. Indas rimarki tion Enigo-Agoj ne estas ignorataj, sed simple flankenlasitaj.
  • Plena revena latenco: La servilo provas diveni, kia estas la rondira latenco inter la kliento kaj servilo por ĉiu kliento. Ĉiujn 5 sekundojn, ĝi negocas novan latentecon kun la kliento se necese (surbaze de kiel la konekto kondutis en la pasinteco), kaj pliigas aŭ malpliigas la rondveturan latentecon laŭe.

En si mem, ĉi tiuj mekanismoj estas sufiĉe simplaj, sed kiam ili estas uzataj kune (kio ofte okazas kun konektproblemoj), la logiko de la kodo fariĝas malfacile administrebla kaj kun multaj randkazoj. Plie, kiam ĉi tiuj mekanismoj eniras en ludon, la servilo kaj prokrasta vico devas konvene efektivigi la specialaĵon Eniga Ago sub la nomo StopMovementInTheNextTick. Dank' al ĉi tio, se estas problemoj kun la konekto, la rolulo ne kuros memstare (ekzemple antaŭ trajno).

Nun ni devas klarigi al vi kiel funkcias elekto de entoj. Unu el la transdonitaj tipoj Eniga Ago estas ŝanĝo en la enta elekta stato. Ĝi rakontas al ĉiuj, kiun unuon la ludanto ŝvebas. Kiel vi povas imagi, ĉi tiu estas unu el la plej oftaj enigo-agoj senditaj de klientoj, do por ŝpari bendolarĝon, ni optimumigis ĝin por okupi kiel eble plej malmulte da spaco. La maniero kiel ĝi funkcias estas ke ĉar ĉiu ento estas elektita, anstataŭ stoki absolutajn, altprecizajn mapkoordinatojn, la ludo stokas malalt-precizecan relativan ofseton de la antaŭa elekto. Ĉi tio funkcias bone ĉar muselektoj tendencas esti tre proksimaj al la antaŭa elekto. Ĉi tio levas du gravajn postulojn: Enigo-Agoj Ili neniam devus esti preterlasitaj kaj devas esti kompletigitaj en la ĝusta ordo. Ĉi tiuj postuloj estas plenumitaj por Ludo Ŝtato. Sed ekde la tasko Latencia stato en "aspekti sufiĉe bona" ​​por la ludanto, ili ne estas kontentaj en la prokrasta stato. Latenta ŝtato ne konsideras multaj randkazoj, asociita kun transsaltado de horloĝcikloj kaj ŝanĝado de rondveturaj dissendoprokrastoj.

Vi jam povas diveni kien ĉi tio iras. Ni finfine komencas vidi la kialojn de la megapack-problemo. La radiko de la problemo estas, ke la enta elekta logiko dependas Latenta ŝtato, kaj ĉi tiu stato ne ĉiam enhavas la ĝustajn informojn. Tial, megapako estas generita io kiel ĉi tio:

  1. La ludanto havas problemojn pri konekto.
  2. Mekanismoj por transsalti horloĝajn ciklojn kaj reguligi la prokraston de rondvetura dissendo eniras.
  3. La prokrasta statovico ne enkalkulas tiujn mekanismojn. Ĉi tio kaŭzas kelkajn agojn esti forigitaj trofrue aŭ faritaj en malĝusta sinsekvo, rezultigante malĝustan Latenta ŝtato.
  4. La ludanto havas konektan problemon kaj, por atingi la servilon, simulas ĝis 400 ciklojn.
  5. Ĉe ĉiu tiktako, nova ago, ŝanĝanta la entan elekton, estas generita kaj preta por sendi al la servilo.
  6. La kliento sendas mega-aron de 400+ entaj elektoŝanĝoj al la servilo (kaj kun aliaj agoj: pafado-ŝtatoj, marŝantaj ŝtatoj, ktp ankaŭ suferis ĉi tiun problemon).
  7. La servilo ricevas 400 enigajn agojn. Ĉar ĝi ne rajtas preterlasi iujn ajn enigajn agojn, ĝi ordonas al ĉiuj klientoj plenumi tiujn agojn kaj sendas ilin tra la reto.

La ironio estas, ke mekanismo desegnita por ŝpari bendolarĝon finis kreante grandegajn retajn pakaĵojn.

Ni traktis ĉi tiun problemon riparante ĉiujn randajn kazojn de ĝisdatigo kaj restaŭdovicsubteno. Kvankam ĝi bezonis sufiĉe da tempo, finfine valoris ĝustigi ĝin prefere ol fidi je rapidaj hakoj.

fonto: www.habr.com

Aldoni komenton