Megapack: Hoe't Factorio it probleem mei 200 spielers hat oplost

Megapack: Hoe't Factorio it probleem mei 200 spielers hat oplost
Yn maaie fan dit jier die ik as spiler mei oan MMO events KatherineOfSky. Ik fernaam dat doe't it oantal spilers berikt in bepaald oantal, elke pear minuten guon fan harren "falle off". Lokkich foar dy (mar net foar my), Ik wie ien fan dy spilers dy't loskeppele eltse kear, sels mei in goede ferbining. Ik naam dit as in persoanlike útdaging en begon te sykjen nei de oarsaken fan it probleem. Nei trije wiken fan debuggen, testen en reparaasjes waard de brek einlings reparearre, mar de reis wie net sa maklik.

Problemen mei multiplayer-spultsjes binne heul lestich om op te spoaren. Se meastal foarkomme ûnder hiel spesifike netwurk parameters en hiel spesifike spultsje betingsten (yn dit gefal, hawwende mear as 200 spilers). En sels as it probleem kin wurde reprodusearre, kin it net goed debugge, om't it ynfoegje fan breakpoints it spultsje stopet, timers betizet en meastentiids de ferbining feroarsaakje. Mar tank oan persistinsje en in prachtich ark neamd lomp Ik wist út te finen wat der oan de hân wie.

Koartsein, troch in brek en ûnfolsleine ymplemintaasje fan 'e latency-state-simulaasje, soe de kliïnt himsels soms yn in situaasje fine wêr't hy in netwurkpakket stjoere moast besteande út de ynfierseleksjeaksjes fan 'e spiler fan likernôch 400 spultsje-entiteiten yn ien kloksyklus ( wy neame dit in "mega-pakket"). De tsjinner moat dan net allinich al dizze ynfieraksjes goed ûntfange, mar se ek stjoere nei alle oare kliïnten. As jo ​​​​200 kliïnten hawwe, wurdt dit gau in probleem. De keppeling nei de tsjinner wurdt fluch ferstoppe, wat liedt ta pakketferlies en in kaskade fan opnij oanfrege pakketten. It fertrage fan de ynfieraksje feroarsaket dan noch mear kliïnten om megapakketten te stjoeren, wêrtroch't de lawine noch grutter wurdt. Lokkige kliïnten slagje te herstellen; alle oaren falle ôf.

Megapack: Hoe't Factorio it probleem mei 200 spielers hat oplost
It probleem wie frij fûneminteel en it duorre my 2 wiken om it te reparearjen. It is frij technysk, dus ik sil de sappige technyske details hjirûnder útlizze. Mar earst moatte jo witte dat sûnt ferzje 0.17.54, útbrocht op 4 juny, yn it gesicht fan tydlike ferbiningsproblemen, multiplayer stabiler wurden is, en ferbergjen fan fertragingen is folle minder buggy wurden (minder fertraging en teleportearjen). Ik haw ek feroare de manier wêrop combat lag is ferburgen en ik hoopje dat dit sil meitsje it in bytsje soepeler.

Multiplayer Mega Pack - Technyske details

Om it gewoan te sizzen, multiplayer yn in spultsje wurket sa: alle kliïnten simulearje de steat fan it spul, ûntfange en stjoere allinich spilerynput (neamd "ynputaksjes", Ynput aksjes). De wichtichste taak fan de tsjinner is te oerdrage Ynput aksjes en kontrolearje dat alle kliïnten deselde aksjes útfiere yn deselde kloksyklus. Jo kinne mear lêze oer dit yn 'e post FFF-149.

Sûnt de tsjinner moat nimme besluten oer hokker aksjes te fieren, de spiler syn aksjes bewege likernôch op dit paad: spiler aksje -> game client -> netwurk -> tsjinner -> netwurk -> game client. Dit betsjut dat de aksje fan elke spiler allinich wurdt útfierd nei it meitsjen fan in rûnreis oer it netwurk. Hjirtroch soe it spultsje ferskriklik stadich lykje, dus hast fuortendaliks nei de ynfiering fan multiplayer yn it spul, waard in meganisme ynfierd om fertragingen te ferbergjen. Fertraging ferbergje simulearret spilerynput sûnder rekken te hâlden mei de aksjes fan oare spilers en de besluten fan 'e tsjinner.

Megapack: Hoe't Factorio it probleem mei 200 spielers hat oplost
Factorio hat in spultsje steat Game State is de folsleine steat fan de kaart, spiler, entiteiten en al it oare. It wurdt deterministysk simulearre yn alle kliïnten basearre op de aksjes ûntfongen fan de tsjinner. Game state is hillich, en as it oait begjint te ferskille fan de tsjinner of in oare client, dan komt desync.

útsein Game State wy hawwe in steat fan fertraging Wachttiid steat. It befettet in lytse subset fan 'e grûn tastân. Wachttiid steat net hillich en fertsjintwurdiget gewoan in byld fan hoe't it spul steat sil útsjen yn 'e takomst basearre op spiler ynput Ynput aksjes.

Foar dit doel bewarje wy in kopy fan 'e makke Ynput aksjes yn de fertraging wachtrige.

Megapack: Hoe't Factorio it probleem mei 200 spielers hat oplost
Dat is, oan 'e ein fan it proses oan' e kant fan 'e klant sjocht de ôfbylding der sa út:

  1. Wy jilde Ynput aksjes alle spilers oan Game State de manier wêrop dizze ynfier-aksjes waarden ûntfongen fan de tsjinner.
  2. Wy fuortsmite alles út de fertraging wachtrige Ynput aksjes, dêr't neffens de tsjinner al op tapast binne Game State.
  3. Wiskje Wachttiid steat en reset it sadat it liket krekt itselde as Game State.
  4. Wy tapasse alle aksjes út de fertraging wachtrige oan Wachttiid steat.
  5. Op grûn fan gegevens Game State и Wachttiid steat Wy jouwe it spultsje oan de spiler.

Dit alles wurdt werhelle yn elke maat.

Te dreech? Net ûntspanne, dit is net alles. Om te kompensearjen foar ûnbetroubere ynternetferbiningen hawwe wy twa meganismen makke:

  • Miste tiken: as de tsjinner beslút dat Ynput aksjes sil wurde útfierd op 'e beat fan it spul, dan as er net ûntfange Ynput aksjes guon spiler (bygelyks, fanwege ferhege fertraging), hy sil net wachtsje, mar sil ynformearje dizze klant "Ik haw gjin rekken hâlden mei jo Ynput aksjes, Ik sil besykje se ta te foegjen yn 'e folgjende bar." Dit wurdt dien sadat troch problemen mei de ferbining (of komputer) fan ien spiler de kaartfernijing net fertrage foar alle oaren. It is de muoite wurdich opskriuwen dat Ynput aksjes wurde net negearre, mar gewoan oan 'e kant set.
  • Folsleine round-trip latency: De tsjinner besiket te rieden wat de round-trip latency tusken de kliïnt en tsjinner is foar elke klant. Elke 5 sekonden ûnderhannelet it as it nedich is in nije latency mei de kliïnt (basearre op hoe't de ferbining har gedrage hat yn it ferline), en fergruttet of fermindert de rintiid-latinsje neffens.

Op har eigen binne dizze meganismen frij ienfâldich, mar as se tegearre wurde brûkt (wat faaks bart mei ferbiningsproblemen), wurdt de logika fan 'e koade dreech te behearjen en mei in protte rânegefallen. Derneist, as dizze meganismen yn spiel komme, moatte de tsjinner en de fertragingswachtrige de spesjale goed útfiere Ynput Aksje ûnder de namme StopMovementInTheNextTick. Mei tank oan dit, as der problemen mei de ferbining, it karakter sil net rinne op syn eigen (bygelyks, foar in trein).

No moatte wy jo útlizze hoe't seleksje fan entiteiten wurket. Ien fan 'e oerdroegen typen Ynput Aksje is in feroaring yn de entiteit seleksje steat. It fertelt elkenien oer hokker entiteit de spiler sweeft. Lykas jo jo kinne foarstelle, is dit ien fan 'e meast foarkommende ynfieraksjes dy't troch kliïnten ferstjoerd binne, dus om bânbreedte te besparjen, hawwe wy it optimalisearre om sa min mooglik romte yn te nimmen. De manier wêrop it wurket is dat as elke entiteit wurdt selektearre, ynstee fan it bewarjen fan absolute, hege-precision map koördinaten, it spultsje bewarret in lege-precision relative offset út de foarige seleksje. Dit wurket goed om't mûs-seleksjes de neiging hawwe om tige ticht by de foarige seleksje te wêzen. Dit ropt twa wichtige easken op: Ynput aksjes Se moatte nea wurde oerslein en moatte wurde foltôge yn 'e juste folchoarder. Dizze easken wurde foldien foar Game State. Mar sûnt de taak Wachttiid steat yn "sjocht goed genôch" foar de spiler, se binne net tefreden yn de fertraging steat. Wachttiid steat nimt gjin rekken mei in protte râne gefallen, assosjearre mei it oerslaan fan kloksyklusen en it feroarjen fan fertragingen foar rûnreis oerdracht.

Jo kinne al riede wêr't dit hinne giet. Wy begjinne einlings de redenen te sjen foar it megapack-probleem. De woartel fan it probleem is dat de entiteit seleksje logika fertrout op Wachttiid steat, en dizze steat befettet net altyd de juste ynformaasje. Dêrom wurdt in megapacket sa'n ding generearre:

  1. De spiler hat ferbining problemen.
  2. Mechanismen foar it oerslaan fan kloksyklusen en it regeljen fan de fertraging fan oerdracht rûn-trip komme yn it spul.
  3. De fertraging steat wachtrige net nimme rekken mei dizze meganismen. Dit soarget derfoar dat guon aksjes te betiid fuortsmiten wurde of yn 'e ferkearde folchoarder útfierd wurde, wat resulteart yn ferkeard Wachttiid steat.
  4. De spiler hat in ferbiningsprobleem en, om de server yn te heljen, simulearret maksimaal 400 syklusen.
  5. By elke tick wurdt in nije aksje, dy't de entiteitseleksje feroaret, oanmakke en taret foar ferstjoeren nei de tsjinner.
  6. De kliïnt stjoert in mega-batch fan 400+ entiteit seleksje feroarings oan de tsjinner (en mei oare aksjes: sjitten steaten, kuierjen steaten, ensfh ek lêst fan dit probleem).
  7. De tsjinner ûntfangt 400 ynfieraksjes. Om't it net tastien is om ynputaksjes oer te slaan, bestelt it alle kliïnten om dy aksjes út te fieren en stjoert se oer it netwurk.

De irony is dat in meganisme ûntworpen om bânbreedte te besparjen einige mei it meitsjen fan enoarme netwurkpakketten.

Wy hawwe dit probleem oanpakt troch alle rânegefallen fan update- en efterstânwachtrige-stipe te reparearjen. Hoewol it nochal wat tiid duorre, wie it úteinlik de muoite wurdich om it goed te krijen ynstee fan te fertrouwen op rappe hacks.

Boarne: www.habr.com

Add a comment