\chapter{Vývoj hry} \label{chap:main} Přenos starého projektu na~další major verzi~UE nebyl nijak problematický, dokonce v~editoru je~možnost rychlého exportu assetů do~jiného projektu. Rozhodně tomu pomohlo, že~se~C++~kód nepřenášel, ale~byl napsán znovu. UE~citelně rozšířil seznam dostupných tříd, přitom~některé jsou~již deprecated nebo~odstráněny úplně. Tak~mimo~jiné byly~odstraněny třídy Matinee (bývalý formát a editor animací objektů) pro~podporu novejší třídy Sequencer nebo~starý PhysX\footnote{PhysX je open-source fyzický engine s hardwarovou akcelerací pro grafiky s CUDA architekturou (GPU společnosti NVIDIA).} rozhraní, které~je nahrazeno systémem Chaos. Přesto se~něco pokazilo při~exportu objektů s~dynamickou fyzikou (závěsy, které~reagují na~simulaci větru, se~musely předělat). Přenos byl~odůvodněn převážně malou velikostí starého projektu a~taky lákavou nabídkou nových technologií, zejména Nanite a~Lumen. Navíc pátá verze Unrealu -- přesněji verze~5.5 -- přinesla značná vylepšení jako: \begin{itemize} \item Nový systém zpracování vstupu Enhanced Input\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/enhanced-input-in-unreal-engine}. Místy má~příliš mnoho objektové abstrakce, ale~rozhodně velký krok vpřed. Umožňuje snadné dynamické přepínání různých sad ovládání (multiplayer hry, gameplay/menu), dynamické modifikátory a~spouštěče vstupu (změna senzitivity, víceklik, podržení tlačítka určitou dobu), podpora vstupu více než~jedné periferie naráz a~podpora přeřazení vstupu (např.~změna tlačítka odpovídající za~skok herní postavy). Předtím tohle a~spoustu dalšího se~muselo naprogramovat ručně. \item Podporu vektorové grafiky v~UI. Veškeré staré UI~elementy byly~tvořeny pomocí základních vektorových obdélníkových tvarů právě proto, aby~se~vyhnulo použití rastrové grafiky, která~je~velmi závislá na~rozlišení. Aktuálně všechny UI~elementy jsou tvořeny ještě starou metodou, pro~udržení konzistentního vzhledu. V~budoucnu bychom určitě využili této~možnosti. \item Přepracované vykreslování textů -- rychlejší vykreslování a~efektivnější využití paměti. \item MetaSound\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/metasounds-the-next-generation-sound-sources-in-unreal-engine} pro~přehrávaní nebo procedurální generování zvuků, který~nahrazuje starou třídu~Cue. De-facto se~jedná o~Digital Signal Processing (DSP) grafový engine a~editor. Bohůžel jsem nestihl tento nástroj využit v~práci. \item World partition systém\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/world-partition-in-unreal-engine}, který~dokáže automaticky rozdělit jeden velký svět na~streamovací kousky a~propojit sdílení dat mezi nimi i~při multiplayer hře přes internet. Taky není využit v~této práci. \end{itemize} Samozřejmě je~toho daleko víc, ale~většina ostatních vylepšení jako~rovněž nový systémy animací postav Motion Matching\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/motion-matching-in-unreal-engine} nebo~nový fyzikální engine Chaos\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/destruction-overview} neměly vliv na~rozhodnutí. Podrobné informace jak~každá implementace funguje a~jak s~ní~pracovat, je~popsáno v~přiložené programátorské dokumentaci. \section{Herní logika, systémy, mechaniky} \label{sec:systemsAndMechanics} \subsection{Architektura} Protože Unreal Engine byl~na~začátku vyvíjen primárně pro~online multiplayer hru Unreal Tournament a~dnes~je stejně~tak vyvíjen spolu s~extrémně velkou online multiplayer hrou Fortnite, je~backend enginu velmi abstraktní. Například každý svět musí obsahovat vlastní game mode (třída AGameMode), který~funguje jako~správce daného světa -- přestože svět se~může spravovat sám. Veškerá funkcionalita používaná v~singleplayer hrách mohla být přímo v~kódu levelu nebo~v~globální instanci celé hry. Důvodem této abstrakce je~právě nativní podpora multiplayer her, která~potom vývoj takových her zjednodušuje. Protože tento projekt je~zaměřen pro~hru jednoho hráče, práce je~často programována navzdory ustáleným UE~C++ zásadám (guidelines) pro~pohodlí a~rychlost vývoje. Proto~často třídy manažerů systémů, game~modů, instance hráče a~další jsou na~architektuře singletonu. Přináší~to nejen zmíněné pohodlí, ale~navíc šetří od~tří do~deseti volání getterů, reflexí (castů), vyhledávání v~hash tabulkách a~iteraci polí v~každém místě použití. Přesto nemá žádný vliv na~stabilitu programu a~dokonce šetří výkonem zařízení. Jen pro představu, co~obnáší klasické získání reference na~instanci vlastní třídy hráče na~pozadí. GetGameMode()\textrightarrow GetPlayerController(index)\textrightarrow GetPlayerPawn()\textrightarrow Cast(). A~blueprinty disponují zkrácenou verzí GetPlayerPawn(index)\textrightarrow Cast(). V~případě~C++ je~potřeba navíc ověřovat zda~nějaké z~volání nevrátilo nullptr. \subsection{Scény a ukládání hry} Scény, resp. levely (třídy UWorld a ALevelScriptActor)\footnote{UWorld instance je~přímo celý svět, který~funguje jako~balík metadat a~kontejner pro~veškeré instancované objekty v~něm. ALevelScriptActor je~objekt instancovaný v~UWorld automaticky a~obsahuje uživatelskou logiku světa.}, lze~taktéž získat v~podobě singletonu. Základní implementace byla~rozšířená pro~high level mechanismus volání událostí ve~scéně. Ten~je~zapotřebí například, když~hráč aktivuje spínací plošinu ve~hře a~ta~následně otevře dveře. \newpage Na rozdíl od~jiných enginů, v~UE objekty ve~světě nemůžou referencovat jiné~nezávislé objekty. Jednoduše referenci nelze přiřadit z~důvodu abstrakce popsané v~předchozí podsekci, protože~každý objekt může~mít vlastní herní svět (a~nejen~to). Proto~pokud~plošina z~našeho příkladu chce otevřít dveře, musí~zkusit poslat požadavek správci herního světa, ten~požadavek se~nějak zpracuje a~teprvé~poté správce buď~provede akci otevírání dveří samostatně nebo~zavolá odpovídající funkci v~instanci objektu. Pokud~by~bylo potřeba opustit singleton architekturu pro~podporu paralelní existenci světů, stačí předělat členskou (member) funkci instance světa na~statický multicast delegate\footnote{Delegate jsou obaly na~C++ funkce, lambdy, funkce s~reflexi a~funkce z~Blueprintu. Delegate může~být typu single, pro~uložení reference na~jednou funkci, nebo~multicast pro~uložení dynamického seznamu funkcí. Podrobněji jsou~popsané v~programátorské dokumentaci.}, ke~kterému se~každý svět při~konstrukci bude vázat. Navíc hra byla rozšířena o~implementaci obnovení hry z~úložených dat. Při~návrhu byla~snaha udělat postup co~nejjednodušší. Hra se ukládá pomoci globální herní instance (třída GameInstance)\footnote{GameInstance je~první objekt vytvořený enginem hned po~úvodním načtení základu enginu a~taky poslední objekt na~destrukci při~vypínání hry.} při~vypínání hry a~načítá taktéž při~spuštění. Byl~využit existující systém serializace v~UE, který~ukládá inventář postavy, jméno levelu a~checkpoint na~něm spolu s~posledním stavem levelu. \subsection{Interakce} Interakce jsou~často řešeny pomocí architektury interface tříd\footnote{Interface třídy jsou~konkurenčním přístupem komponentní architektuře. Interface je~běžná praktika v~OOP (Objektově Orientovaném Jazyce), která~funguje jako~domluva, že~objekt bude obsahovat určité member funkce. Komponenty jsou~samostatné určité podinstance objektu. Komponentní přístup se~osvědčuje jako~intuitivnější a~více flexibilní zatímco Interface přístup při~vývoji her je~spíše nepříjemné vynucení ze~světu~OOP.} především kvůli populárním návodům vyzdvihující tuto metodu jako~nejlepší ještě~z~doby, kdy~Unreal Engine~4 pouze vznikal. Nevýhodou je~potřeba v~obsáhlém a~repetitivním nastavení každého objektu, který~chceme zapojit do~mechaniky interakce. Byl navržen komplexní systém pro~správu každého interakčního objektu a~komponent (viz.\Cref{fig:InteractableSystemDiagram}). Objekt dědící třídu AInteractable při~instancování samostatně nastaví a~následně přepíná potřebné kolize. Zároveň spravuje interakční komponenty a~reaguje na~požadavky, které~jsou na~ně směřovány. Komponenty se~dělí na~aktivátory a~modifikátory. \begin{figure} \centering \includegraphics[width=1\linewidth]{img/InteractableSystemDiagram.pdf} \caption{Diagram zpracování systému interakčních objektů.} \label{fig:InteractableSystemDiagram} \end{figure} \newpage \paragraph{AInteractableActivator} Aktivátory jsou~komponenty s~určitými mechanismy detekce objektů. Instance hráče automaticky vytváří pro~sebe jednu podinstanci každého aktivátoru registrovaného v~enginu. Libovolný objekt může rovněž obsahovat libovolný aktivator. Práce obsahuje klasický způsob detekce objektů pomoci ray~tracingu a~následného dereferencování objektu v~případě nárazu paprsku. Navíc je~k~dispozici detekce objektů v~zorném poli hráče. Ta~funguje na~zpomaleném snímání určité stencil vrstvy\footnote{Stencil Buffer sousedí s~Z-Bufferem a~má~pouze jeden osmi~bitový celočíselný kanál. Slouží především jako~pomocník při~tvorbě specifických renderovacích technik a~efektů. Nejběžnější použití je~renderování obrysů objektů, označení objektů pro~následné zpracování v~nějaké render pipeline a~tvorba portálů.} s~vynecháním většiny render pipeline a~v~malém rozlišení. Zachycený snímek obsahuje pouze viditelné hráčem interakční objekty v~podobě masky. Následně je~maska v~grafickém vlákně zpracovaná pomocí algoritmu vyhledávání komponent z~počítačového vidění, kterou~poskytuje knihovna OpenCV. Nakonec do~středu nalezených komponent se~promítne paprsek a~zachytí objekty (viz.~\Cref{fig:InteractableScreenCapture}). Původně bylo předpokládáno využití HLSL compute shaderu\footnote{High-Level Shader Language je~proprietární shader jazyk používaný v~DirectX.} pro~vyhledání komponent v~textuře, ale~z~časových důvodů jsem nedodělal přenos dat mezi CPU a~GPU, jelikož dohledat dokumentaci o~použití shaderu je~poměrně náročné. Proto~aktuální vyhledávání komponent je~spouštěno na~procesoru a~v~renderovacím vlákně na~moderních zařízeních trvá pět až~deset milisekund. V~praxi se~tento problém často řeší náhodným promítáním velkého množství paprsků nebo~velkého hitboxu napodobujícího tvar pohledového frustrumu kamery. Tato řešení jsou sice~rychlá na~implementaci, avšak~při~větších vzdálenostech vykazují výrazné snížení přesností a~větší spotřebu výpočetních prostředků. Navíc zahrnují časté počítání nárazů na~velké množství objektů, čímž~výkonnostně nejsou o~nic~lepší metody implementované v~této práci. \begin{figure} \centering \includegraphics[width=1\linewidth]{img/InteractableScreenCapture.pdf} \caption{Debug náhled aktivace interakčních objektů v zorném poli hráče.} \label{fig:InteractableScreenCapture} \end{figure} \paragraph{AInteractableModificator} Modifikátory jsou~komponenty s~určitou logikou libovolné modifikace objektu, ve~kterém jsou~instancovány. Tyto~komponenty mohou obsahovat pouze objekty označené jako~interakční (dědí třídu interakčního objektu). Aktuální implementace nabízí modifikátory pro~aktivaci nějaké události pomoci dosahu~,,ruky'' nebo zahlédnutím~,,očima'' hráče, pohyb a~rotace předmětu v~prostoru, ukládání předmětu do~inventáře hráče. Z~časových důvodů byla zamítnuta implementace modifikace geometrie objektu, která~by~využívala nového rozhraní Chaos. Největší přínos nového systému zpracování vstupu v~Unreal Engine~5 se~projevil právě u~modifikátorů. Ty~využívají možnost dynamického přidávání nebo~odstraňování vstupních kontextů za~běhu. \subsection{Cutscény a Quick Time Events} Unreal Engine je~známý~tím, jak~dobře umožňuje animovát scény. Rozhraní a~editor systému Sequencer jsou~přívětivé a~nabízejí široké možnosti. Bohužel~však většina těchto výhod končí mimo samotný editor, jelikož~chybí pohodlné prostředky pro~režii různých souborů animací (totéž platí i~pro~UI animace). Proto byl~dodán systém UCutsceneManager implementující frontu animací spolu s~uživatelským rozhraním pro~jejich přeskakování. Pro~přiblížení problému, vyjmenuji časté potřeby, které~vznikají při~běžném použití animací. \begin{itemize} \item Zároveň spuštěné animace bojují o~vlastnictví objektů, \item animace nelze přetáčet, \item u~animace nelze zjistit zpětně zda~byla přehrána až~do~konce, pouze přivázat volání funkce po~ukončení, \item systém dokáže určit, zda~se~animace někde přehrává, ale~není schopen ukázat, kde~přesně. \end{itemize} Převážně pro~použití v~animacích je~implementována fronta rychlých interaktivních událostí (QTE - Quick Time Events), což~jsou~interaktivní UI~elementy na~obrazovce hráče. V~herním průmyslu jsou~využívány zejména v~cutscénách, pro~,,hlubší ponoření'' hráče do~děje. Klasickými příklady jsou~animace šplhání herní postavy po~nějaké překážce nebo~kinematografický souboj mezi postavami. Při~takových událostech lze~přiblížit hráče k~dynamické a~napínavé situaci pomocí klikání na~stejně dynamické UI~elementy na~obrazovce v~souladu s~pohybem herní postavy. V~praxi se~objevují i~pokročilejší varianty napodobení děje pohybem myší a~joystickem nebo~gyroskopem ovládače. V~implementaci jsou~k~dispozici eventy jednotného a~vícenásobného klikání a~držení tlačítka v~časovém intervalu. \subsection{Dialogy} V~enginu je~zavádějící implementace pokročilého dialogového systému. Dialogy jsou~neintuitivní pro~tvorbu a~použití, vyžadují časté repetitivní kopírování stejných parametrů mezi~soubory dialogů a~k~tomu celý systém má~nedostatečnou dokumentaci. Navíc~,,dialogy'' v~tomto systému jsou~pouze samostatné věty, které~musí přehrávat nějaký zvuk a~mohou se~vybírat v~závislosti na~omezeném kontextu typu "kdo~na~koho mluví". O~nepoužitelností takového rozhraní svědčí návody na~tvorbu vlastních dialogů nebo~vývojářský obchod plný pluginů implementujících tento systém lépe. \newpage Protože kvalitní řešení jsou~placená a~ty~zdarma jsou~často nevyhovující kvality, byla~navržená vlastní implementace. Jedná~se o~frontu, která~umí přehrávat celé tabulky dialogových vět. Dialog, resp.~množinu vět společného kontextu, lze~pohodlně zapsat do~tabulkového formátu přímo v~editoru. Jednotlivá věta obsahuje id, text, dobu přehrání nebo~zvukovou stopu. Ve~výsledku lze~do~fronty zařadit několik tabulek, které~se~mohou přehrávat sekvenčně od~n-té věty po~poslední, jednu náhodnou větu nebo~přesně jednu větu podle id. \subsection{Minihry} Herní průchod druhého levlu je~celý složen z~miniher. V~době vydání práce obsahuje pouze pět~hlavních miniher v~podobě ,,proof of~concept''. Z~časových důvodů nebyly vedlejší minihry implementovány. Každá z~miniher je~parodie na~již existující známou hru. Minihry jsou samostatné objekty, které~může správce scény restartovat nebo~vypnout. Po~spuštění si~minihra sama přepne kontext ovládání na~sebe a~řídí svůj vlastní stav. Jestli~minihra nebyla ukončena dočasně, ale~dohraná, vráti ovládání zpět hráči spolu s~výsledkem a~skóre. Dostupné zkušební implementace: \begin{itemize} \item Parodie flash hry Age of~War. V~pozadí scény s~úklidem učebnic dějepisu jsou~umístěny základny hráče a~soupeře (umělé inteligence). Hráč ovládá minihru pomicí~UI, kde~nakupuje jednotky typu: pěšák, střelec a~tank. Peníze získává za~zničení nepřátelských jednotek. Vyhrává ten, kdo~dokáže proniknout přes obranu nepřítele až~k~jeho základně a~zničit~ji. V~aktuální implementaci chybí vylepšení jednotek, zvuky, grafické efekty, modely a~animace jednotek. Přesto~lze vyzkoušet nákup a~,,souboj'' jednotek. \item Parodie na~mobilní hru Subway Surfers. Aktuálně má~minihra nevhodné pozadí, neobsahuje audio a~grafické prvky. Podle návrhu hráč nahání veverku v~lese, která~mu ukradla část důležitého pro~příběh předmětu. Pomocí pohybů nahoru, dolů, vlevo a~vpravo se~hráč vyhýbá objevujícím se~překážkam v~lese. Překážková dráha má~šířku tří~běžeckých pruhů a~překážky mohou vyžadovat přeskočení, sklouznutí nebo~úhyb do~strany. \item Podoba počítačové rytmické hry Osu!. Hráč má~za~úkol klikat na~objevující~se na~obloze hvězdičky v~souladu s~rytmem hudby (v~pořadí ve~kterém se~objevily). Aktuálně ,,hvězdičky'' jsou~v~podobě čtverečků, ale~hudba je~zcela hotova. Již~teď lze vyzkoušet klikání během prvních 10~sekund hudby. \item Podoba mobilní hry Crossy Road. Hráč pomocí pohybu dopředu, dozadu, doleva a~dolů potřebuje posouvat se~vpřed po~překážkové dráze. Dráha je~složená z~pěti~pruhů kolmých ke~kameře, a~každý pruh je~složen z~dvanácti políček, na~které~může stoupnout hráč. Náhodně na~krajích pruhu se~objevují divoká zvířata, laviny a~silný vítr (v~originální hře to~jsou auta na~silnici), které~se~posouvají k~opačnému kraji přes všechna políčka a~mohou ukončit běh hráče. Podle návrhu se~minihra odehrává v~ledovém prostředí, kde~hráč prochází sněžnou krajinou. Audiovizuální prvky opět nejsou k~dispozici, ale~již~teď lze vyzkoušet posun dopředu a~úhyb překážkám. \item Jednoduchá minihra rybolovu (více podob napříč různými hry). Hráč má~na~obrazovce svislý obdélníkový indikátor znázorňující vodní hlubinu. Podél indikátoru se~náhodně pohybuje obrázek rybičky, kterou~hráč musí udržovat v~malé pohyblivé zóně. Zóna se~pohybuje automaticky dolů nebo~nahoru držením tlačítka myší (rychlost pohybu není lineární, ale~kvadratická). V~implementaci chybí zvukové assety a~vyváženost složitosti, ale~je k~dispozici kompletní~UI a~mechanika lovu. \end{itemize} \subsection{Nehratelné postavy} Pro~tvorbu NPC (Non-Playable Characters) byly použité základní prostředky enginu. Podle návrhu hry, k~dispozici měly~by~být tři~druhy logiky pro~NPC, ale~z~časových důvodů jsou~implementovány pouze~dvě. Jedno~z~chování je~pouhá chůze k~dynamickým bodům. Toto~základní chování se~potom rozděluje na~střežení oblasti nebo~boj s~hráčem. Postavy, které~střeží oblast využívají v~UE5 nový systém vjemů nehratelných postav. Postavy umí reagovat na~zvuky, dotyky nebo~zahlédnutí jiných objektů. Toto~je~využito pro~postavy, které~hlídají vězení v~levelu 4. Ty~patrolují předem navržené trasy a~spouští určité akce až~zahlédnou hráče. V~implementaci chybí kompletní logika boje s~hráčem. Aktuálně postavy pouze běží k~hráči pokud ho~zahlédnou. Zbytek nedodělané logiky je~spíš vizuálního charakteru a~spočíval~by v~jednoduchých animacích použití střelné nebo~ruční zbraně ve~hře. Každé chování využívá Navmesh pro~orientaci na~úrovni. \subsection{Nastavení} Hra využívá existující v~enginu de/serializaci v~textovém formátu~,,.ini''. Při~exportu hry v~podobě samostatného buildu lze~využívat i~binární formát konfiguračních souborů. Tento~přístup značně zjednodušuje tvorbu konfiguračních proměnných. Díky~tomu stačí pro~tvorbu vlastních parametrů pouze~deklarovat potřebné proměnné v~C++~třídě. Triviálně se~pracuje s~preferencemi hráče, které~určují hlasitost různých kategorií zvuků nebo~preferencemi ovládání. U~těchto preferencí stačí pouze~přečíst resp.~zapsat hodnotu. Jednoduché to~přestává~být v~momentě nastavení kvality grafiky a~parametrů zobrazení okna aplikace. Zejména změny zaměřené na~okno aplikace mohou způsobit pád~aplikace nebo~ještě hůř zablokovat vstup celého počítače a~donutit uživatele ke~kompletnímu restartování zařízení. Takové~situace mohou nastat celkem běžně, a~nemusí znamenat problém v~aplikaci. Například předčasný zásah~OS k~neodpovídajícímu procesu (hra se~delší dobu načítá po~aplikování nového nastavení) nebo~nevhodná reprezentace rozlišení, které~monitor nebo~GPU uživatele nepodporuje. V~libovolném případě hra musí~být~schopna obstát nečekané závady, a~proto byl~navržen mechanismus obnovení předchozích funkčních nastavení. Po~zvolení nových parametrů a~jejich aplikování, hra nejprv~uloží stávající nastavení a~až~poté aplikuje ty~nová. Po~aplikování a~až se~proces okna vrátí zpět do~renderujícího stavu, v~menu se~objeví okénko po~dobu pěti~sekund očekávající schválení od~uživatele. Pokud~uživatel stihne potvrdit úspěšnou změnu parametrů, jsou~uložené jako~funkční. Pokud~uživatel z~libovolného důvodu změnu neschválí, potom jsou~obnoveny předchozí parametry. \newpage Právě nastavení zobrazení okna (a~výběr zhlazovácí metody) byly implementovány navíc, jelikož~nejsou volně k~dispozici v~high-level implementaci enginu. Jedná~se~o~možnost výběru rozlišení a~jeho třídění podle poměru stran, změna režimu vykreslování okna (bezokenní, okenní bez~rámce, okenní s~rámcem) aЁzměná obnovovací frekvence. Při~výběru a~nastavení rozlišení se~pracuje přímo s~DirectX\footnote{DirectX je~množina API pro~práci s~grafikou a~převážně pro~počítačové hry.} rozhraním a~zhlazovací metoda se~nastavuje přes~příkazové rozhraní enginu. \section{Návrh tvorby generativního obsahu a jeho načítání za běhu} \label{sec:contentGenerationAndIntegration} \subsection{Možností generativních modelů v tomto projektu} Herní úrovně jsou navrženy~tak, aby~pokrývaly rozsáhlé herní žánry a~situace, které~dosud~nebyly nebo~nejsou~často využívané s~generovanou tvorbou. \begin{enumerate} \item Level je~zaměřen na~tvorbu hororového obsahu. Je~to~skvělá příležitost vývoje a~použití modelu, který~využívá naše~fyzické, chemické a~psychické znalosti o~lidském organismu, aby~dokázal generovat strašidelný obsah a~následně ho~vhodně začlenit. \item Level slouží k~testování modelu schopného tvorby libovolných miniher. Nabízí~se~tady~taktéž online tabulka skóre pro~základní a~vygenerované minihry. \item Level existuje pro~generování nových logických úseků a~úkolů a~modifikaci stávajících logických překážek. Například nová logika zapojení kabelů v~elektrotechnické místnosti nebo~přestavba bludiště. \item Level umožňuje vyzkoušet generování sekvencí chodeb. Chodby by~musely obsahovat patroly a~kryty~tak, aby~hráč dokázal nenápadně prolézt skrz patroly. \item Poslední Level bude testovat schopnost navržení herních nepřátel, jejich logiku a~rozmístění na~úrovni. \end{enumerate} \subsection{Návrh architektury} Architektura generování obsahu je~založená na~použití zřetězení různých modelů a~kontrolních mechanismů. Kompletní řetězce modelů jsou~nasazeny na~soukromých serverech, které~v~různých intervalech nezávisle produkují nové assety. Po~generování jsou hotové soubory přemístěny na~veřejné úložiště, odkud~hra při~zapínání stahuje několik~,,náhodných'' assetů (přesnou definici výběru obsahuje \cref{par:contentSharing}). \paragraph{Fine-tuning} V~podobě open-source je~k~dispozici většina potřebných druhů modelů. Po~analýze vyplývá, že~bude~potřeba vytvořit pouze jeden~model, který~bude~schopen pracovat s~kódem v~Unreal Engine. Je~to~potřeba pro~programování assetu nebo~aspoň~jeho~umístění ve~světě hry. Nejjednodušší a~zároveň efektivní cesta je~založená na~fine-tuningu resp.~dotrénování modelu, který~se~již~využívá pro~programování. \newpage Dotrénování může~mít více~podob. Nejspíš by~se~jednalo o~fine-tuning programovacího modelu v~C++ s~dodatečnou syntaxí Unreal Enginu nebo~fine-tuning tvorby diagramů v~Blueprintech. Výsledné blueprinty potom~lze konvertovat do~Python příkazů, které~vytvoří vygenerovaný diagram v~editoru. Nelze jednoznačně říct, který~přístup je~vhodnější. Pro~C++~model je~k~dispozici více dat a~toto prostředí umožňuje větší tvůrčí svobodu, přestože~může zhavarovat aplikaci. Blueprinty jsou~zdaleka bezpečnější, ale~na~oplátku bude~těžší sbírat trénovací data. \paragraph{Postup generování} Vše~by~začínalo v~textovém modelu, který~vytvoří typ a~popis generovaného objektu. Pomocí třídícího mechanismu se~vybere příslušná množina dalších modelů, kontrolních mechanismů a~konverzních nástrojů. Asset bude~postupně procházet takovým řetězcem až~nabyde finální podoby. Na~konci bude~vždy kontrolní mechanismus, který~zvaliduje soubor a~ověří funkčnost assetu pomocí unit-testů ve~hře. Pokud~asset neprojde validací, celý postup, soubor a~vstupní popis se~zaznamenají pro~budoucí ruční doladění modelu. Příklad tvorby interakčního objektu: \begin{enumerate} \item LLM vytváří popis assetu, v~tomto případě interakční objekt, který~přehrává specifický zvuk a~je~umístěn na~konkrétním místě v~levelu~3. \item Kontrolní mechanismus vybírá následující potřebné modely a~nástroje. \item Popis prochází modelem generující obrázky. \item Obrázky prochází modelem generující 3D~model (nejdřív se~generuje 360°~video potřebného objektu, ze~kterého se~následně generuje mesh). \item Další část popisu je~použita modelem generující zvukové stopy. \item Poslední část popisu se~vloží do~našeho dotrénovaného programovacího modelu. Tento~model se~zároveň stará o~umístění assetu v~herních světech, protože~jako~jediný je~natrénovaný na~kontext této~hry. \item Výsledné kousky linkovací mechanismus spojí do~jedné~třídy resp.~vloží do~jednoho Blueprintu. Předtím převede jednotlivé části na~assety v~enginu a~případně aktualizuje cesty referencí. \item Konečný asset se~zkouší na~kompilaci a~prochází unit-testy. Pokud~tento~krok bude úspěšný, asset je~exportovan v~podobě~DLC nebo~patch~obsahu. Jinak~popis, vygenerováné částí a~výsledek se~logují pro~budoucí investigaci. \end{enumerate} \subsection{Poskytování obsahu} \paragraph{Nasazování generátoru} Nezávislé řetězce modelů zjednodušují řízení sítě workerů. Pomocí Docker kontejneru\footnote{Docker je~software umožňující lokální virtualizaci prostředí nazývané kontejnery. Kontejnery jsou~předvytvořené samostatné prostředí s~potřebnými nástroji.} nebo~nasazovacího skriptu by~se~snadno vytvořil další worker (naše~generující jednotka), který~může ihned~začít s~generováním. Vygenerovaný obsah je~poté přemístěn na~veřejné úložiště, tedy~worker nepotřebuje nijak~velké vlastní úložiště. \newpage Protože~workery nemusí~odpovídat na~požadavky uživatele v~reálném čase a~plánovaná doba jedné hry je~15-30~minut, generátory nemusí~být~rychlé a~tedy~ani~náročné na~výpočetní prostředky. Nezáleží~nám ani~na~dlouhodobé životnosti workerů, jelikož~modely se~často sekvenčně přepínají (běží vždy pouze jeden model najednou). Takový~přístup přináší flexibilitu v~řízení prostředků a~umožňuje ukládat mezistavy generátorů. Dokonce nepotřebujeme nijak~velkou propustnost sítě, protože~jednoduché assety nemohou přesahovat velikost jednotek megabajtů a~jistě~máme větší časové intervaly mezi~vznikem souborů. \paragraph{Stahování obsahu}\label{par:contentSharing} Hra automaticky stahuje a~aktivuje obsah před začátkem nové hry. Z~podrobné analýzy jsem~rozhodnul, že~nejsou~zapotřebí žádné autentifikační nebo~šifrovací vrstvy. Vždy~by~byla~možnost zpětnou analýzou (reverse-engineeringem)\footnote{Reverse-engineering je~metoda analýzy hotového produktu (v~nášem~případě binárního souboru), pro~získání neveřejných informací popisujících funkčnost produktu.} získat klíč z~binárních souborů hry a~napadnout celý systém. Když~se~nad~tím zamyslíme, volný přístup k~generovaným assetům nemá žádné zápory. Je~jednoduchý na~implementaci a~údržbu. Očekává~se ale připojení pomocí HTTPS\footnote{Hypertext Transfer Protocol Secure je~protokol pro~šifrovaný přenos dat využívaný pro~poskytování webových serverů.} a~ověření certifikátu\footnote{Certifikáty v~digitální podobě jsou~řetězcem veřejných asymetrických klíčů různých vydavatelů. Každý~předchozí vydavatel ručí za~důvěryhodnost dalšího vydavatele.} s~kopií uloženou v~aplikaci. Mohlo~by~totiž dojít k~man-in-the-middle útoku\footnote{Man-in-the-middle (MITM) je~druh kyberútoku, ve~kterém útočník tajně sleduje nebo~upravuje komunikaci mezi~dvěma uzly.} a~hráč by~mohl spustit ve~hře nebezpečný obsah. Hra zahájí stahování pomocí API, který~vybere nějaké soubory. V~základu assety jsou~vybírány náhodně, ale~zároveň se~používá hodnocení získané od~hráčů, které~váhově lehce~mění hustotu pravděpodobnosti normálního rozdělení. \paragraph{Hodnocení obsahu} Poté, co~si~hráč zahraje s~určitým assetem, máme~možnost získat zpětnou vazbu od~hráče. Hodnocení využíjeme k~váhové manipulaci náhodného výběru a~zároveň jako~data pro~doladění generátorů. Návrh~systému hodnocení staženého obsahu je~již náročnější problém. Úkolem je~umožnit pouze unikátní hodnocení a~pouze od~hráčů, kteří~si~s~tímto obsahem opravdu zahráli. Protože~nemáme žádnou autentifikaci, volné~hodnocení nemusí fungovat. Kdokoliv může~spamováním falešných hodnocení přemístit špatně hodnocený obsah do~kategorie lepších a~naopak. Autentifikace tomu~také nezabrání, pouze~oddálí takovou situaci. Některé hry v~praxi používají sofistikováné metody využívající detekci nelegální kopie hry, nebo~využití API herních obchodů (achievementy, odznaky, ID~účtu~atd.). Takové metody se~zdají~být účinné, ale~už~dávno se~lehce obchází pomocí triviální simulace odpovědí API. Táto práce nabízí sledování ID~účtu hráče, který~hru zahrál a~jeho seznam stažených souborů, pokud~hra bude šířená na~platformě Steam. UUID (Unique User Identifier) účtu ví~pouze vlastník účtu, čili~je~to citlivá informace. Proto~před odesláním takových dat je~budeme vždy šifrovat asymetrickým klíčem (veřejným certifikátem webu ze~kterého~zároveň obsah stahujeme). Až~bude hráč chtít ohodnotit ve~hře obsah se~kterým~zahrál, API~zkontroluje zda~UUID~hráče na~Steamu opravdu vlastní hru, že~toto~UUID stahovalo tento~obsah z~našeho serveru a~že~toto~UUID ještě tento~obsah nehodnotilo. Pokud~by~hra byla~šířená zdarma, bude~potřeba zavést omezení na~N~hodnocení denně pro~jedno~UUID, protože~bude~možné bezproblémově vytvářet falešné účty. Jinak, z~ekonomických důvodů, nám~nebude vadit, že~někdo bude~nakupovat hru víckrát, aby~víckrát nevhodně ohodnotil obsah. Pořád bude možné reverse-engineerovat~API a~zapsat stažení libovolného obsahu pro~nějaký účet. Taková situace je~zcela zanedbatelná, jelikož~jedno~hodnocení má~malý vliv na~průměr ve~větších číslech. \subsection{Problémové typy obsahu} Již teď je možné předpovědět co~nebude kompletně fungovat nebo~nebude fungovat v~dostatečné kvalitě. \begin{itemize} \item Herní obsah tvořený ručně nástroji v~editoru vyžadují samostatné modely. Například animace objektů na~levelu tvořené v~Sequencer, tvorba~UI~v editorovém designeru, práce~se~zvuky v~Cue, statická tvorba úrovní a~tedy i~Landscape nebo~foliáž a~tvorba fyzických objektů (simulace tkáně, destrukce, pružnosti a~dalších~jevů). Pravděpodobně i~jiné, ale~víc technologií v~této práci využito nebylo. \item Materiály též vyžadují vlastní model, ale~jsou tvořeny pomocí grafových prvků podobné blueprintům a~máme k~dispozici velké~množství dat pro~trénování takového modelu. V~základu můžeme vystačit si~bez~generování materiálů a~pouze vytvářet variace barev. \item Grafické provedení generovaných objektů může~mít velký dopad na~výkon hry. Optimalizaci může provést další model, který~bude provádět retopologii\footnote{Retopologie je proces zjednodušení složité topologie 3D~objektu bez~značně viditelných změn.} a~pro~tvorbu kolizí lze~použít k-DOP\footnote{k-DOP (k-Discrete Oriented Polytope) je~jeden z~postupů obalování složitých 3D~objektu do~jednodušších tvarů.} algoritmus dostupný~v~UE. \end{itemize} \section{Grafika} \label{sec:graphics} \subsection{Statické objekty} \subsection{Dynamické a procedurální objekty} %kytky %trava \subsection{Osvětlení, efekty, Post-Processing} \subsection{Materiály a shadery} \subsection{UI} \subsection{Načítací obrazovka} \subsection{Textové překlady} \section{Audio} \label{sec:audio} \subsection{Kategorie a parametry audio assetů} \subsection{Dynamický hudební doprovod} \subsection{Dabing dialogů} \section{Tipy při vývoji v UE} \label{sec:UETips} \paragraph{Skripty pro editor} % Blueprunty a python \paragraph{C++ typy a reflexe} \paragraph{Kompilace a export projektu} \section{Co se nestihlo nebo změnilo}