Megapack: Jak Factorio vyřešilo problém pro 200 hráčů pro více hráčů

Megapack: Jak Factorio vyřešilo problém pro 200 hráčů pro více hráčů
V květnu tohoto roku jsem se zúčastnil jako hráč KatherineOfSky MMO události. Všiml jsem si, že když počet hráčů dosáhne určitého počtu, každých pár minut někteří „spadnou“. Naštěstí pro vás (ale ne pro mě) jsem byl jedním z těch hráčů pokaždéi s dobrým spojením. Vzal jsem to jako osobní výzvu a začal pátrat po příčinách problému. Po třech týdnech ladění, testování a oprav je chyba konečně opravena, ale cesta nebyla tak snadná.

Problémy ve hrách pro více hráčů je velmi obtížné vystopovat. Obvykle se vyskytují za velmi specifických parametrů sítě a za velmi specifických herních stavů (v tomto případě více než 200 hráčů). A i když lze problém reprodukovat, nelze jej správně odladit, protože vkládání bodů přerušení zastaví hru, zkazí časovače a obvykle způsobí časový limit připojení kvůli vypršení časového limitu. Ale díky vytrvalosti a úžasnému nástroji tzv neohrabaný Podařilo se mi zjistit, co se děje.

Stručně řečeno, kvůli chybě a nedokončené implementaci simulace stavu zpoždění se klient někdy dostal do situace, kdy musel odeslat síťový paket v jednom hodinovém cyklu sestávající z akcí vstupu hráče pro výběr přibližně 400 herních entit ( nazýváme to "megapacket"). Poté musí server nejen správně přijímat všechny tyto vstupní akce, ale také je odesílat všem ostatním klientům. Pokud máte 200 klientů, stává se to rychle problémem. Kanál k serveru se rychle ucpe, což má za následek ztrátu paketů a kaskádu znovu vyžádaných paketů. Odkládání vstupních akcí pak způsobí, že více klientů začne posílat megapakety a jejich lavina je ještě silnější. Úspěšní klienti se zvládnou uzdravit, všichni ostatní odpadnou.

Megapack: Jak Factorio vyřešilo problém pro 200 hráčů pro více hráčů
Problém byl docela zásadní a jeho odstranění mi trvalo 2 týdny. Je to dost technické, takže šťavnaté technické detaily vysvětlím níže. Nejprve ale musíte vědět, že od verze 0.17.54, vydané 4. června, se tváří v tvář dočasným problémům s připojením stal multiplayer stabilnější a skrývání zpoždění je mnohem méně chybné (méně brzdění a teleportování). Také jsem změnil způsob, jakým jsou skryta bojová zpoždění, a doufejme, že je to trochu zjemní.

Multiplayer Mega Pack - Technické detaily

Jednoduše řečeno, multiplayer ve hře funguje takto: všichni klienti simulují stav hry tím, že přijímají a odesílají pouze vstup od hráče (tzv. „akce vstupu“ Vstupní akce). Hlavním úkolem serveru je přenos Vstupní akce a zajistit, aby všichni klienti prováděli stejné akce ve stejném cyklu. Více si o tom můžete přečíst v příspěvku. FFF-149.

Vzhledem k tomu, že server musí rozhodovat o tom, jaké akce má provést, akce hráče se pohybují po následující cestě: akce hráče -> herní klient -> síť -> server -> síť -> herní klient. To znamená, že každá akce hráče je provedena až poté, co provedl okružní cestu přes síť. Kvůli tomu by se hra zdála strašně pomalá, takže téměř okamžitě po objevení se multiplayeru ve hře byl představen mechanismus pro skrytí zpoždění. Skrytí latence simuluje vstup hráče bez ohledu na akce ostatních hráčů a rozhodování serveru.

Megapack: Jak Factorio vyřešilo problém pro 200 hráčů pro více hráčů
Factorio má herní situaci herní stav je kompletní stav mapy, hráče, entit a všeho ostatního. Je deterministicky simulován ve všech klientech na základě akcí přijatých ze serveru. Stav hry je posvátný, a pokud se někdy začne lišit od serveru nebo jiného klienta, dojde k desynchronizaci.

Ale herní stav máme stav zpoždění Stav latence. Obsahuje malou podmnožinu hlavního stavu. Stav latence není posvátný a pouze představuje obrázek toho, jak bude stav hry vypadat v budoucnu na základě vstupů od hráče Vstupní akce.

K tomu uchováváme kopii vygenerovaného Vstupní akce ve frontě zpoždění.

Megapack: Jak Factorio vyřešilo problém pro 200 hráčů pro více hráčů
To znamená, že na konci procesu na straně klienta vypadá obrázek asi takto:

  1. Aplikovat Vstupní akce všem hráčům herní stav způsob, jakým byly tyto vstupní akce přijímány ze serveru.
  2. Odstraňte vše z fronty zpoždění Vstupní akce, na které již bylo podle serveru aplikováno herní stav.
  3. Odstranit Stav latence a resetujte to tak, aby to vypadalo úplně stejně jako herní stav.
  4. Použít všechny akce z fronty zpoždění na Stav latence.
  5. Na základě dat herní stav и Stav latence vykreslit hru hráči.

To vše se opakuje v každém taktu.

Příliš obtížné? Neuvolňujte se, to není vše. Abychom kompenzovali nespolehlivá připojení k internetu, vytvořili jsme dva mechanismy:

  • Přeskočená tiká: když o tom server rozhodne Vstupní akce bude vykonán v taktu hry, pak pokud neobdržel Vstupní akce některého hráče (například z důvodu zvýšeného zpoždění), nebude čekat, ale bude informovat tohoto klienta „Nebral jsem v úvahu vaše Vstupní akce, zkusím je přidat v dalším taktu. Děje se tak proto, aby se kvůli problémům s připojením (nebo s počítačem) jednoho hráče aktualizace mapy nezpomalila všem ostatním. To stojí za zmínku Vstupní akce nejsou ignorovány, ale jednoduše odkládány.
  • Plná zpětná latence: Server se snaží uhodnout, jaká je zpětná latence mezi klientem a serverem pro každého klienta. Každých 5 sekund vyjednává s klientem podle potřeby nové zpoždění (podle toho, jak se spojení chovalo v minulosti), a podle toho zvyšuje nebo snižuje zpoždění zpáteční cesty.

Tyto mechanismy jsou samy o sobě docela jednoduché, ale když se používají společně (což se často stává při problémech s připojením), logika kódu se stává obtížně ovladatelnou a se spoustou okrajových případů. Kromě toho, když tyto mechanismy vstoupí do hry, server a fronta zpoždění musí správně implementovat speciální Vstupní akce oprávněn StopMovementInTheNextTick. Díky tomu v případě problémů se spojením postava sama neuteče (třeba pod vlak).

Nyní vám musím vysvětlit, jak funguje výběr entit. Jeden z prošlých typů Vstupní akce je změna stavu výběru entity. Všem řekne, nad kterou entitou hráč najel myší. Jak vidíte, jedná se o jednu z nejčastějších vstupních akcí zasílaných klienty, proto jsme ji z důvodu úspory šířky pásma optimalizovali tak, aby zabírala co nejméně místa. To je implementováno takto: když je vybrána každá entita, místo ukládání absolutních, vysoce přesných souřadnic mapy, hra ukládá relativní offset s nízkou přesností od předchozího výběru. To funguje dobře, protože výběr myší obvykle probíhá velmi blízko předchozímu výběru. Z toho vyplývají dva důležité požadavky: Vstupní akce by nikdy neměl být přeskočen a musí být proveden ve správném pořadí. Tyto požadavky jsou splněny pro herní stav. Ale od úkolu stav latence když hráč „vypadá dost dobře“, nejsou ve stavu zpoždění spokojeni. Stav latence nebere v úvahu mnoho hraničních případůspojené s přeskakováním hodin a změnou zpátečních přenosových zpoždění.

Už tušíte, kam to směřuje. Konečně začínáme vidět příčiny problému s megabalíky. Kořenem problému je, že logika výběru entity spoléhá na Stav latencea tento stav ne vždy obsahuje správné informace. Takže megapaket je generován takto:

  1. Přehrávač má problémy s připojením.
  2. Do hry vstupují mechanismy pro přeskakování cyklů a regulaci zpoždění přenosu.
  3. Fronta stavu zpoždění nebere v úvahu tyto mechanismy. To způsobí, že některé akce budou předčasně odebrány nebo spuštěny v nesprávném pořadí, což má za následek nesprávné Stav latence.
  4. Přehrávač nemá problém s připojením a simuluje až 400 cyklů, aby dohnal server.
  5. V každém cyklu se vygeneruje nová akce a připraví se k odeslání na server, čímž se změní výběr entity.
  6. Klient odešle megapaket 400+ změn výběru entit na server (a s dalšími akcemi: stav spouštění, stav chůze atd. také trpěl tímto problémem).
  7. Server obdrží 400 vstupních akcí. Protože není povoleno přeskočit jednu vstupní akci, instruuje všechny klienty, aby tyto akce provedli, a odešle je po síti.

Ironií je, že mechanismus navržený tak, aby šetřil šířku pásma, vedl k obrovským síťovým paketům.

Tento problém jsme vyřešili tím, že jsme opravili všechny případy okrajů aktualizací a podporu fronty zpoždění. I když to trvalo docela dlouho, stálo to za to, aby to nakonec bylo správně, než se spoléhat na rychlé hacky.

Zdroj: www.habr.com

Přidat komentář