
Sel aasta mais osalesin mĂ€ngijana . MĂ€rkasin, et kui mĂ€ngijate arv jĂ”uab teatud piirini, katkeb osa neist iga paari minuti tagant. Ănneks teie jaoks (kuid mitte minu jaoks) olin ma ĂŒks nendest mĂ€ngijatest, kes katkestas igal korral, isegi hea ĂŒhenduse korral. VĂ”tsin seda kui isiklikku vĂ€ljakutset ja hakkasin otsima probleemi pĂ”hjuseid. PĂ€rast kolme nĂ€dala pikkust tĂ”rkeotsingut, testimist ja parandusi suudeti viga lĂ”puks kĂ”rvaldada, kuid see teekond polnud sugugi lihtne.
Mitme mĂ€ngija mĂ€ngude probleemide jĂ€lgimine on vĂ€ga keeruline. Need tekivad tavaliselt vĂ€ga spetsiifiliste vĂ”rguparameetrite ja mĂ€ngu konkreetsete tingimuste korral (antud juhul - ĂŒle 200 mĂ€ngija olemasolu). Isegi kui probleemi Ă”nnestub korrata, ei saa seda korralikult siluda, kuna kontrollpunktide sisestamine peatab mĂ€ngu, segab ajastust ja viib tavaliselt ĂŒhenduse katkestamiseni ajapiirangute tĂ”ttu. Kuid tĂ€nu visadusele ja suurepĂ€rasele tööriistale nimega Ă”nnestus mul vĂ€lja selgitada, mis toimub.
KokkuvĂ”ttes: simuleerimise viivituste viga ja mittetĂ€ielik rakendamine pĂ”hjustas olukorra, kus klient pidi mĂ”nikord ĂŒhes tsĂŒklis saatma vĂ”rku paketi, mis sisaldas umbes 400 mĂ€nguobjekti tegevust (me nimetame seda âmegapakendiksâ). PĂ€rast seda peab server mitte ainult kĂ”iki neid sisendi tegevusi Ă”igesti vastu vĂ”tma, vaid ka need kĂ”igile teistele klientidele edastama. Kui sul on 200 klienti, muutub see kiiresti probleemiks. Serverikanal tĂ€itub kiiresti, mis viib pakettide kadumiseni ja nĂ”utud pakettide kaskaadi. Sisendi viivitamine toob kaasa veelgi rohkem kliente, kes hakkavad megapakette saatma, ja nende laviin suureneb veelgi. Ănnelikud kliendid suudavad taastuda, kĂ”ik teised aga âlangevad vĂ€ljaâ.

Probleem oli piisavalt fundamentaalne ja selle lahendamine vĂ”ttis mul kaks nĂ€dalat. See on ĂŒsna tehniline, seetĂ”ttu selgitan allpool mĂ”ned olulisemad tehnilised ĂŒksikasjad. Kuid esmalt peate teadma, et alates versioonist 0.17.54, mis ilmus 4. juunil, on vĂ”rguĂŒhenduse probleemide korral mitmikmĂ€ngu stabiilsus paranenud ning viivituste varjamine on palju vĂ€hem hĂ€iriv (vĂ€hem tĂ”rkeid ja teleportimist). Lisaks olen muutnud viivituste varjamise meetodit lahingus ning loodan, et need on seelĂ€bi natuke sujuvamad.
MitmikmĂ€ngu megapakett â tehnilised ĂŒksikasjad
Lihtsalt seletades töötab mĂ€ngus mitmikmĂ€ng jĂ€rgmiselt: kĂ”ik kliendid simuleerivad mĂ€ngu seisundit, saates ja vastu vĂ”ttes ainult mĂ€ngija sisendeid (mida nimetatakse 'sisendtoiminguteks', Input Actions). Serveri peamine ĂŒlesanne on tagada Input Actions ja kontrollida, et kĂ”ik kliendid teevad ĂŒhes taktis samu toiminguid. Selle kohta saate rohkem lugeda postitusest .
Kuna server peab otsustama, milliseid toiminguid teha, liiguvad mĂ€ngija tegevused ligikaudu jĂ€rgmise tee kaudu: mĂ€ngija tegevus -> mĂ€nguklient -> vĂ”rk -> server -> vĂ”rk -> mĂ€nguklient. See tĂ€hendab, et iga mĂ€ngija tegevus tĂ€idetakse alles pĂ€rast seda, kui see on teinud edas-tagasi tee ĂŒle vĂ”rgu. SeetĂ”ttu nĂ€eks mĂ€ng vĂ€lja ÀÀrmiselt aeglane, mistĂ”ttu peaaegu kohe pĂ€rast mitmikmĂ€ngu ilmumist mĂ€ngus tutvustati latentsuse varjestamise mehhanismi. Latentsuse varjestamine simuleerib mĂ€ngija sisendit, arvestamata teiste mĂ€ngijate tegevusi ja serveri otsuseid.

Factorios on mĂ€ngu olek MĂ€ngu olek â see on tĂ€ielik kaardi, mĂ€ngija, ĂŒksuste ja kĂ”ige muu seisund. Seda simuleeritakse mÀÀratult kĂ”igis klientides serverilt saadud tegevuste pĂ”hjal. MĂ€ngu olek on pĂŒha, ja kui see kunagi hakkab eristuma serverist vĂ”i mĂ”nest muust kliendist, tekib desĂŒnkroonsus.
Lisaks MĂ€ngu olek meil on latentsuse olek Latentsuse olek. See sisaldab vĂ€ikest alamhulka pĂ”hiseisundist. Latentsuse olek ei ole pĂŒha ja lihtsalt kujutab ette, milline on mĂ€ngu seis tulevikus, pĂ”hinedes mĂ€ngija sisestatud andmetele Input Actions.
Selleks salvestame koostatud koopiat Input Actions viivituste jÀrjekorras.

Ehkki lÔppprotsess kliendi poole nÀeb vÀlja umbes nii:
- Kasutame Input Actions kÔigi mÀngijate jaoks MÀngu olek niimoodi, nagu need sisestusteaded serverilt saadi.
- Kustutame kÔik jÀrjekorrast viivitused Input Actions, mis serveri andmetel on juba rakendatud MÀngu olek.
- Kustutame Latentsuse olek ja lÀhtestame selle, et see nÀeks vÀlja just selline, nagu MÀngu olek.
- Rakendame kÔik tegevused viivituste jÀrjekorrast Latentsuse olek.
- PÔhinedes andmetele MÀngu olek ja Latentsuse olek renderdame mÀngu mÀngijale.
KÔike seda korratakse igas taktis.
Liialt keeruline? Ărge muretsege, see ei ole veel kĂ”ik. Interneti-ĂŒhenduste ebaregulaarsete omaduste kompenseerimiseks oleme loonud kaks mehhanismi:
- VahelejĂ€tetud taktide puhul: kui server otsustab, et Input Actions teostatakse mĂ€ngu takt, siis kui ta ei saanud Input Actions mingi mĂ€ngija andmeid (nĂ€iteks suurenenud viivituse tĂ”ttu), siis ta ei oota, vaid teatab sellele kliendile: "ma ei arvestanud sinu Input Actions, pĂŒĂŒan need jĂ€rgmistesse takti lisada." See on tehtud selleks, et ĂŒhe mĂ€ngija ĂŒhenduse (vĂ”i arvuti) probleemide tĂ”ttu ei aeglustuks kaardi uuendamine kĂ”igi teiste jaoks. Tasub mĂ€rkida, et Input Actions ei ignoreerita, vaid lihtsalt lĂŒkatakse edasi.
- Ăksuse tagasipöördumise latentsus: server pĂŒĂŒab arvata, milline on andmete tagasisaatmise latentsus kliendi ja serveri vahel iga kliendi jaoks. Iga 5 sekundi jĂ€rel arutab ta vajadusel kliendiga uut latentsust (sĂ”ltuvalt sellest, kuidas ĂŒhendus on minevikus kĂ€itunud) ning vastavalt suurendab vĂ”i vĂ€hendab tagasisaatmise latentsust.
Need mehhanismid iseenesest on ĂŒsna lihtsad, kuid kui nad töötavad koos (mis sageli juhtub ĂŒhenduse probleemide korral), muutub koodi loogika keeruliseks ja tĂ€is piirjuhtumeid. Lisaks, kui need mehhanismid peavad sekkuma, peavad server ja viivituste jĂ€rjekord Ă”igesti rakendama erilist Sisendi tegevus nimetusega StopMovementInTheNextTick. TĂ€nu sellele, kui esinevad ĂŒhenduse probleemid, ei jookse tegelane iseenesest (nĂ€iteks rongi alla).
NĂŒĂŒd on vaja selgitada, kuidas olendite valimine töötab. Ăks edastatavatest tĂŒĂŒpidest Sisendi tegevus on olendi valimise oleku muutmine. See teatab kĂ”igile, millisele olendile mĂ€ngija hiirekursor osutab. Nagu vĂ”ib aru saada, on see ĂŒks kĂ”ige sagedasemaid sisendite tehinguid, mida kliendid saadavad, seega oleme selle kanali ribalaiuse kokkuhoiu huvides optimeerinud, et see tooks nii vĂ€he ruumi kui vĂ”imalik. See on rakendatud nii, et iga olendi valimisel ei salvestata mitte absoluutse, tĂ€psete kaardikoordinaate, vaid salvestatakse madal tĂ€psuseline suhteline nihke eelnevast valikust. See toimib hĂ€sti, kuna hiirega valimine toimub tavaliselt vĂ€ga lĂ€hedal varasemale valikule. Selle tĂ”ttu on kaks olulist nĂ”uet: Input Actions kunagi ei tohi vahele jĂ€tta ja neid tuleb tĂ€ita Ă”iges jĂ€rjekorras. Need nĂ”uded on tĂ€idetud MĂ€ngu olek. Kuid kuna ĂŒlesanne Latency state on nĂ€ha vĂ€lja piisavalt hea mĂ€ngijale, siis viivituste ajal ei ole need tĂ€idetud. Latentsuse olek ei vĂ”ta arvesse , mis on seotud vahejuhtumite ja edasi-tagasi edastusviivitustega.
Sa vÔiksid juba aimata, kuhu see kÔik viib. LÔfinally me hakkame nÀgema megapaketi probleemide pÔhjuseid. Probleemi juured seisnevad selles, et otsustamisel, kas edastada valiku muutmise tegu, tugineb olendi valimise loogika Latentsuse olek, kuid see seisund ei sisalda alati Ôiget teavet. SeetÔttu genereeritakse megapakett umbes nii:
- MĂ€ngijal on ĂŒhenduse probleemid.
- Kasukste muutmise ja edastusviivituse regulatsiooni mehhanismid astuvad mÀngu.
- Viivituste jÀrjekord ei arvesta neid mehhanisme. See toob kaasa asjaolu, et mÔned teod kustutatakse liiga varakult vÔi esitlets toimivad vale jÀrjekorras, mis pÔhjustab vale Latentsuse olek.
- MĂ€ngijal kaob ĂŒhenduse probleem ja ta simuleerib, et jĂ€rgneb serverile, kuni 400 takti.
- Igas taktis genereeritakse ja valmistatakse serverile edastamiseks uus tegevuse muutmise tegu.
- Kliendi megapakett koosneb ĂŒle 400 olendi valiku muutmisest (ja teiste tegevuste, nagu laskmise ja kĂ”ndimise seisundid, samuti kannatasid selle probleemi all).
- Server saab 400 sisendi toimingut. Kuna tal ei lubata ĂŒhtegi sisenditegevust vahele jĂ€tta, kĂ€sutab ta kĂ”iki kliente neid samme tegema ja saadab need ĂŒle vĂ”rgu.
Ironia seisneb selles, et mehhanism, mis pidi kanaliteed sÀÀstma, pÔhjustas tegelikult tohutuid vÔrgu pakette.
Lahendasime selle probleemi, parendades kĂ”ik piirjuhtumid uuendamise ja viivituste jĂ€rjekorra toetamisel. Kuigi see vĂ”ttis ĂŒsna palju aega, tasus lĂ”puks kĂ”ik Ă”igesti ellu viia, mitte toetuda kiiretele hack'idele.
Allikas: habr.com
