Masarykova univerzita Fakulta informatiky

Technologie pro síťové hry v herním engine

Bakalářská práce

Tomáš Pagáč

Brno, jaro 2020 Místo tohoto listu vložte kopie oficiálního podepsaného zadání práce a prohlá- šení autora školního díla. Prohlášení

Prohlašuji, že tato bakalářská práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj.

Tomáš Pagáč

Vedoucí práce: Mgr. Jiří Chmelík, Ph.D.

i Poděkování

Chtěl bych poděkovat Mgr. Jiřímu Chmelíkovi, Ph.D. a MgA. Hele- ně Lukášové, ArtD. za vedení práce a podporu při její tvorbě. Dále bych chtěl poděkovat Mgr. Lukášovi Pevnému za pomoc při tvorbě písma.

ii Shrnutí

Práce zkoumá problematiku vývoje online her. První část popisuje výběr vhodné architektury, metody pro snížení datového toku a kom- penzaci síťové odezvy. Druhá část popisuje implementaci prototypu online hry za použití herního enginu Unity a síťové knihovny Mirror. Součástí práce je grafický manuál pro vytvořený prototyp.

iii Klíčová slova online hry, síťování, architektura herního serveru, Unity

iv Obsah

Úvod 1

1 Slovník 2

2 Požadavky specifické pro síťování her 3 2.1 Úvod do síťování her ...... 3 2.2 Podvádění ...... 4 2.3 Problematika architektury ...... 4 2.3.1 Client-server model ...... 4 2.3.2 Peer-to-peer model ...... 5 2.3.3 Platforma serveru ...... 5 2.3.4 Samostatná aplikace ...... 6 2.3.5 Webový server ...... 6 2.3.6 In-engine server ...... 6 2.3.7 Distribuovaný server ...... 7 2.4 Problematika šířky pásma ...... 8 2.4.1 Filtrování příjemců dat ...... 8 2.4.2 Snížení kvality dat ...... 9 2.4.3 Serializace ...... 10 2.4.4 Komprese ...... 10 2.5 Problematika odezvy ...... 11 2.5.1 Doba mezi vznikem informace a jejím sdílením 11 2.5.2 Zpoždění kvůli síťovému protokolu ...... 11 2.5.3 Skrývání odezvy a konzistence ...... 12 2.5.4 Interpolace ...... 12 2.5.5 Striktní konzistence ...... 12 2.5.6 Optimistická konzistence ...... 13 2.5.7 Kauzální konzistence ...... 14 2.6 Shrnutí ...... 15

3 Tvorba prototypu 16 3.1 Záměr hry ...... 16 3.2 Výběr nástrojů ...... 16 3.3 Unity ...... 16 3.4 Mirror ...... 17

v 3.5 Další síťová rozšíření pro Unity ...... 18 3.6 Persistence ...... 19 3.7 Připojování do hry ...... 19 3.8 Scény ...... 20 3.9 Herní levely ...... 20 3.10 Čas ...... 21 3.11 Periodicky sdílené informace ...... 22 3.12 Pohyb ...... 23 3.13 Animace ...... 24 3.14 NPC ...... 25 3.15 Úkoly ...... 26 3.16 Inventář a vzhled ...... 26 3.17 Zprávy ...... 26 3.18 Chat ...... 26 3.19 Zkušenosti z vývoje ...... 27 3.20 Grafický styl ...... 27 3.20.1 Inspirace ...... 27 3.20.2 Barvy ...... 28 3.20.3 Písmo ...... 29 3.20.4 Logotyp ...... 30 3.20.5 Uživatelské rozhraní ...... 30 3.20.6 Grafický manuál ...... 30

4 Závěr 32

Bibliografie 34

A Přílohy 36

vi Seznam obrázků

2.1 Struktura systému v client-server modelu 8 2.2 Filtrování příjemců 9 2.3 Rozdílné výsledky simulace způsobené predikcí pohybu 14 3.1 Geometrie herních scén, pohled shora 21 3.2 Animátor obsahující animační stavy a přechody mezi nimi, tento graf zobrazuje všechny stavy pro pohyb a boj 25 3.3 Logotyp hry 28 3.4 Experimentální písmo 29 3.5 Uživatelské rozhraní 30

vii Úvod

Hry tvoří prostředí pro mezilidskou komunikaci, kooperaci a soutě- žení. Online hry to umožňují v pohodlí domova, a dokonce přinášejí nové možnosti, jako jsou esporty. Díky moderním a mnohdy volně do- stupným herním enginům mohou hry na profesionální úrovni tvořit i jednotlivci či malé týmy. Avšak implementace síťové funkcionality je stále netriviální problém, který může určovat složitost realizace celého projektu. Vývojáři se musí potýkat se synchronizací herního stavu, který může sahat do všech částí systému, a různorodostí šířky pásma a odezvy v síti. Cílem této práce je seznámit se s typickými problémy, které jsou řešeny při vývoji online her, prozkoumat jejich řešení v závislosti na požadavcích hry, a implementovat prototyp online hry na základě zjištěných skutečností. Součástí prototypu bude i jeho grafický styl.

1 1 Slovník

• Herní klient – aplikace umožňující připojení do online hry

• Hráč – osoba využívající herní klient

• Gameplay – hraní hry, průběh hry, interakce se hrou

• Entita – objekt synchronizovaný mezi serverem a klientem

• Postava – entita ovládaná hráčem

• NPC (non-player character) – ekvivalent postavy ovládaný serverem

• Simulace – průběh hry složený z diskrétních kroků

• Herní engine – komplexní framework zajišťující vykreslování, fyziku, zvuk atd.

• Odezva (latence) – čas cesty dat z klienta na server a zpět

• Hostitel – server a klient tohoto serveru zároveň

• Tahová (turn-based) hra – hra s explicitními tahy, které nevy- žadují rychlé reakce

• MMO (massively multiplayer online) – žánr her s vysokým počtem současných hráčů

• live-service hry – dlouhodobě udržované hry nabízené ve formě služby

• REST – architektura webových služeb pro komunikaci pomocí bezstavových operací

2 2 Požadavky specifické pro síťování her

2.1 Úvod do síťování her

Síťování je obor zabývající se komunikací mezi počítači [1]. Počítače se zapojují do sítě, která jim umožňuje výměnu informací. Komunikace mezi počítači je prostředkem pro mezilidskou komunikaci, sdílení zdrojů, zadávání a přenos dat. Referenční model ISO/OSI dělí fun- gování sítě mezi sedm vrstev, které řeší fungování sítě od fyzického propojení počítačů až po reprezentaci přenášených dat. V praxi Inter- net používá rodinu protokolů TCP/IP, která dělí fungování sítě mezi vrstvu síťového rozhraní, síťovou vrstvu, transportní vrstvu a aplikač- ní vrstvu. Tato práce se týká transportní a aplikační vrstvy – výběru z protokolů transportní vrstvy, udržování, zpracování a reprezentace sdílených dat. Obecně se síťování her od ostatních programů neliší. Účastníci hry se spojí pomocí vyhovujícího protokolu a svými akcemi modifikují společný herní svět. Jednoduché hry nic víc nevyžadují, ale pro do- sažení rychlé akce nebo masivního počtu současných hráčů je třeba věnovat síťovému řešení velkou pozornost. Čím více hráčů má zároveň komunikovat a čím rychleji probíhá herní simulace, tím větší objem dat se musí přenést mezi serverem a klienty. Pro složitější hry přestává být praktické v každém kroku si- mulace odesílat celý herní stav všem klientům. Naivní implementace může způsobit zahlcení datové linky, vysokou odezvu a přebyteč- nou zátěž serveru. Mimo to odezva jednotlivých klientů, pokud není kompenzována, může mít negativní dopad na hru [2]. Systém by měl: • Sdílet klientům informace, které jsou pro ně relevantní [3] • Minimalizovat objem sdílených dat, eliminovat datové špič- ky [4] • Udržovat přesnou, „férovou“ simulaci na straně serveru • Udržovat dojem plynulé simulace na straně klienta Výběrem z možných řešení těchto bodů vzniká kompromis mezi veli- kostí datového toku, odezvou a úplností informací, které klient dosta- ne.

3 2. Požadavky specifické pro síťování her

Dalším neméně důležitým požadavkem, který získává na význa- mu u dlouhodobě udržovaných live-service her, je kvalitní architektura systému. Výběr platformy serveru záleží na potřebách hry, může jít od jednoduché aplikace až po distribuovaný systém. Pro programátora by mělo být jednoduše nastavitelné, která data (a s jakými vlastnostmi) má server sdílet, s možností manuální optimalizace přenášených dat. Mělo by být jednoduché dohledat původ sdílených dat, kvůli ladě- ní a optimalizaci. Ideálně by síťová funkcionalita neměla být pevně provázaná s ostatními částmi systému.

2.2 Podvádění

Síťování her významně ovlivňuje možnost hráčů podvádět. Tzv. che- aty, hacky, exploity jsou způsoby přístupu ke skrytým datům nebo provedení nezamýšlených akcí. Všechna data na klientovi mohou být odhalena, neošetřené požadavky na server mohou být zneužity. Nej- lepší ochranou proti podvádění na klientech je neposílat jim žádná nadbytečná data, to ale není vždy možné. Většina přístupů představe- ných v dalších tématech je možností podvádění nějak ovlivněna. Při navrhování hry je třeba zvážit dopady podvádění – vzniká kompromis mezi technickou efektivitou systému a potenciálem ke zneužití.

2.3 Problematika architektury

Při navrhování online hry je potřeba definovat celkovou architekturu systému. Na nejvyšší úrovni architektura určuje, jakým způsobem účastníci hry komunikují a čím jsou tito účastníci tvořeni [5, kap. 3]. Dva nejrozšířenější modely komunikace jsou client-server a peer-to- -peer. Na nižší úrovni je rozhodnutí, na jaké platformě systém stavět.

2.3.1 Client-server model

Client-server je ve hrách nejpoužívanější a nejvíc prozkoumaný model. V tomto modelu server drží všechna herní data a klienti navzájem komunikují pouze přes server. Výhodou je, že server má absolutní autoritu nad simulací. Nevýhodou je, že server musí mít dostatek

4 2. Požadavky specifické pro síťování her výkonu pro udržení komunikace se všemi klienty a simulování celé hry, a šířku linky odpovídající všem klientům dohromady. Potřebný výkon se dá snížit použitím hybridního modelu. Server jedná jako prostředník (tzv. matchmaking server), který rozdělí klien- ty na skupiny a v každé skupině určí klienta s nejlepším připojením hostitelem jedné instance hry. Alternativně dělí klienty na skupiny podle jejich vzájemné odezvy [6]. Tento postup je vhodný pro hry, které obsahují oddělené zápasy nebo skupinové aktivity. Přenecháním hostování hry klientovi vzniká risk zneužití nebo nestability herní in- stance. Existují i řešení, která hybridně spravují celý herní svět [7], ale nepodařilo se mi najít příklad hry v produkci, která by něco takového používala.

2.3.2 Peer-to-peer model Peer-to-peer model nepoužívá jedno zařízení pro simulaci hry, místo toho spolu všichni klienti (peerové) komunikují přímo. Na rozdíl od client-server modelu je zatížení sítě rovnoměrné, ale vzniká otázka, jak simulovat běh hry. Všichni účastníci hry se musí shodnout na průběhu simulace, na to existuje několik řešení: • Lockstep – každý klient čeká na vstupy všech ostatních a poté provede krok deterministické simulace. Je vhodný při hraní na lokální síti s minimální odezvou nebo pro tahové hry. • Konsens účastníků – kategorie algoritmů, podle kterých se klienti rozhodují, jak vypadá další krok simulace. Např. každý klient provede krok simulace, kroky se porovnají a provede se ten s největším zastoupením. Používá se spíš v jiných odvětvích, např. blockchain, redundantní distribuované systémy. • Důvěra účastníkům – každý klient má autoritu nad částí simu- lace, například nad svou postavou. Je to nejjednodušší řešení, ale má velký prostor pro zneužití.

2.3.3 Platforma serveru Výběr platformy serveru ovlivňuje obtížnost implementace, škálova- telnost a náklady na provoz. Jde o rozhodnutí, jestli a jaké existující řešení nebo ekosystém použít, na jaké jednotky dělit funkcionalitu.

5 2. Požadavky specifické pro síťování her

2.3.4 Samostatná aplikace

Jednoduchý server se dá naprogramovat v téměř kterémkoliv progra- movacím jazyce. Stačí na serveru a klientovi otevřít TCP, respektive UDP socket a navázat spojení, respektive naslouchat na volném portu. Nyní lze přijímat a odesílat data. Jednoduché hry si vystačí s posílá- ním dat přímo přes socket ve formě polí bytů. Na takovém základě staví většina serverů.

2.3.5 Webový server

Webový server vznikne výměnnou holých socketů za HTTP protokol. Implementace zde je už složitější, ale takřka pro každý jazyk exis- tuje implementace HTTP protokolu a různých knihoven pro práci s webem. Klient může se serverem komunikovat pomocí HTTP po- žadavků, server není limitovaný na zobrazování webových stránek v prohlížeči. Nevýhodou je, že HTTP je založený na TCP a k tomu ještě přidává další komplexitu, takže komunikace může být zbytečně pomalá, pokud hra nevyžaduje všechny funkce protokolu. Webové servery často obstarávají služby kolem samotné hry jako například správu uživatelských účtů, herní statistiky apod. Cloudové služby (Azure, AWS) umožňují automatické škálování webových serverů zvýšením výkonu nebo přidáváním instancí serve- ru. To znamená, že náklady na provoz odpovídají reálnému zatížení a škálování je neomezené (avšak v době nečekaných globálních změn mohou i cloudové služby mít plnou kapacitu). U takového řešení je důležité mít na paměti, že u webových serverů se očekává REST archi- tektura, zejména neudržování stavu v operační paměti (statelessness). Instance serveru mohou v kterýkoliv moment přestat existovat, musí komunikovat přes sdílenou databázi nebo jiného prostředníka (např. Redis). Je to ideální řešení pro hry, které používají síť jenom pro asyn- chronní komunikaci, jako jsou herní statistiky, pozvánky do hry atd.

2.3.6 In-engine server

Zvláštním případem je server, který běží v herním enginu stejně jako klient. Samotná síťová část je stejná jako u jiných serverů, rozdíl je v možnostech herního enginu. Takto server může mít přístup ke geo-

6 2. Požadavky specifické pro síťování her

metrii herních levelů, nechat engine počítat fyziku nebo navigaci NPC. Vývojáři nemusí řešit způsoby importování různých herních prvků, použijí stejný způsob jako v klientovi. Toto řešení omezuje možnost škálování, většina herních enginů není uzpůsobena k distribuovanému použití. Také není vždy možné vypnout všechny nepotřebné funkce jako výpočet fyziky, vykreslování nebo zvuk. Příklady zajímavých řešení: SpatialOS je distribuovaný systém, který dělí herní plochu mezi mnoho serverů a podle potřeby přiděluje oblastem instance herních enginů pro výpočty fyziky a AI. MMO hra Albion Online používá pro herní klient Unity, ale na serveru naopak implementuje vlastní systémy pro kolize, pathfinding a podobně [8]. Distribuovaný server je složený z více samostatných zařízení. Mů- žou to být fyzické servery nebo virtuální stroje, které spolu komu- nikují v lokální síti, v některých případech přes internet. Jednotlivé servery mají typicky různé povinnosti, při dobrém rozdělení zátěže mají skvělou škálovatelnost, ale takové rozdělení je specifické každé hře. Neexistuje mnoho hotových řešení, která by výrazně usnadnila implementaci distribuovaného serveru. MMO hry často používají schéma typu (obrázek 2.1):

• Jeden server, který komunikuje s klienty a rozděluje provoz

• Velký počet pracovních serverů rozdělených mezi oblasti hry, nebo dynamicky přidělených kde jsou třeba

• Pomocné servery jako chat server, přihlašovací server atp.

Pro dosažení globální dostupnosti je buď v každém regionu jeden distribuovaný server, nebo má jeden distribuovaný server své součásti ve více regionech. Ve druhém případě se musí řešit internetová ko- munikace mezi součástmi serveru, která může selhat a má znatelnou odezvu.

2.3.7 Distribuovaný server Existují moderní frameworky, jako Orleans (obrázek 2.1) nebo Akka, dovolující škálování bez manuálního dělení funkcionality mezi více

7 2. Požadavky specifické pro síťování her

Obrázek 2.1: Struktura systému v client-server modelu

serverů. Vyžadují ale neobvyklou strukturu kódu (actor model) a ne vždy dokážou minimalizovat mezi-serverovou komunikaci.

2.4 Problematika šířky pásma

Nedostatečná kapacita síťové linky v současnosti už obvykle není problém, alespoň ne pro klienty. Server, který sdílí data všem klien- tům najednou, může stále zahltit síť. To výrazně zhorší odezvu, nebo dokonce přeruší spojení klientů. Stále existují služby jako mobilní internet, které nabízejí omezený objem dat nebo podle využitého ob- jemu dat účtují. Optimalizovat objem odesílaných dat se dá pomocí filtrování nepotřebných dat a kompresí těch potřebných.

2.4.1 Filtrování příjemců dat Prvním krokem pro snížení objemu odesílaných dat je vůbec neodesí- lat data, která klient nepotřebuje. To vypadá očividně, ale je obtížné přesně rozlišit, která data jsou opravdu navíc. Největší objem dat mí- vají informace o entitách, které aktivně něco dělají – pohyb, animace apod. Frekvence sdílení těchto dat bývá mezi 10-120 hz v závislosti na rychlosti hry. Pokud je hra přirozeně rozdělená na samostatné oblasti, každý kli- ent potřebuje jen data z oblasti, ve které se nachází. V opačném případě nebo jako druhotné filtrování, je možné herní plochu rozdělit podle mřížky a každému klientovi posílat jen data z oblastí přilehlých jeho

8 2. Požadavky specifické pro síťování her

Obrázek 2.2: Filtrování příjemců

postavě. Dále se používají geometrické algoritmy [3] – nejjednodušší je filtrovat podle euklidovské nebo manhattanské vzdálenosti. Upřes- ných algoritmů, jako je filtrování podle zorného pole, hrozí nebezpečí, že kvůli odezvě klient včas nedostane potřebná data. Na druhou stra- nu, všechna přebytečná data mohou být použita k podvádění. Tyto druhy filtrování jsou znázorněny na obrázku 2.2. Pokud vznikne příliš velká koncentrace postav na jednom místě, některé MMO hry rozdělí tuto oblast na více vrstev/instancí, které spolu nekomunikují. To má ale vliv na gameplay, a může vést ke zmatku, když se dva hráči chtějí setkat na jednom místě, ale jejich postavy jsou v různých instancích.

2.4.2 Snížení kvality dat

Pomocí geometrických algoritmů je možné vytvořit několik zón zájmu místo binárního rozhodnutí, zda data odesílat nebo ne. Lze například pro vzdálené postavy snížit frekvenci sdílení dat, nebo data ztrátově zkomprimovat. Čím je více zón zájmu a čím složitější algoritmy jsou použity, tím více výkonu musí server věnovat třídění entit do těchto zón, proto se nevyplatí vždy implementovat složitější řešení.

9 2. Požadavky specifické pro síťování her

2.4.3 Serializace

Serializace je proces přeměny objektů do formátu vhodného k uložení nebo přenosu. Serializace dat pro přenos se někdy označuje marshal- ling. Pro sdílení herního stavu je třeba ho serializovat do podoby, kterou vyžaduje použitý síťový protokol – většinou se jedná o string nebo pole bytů. Není možné odeslat objekty tak, jak jsou uloženy v ope- rační paměti – hardwarové architektury různě ukládají data (např. endianita), reference dávají smysl jen v konkrétním běžícím procesu, objekty jednoho programu nemusí mít stejnou strukturu jako objekty jiného. Nejpopulárnějším způsobem serializace jsou formáty JSON a XML. Prakticky každý jazyk má nástroje pro serializaci do těchto formátů, výstupem jsou strukturované textové soubory čitelné lidmi. Nevýho- dou je relativně velký objem dat. JSON nepodporuje cyklické reference. Binární serializační nástroje využívají místo efektivněji, většina jazyků nějaký obsahuje. Řada open-source serializačních knihoven se nachá- zí na službě GitHub, spolu s porovnáními jejich funkcí, rychlosti a velikosti výstupů.

2.4.4 Komprese

Serializovaná data je možné transformovat některým z obecných kom- primačních algoritmů jako například LZMA. Efektivnější komprimace lze dosáhnout využitím vědomostí o odesílaných datech. Při znalosti použitého rozsahu proměnných lze při serializaci snížit počet bitů tak, aby snížení nezasáhlo do tohoto rozsahu. S odpovídající ztrátou přesnosti se dá počet bitů snížit i více. Delta komprese (jinak diff, patching) je metoda, kdy se posílá změ- na od předchozích hodnot. Za předpokladu, že změna je menší než samotné hodnoty, tato metoda šetří data. Nevýhodou je větší komple- xita – je nutné na začátku poslat iniciální hodnotu a až potom změny, a je nutné řešit ztrátu paketů. Při opakované aplikaci změn se může hodnota odchylovat, třeba akumulací chyby v plovoucí aritmetice.

10 2. Požadavky specifické pro síťování her 2.5 Problematika odezvy

Odezva je největší problém, kterému online hry čelí. Nedá se totiž zcela odstranit – i nejrychlejší cesta přes internet je omezená rychlostí světla [9, 10]. U akčních her má negativní dopad na gameplay už odezva v řádech desítek milisekund [2]. Hry s pomalejším dějem jsou hratelné s větší odezvou, ale až na čistě tahové hry je odezva nad půl sekundy obvykle považována za nepřijatelnou. Nehledě na pocitové opoždění hry je také těžké zaručit konzistenci simulace ve smyslu udržení správného sledu událostí. Kromě přesunu serverů blíž ke hráčům se odezva řeší dvěma způsoby: odstraněním elementů zvy- šujících odezvu nad síťové minimum a aplikací algoritmů pro skrytí odezvy. Jsou dva elementy zvyšující odezvu, které je možné optima- lizovat: doba mezi vznikem informace a jejím sdílením, a zpoždění zapříčiněné síťovým protokolem.

2.5.1 Doba mezi vznikem informace a jejím sdílením Pokud se data odesílají v pravidelné periodě, je vhodné zvážit, která data by se dala odeslat hned při vzniku. Pokud je odchozí zpráva reakcí na zprávu příchozí, je vhodné minimalizovat výpočty mezi nimi. Tyto metody zvýhodňují klienty s nižší odezvou – většina her zprávy sbírá a periodicky všechny zprávy aplikuje, tím se sice zvýší odezva, ale klienti mají větší šanci provést akci v rámci periody. Periodicky odesílané zprávy (např. pohyb postavy) většinou mají pevně danou periodu, vzniká tedy odezva mezi změnou stavu a jejím sdílením, ale klient s nižší síťovou odezvou nemůže přijímat nebo odesílat data častěji než ten s vyšší.

2.5.2 Zpoždění kvůli síťovému protokolu Téměř všechny síťové protokoly jsou založené na TCP nebo UDP. TCP mimo jiné sdílí zprávy spolehlivě a ve správném pořadí. To může mít velký vliv na odezvu – protokol čeká na potvrzení o doručení, případně opakovaně zprávu odesílá, zatímco ostatní zprávy musí čekat. Ne všechny informace jsou ale nutné a ne vždy záleží na pořadí. Pro větší kontrolu nad chováním protokolu vznikly knihovny (např. ENet) založené na UDP, které implementují funkcionalitu TCP,

11 2. Požadavky specifické pro síťování her

kde uživatel může zvolit, jaké záruky potřebuje. Lze používat několik konfigurací pro různá data, tedy zahazovat zastaralá data přijatá po novějších, nutná data sdílet spolehlivě atp.

2.5.3 Skrývání odezvy a konzistence

Skrývání odezvy před hráči a konzistence simulace jsou provázaná témata. V současné době už existuje celá řada matematických mode- lů [11] pro udržení konzistence u distribuovaných systémů, ty řeší prakticky stejné problémy, jako jsou u her mezi serverem a klienty. U her nejde tolik o úplné udržení konzistence jako o udržení zdání konzistence („férové“ hry) všemi stranami. A pocit instantní odezvy hry na akce provedené hráčem je v mnoha případech důležitější než konzistence. Proto jsou většinou používány volnější modely konzis- tence a odezva se skrývá pomocí extrapolace dat a predikce na straně klienta.

2.5.4 Interpolace

Pro udržení iluze kontinuity simulace je nutné interpolovat přícho- zí data, jako je pozice, rotace atd. Interpolace mezi příchozími stavy prakticky zvyšuje odezvu (musí přijít více stavů, mezi kterými se interpoluje), zatímco extrapolace může způsobit nesmyslné situace (např. postava vejde do zdi). Vhodné řešení závisí na typu hry, méně korektní (z pohledu přesnosti napodobení stavu na serveru) řešení může být pocitově přijatelnější. Programovací model zvaný timelines umožňuje intuitivní manipulaci proměnných v čase, mohl by v bu- doucnu zjednodušit řešení problémů interpolace [12].

2.5.5 Striktní konzistence

Striktní konzistence vyžaduje, aby všichni viděli události ve stejném pořadí. Zaručuje, že simulace probíhá konzistentně na klientech a serveru, ale má největší odezvu.

12 2. Požadavky specifické pro síťování her

2.5.6 Optimistická konzistence

Optimistická konzistence je opakem striktní, nevyžaduje a nedává žádné záruky. Bez požadavků na konzistenci je možné použít triky pro skrytí odezvy, proto tento model používá většina her. To ale znamená, že simulace na klientech a serveru nejsou nutně stejné. Pro periodicky odesílaná data, jako je pohyb postavy, se používá predikce na straně klienta (client-side prediction). Když klient odesílá své vstupy, rovnou je aplikuje na svou simulaci. Klient cítí nulovou odezvu. Nevýhoda tohoto přístupu je, že lokální postava na klientu je v „budoucnosti“ oproti ostatním postavám, jejichž vstupy musí projít cestu od svých klientů přes server až k tomuto klientu. Každý klient tedy vidí starý stav ostatních postav, může vidět postavy, které mají být skryté a opačně. Jaký je stav na serveru není jasné ze stavu žádného klienta. Tento problém dobře demonstruje hra Planetside 2, která detekuje zásahy zbraní na klientech, a tedy je možné zastřelit postavu, která ve svém referenčním rámci už utekla do bezpečí – obrázek 2.3). Simulace klientů a serveru se může rozejít kvůli rozdílným stavům (např. postava narazí do jiné, která na klientu ještě v cestě nestála). Potom server opravuje stav klienta, tzv. rubber-banding. Příkladem pokročilé implementace optimistické konzistence je hra Overwatch [13]. Hra je simulována deterministicky včetně fyziky a schopností postav. Server udržuje historii akcí postav, při příchodu nové akce ji zařadí do historie na základě odezvy klienta a na základě toho odsimuluje současný stav hry. Pokud není akce validní (nebylo možné ji provést ve stavu hry, o kterém klient v té době nevěděl), server ji zakáže a klient (který použitím predikce akci lokálně provedl) se vrátí do času provedení akce a odsimuluje hru do současné chvíle bez provedení této akce (forma rubber-bandingu). Díky kompletnímu determinismu je možné vracet hru a znovu simulovat do validního stavu. Takové řešení je velmi těžké implementovat, většina systémů pro realtime simulaci fyziky deterministická buď není vůbec, nebo jen za dodržení přísných podmínek. Pro možnost posunu v čase i při simulaci schopností postav Overwatch používá vlastní scriptovací systém, který je schopný svůj běh deterministicky obrátit, tedy lze provést inverzi provedených akcí.

13 2. Požadavky specifické pro síťování her

Obrázek 2.3: Rozdílné výsledky simulace způsobené predikcí pohybu

2.5.7 Kauzální konzistence

Tento model leží mezi striktní a optimistickou konzistencí, má větši- nu výhod striktní konzistence s nižší odezvou. Kauzální konzistence zaručuje, že události spojené kauzalitou (tzn. jedna událost způso- bila druhou) budou všude provedeny ve stejném pořadí. Použitím kauzální konzistence na prostor (plochu hry) vzniká lokální percepční filtr [11, 14]. Upravuje rychlost simulace objektů v závislosti najejich vzdálenosti k postavám a odezvě klientů ovládajících tyto postavy. Ko- lem postav s vyšší odezvou čas běží pomaleji. Nenašel jsem hru, která by přímo tento postup používala, ale některé hry při interpolaci berou v úvahu odezvu postavy. Je to zajímavý přístup, který by u některých typů her rozhodně zvýšil plynulost. Koncept časové dilatace používá i MMO hra EVE Online, která ho ale pojímá jinak – v oblastech s nadměrnou koncentrací hráčů zpomaluje herní simulaci, aby server nebyl přetížen. To nemusí nut- ně znamenat, že celá hra je několikrát pomalejší – jen je limitovaná frekvence akcí, které hráč může provést [15].

14 2. Požadavky specifické pro síťování her 2.6 Shrnutí

Není jeden postup vhodný pro každou hru. Vývojáři musí volit me- tody vyhovující vlastnostem jejich hry. Zatím neexistuje mnoho kom- pletních systémů, které by vývoj online her usnadňovaly, hry mají většinou síťové řešení vyvinuté specificky pro vlastní použití.

15 3 Tvorba prototypu

3.1 Záměr hry

Cílem bylo udělat hru, kde je zapotřebí použít některé z technik zmíně- ných dříve. Proto hra obsahuje mnoho NPC, které je třeba synchroni- zovat, a obsahuje několik druhů interakcí mezi hráčskými postavami, NPC a prostředím. Hra se odehrává ve městě zločinu, kde se postavy snaží přežít za jakoukoliv cenu. Postavy se pohybují po městě v reál- ném čase. Mohou získávat předměty v prostředí, chatovat a bojovat mezi sebou. Každá postava také může zadávat úkoly s odměnou za jejich provedení. Je to hra žánru sandbox – hráči nemají daný cíl, mo- hou si dělat co chtějí v rámci systému. Postavy jsou ovládané hráči nebo serverem, ze strany hráče nelze od pohledu poznat koho ovládá opravdový člověk.

3.2 Výběr nástrojů

Chtěl jsem, aby na jednom serveru mohly hrát desítky lidí zároveň. Server by také měl řídit chování a navigaci NPC. Pro Unity existuje open-source síťová knihovna Mirror, která kombinuje server a klient v jednom Unity projektu. Díky této knihovně je možné použít Unity pro tvorbu klienta i serveru. To znamená, že můžu využít Unity pro navigaci NPC, animace a fyziku na serveru. Spojení serveru a klienta v Unity také dovoluje jednoduché importování prostředků, jako je geometrie levelů.

3.3 Unity

Unity je jedním z nejpopulárnějších herních enginů. Vývoj v Unity probíhá v jazyce C# komunikujícím s uzavřeným C++ backendem. Umožňuje kompilaci na většinu platform – Windows, Mac, , Android, iOS, WebGL a další. Unity obsahuje mnoho nástrojů potřebných pro fungování této hry. Na straně serveru navigace po NavMeshi ve spojení s fyzikou a anima- cemi řídí pohyb NPC po levelech, které jsou sestavené v v editoru scén

16 3. Tvorba prototypu

pomocí importovaných modelů. Na straně klienta hráčské postavy také ovládá fyzika a animace, dále je použitý systém pro vykreslová- ní, systém pro správu vstupů, systém responsivního uživatelského rozhraní a více. Hra v Unity se skládá ze scén, které obsahují stromy herních objek- tů. Herní objekty mají asociované komponenty, což jsou instance tříd s přístupem k funkcionalitě Unity. Předem připravené komponenty obstarávají funkce enginu – fyziku, vykreslování atp.

3.4 Mirror

Mirror je open-source síťová knihovna pro Unity. Unity ukončilo vývoj svého síťového řešení UNet ve prospěch nového, dosud nevydaného, a UNet vydali jako open-source. Komunita UNet převzala a vznikl Mirror. Vývoj Mirror stále pokračuje a jeho hlavní vývojář na něm zakládá svá další (placená) řešení. Mirror slibuje škálování na úrovni MMO her, existují testy ukazující 480 současných navzájem synchro- nizovaných klientů. Server a klient používající Mirror se nachází v jednom Unity pro- jektu. To znamená, že server a klient sdílí kód – v kódu jde rozeznat, jestli zrovna běží na serveru nebo klientu. Po přidání komponentu NetworkIdentity na objekt mu Mirror dá jedinečné ID, kterým se dá objekt mezi serverem a klienty identifikovat. Potom je možné na objekt přidávat komponenty přistupující k síti. Pomocí atributů lze metody na síťovaných komponentech spouštět vzdáleně – volání metody spolu s argumenty se automaticky zabalí do zprávy a odešle. Podobně lze atributem označit proměnné, aby se při změně jejich hodnoty nová hodnota odeslala klientům. Mirror také dovoluje zápis přímo do pole bytů, který se děje periodicky při sbírání změn proměnných a volání metod (tyto zprávy nejsou odesílány hned, hromadí se a odesílají se najednou). Je taky možné definovat vlastní zprávy a přímo je odesílat. Pro Mirror také existuje několik vyměnitelných tzv. transportů, které řeší samotné odesílání a přijímání paketů. Existuje několik trans- portů pro TCP a UDP, transport pro WebSockety a transport využíva- jící Steam síťové služby. Většina těchto transportů je také open-source. V tomto projektu používám transport Ignorance, který je založený na ENet-CSharp implementaci spolehlivého UDP.

17 3. Tvorba prototypu 3.5 Další síťová rozšíření pro Unity

Pro Unity existuje více síťových řešení, dokonce existuje kniha [16], která některá z nich představuje. Je už trochu zastaralá, ale zmiňu- je i dvě dosud nejvíce používaná řešení – UNet (nyní už Mirror) a Photon. Photon je uzavřená platforma, která nabízí několik různých řešení, včetně služeb pro textovou a hlasovou komunikaci. Servery běží pri- márně ve Photon Cloudu, ale je možné hostovat i vlastní – to ale stále stojí peníze za licenci.

• Realtime: Určeno pro hry založené na oddělených místnos- tech, dovoluje neomezené škálování, synchronní i asynchronní gameplay, a neváže se na žádný specifický herní engine.

• PUN: Je to Realtime řešení integrované do Unity, podobně jako Mirror umí přímo synchronizovat herní objekty. Většina funkcionality se programuje na klientu.

• Bolt: Také je integrovaný do Unity, nabízí úplnou autoritu serve- ru, automatické sdílení stavu a kompenzaci odezvy. Umožňuje i přímé spojení dvou hráčů nebo hru na lokální síti.

• Quantum: Je to deterministický herní engine – používá Uni- ty k vykreslování, ale pro samotnou simulaci hry má vlastní deterministický systém (Unity nemá žádné záruky pro determi- nismus). Kód je stejný pro hraní offline, lokálně i přes internet. Používá predikci, ale herní stav je všude je stejný, manipulace stavu je nemožná.

Photon se zdá být nejkompletnějším síťovým řešením, vhodným pro profesionální produkci. Jedinou nevýhodou je uzavřenost systému a závislost na službách jedné platformy. Cloudové řešení Amazon GameLift nabízí globální dostupnost a nastavitelné škálování. Dá se použít s Unity, ale nemá žádnou integraci. Samotné Unity nabízí cloudovou službu Multiplay s integrací do několika enginů. Pro použití je nutné kontaktovat Multiplay tým.

18 3. Tvorba prototypu 3.6 Persistence

Protože má hra má poměrně rychlý gameplay, nemůže si dovolit udr- žovat všechen stav v databázi. Udržovat aktuální stav hry, jako pozice postav, v operační paměti není problém, protože server běží celý v jed- nom procesu. Při pádu serveru se může ztratit poslední pozice postav, ale to není velký problém. Důležitá data, která musí zůstat konzistentní, jsou držena v data- bázi. Vybral jsem databázi SQLite za použití SQLite4Unity3D, která zajišťuje komunikaci mezi C# a SQLite knihovnou. SQLite jsem vybral, protože je pro tohle použití extrémně rychlé – databáze je součástí procesu aplikace, tedy komunikace s databází probíhá přímo, a je možné celou databázi držet v operační paměti. SQLite má omezenou propustnost, ale pro mé použití bohatě stačí. Udělal jsem několik tříd s metodami pro manipulaci dat v databázi pro postavy, úkoly, předměty a zprávy. Přidal jsem třídu DatabaseQue- ue držící frontu akcí, které periodicky asynchronně vykonává. Zápisy do databáze jsou relativně nákladné (časově), takže takové akce jsou shromažďovány do fronty a prováděny jako jedna transakce. Klient samozřejmě nemá přístup k databázi, ale v kódu jsou data- bázové třídy stále dostupné, i když ne připojené k databázi. Spojení projektu serveru a klienta má výhody, ale v tomto případě může umožnit vznik chyb.

3.7 Připojování do hry

Pro registraci a přihlášení jsem použil Insight s TCP transportem. Insight je plugin pro Mirror, který umožňuje komunikaci pomocí jednoduchých zpráv mimo herní server. Mohl jsem použít přímo herní server, ale bylo jednodušší mít připojené k hernímu serveru pouze ty klienty, kteří jsou přítomní v herním světě. Vedle herního serveru tedy běží přihlašovací server. Klient se k ně- mu připojí a dostane veřejný RSA klíč. Uživatel zadá přihlašovací údaje, ty se zašifrují a odešlou na server. Server ověří údaje a v pří- padě úspěchu pošle klientu náhodný identifikátor ve formě GUID. Klient se odpojí od přihlašovacího serveru, připojí k hernímu serveru a pomocí identifikátoru dostane přístup ke své postavě.

19 3. Tvorba prototypu

Pokud přihlašovací jméno neodpovídá žádnému v databázi, se- ver vytvoří nový účet se zadanými údaji. Pokud jsou údaje validní, do databáze se uloží uživatelské jméno, heslo zahashované pomocí PBKDF2 a náhodný salt.

3.8 Scény

Scény v Unity slouží pro logické nebo prostorové dělení hry, vždy běží alespoň jedna scéna. Udělal jsem tři druhy scén:

• Offline scéna – Otevře se při zapnutí klienta. Při startu senapojí na přihlašovací server, obsahuje formulář pro přihlášení. Po přihlášení se zavře. Na serveru se tato scéna po startu hned přepne na Online scénu.

• Online scéna – Otevře se po přihlášení. Obsahuje objekty po- třebné pro běh samotné hry jako databázi, správce levelů nebo kameru.

• Herní scény – Otevírají se aditivně k Online scéně. Každá obsa- huje jednu oblast hry – geometrii levelu, objekty postav, inter- aktivní objekty (obrázek 3.1). Klient vždy otevře jen scénu, ve které se nachází jeho postava. Server otevře všechny scény.

3.9 Herní levely

Herní svět je rozdělený na levely (herní scény), které jsou úplně od- dělené. Každá scéna má svou lokální scénu fyziky. Díky tomu se nemusí počítat fyzika mezi objekty, které se stejně nemají ovlivňovat, a v případě, že se levely v prostoru překrývají, nevznikají chyby. Ví- ce fyzikálních scén začalo Unity podporovat relativně nedávno, a je nutné je explicitně vytvářet a simulovat. Bohužel nemají dostupných tolik funkcí jako výchozí fyzikální scéna, ale pro mé využití stačily. Mirror podporuje skrývání síťovaných objektů podle relevance (area of interest). V základu obsahuje script pro skrytí objektů překra- čující určitou vzdálenost od postavy. To není pro moje použití ideální, protože zobrazení objektů z jiných levelů nedává smysl, i když jsou

20 3. Tvorba prototypu

Obrázek 3.1: Geometrie herních scén, pohled shora

blízko postavy. Také se pak při pohybu postav musí pro každou posta- vu přepočítávat, které objekty má vidět. Velký problém je, že Mirror nechápe koncept scén, server jednoduše synchronizuje všechny ob- jekty, které má registrované. Naštěstí je řešení jednoduché – udělat seznam postav v každém levelu, a ten v Mirroru přiřadit jako oblast zájmu těm samým postavám. K tomu by se ještě dala přidat kontro- la vzdálenosti, ale levely nejsou tak velké, aby významně pomohlo objekty skrývat. Při přechodu mezi scénami je postava přesunuta do Online scény a po načtení nové scény (na klientu) se přesune do ní. Na serveru je navíc postava odebrána ze seznamu synchronizovaných jedné scény a po načtení přidána do seznamu druhé.

3.10 Čas

V Unity je čas od startu hry uložený v 32bitové proměnné s plovoucí řádovou čárkou. Znalost času potřebuje velká část projektu: průběh animací, interpolace pohybu, časování úkolů, chování NPC a podobně. Po několika hodinách běhu začne tento čas ztrácet přesnost v řádu milisekund. Pro server, který může nepřetržitě běžet i několik dní, to

21 3. Tvorba prototypu

může mít katastrofické následky. Udělal jsem tedy třídu DoubleTime, která používá 64bitovou proměnnou a Kahanův sčítací algoritmus (Kahan summation algorithm) pro minimalizaci chyb při opakovaném přidávání času mezi kroky simulace. Protože zdrojový kód Unity není dostupný, není jasné, jestli ve svých systémech používá přesnější vyjádření času, než jaké dává k dispozici na straně C# (podle diskuzí online je časový rozdíl mezi snímky počítán z přesnějšího zdroje než čas od startu hry).

3.11 Periodicky sdílené informace

U jednotlivých komponentů síťovaných knihovnou Mirror lze nastavit frekvenci synchronizace. Mirror periodicky volá generovanou metodu, která serializuje změněné proměnné označené pro synchronizaci. Tato metoda se dá přepsat pro ruční optimalizaci nebo třeba serializaci dat, která nelze serializovat automaticky. Jeden z vývojářů pluginů pro Mirror mi ale doporučil synchroni- zovat pohyb a animace hned po kroku fyzikální simulace, v tu chvíli jsou data nejčerstvější. Fyzika v Unity je nedeterministická a simuluje se v konstantních časových intervalech na rozdíl od zbytku simulace, která běží co nejčastěji. Unity nenabízí callback hned po kroku fyziky. Kroků fyziky se může odehrát několik za sebou – pokud je fyzika pozadu, nebo mohou být prolnuty několika kroky normální simulace. Proto je nutné v metodě FixedUpdate (běžící před krokem fyziky) označit, že v tu chvíli fyzika poběží, a ve FixedUpdate i Update (běžící co nejčastěji) kontrolovat, zda fyzika zrovna běžela. Udělal jsem pro to třídu NetworkFixedTick, ve které se mohou při- hlásit komponenty, které chtějí být synchronizovány po kroku fyziky. Tyto komponenty jsou serializovány a synchronizovány spolu, a tako- vá příchozí data se ukládají do kruhového bufferu, ze kterého je po každém kroku fyziky odebráno. Příjem a konzumace dat by tedy měly probíhat stejnou rychlostí, to dovoluje přihlášeným komponentům jednoduše interpolovat. Pokud z nějakého důvodu data do bufferu přibývají rychleji, než jsou konzumována, konzumace zrychlí, aby simulace nebyla moc pozadu. Protože v této hře nezáleží úplně na přesnosti fyziky a aktuální pozici postav, přidal jsem později možnost snížit frekvenci simulace fyziky na serveru a s tím i frekvenci synchro-

22 3. Tvorba prototypu

nizace tak, že klientům zůstává plynulá simulace fyziky, ale odesílají a přijímají data méně často. Důležitá otázka je, kdo odesílá data a kdo je přijímá, kdo má autori- tu. V případě pohybu a animací má autoritu nad svou postavou klient. Znamená to, že by mohl podvádět – teleportovat se, spouštět nedo- stupné animace a podobně. V praxi si ale v této hře hráč podváděním tolik nepomůže, a takové jednání by bylo ostatním hráčům očividné. Server může kontrolovat validitu akcí klienta, například jestli se za jeden krok fyziky postava nepohnula o nemožnou vzdálenost. Server může klientovu autoritu ignorovat a odesílat vlastní data, to dělá tře- ba při přechodu mezi scénami. Samozřejmě by bylo korektnější dát autoritu serveru a nechat klienta jen odesílat vstupy, ale udržet pak plynulost zážitku by bylo nepřiměřeně komplikované pro nemnoho výhod.

3.12 Pohyb

Synchronizaci pozice a rotace postav jsem začal s komponentem, který na to měl Mirror připravený. Výsledky mi ale ani na lokální síti nepřišly přijatelné, pohyb nebyl plynulý. Přepsal jsem tento komponent (třída FixedNetworkTransform) tak, aby využíval NetworkFixedTick výše. Pozice i rotace se posílají celé, bez spolehlivého doručení. Protože se posílají s vysokou frekvencí kroků fyziky, nemělo by velký smysl snažit se za každou cenu data doručit. Z Mirror komponentu jsem ponechal možnosti komprese rotace. Ani při nejvyšší kompresi ze tří 32bitových čísel (úhly na třech osách) do jednoho 16bitového jsem nesledoval zhoršení kvality. Pozice i rotace lineárně interpolují mezi dvěma posledními přijatými hodnotami na základě periody kroků fyziky. V případě, že nepřijdou včas nové hodnoty, extrapolují ve smě- ru posledních hodnot, ale pouze pod odmocninou uběhlé periody. Pokud do dalšího kroku fyziky nové hodnoty stále nepřijdou, extra- polace se zastaví. Díky tomu v případě krátkého výpadku není chyba v pohybu znatelná, a u delšího výpadku postava zastaví, místo aby měla možnost extrapolovat do nemožných míst. Pokud je vzdálenost mezi posledními dvěma hodnotami příliš velká, postava se na novou pozici prostě teleportuje.

23 3. Tvorba prototypu 3.13 Animace

Pohyb postav je zde ovládaný animacemi – tzv. root motion. Takový vypadá mnohem přirozeněji než při spouštění animací v reakci na pohyb. Z každé animace vyplývá určitý posun a rotace v prostoru. To znamená, že teoreticky, kdyby simulace byla deterministická a všech- ny vstupy a časování spuštěné animace přesně předávány serveru, nebylo by vůbec nutné sdílet pozici a rotaci postavy. Tyto podmínky ale neplatí, vznikl tedy jakýsi hybrid, kde animace řídí pohyb posta- vy ovládané hráčem na klientovi (respektive ovládané serverem na serveru), ale ostatní postavy mají pozici a rotaci aplikovanou přímo a animace jsou pouze vizuální. Stejně jako u pohybu, moje sdílení animací začalo předpřiprave- ným komponentem. Ten nepodporoval více vrstev animátoru (kompo- nentu spravujícího animace) a triggery, které jsem používal – v nové verzi tuto funkcionalitu přidali, pro mě pozdě. Komponent jsem pře- psal (třída FixedNetworkAnimator), aby využíval NetworkFixedTick a přidal jsem funkce zmíněné výše. Synchronizace je mnohem složitější než u pohybu, protože ani- mátor může obsahovat neomezené množství proměnných různého druhu, animace může být ve stavu přechodu do jiné animace, a každá vrstva animátoru má váhu a spuštěnou animaci. Tyto informace se tedy sdílí jen, když se změní. Proměnné animátoru mají asociovanou bitmasku, kde se označují (tzv. dirty bit) a sdílí jen změněné proměnné. Podobně jsou ve sdílené zprávě taky přítomné bity značící, jestli jsou ke zprávě připojeny váhy vrstev a běžící animace. Animátor rozhoduje běh a přechody animací na základě svých proměnných, ale někdy je potřeba odeslat běžící animace explicitně – při první synchronizaci postavy, nebo při spuštění animace z kódu. Informace o spuštění ani- mace nebo triggeru je odesílána jen jednou a může se ztratit, proto se jednou za sekundu také posílá celý stav animátoru. K běžící animaci může být připojený kód, jehož běh spravuje ani- mátor. To používám například pro střelbu z pistole – k animaci střelby je připojený kód, který ve správnou chvíli vytvoří instanci kulky. Tento kód nepotřebuje žádné síťování, protože pohyb a animace jsou syn- chronizovány najednou. Postava může být kvůli odezvě opožděná, ale vystřelí ze správného místa, správným směrem.

24 3. Tvorba prototypu

Obrázek 3.2: Animátor obsahující animační stavy a přechody mezi nimi, tento graf zobrazuje všechny stavy pro pohyb a boj

Moje hra používá dvě animační vrstvy – první obsahuje animace pro ovládání postavy a boj (obrázek 3.2), druhá přepisuje první pro speciální akce jako tanec nebo prohrabávání odpadků. Tyto animace jsou spouštěné hráčem u interaktivních objektů. V animátoru běží všechny vrstvy současně, ale druhá vrstva má normálně nulovou váhu. Váhy vrstev interpolují podobně jako pohyb, změna mezi normální a speciální animací je plynulá, i když mezi nimi není přechod.

3.14 NPC

Postavy ovládané serverem mají stejné možnosti jako hráčské postavy. Ze strany klientů se jeví stejně jako hráčské postavy. Ovládá je jedno- duchý behaviour tree – postavy se snaží vydělat peníze vykonáváním úkolů, v ohrožení se brání a zadávají úkoly zabít svého protivníka. Pro navigaci používají Unity NavMesh, akce rozhodují podle sezna- mu aktivit v levelu a seznamu postav jim blízkých (to vše pouze na serveru).

25 3. Tvorba prototypu 3.15 Úkoly

Úkoly mají několik typů cílů: zabití, omráčení, zatčení a navštívení postavy, získání předmětu a provedení animace. Úkoly mohou zadá- vat hráči pomocí uživatelského rozhraní a NPC v reakci na ohrožení. Každý úkol je určitého typu, má cíl a odměnu. První postava, která splní podmínku úkolu dostane odměnu, u úkolu typu získání před- mětu musí postava potvrdit předání interakcí se zadavatelem. Některé aktivity jsou implementované jako opakovatelné úkoly – například vyhrabání peněz z odpadků je úkolem provedení animace. Všechny úkoly a jejich vykonávání se vyhodnocuje na serveru (třída QuestRu- ler), klient může jen požádat o zadání úkolu nebo zobrazit seznam úkolů týkajících se určité postavy interakcí s ní.

3.16 Inventář a vzhled

Každá postava má několik míst inventáře pro obecné předměty, jedno místo pro zbraň a jedno pro doplněk (třída CharacterInventory). Při manipulaci s inventářem se všechny změny předmětů přímo uklá- dají do databáze, aby nedošlo k nekonzistencím při pádu serveru. Držená zbraň a doplněk se promítají do vzhledu postavy, to řeší třída NetworkEquipSync.

3.17 Zprávy

Po splnění úkolu dostane postava zprávu o úspěchu. Pokud má místo v inventáři, může ze zprávy převzít odměnu za splnění úkolu a zprávu odstranit. Po otevření okna zpráv klient požádá o seznam zpráv pro svou postavu. Možným rozšířením by bylo přidat možnost odesílání vlastních zpráv.

3.18 Chat

Aby hráči mohli komunikovat, přidal jsem možnost chatu (třída Ne- tworkChatter). Ten je ve formě bublin textu nad hlavou postav. Bubliny zůstávají viditelné jen několik sekund v závislosti na délce textu. Přidal

26 3. Tvorba prototypu

jsem několik užitečných příkazů pro administrátory (třída AdminCom- mands), které se volají pomocí chatu. Status administrátora lze nyní nastavit pouze ruční editací databáze.

3.19 Zkušenosti z vývoje

Mirror je rozhodně ideální pro jednoduché hry – sdílení proměnných a vzdálené volání metod jen použitím atributů je skvělé. Problematické se mi zdá propojení vlastního C# kódu s Unity a Mirror. Už samotné Unity svádí k používání komponentů pro herní logiku, to často vede k přebytečnému provázání logiky a prezentace hry. K tomu Mirror, který používá Unity komponenty a je hodně integrovaný do Unity systému, ještě k možnosti přebytečného provázání přidává. Když ser- ver a klient sdílí kód, je těžké stále myslet na to, kde může určitý kód běžet. Některé proměnné, metody nebo celé třídy mohou postrádat na klientu nebo na serveru smysl. Mohla by pomoct řešení, která vy- nucují určitý způsob programování a díky tomu jsou schopné správně synchronizovat co je třeba (např. Photon Quantum). V dalším projektu bych se rozhodně vydal cestou odděleného serveru a klienta, a Unity použil pouze pro prezentaci, oddělené co nejvíce od logiky hry. Nicméně tento projekt by bylo velmi nepraktické dělat mimo herní engine (beze změny návrhu hry), takže použití Unity a Mirror bylo dle mého názoru stále výhodné.

3.20 Grafický styl

Pro tuto hru jsem tvořil i grafický styl. To zahrnuje logotyp (obrá- zek 3.3), uživatelské rozhraní ve hře (obrázek 3.5), grafický manuál, experimentální písmo (obrázek 3.4) a několik plakátů. Programy po- užité pro tvorbu jsou: Inkscape pro vektorovou grafiku, Scribus pro sazbu grafického manuálu, Blender pro renderování reklamních před- mětů, GIMP pro úpravu rastrových obrázků.

3.20.1 Inspirace Hra se odehrává ve městě zločinu, jehož obyvatelé bojují o zdroje. Vznikají zde různé dohody, probíhají podezřelé obchody, v ulicích

27 3. Tvorba prototypu

Obrázek 3.3: Logotyp hry

propukává násilí. Takový děj by se dal dobře zasadit do žánru zvaného cyberpunk. Cyberpunk (psáno také kyberpunk) je vědeckofantastický žánr zobrazující dystopickou budoucnost, ve které lidstvo technologicky pokročilo, ale obyvatelé přesto žijí ve špatných podmínkách. Často zde hrají roli zlé korporace, nefunkční vláda nebo zničené životní prostředí. Děj se většinou odehrává v chátrajících velkoměstech, kde se chudí obyvatelé obracejí ke drogám a zločinu. Zatímco příběhy tohoto žánru se většinou týkají společenských změn způsobených novými technologiemi, moje hra zobrazuje život společenské spodiny. Protože se akce v mojí hře s tímto žánrem dobře slučuje, rozhodl jsem se použít jeho prvky v grafickém stylu.

3.20.2 Barvy

Jako hlavní barvy jsem vybral sytou modrou, fialovou a oranžovou. Pro pozadí používám tmavě hnědou a šedou. Tyto barvy mají při- pomínat neonová světla v industriálním prostředí. V uživatelském rozhraní je pozadí poloprůhledné jako imitace barevného skla, to zvyšuje viditelnost herní plochy.

28 3. Tvorba prototypu

Obrázek 3.4: Experimentální písmo

3.20.3 Písmo

Pro použití v logotypu a uživatelském rozhraní jsem vytvořil expe- rimentální futuristické písmo (obrázek 3.4). Je složené pouze z troj- úhelníků, každý trojúhelník má jednu ze dvou barev. Původně byly vrcholy trojúhelníků zarovnané do pravidelné mřížky, ale ve finální verzi jsou některé vrcholy u ostrých úhlů posunuty. Písmo obsahu- je velká písmena anglické abecedy – malá písmena kvůli čitelnosti nepřipadají v úvahu. Pro delší texty používám písmo Ubuntu.

29 3. Tvorba prototypu

Obrázek 3.5: Uživatelské rozhraní

3.20.4 Logotyp

Logotyp (obrázek 3.3) je tvořený stylizovaným panoramatem města a nápisem Convict. Convict je název, který jsem zvolil pro prezentaci hry. Text používá mé experimentální písmo, trojúhelníky jsou sloučeny a obtaženy. Některá písmena jsou upravena pro lepší čitelnost. Městské panorama je tvořeno překrývanými trojúhelníky a obdélníky, a je obtaženo stejně jako písmo.

3.20.5 Uživatelské rozhraní

Uživatelské rozhraní (obrázek 3.5) se skládá z poloprůhledných pa- nelů. Ve spodním panelu se nachází ikony otevírající různá okna. V prostředním panelu se nachází právě otevřené okno. Vpravo do- le je panel inventáře, který obsahuje předměty vlastněné postavou. Kromě hlavního rozhraní hra obsahuje menu pro spouštění animací a kontextové menu.

3.20.6 Grafický manuál

Grafický manuál definuje správné použití stylu. Obsahuje informace o použitých barvách, představuje dvě varianty logotypu a jejich správ-

30 3. Tvorba prototypu

né použití. Představuje experimentální písmo a také písmo Ubuntu. Dále obsahuje popis uživatelského rozhraní, ukázky firemních tisko- vin a reklamních předmětů.

31 4 Závěr

V této práci jsem zkoumal problémy vznikající při tvorbě online her. Rozebral jsem rozhodnutí, která je nutné provést, aby hra fungovala podle představ – aby byla škálovatelná a běžela plynule, aby všichni hráči měli stejné podmínky a měli minimální možnost podvádět. Pro tento účel jsem z oblasti síťování her vybral tři důležité skupiny pro- blémů – problematiku architektury, šířky pásma a odezvy. Na základě zjištěných informací jsem potom udělal prototyp hry. Architektura systému a platforma, na které systém staví, určují škálovatelnost, rozšířitelnost a náročnost údržby systému. Architektu- ra a platforma jsou poměrně nejasné pojmy, v této práci jsem definoval architekturu jako celkové rozdělení systému – modely peer-to-peer a client-server, zatímco za platformu považuji nějaký softwarový eko- systém nebo logické či fyzické rozdělení uvnitř systému. Podmínky podněcující volbu architektury a platformy jsou pro každou hru velmi individuální – záleží nejen na požadavcích na hru, jako je rychlost si- mulace nebo počet současných hráčů, ale například i na geografickém rozložení hráčů. Samotná struktura kódu a integrace síťové funkci- onality také hraje velkou roli, síťový kód by měl být schopný sdílet veškeré potřebné informace a zároveň by neměl být pevně provázaný s ostatními částmi hry kvůli údržbě a rozšířitelnosti. Existuje mnoho knihoven ulehčujících síťování, ale většina nemá funkcionalitu speci- fickou pro hry. Knihovna Mirror, kterou jsem použil v prototypu, se dokonale integruje s Unity a C# prostředím. To ale takovým způso- bem, že oddělit sdílení dat od herní simulace je takřka nemožné, takže vývoj většího projektu s využitím této knihovny mi přijde nepraktický. Problematika šířky pásma je v současnosti méně důležitá než dříve, protože kapacita současných síťových linek pro většinu her bohatě stačí. Jiná situace může nastat v případě serveru, který obsluhuje mnoho klientů zároveň – ten už může linku zahltit. Mimo to stále existují datové plány, hlavně pro mobilní zařízení, kde zákazník platí za objem použitých dat. Podobně cloudové služby často účtují mimo jiné i za síťový provoz. Proto jsem v této části popsal, jak zmenšit objem sdílených dat zvýšením kontroly nad jejich příjemci a komprimací. Síťová odezva může být pro online hru ten největší problém, pro- tože přímo ovlivňuje zážitek ze hry a nedá se úplně odstranit. Kvůli

32 4. Závěr

odezvě se stav hry ve stejném čase mezi účastníky liší, to přináší různé problémy: je nutné rozhodnout, který stav je v daný moment ten správ- ný a hráči tedy reagují na stav, který nemusí být aktuální. Akce hráčů nemusí být validní ve stavu, který nastal mezi odesláním a přijetím zprávy o této akci. Nejhorší je tento problém u akčních her, kde může proběhnout několik kroků simulace dřív, než jeden stav hry dorazí ke hráčům. Popsal jsem způsoby minimalizace odezvy, a metody pou- žívané pro skrytí nebo kompenzaci odezvy a udržení zdání plynulé simulace. Přestože některé hry využívají velmi pokročilá řešení pro kompenzaci odezvy, zatím neexistuje mnoho obecnějších řešení, která by se dala integrovat s jakoukoliv hrou. Slibně vypadají Photon Bolt a Photon Quantum, což jsou síťová řešení se zabudovanou kompenzací odezvy. Po průzkumu problematiky síťování jsem udělal prototyp hry, který demonstruje některé techniky popsané v této práci. Použil jsem k tomu herní engine Unity spolu se síťovou knihovnou Mirror. Tvorba prototypu byla úspěšná, synchronizace mezi serverem a klienty se zdá být plynulá a stabilní. Při tvorbě jsem kladl důraz na to, aby se prototyp co nejvíce podobal hře, která by se dala publikovat – tedy snažil jsem se neudělat pouze ukázku synchronizace dat, ale spíš ukázku funkční online hry, která má určitou úroveň kvality. K prototypu jsem vytvořil i grafický styl. S výsledným prototypem jsem poměrně spokojený, ale vzhledem k obrovskému množství času, který jeho vývoj zabral, by pro mě vytvoření kompletní hry na této úrovni bylo téměř nemožné. Zdá se tedy, že i s moderními nástroji je tvorba online her pro jednotlivce velmi náročná. Pro další výzkum v této oblasti bych se vydal směrem studia návr- hu projektů a kvalitní struktury kódu. Dalším krokem by byla tvorba univerzálního síťového řešení s podporou pro techniky zmíněné v této práci. Vytvořit takové univerzální řešení, které by zároveň drasticky nezhoršovalo čistotu kódu, by samozřejmě bylo velmi obtížné až ne- možné, ale například už řešení, které by samo bralo v potaz síťovou odezvu, bych považoval za dobrý krok vpřed.

33 Bibliografie

1. KUROSE, James F.; ROSS, Keith W. Computer networking : a top- -down approach. Addison-Wesley, 2010. ISBN 9780136079675. 2. PANTEL, Lothar; WOLF, Lars C. On the impact of delay on real-ti- me multiplayer games. In: ACM, 2002, s. 23–29. ISBN 9781581135121. Dostupné z DOI: 10.1145/507670.507674. 3. BOULANGER, Jean-Sébastien; KIENZLE, Jörg; VERBRUGGE, Clark. Comparing interest management algorithms for massively multiplayer games. In: ACM, 2006, s. 1–12. ISBN 9781595935892. Dostupné z DOI: 10.1145/1230040.1230069. 4. CHEN, Kuan-Ta; HUANG, Polly; LEI, Chin-Laung. Game traffic analysis: An MMORPG perspective. Computer Networks. 2006, roč. 50, č. 16, s. 3002–3023. ISSN 1389-1286. Dostupné z DOI: 10.1016/j.comnet.2005.11.005. 5. THOMPSON, Guy. Fundamentals of network game development. Bos- ton, MA: Charles River Media, 2009. ISBN 9781584505570. 6. AGARWAL, Sharad; LORCH, Jacob R. Matchmaking for Onli- ne Games and Other Latency-Sensitive P2P Systems. ACM SI- GCOMM Computer Communication Review. 2009, roč. 39, č. 4, s. 315–326. ISSN 0146-4833. Dostupné z DOI: 10.1145/1594977. 1592605. 7. KNUTSSON, B.; HONGHUI, Lu; WEI, Xu; HOPKINS, B. Peer- -to-peer support for massively multiplayer games. In: INFOCOM 2004. IEEE, 2004, s. 96–107. ISBN 0780383559. Dostupné z DOI: 10.1109/INFCOM.2004.1354485. 8. SZEDLAK, Thomas; SALZ, David. Albion Online: The Technolo- gy of Albion [online] [cit. 2020-04-21]. Dostupné z: https : / / www.makinggames.biz/programming-2/albion-online-the- technology-of-albion2331959.html. 9. PATTERSON, David A. Latency lags bandwith. Communications of the ACM. 2004, roč. 47, č. 10, s. 71–75. ISSN 0001-0782. Dostupné z DOI: 10.1145/1022594.1022596.

34 BIBLIOGRAFIE

10. CHESHIRE, Stuart. It’s the Latency, Stupid [online] [cit. 2020-04-21]. Dostupné z: http://www.stuartcheshire.org/rants/Latency. html. 11. LYSENKO, Mikola. Replication in networked games: Latency (Part 2) [online] [cit. 2020-04-21]. Dostupné z: https://0fps.net/2014/ 02/17/replication-in-networked-games-latency-part-2/. 12. SAVERY, Cheryl; GRAHAM, T. C. Nicholas. Timelines: simplify- ing the programming of lag compensation for the next generation of networked games. Multimedia Systems. 2013, roč. 19, č. 3, s. 271– 287. ISSN 0942-4962. Dostupné z DOI: 10.1007/s00530-012- 0271-3. 13. FORD, Timothy. ’Overwatch’ Gameplay Architecture and Netcode [online]. 2017 [cit. 2020-04-21]. Dostupné z: https://www.gdcvault. com/play/1024001/-Overwatch-Gameplay-Architecture-and Game Developers Conference. 14. SHARKEY, Paul M.; RYAN, Matthew D.; ROBERTS, David J. A lo- cal perception filter for distributed virtual environments. In: Pro- ceedings of the Virtual Reality Annual International Symposium. IEEE, 1998, s. 242–249. ISBN 0818683627. Dostupné z DOI: 10.1109/ VRAIS.1998.658502. 15. VERITAS. Time Dilation – How’s That Going? [online] [cit. 2020-04-21]. Dostupné z: https : / / www . eveonline . com / article / time - dilation-hows-that-going. 16. STAGNER, Alan R. Unity Multiplayer Games : Build Engaging, Fully Functional, Multiplayer Games with Unity Engine. Packt Publishing, 2013. Community Experience Distilled. ISBN 9781849692328.

35 A Přílohy

• README.txt – informace k použití herního klientu a serveru

• ConvictClient.zip – herní klient

• ConvictServer.zip – herní server

• Source.zip – zdrojové soubory prototypu

• ArtFiles.zip – soubory grafického stylu

• Brandguide.pdf – grafický manuál

• Gifs.zip – animace ukazující herní prototyp v akci

36