Alt-F4 #26 - Dávání Multi do Playeru  05-03-2021

Napsal oof2win2, upravil stringweasel, Nanogamer7, Conor_, Therenas, Firerazer,
přeložil oof2win2

Obsah

V této 26. edici Alt-F4 (půl roku výtusků!), oofěwině jde do Factorio multiplayeru a vysvětluje trochu více o technických věcí za tím. Pokud jste si někdy lámali hlavu o tom, jak hra dokáže zvládat stovky hráčů a mnohy tisíc entit najednou, jste vítání se podívat do této edice!

Factorio Servery oof2win2

Většina z nás se již někdy připojila na Factorio server alespoň jednou, buďto aby jste si zahráli s kamarády nebo se podívaly na stavby jiných. V této edici Alt-F4, krátce vysvětlím historii multiplayeru, a poté se trochu více do hloubky podívám jak multiplayer funguje technicky. Budu vysvětlovat využívání plně deterministických algoritmů a lockstepových algoritmů mimo jiné věci.

Historie Multiplayeru

V říjnu 204 s Factoriem 0.11.0, multiplayer byl přidán do hry, i když se na něm pracovalo od verze Factoria 0.9.4. Tento multiplayer byl něco kompletně jiného od toho co známe dnes, třeba jste nemohli kliknout na “Připojit se k kamarádovi” přes Steam nebo použít prohlížeč serverů - museli jste znát přesnou IP adresu serveru. Když multiplayer poprvé vyšel, bylo v něm docela dost bugů jako tento, který nedovolil hráčum hrát přes 20 sekund. Byl ale rychle opraven, ani ne o tři hodiny později, jako je to u Wubu normální. Existoval také tento bug, který nedovolil více než třem hrácům být online najednou - narozdíl od tohoto online sessionu, kde se vyskytlo přes 500 hráčů zhruba o šest let později. Hodně práce šlo do toho, aby se mohlo více než 500 hráčů připojit najednou.

V Factorio 0.12.0, jako hlavní funkce, bezhlavé servery byly přidány. Toto znamenalo, že servery teď mohou bežet na počítačích bez GPU, což značne snížilo cenu Factorio serverů a jejich dostupnost. Také to umožnilo, aby několik instancín beželo najednou na stejném počítači, což je velmi užitečné v některých případech.

S Factoriem 0.14.0, Factorio servery již nepausijí hru pro všechny hráče, pokud počítač jednoho hráče je moc pomalý, aby procesoval updaty současně s ostatními. Toto znamená, že pokud máte starší počítač, server na vás již nebude čekat, aby jste se dohnali v procesování updatů. Toto je velmi užitečné na hrách s větším počtem hráčů, které mají tendenci mít desítky až stovky hráčů online najednou, protože nikdo nemusí čekat aby si mohli zahrát.

Plně Deterministický Přístup

Jako bylo řečeno v FFF-30, všichni klienti a server musí simulovat hru stejným způsobem, stejné akce v stejně přesný čas. Toto znamená, že když jeden člověk udělá něco na svém počítači, instance Factoria ostatních lidí musí udělat tu stejnou věc. Instance je výskyt něčeho, třeba, může být několik instancí jablek v košíku nebo záložek v Chromu. Factorio je podstatně jiné od jiných populárních her jako CS:GO nebo Overwatch, takže vývojáři nemohli prostě vzít přístup jiné hry a přidat ho do Factoria, protože by to nefungovalo správně.

Místo toho, při vývoji multiplayeru, vývojáři ho vytvořili s použitím lockstepového protokolu. V Factoriu, připojení k serveru začíná tím, že vám serveru pošle mapu. Poté, server vám pouze posílá informace, pokud je nějaká změná od hráče, třeba kdyby hráč položil pás na nějaké součadnice, umřel kvůli kousači (nebo vlaku), atd. Je vám řečeno pouze že se to stalo, a poté vaše instance hry musí aktualizovat lokální simulaci sama od sebe. Nedostane detailovaný výpys toho, co se aktuálně děje, třeba jako pohyb logistických robotů a posun vlaků.

Přenos všeho co se děje, každý tik hry, by využilo neskutečné množství internetového připojení, a potřebovali by jste přenášet informace jako “tento logistický robot se posunul sem”, což by se muselo dít desítky tisíc krát za herní tik na velkých bázích. Nemluvě o jiných informacích, což by vedlo k neuvěřitelně velkým přenosům dat, z čeho by mohly vznikat přenosy až 1500MB v některých případech. Místo toho, jsou vám řečeny pouze důležité změny, které jsou většinou interakce hráču s hrou, které váš klient poté simuluje, jako kdyby tam nikdo jiný nebyl.

Je mnoho jiných způsobů, kterými by hra mohla přistupovat k multiplayeru. Například, Overwatch je hra, která sleduje skoro vše centrálně na jejich serverech, monitorují všechny itemy, hráče, kulky atd. a aktivně opravují váš klient, pokud se něco stalo špatně. Factorio monitoruje pouze vstupy hráče a hází desynchronizace, pokud se něco udělá špatně. Vysvětlím, co desynchronizace je později. Tyto dvě implementace jsou od sebe odlišné, protože hry jsou od sebe radikálně odlišné: v Overwatchi, jste schopni mít všechny mapy předem staženy když stáhnete hru, takže pouze potřebujete přesouvat data o projektilech a o hráčích. V Factoriu, mapy se ale mění pořád.

V Factoriu, máte různé pozice monvoten, lamp, pásů, elektrických tyčí, podavačů a obecně všeho, protože každá báze v Factoriu je jiná. To je důvod, proč pouze změny od hráčů jsou přenášeny, protože Factorio je schopné simulovat hru jako kdyby jste ji hráli sami, pouze příjmá vstupy od jiných hráčů od serveru. Než přenášet celou mapu každý tik, je mnohem lehčí přenést mapu když se hráč připojí a poté mu posílat pouze změny do jeho simulace hry, třeba kdyby se hráč pohnul o 10 kostiček doprava atd. Viz obrázek níže. Pro někoho, komu to příjde zajímavé, multiplayer Overwatche se vyzvětluje zde (kratší video) a možná zde Overwatch vývojáři ve větším detailu.

Player: Ahoj! Můžu se připojit na Factorio server?

Server: Jo, klidně! Zde je aktuální mapa, stáhni si jí [mapa jako příloha]

Server: Spawnuješ se na x=0, y=3

Server: Tvůj kamarád ’potatoman’ si nastavil jeho logistický filter v slotu č. 33 na item “fast-transport-belt”. Nastav to pro něj taky a simuluj dál

Server: Tvůj kamarád ’potatoman’ se posunul o 3 bloky doprava

Player: Posunul jsem se o 4 bloky doleva

Server: Rozumím. Přeposílám

Log chatu k ilustraci jak Factorio servery fungují

— Factorio Server

Plně deterministické algoritmy jsou používány v Factoriu a takové algoritmy budou mít stejný výstup, pokud jim jde dán stejný vstup. To znamená, že není náhodnost v výstupu, což je nutno pro některé účely jako Factorio. Plně deterministický algoritmus je nutný, aby jste mohli mít několik instancí Factoria v lockstepovém algoritmu a aby byly v synchronizaci. Důvod, proč používat plně deterministické algoritmy by byl, že pokud nejste schopni mít funkce, které mají stejné výstupy na stejné vstupy, nejste schopni mít lockstepovou architekturu, a celý systém jde do háje pokud všechny instance mají jiné výstupy. Plně deterministický algoritmus je definován následujícími pravidly:

  • Nesmí použít jiná data než vstup do algoritmu. Zakázaná data: náhodná čísla, uložené soubory na disku, globální proměnné, časovače (čas od začátku programu)
  • Algoritmus musí pracovat cestou, která není časově sensitivní

Příklad opaku by bylo pokud máte několik instancí programu, který zapisuje do Excelové tabulky a jiný program by si chtěl přečíst poslední řádek tabulky. Toto by učiniloo program časově sensitivním, protože když jedna instance bude být o trochu opožděna o pár vteřin, tak to může vytvořit úplně jiné pořadí řádků v té tebulce, což nechá program který si to čte s úplně jiným vstupem.

Příklad lockstepového a plně deterministického algoritmu by byl kdyby klient položil plán. Když kliknete na plán, aby se importoval do sdílené knihovny, ikonky plánu poté nebudou zašedivělé, jako obrázek na pravé straně. Toto je protože když kliknete na plán, váš klient ho sdílí do sdílené herní knihovny. Když plán někde položíte, váš klient řekne serveru, že jste položili plán na specifické XY souřadnice. Server to poté řekne všem ostatním připojeným klientům, že plán byl položen na ty stejné souřadnice. Každý individuální klient poté simuluje pohyb všech robotů, sbírání surovin, pokládání entit a vracení se k jejich vybranému roboportu. Všichni klienti musí toto simulovat sami, bez jakýchkoli jiných vstupů, a dělají to v stejném způsobu díky předem řečeným plně deterministickým algoritmům.

Desynchronizace (‘desync’) je když několik počítačů má něco dělat v stejný čas stejným způsobem s stejnými výsledky díky plně deterministickým algoritmům, ale nedělají to. Normálně, když klient a server dělají to stejné, jsosu štastní, protože jsou synchronizování (‘v syncu’). Desync se může stát protože dva klienty vypočítali update s jinými výsledky, což se většinou stává kvůli programátorské chybě. Podívejte se na obrázek níže, jak se desynchronizace může stát. Pokud moddér nebo vývojář scénáře nedělá management dat správně, desynchronizace se tím také může stát. Desynchronizace odpojí váš klient od serveru a váš klient začne generovat desynchronizační zprávu, což je něco užitečného co vývojáři využívají k vyšetřování desynchronizací.

Player: Hej, můj výsledek na výpočet na netto elektřiny při tiku 33859 je 348. Mám to správně?

Server: Cože?? Já dostal 936. Máš to špatně. Pošlu ti mapu a odpojím tě, můžeš se poté připojit později

Obrázek na ilustraci, co se stane během desynchronizace

— Factorio Server

Můžete si myslet, jak se desynchronizace nestávají s roboty, kteří se posouvají přes mapu? Jistěže, když udělají všechny úkoly a někteří roboti jsou vybráni na udělání specifických úkolů, různí klienti si vyberou jiné roboty, aby udělali dané úkoly, ne? Ne. Každý klient si vždy vybere stejné roboty ve stejný čas, protože algoritmus na vybírání robotů je plně deterministický. Dva vlaky přicházející z stackeru do stanice? Pokaždé stejný vlak, protože toto je také plně deterministické. Na kterou věž kousač zaútočí první na vaší těžící základně? Také plně deterministické. Toto bylo pouze pár příkladů, ale všechno v hře je plně deterministické. Kdyby to nebylo, měli by jste jednu desynchronizaci zde, druhou jinde, a multiplayer by nebyl vůbec hratelný. V multiplayeru, desynchronizace mohou být způsobeny několika věcmi, třeba konstrukcí robotů, simulace AI kousače, a nejvíce ze všech, věci od moddérů.

I kdyby jste chtěli použít něco lehkého jako math.random() aby jste získali náhodné číslo v módu nebo scénáři, byly by konsistentní výsledky - všichni klienti by získali stejný výsledek z funkce. Toto je protože generátor náhodných čísel Factoria je seedován. Je mu dáno číslo, s kterým poté generuje další náhodná čísla. Pokud budete seedovat všechny klienty stejným způsobem, vaše náhodná čísla budou v synchronizaci. Je důležité poznamenat, že to je pseudonáhodný generátor, a proto není úplně náhodný, protože je inicializován předem dohodnutým číslem, které dovoluje tomu, aby výsledky byly reprodukované. Podívejte se zde pro další informace o náhodných seedech.

Teď vítetrochu více o tom, co se stává když se připojíte na server v prohlížeči serverů, připojíte se přes IP adresu, přes Steam nebo přes LAN. Vývojáři Factoria strávili hodně času prácí na multiplayeru, což nám dovolilo dělat projekty jako přes 500 hráčů v multiplayeru najednou nebo Clusterio setupy, což dává tvůrcům nástroje na vyvíjení skvělých věcí které vytvářejí. Existuje méně a méně limitací k tomu, co jste schopni dělat, masivní báze, masivní množství hráčů, možná i obojí! Vše z toho je pouze na vás, aby jste to založili.

Přispívání

Jako vždy, hledáme lidi, kteří chtějí přispívat k Alt-F4, buď to je přidáváním zajímavěho článku nebo překladem. Pokud máte něco zajímavého na mysli co by jste chtěli sdílet s komunitou v hezkém způsobu, toto je ideální místo kde o tom diskutovat. Pokud si nejste moc jisti o tom, rádi pomůžeme s diskuzí nápadů o obsahu a strukturování otázek. Pokud to zní jako něco zajímavého, připojte se na Discord aby jste začali!