
KĂ€esoleva aasta mail osalesin mĂ€ngijana . MĂ€rkasin, et kui mĂ€ngijate arv jĂ”uab teatud numbrini, viskab osa neist igal paaril minutil mĂ€ngust vĂ€lja. Teie rÔÔmuks (aga mitte minu jaoks) olin mina ĂŒks neist mĂ€ngijatest, kes igakord "kukkus vĂ€lja" igal korral, isegi hea ĂŒhenduse olemasolul. VĂ”tsin seda isikliku vĂ€ljakutsena ja hakkasin probleemi pĂ”hjuseid uurima. Kolme nĂ€dala debugimise, testimise ja parandamise jĂ€rel saime lĂ”puks vea kĂ”rvaldada, kuid see reis ei olnud sugugi lihtne.
MitmikmĂ€ngu probleemide jĂ€lgimine on vĂ€ga keeruline. Need tekivad tavaliselt vĂ€ga spetsiifilistes vĂ”rguparametrites ja mĂ€ngu spetsiifilistes olukordades (antud juhul â ĂŒle 200 mĂ€ngija olemasolul). Ja isegi kui probleemi suudetakse replikeerida, on selle nĂ”uetekohane debugeerimine peaaegu vĂ”imatu, kuna kontrollpunktide lisamine peatab mĂ€ngu, segab taimerid ja pĂ”hjustab tavaliselt ĂŒhenduse katkemise, kuna ooteaeg on ĂŒletatud. Kuid tĂ€nu visadusele ja suurepĂ€rasele tööriistale nimega suutsin vĂ€lja selgitada, mis juhtub.
LĂŒhidalt: vea ja semi-funktsionaalse viivituse simulatsiooni rakendamise tĂ”ttu sattus klient mĂ”nikord olukorda, kus pidi ĂŒhe kĂ€iguga saatma vĂ”rku paketi, mis koosnes mĂ€ngija valitud umbes 400 mĂ€ngujuhtimisest (me nimetame seda "megapakettideks"). PĂ€rast seda peab server Ă”igesti vastu vĂ”tma kĂ”ik need sisenditegevused ja saatma need kĂ”igile teistele klientidele. Kui sul on 200 klienti, muutub see kiiresti probleemiks. Serveri kanal kipub kiiresti ummistuma, mis toob kaasa pakettide kaotuse ja uuesti nĂ”utud paketide kaskaadi. Sisenditegevuste viivitamine toob seejĂ€rel kaasa rohkemate klientide saatmise megapakettidena, ja nende laviin muutub veelgi tugevamaks. Ănnelikud kliendid suudavad taastuda, kĂ”ik teised "kukuvad vĂ€lja".

Probleem oli piisavalt pĂ”hjalik ning selle lahendamine vĂ”ttis mul kaks nĂ€dalat. See on ĂŒsna tehniline, seega selgitan allpool ĂŒksikasjalikult. Kuid kĂ”igepealt peate teadma, et alates versioonist 0.17.54, mis ilmus 4. juunil, on mitmikmĂ€ngu ĂŒhendus problemaatilisemates tingimustes palju stabiilsem ja viivituste varjamine on oluliselt sujuvam (vĂ€hem viivitusi ja teleportimist). Lisaks muudab ma viivituste varjamise meetodit lahingus ja loodan, et see teeb need veidi sujuvamaks.
MitmikmĂ€ngu megapakett - tehnilised ĂŒksikasjad
Lihtsalt öeldes töötab mĂ€ngus mitmikmĂ€ng jĂ€rgmiselt: kĂ”ik kliendid simuleerivad mĂ€ngu seisundit, saades ja edastades ainult mĂ€ngija sisendeid (nimetatakse "sisendite tegevusteks", Input Actions). Peamine ĂŒlesanne serveri puhul on edastada Input Actions ja kontrollida, et kĂ”ik kliendid teevad sama tegevust ĂŒhes voorus. Selle kohta saab rohkem lugeda postitusest .
Kuna server peab langetama otsuseid, milliseid tegevusi lÀbi viia, liigub mÀngija tegevus umbes sellist teed: mÀngija tegevus -> mÀngikliendi -> vÔrk -> server -> vÔrk -> mÀngikliendi. See tÀhendab, et iga mÀngija tegevus toimub alles pÀrast seda, kui see on vÔrgus edasi-tagasi rÀndanud. Selle tÔttu nÀiks mÀng hirmsasti viivitav, seega peaaegu kohe pÀrast mitmikmÀngu ilmumist mÀngu, kasutusele viidud viivituste varjamise mehhanism. Viivituste varjamine imiteerib mÀngija sisendit, ignoreerides teiste mÀngijate tegevusi ja serveri otsuseid.

Factorios on mĂ€ngu olek Game State â see on kaardi, mĂ€ngija, olendite ja muu tĂ€ielik olek. Seda simuleeritakse kĂ”ikides klientides deterministlikult serverilt saadud tegevuste pĂ”hjal. MĂ€ngu olek on pĂŒha ja kui see kunagi serverist vĂ”i mĂ”nest teisest kliendist erineb, tekib desĂŒnkroniseerimine.
Lisaks Game State on meil viivituste olek Latency State. See sisaldab vĂ€ikest alamosade kogumit pĂ”hiolukorrast. Latency State see ei ole pĂŒha ja lihtsalt kujutab ette, milline mĂ€ngu seisund tulevikus vĂ€lja nĂ€eb mĂ€ngija sisendi pĂ”hjal. Input Actions.
Selleks hoiame me jÀrjekorras toodetud Input Actions viivituste koopiat.

Seega, protsessi lÔpus nÀeb kliendi pool vÀlja umbes nii:
- Rakendame Input Actions kÔiki mÀngijaid Game State niimoodi, nagu need sisestamise toimingud on serverilt saadud.
- Kustutame viivituste jÀrjekorrast kÔik Input Actions, mis, serveri andmete kohaselt, on juba rakendatud Game State.
- Kustutame Latency State ja lÀhtestame selle, et see nÀeks vÀlja tÀpselt nagu Game State.
- Rakendame kÔik viivituste jÀrjekorra toimingud Latency State.
- Serveri andmete pÔhjal Game State ja Latency State kujundame mÀngu mÀngijale.
Kogu see protsess kordub igas taktis.
Liiga keeruline? Ărge muretsege, see ei ole veel kĂ”ik. InternetiĂŒhenduse ebastabiilsuse kompenseerimiseks oleme loonud kaks mehhanismi:
- Puuduvad taktid: kui server otsustab, et Input Actions tuleb teostada mĂ€ngu taktis, kuid ei ole saanud Input Actions mĂ”nelt mĂ€ngijalt (nĂ€iteks suurenenud viivituse tĂ”ttu), siis ei oota ta, vaid teatab sellele kliendile "ma ei arvestanud sinu Input Actions, pĂŒĂŒan need jĂ€rgmises taktis lisada". See on tehtud selleks, et ĂŒhe mĂ€ngija (vĂ”i arvuti) ĂŒhenduse probleemide tĂ”ttu ei aeglustuks kaardi uuendamine kĂ”igi teiste jaoks. Tuleb mĂ€rkida, et Input Actions ei ignoreerita, vaid lihtsalt lĂŒkatakse edasi.
- TĂ€ieliku edasi-tagasi viivituse mÔÔtmine: server pĂŒĂŒab oletada, milline on andmeedastuse viivitus edasi-tagasi kliendi ja serveri vahel iga kliendi jaoks. Iga 5 sekundi jĂ€rel arutab ta vajadusel kliendiga uut viivitust (sĂ”ltuvalt ĂŒhenduse kĂ€itumisest minevikus) ning vastavalt suurendab vĂ”i vĂ€hendab edasi-tagasi andmeedastuse viivitust.
Need mehhanismid on enesest ĂŒsna lihtsad, kuid kui neid kasutatakse koos (mis juhtub sageli ĂŒhendusprobleemide korral), muutub koodi loogika keeruliseks ja sisaldab palju ÀÀrmuslikke juhtumeid. Lisaks, kui need mehhanismid on mĂ€ngus, peavad server ja viivituste jĂ€rjekord Ă”igesti rakendama erilist Sisendi tegevus nimega Peata jĂ€rgmises taktis liikumine. TĂ€nu sellele ei hakka ĂŒhenduse probleemide korral karakter ise liikuma (nĂ€iteks rongi alla).
NĂŒĂŒd on vaja teile selgitada, kuidas toimub olendite valik. Ăks ĂŒlekantud tĂŒĂŒpidest Sisendi tegevus â see olekse juriit tühenduse muutmine. See teavitab kĂ”iki, millele mĂ€ngija hiirega osutab. Nagu aru saada, on see ĂŒks kĂ”ige sagedasemaid sisestuste toiminguid, mida kliendid saadavad, seega oleme selle kanalivĂ”imsuse sÀÀstmiseks optimeerinud, et see vĂ”taks vĂ”imalikult vĂ€he ruumi. See on ellu viidud nii: iga olendi valimise korral, mitte absoluutsete, tĂ€psete kaardikoordinaatide salvestamise asemel, salvestab mĂ€ng suhteliselt madala tĂ€psusega nihke eelmisest valikust. See töötab hĂ€sti, kuna hiirega valimine toimub tavaliselt eelmisest valikust vĂ€ga lĂ€hedal. Sellega kaasnevad kaks olulist nĂ”uet: Input Actions kunagi ei tohi vahele jĂ€tta ja tuleb jĂ€rgida Ă”iget jĂ€rjestust. Need nĂ”uded tĂ€idetakse Game State. Kuid kuna ĂŒlesanne Latency state on "nĂ€ha piisavalt hea" mĂ€ngija jaoks, ei tĂ€ideta neid viivitusolukordades. Latency State ei arvesta , mis on seotud tsĂŒklite vahelejĂ€tmise ja edasi-tagasi edastusviivituste muutumisega.
Sa vÔid juba aimata, kuhu see kÔik viib. LÔpuks hakkame nÀgema probleemide megapaketi pÔhjusi. Probleemi juur peitub selles, et otsuse tegemisel, kas edastada valiku muutuse toiming, tugineb loogika olendite valikule Latency State, ja see olek ei sisalda alati Ôiget teavet. SeetÔttu genereeritakse megapakett ligikaudu nii:
- MĂ€ngijal on ĂŒhenduse probleem.
- Seonduvad mehhanismid tükkide vahelejĂ€tmise ja edasi-tagasi edastusviivituse reguleerimise osas sekkuvad.
- Viivituste olekute rida ei arvesta neid mehhanisme. See toob kaasa selle, et mÔned toimingud eemaldatakse liiga vara vÔi teostatakse vale jÀrjekorras, mis viib vale Latency State.
- MĂ€ngijal on ĂŒhenduse probleem ja ta simuleerib serveriga sündmuste jälgimiseks kuni 400 tsĂŒklit.
- Igas tsĂŒklis genereeritakse ja valmistatakse ette uus olendi valiku muutmise toiming serverile edastamiseks.
- Klient saadab serverile megapaketi, mis koosneb ĂŒle 400 olendi valiku muutmisest (ja teiste toimingutega: tulistamis, kĂ”ndimine jne; see probleem mõjutas ka neid).
- Server saab 400 sisendtoimet. Kuna tal ei ole lubatud ĂŒhtegi sisendtoimet vahele jĂ€tta, kĂ€sib ta kĂ”igil klientidel need toimeted tĂ€ita ja edastab need ĂŒle vĂ”rgu.
Ironia seisneb selles, et mehhanism, mis oli mÔeldud kanalite sademe kokkuhoidmiseks, tekitas lÔpuks tohutuid vÔrgu pakette.
Lahendasime selle probleemi, parendades kĂ”ik ÀÀretaparisugused uuendamise ja jĂ€rjekorra toetamise juhtumid. Kuigi see vĂ”ttis ĂŒsna kaua aega, tasus see end Ă€ra, et kĂ”ik Ă”igesti ellu viia, mitte toetuda kiiretele lahendustele.
Allikas: habr.com
