Compare commits

...

No commits in common. "master" and "gh-pages" have entirely different histories.

43 changed files with 0 additions and 4489 deletions

View File

@ -1,42 +0,0 @@
name: CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
build:
name: Build thesis PDFs
runs-on: ubuntu-latest
container: { image: 'aergus/latex' }
steps:
- name: Install nodejs
run: apt-get update && apt-get install -y nodejs
- uses: https://gitea.com/ScMi1/checkout@v1
- name: Build the thesis
run: latexmk thesis && latexmk abstract-cz && latexmk abstract-en
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: Thesis
path: |
*.pdf
verify:
name: Verify PDF/A
runs-on: ubuntu-latest
needs: build
container: { image: 'ghcr.io/mff-cuni-cz/cuni-thesis-validator' }
steps:
- name: Install nodejs
run: apt-get update && apt-get upgrade -y && apt-get install -y curl && curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
- name: Get PDFs
uses: https://gitea.com/actions/download-artifact@v3
- name: Run VeraPDF
run: verify Thesis/*.pdf | tee /dev/stderr | grep -qE 'nonCompliant="0" failedJobs="0"'

View File

@ -1,35 +0,0 @@
name: CI
on:
push:
branches: [ master ]
jobs:
build:
name: Build thesis PDFs and push them to pages
runs-on: ubuntu-latest
container: { image: 'aergus/latex' }
steps:
- name: Install nodejs
run: apt-get update && apt-get install -y nodejs
- uses: https://gitea.com/ScMi1/checkout@v1
- name: Build the thesis
run: latexmk thesis && latexmk abstract-cz && latexmk abstract-en
- name: Prepare a website directory
run: |
mkdir -p public
cp -v thesis.pdf public
cp -v abstract-*.pdf public
- name: Upload to gh-pages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd public
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git config --global user.name "$GITHUB_ACTOR"
git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com"
GIT_WORK_TREE=. git checkout --orphan gh-pages
GIT_WORK_TREE=. git add .
GIT_WORK_TREE=. git commit -m 'pages'
git push --force --set-upstream origin gh-pages

27
.gitignore vendored
View File

@ -1,27 +0,0 @@
*.aux
*.bbl
*.bcf
*.blg
*.dvi
*.fdb_latexmk
*.fls
*.idx
*.ilg
*.ind
*.lof
*.log
*.lot
*.nav
*.nlo
*.nls
*.out
/*.pdf
pdfa.xmpi
*.snm
.*.swp
*.synctex.gz
thesis-blx.bib
thesis-run.xml
thesis.run.xml
*.toc
*.vrb

View File

@ -1,27 +0,0 @@
#
# This GitLab CI configuration builds the thesis on each push
# The thesis is stored as an repository artifact
#
# It works with the gitlab.mff.cuni.cz instance.
#
stages:
- build
- verify
latexmk:
stage: build
image: aergus/latex
script: |
latexmk thesis && latexmk abstract-cz && latexmk abstract-en;
artifacts:
paths:
- thesis.pdf
- abstract-cz.pdf
- abstract-en.pdf
verapdf:
stage: verify
image: ghcr.io/mff-cuni-cz/cuni-thesis-validator
script: |
verify *.pdf |tee /dev/stderr |grep -qE 'nonCompliant="0"'

View File

@ -1 +0,0 @@
$pdf_mode = 4

View File

@ -1,12 +0,0 @@
NAME=thesis
ABSTRACT=abstract
LATEXMKOPTS=-pdflua #you can also use -pdf for forcing pdflatex, if required
LATEXMK=latexmk $(LATEXMKOPTS)
all:
$(LATEXMK) $(NAME)
$(LATEXMK) $(ABSTRACT)-cz
$(LATEXMK) $(ABSTRACT)-en
clean:
$(LATEXMK) -C

View File

@ -1,90 +0,0 @@
# A slightly improved thesis template
What's new:
- modern packages (biblatex, cleveref, better fonts)
- less confusing directory structure
- slightly more useful examples (figures, diagrams, tables, code listings),
structure&writing hints, some goodies
- autobuilding of PDF/A abstracts directly from metadata
- multiple variants of the front page
- MFF with the new logo
- "traditional" UK variant
- Nature faculty & bioinformatics
- Czech localization with properly translated references
- Automated docker-based & CI build options
See the [pre-built version](https://exaexa.github.io/better-mff-thesis/thesis.pdf) for details.
## CI configuration
The repository contains valid configuration for both *GitLab* CI and the *GitHub* actions.
No matter what Git hosting you use, you can always download latest version of your thesis right from the artifacts!
The GitHub version additionally pushes the files to GitHub pages to enabler easier sharing (incl. the link above); you can disable that by removing `.github/workflow/pages.yml`.
## How-to
1. Type `make`, check that everything compiles. You should get a `thesis.pdf` that passes the [PDF/A validation](https://github.com/mff-cuni-cz/cuni-thesis-validator). If not, complain.
2. Fill in `metadata.tex` and all `xmpdata` files.
3. Look at the example code (there is plenty of advice to follow), then erase it.
4. Write the thesis.
5. Submit and defend the thesis.
### Installing LaTeX
LaTeX installation may be hard (especially on various substandard operating systems).
On most BSD and GNU-style Linux distributions, it should be sufficient to install some random `texlive-*` packages (and add more if non-standard TeX functionality is required); see e.g. [a complete list for Debian](docker/Dockerfile).
- For a single-user distribution on unix, use the provided [installation script](https://www.tug.org/texlive/quickinstall.html).
- On windows, use [MiKTeX](https://www.tug.org/texlive/windows.html).
- On Mac, use any suitable variant of [MacTeX](https://www.tug.org/mactex/).
Optionally, you can use a Docker container with TeX. You can either build the image yourself from the supplied `Dockerfile`:
```sh
cd docker
docker build -t betterthesis/latex .
```
...or get some pre-built one (which is usually much faster:
![image size](https://img.shields.io/docker/image-size/aergus/latex)
)
```sh
docker pull aergus/latex
```
After that, you should be able to compile the thesis using this command (change the container name to `betterthesis/latex` in case you built it yourself):
```sh
docker run -u $UID -ti --rm -v $PWD:/th -w /th aergus/latex make
```
## PDF/A
With a bit of luck, you should get a valid PDF/A right out of LaTeX. Remember that you should use a well-maintained PDF-capable TeX engine, which currently means `lualatex` and may possibly also include `xelatex`. Older `pdflatex` might work, but you may hit problems (e.g. using "small caps" feature with the default Libertinus font triggers glyph validation errors). If you are using GitHub actions or GitLab CI, the CI will run the PDF/A verifier automatically for you.
A PDF/A validator that can point out exact problems is available here: https://github.com/mff-cuni-cz/cuni-thesis-validator
Common PDF/A problems include:
- imported PDF pictures that are not PDF/A.
- the used font does not support PDF/A (including the fonts in imported pictures). See https://martin.hoppenheit.info/blog/2018/pdfa-validation-and-inconsistent-glyph-width-information/ for a very ugly case.
Solutions:
- use `pdfa.sh` to convert the imported picture PDFs to PDF/A-compatible form the "hard way" (although this does _not_ retain the PDF/A metadata mark, see comments in the script)
- read the commentary by Martin Mareš (that describes most of the common problems) here: https://mj.ucw.cz/vyuka/bc/pdfaq.html
- as a last resort if everything other fails, use `pdfa.sh` for the whole `thesis.pdf`
## Ideas/improvements/more examples?
Pull requests welcome.
## License?
Parts of the code (esp. the title page) are based on the original template (available from the faculty website) by Martin Mareš, Arnošt Komárek, and Michal Kulich.
Small and useful fixes were coded or pointed out by Vít Kabele, Jan Joneš, Gabriela Suchopárová, Evžen Wybitul, and many others.
(Many thanks to everyone involved!)
University and faculty logos are a property of the respective universities and faculties.
Everything else in this repository is released into the public domain, not encumbered by any kind of copyright at all.

BIN
abstract-cz.pdf Normal file

Binary file not shown.

View File

@ -1,14 +0,0 @@
\documentclass[12pt]{report}
\usepackage[a-2u]{pdfx}
\usepackage[czech,shorthands=off]{babel}
\usepackage{lmodern}
\input{metadata}
\input{todos}
\begin{document}
\pagenumbering{gobble}
\AbstractCS
\end{document}

View File

@ -1,5 +0,0 @@
% Metadata k uložení do PDF, podrobnější popis viz dokumentace balíčku pdfx.
\Author{Oleg Petruny}
\Title{Vícežánrová příběhová počítačová hra s podporou načítání nového obsahu za běhu}
\Publisher{Univerzita Karlova}

BIN
abstract-en.pdf Normal file

Binary file not shown.

View File

@ -1,13 +0,0 @@
\documentclass[12pt]{report}
\usepackage[a-2u]{pdfx}
\usepackage{lmodern}
\input{metadata}
\input{todos}
\begin{document}
\pagenumbering{gobble}
\AbstractEN
\end{document}

View File

@ -1,5 +0,0 @@
% Metadata to be stored in PDF, see documentation of the pdfx package for more details.
\Author{Oleg Petruny}
\Title{Multi-genre game with support for loading new content in real-time}
\Publisher{Charles University}

View File

@ -1,8 +0,0 @@
\ifEN
\chapwithtoc{Bibliography}
\else
\chapwithtoc{Seznam použité literatury}
\fi
\printbibliography[heading=none]

245
ch1.tex
View File

@ -1,245 +0,0 @@
\chapter{Zásady tvorby počítačových her}
\label{chap:refs}
Vývoj her je~obor, který~je~často mylně interpretován širokou veřejností. Existuje všeobecná představa o~tom, jak~by~hry měly vypadat, jaké prvky musí či~nesmí obsahovat, kdo~a~jak~je~má~vyvíjet a~jaká by~měla být jejich cenová politika. Ve~skutečnosti však průměrného uživatele zajímá především míra \emph{zábavy} a~herní zážitek, který za~investovaný čas a~finanční prostředky získá.
Z~pohledu hráče nejsou faktory jako~pracovní podmínky vývojářů nebo~kontroverzní herní mechaniky primárními rozhodovacími kritérii. Klíčovým aspektem je~optimalizace uživatelského zážitku a~zajištění dostatečné interaktivity, plynulosti a~vtažení do~děje, které přímo ovlivňují retenci a~herní ekonomiku.
Jelikož je~zábava vysoce subjektivním konceptem, neexistuje univerzální model hry, který~by~vyhovoval všem uživatelům. Herní design proto~využívá analytických metod, jako~jsou uživatelské testování, behaviorální analýza a~iterativní vývoj, aby~maximalizoval pozitivní odezvu v~cílové skupině hráčů.
\section{Průběh vývoje}
Pro nikoho snad není překvapivé, že~pro~vznik díla je~potřeba nějaká myšlenka, která~mu předchází. V~tomto jsou~hry stejný jako~jiné kreativní odvětví. Je~potřeba, aby~myšlenka byla funkční, a~v~našem případě zábavná. Bohužel hry už~s~většinou odvětví nesdílí aspekt, při~kterém funkčnost myšlenky lze~ověřit již~na~začátku produkce. A~je~to ještě horší, protože~to~můžeme většinou zjistit pouze u~konce. Nezanedbatelná část her proto potom je~zamítnutá, neviditelná nebo dokonce předěláná hned před koncem. O~jednom takovém případu -- který skončil šťastně -- doporučuji si~přečíst v~knize \textit{Blood, Sweat, and Pixels} \cite{schreier2017blood} o~hře Uncharted 4. Autor převypráví rozhovory s~vývojáři her různých žánrů a~velikostí, které~znázorňují unikátní a~zároveň společné překážky v~oboru vývoje videoher.
\subsection{Design dokument} Nedílnou součástí vývoje hry je~iterace nápadů a~celkový popis prostředí a~způsobů produkce. To~vše~v~sobě zahrnuje Design dokument. Ten~může mít různé podoby, jelikož jeho hlavním cílem je~uchovat potřebné nápady na snadno dostupném a~přehledném místě. Souhrn těchto nápadů, jejích propracovanost a~to, jak~dobře spolu fungují, potom tvoří celou hru i~výslednou zábavu. Proto~dobré písemné zpracování pomůže předat myšlenky designéra a~jejich aktuální verzi celému týmu vývojářů.
Design dokument, jenž~tvoří nedílnou součást této práce, byl~vytvořen s~ohledem na~vývoj hry jedním autorem. Z~tohoto důvodu jsou v~něm jednotlivé nápady popsány poměrně stručně až~abstraktně, neboť~sloužil primárně jako~osobní vodítko. V~případě týmového vývoje by~však bylo vhodné dokument rozšířit o~podrobnější popis nápadů a~jejich zamýšlené realizace.
\section{Téma, motivy, příběh, cíl}
Hra by~měla poskytovat nějakou \emph{myšlenku} relevantní pro~hráče, aby~ten měl zájem si~ji~zahrát. Počáteční myšlenku většinou vytváří a~následně rozvíjí game designer. Ta~následovně může~být zachována i~na~konci vývoje, nebo být zásadně změněná samotnou hrou, jejími mechanikami a~kreativním provedením. Krásný případ je~známá desková hra ``Landlord's Game'' od~Lizzie Magie později známá jako~``Monopoly''. Paní Magiová chtěla vytvořit hru, která~by~hráčům představila hrůzy kapitalismu a monopolů tak, že by poskytla hráčům zkušenosti, kde~jeden jedinec neustále a~nevyhnutelně bohatne zatímco zbytek stejně~tak neustále a~nevyhnutelně chudne. Bohužel hráči moc tuhle myšlenku nepochitili. Místo vystrašení z~kapitalismu, naopak rádi zažívali hazard a~možnost ekonomicky zruinovat soupeře.
Způsobů, jak~předat myšlenku hráči, je~nespočetně mnoho. Pro účely této práce proto probereme možnosti předáni myšlenky v~příběhových hrách. Ty~by~měly~mít nějaké ústřední téma, které~se~následně obohacuje příběhy okolo. Je~velmi důležité, aby~okolní příběhy měly \emph{motivy}, aby~následně i~hráč měl motiv je~prožít. Dokonce hráč nemusí znát motivy až~do~konce hry, stačí aby~byla cítit smysluplná návaznost a~pocit možné odměny. Proto je~za~umění považováno i~velkolepé předstírání existence motivů, které~donutí hráče \emph{strávit ve~hře co~největší množství času}.
Samotná tvorba příběhů je~poněkud podobná tvorbě knižní nebo~kinematografické. Jen~je~zapotřebí oživovat a~propojovat nejen postavy a~svět, ale~i~herní mechaniky s~ohledem na~jejich zábavnost, složitost a~technická omezení.
\paragraph{Údržba pozornosti} Cíle a jejich distribuce pomáhají hře udržet~si hráče. Pokud například za~sebou následuje několik ``nudných" pasáží, nebo~je~hra příliš repetativní, hráč může ztratit zájem. \Cref{fig:pacing} na další stránce znázorňuje ukázkový příklad pěkné distribuce klíčových momentů. Co~přesně jsou~klíčové momenty, je~na~vývojáři. Mohou to~být důležité momenty v~příběhu, vylepšení postavy hráče, představení nové důležité mechaniky atd. Důležité je~nechat hráče v~každém okamžiku pocítit jeho úspěchy na~začátku tohoto momentu nebo~jeho~konci. Je~to~dost~abstraktní, ale~přesto fungující způsob jak~udržet pozornost hráče a~poskytnout mu zábavu.
\begin{figure}
\centering
\includegraphics[width=.5\linewidth]{img/pacing.pdf}
\caption{Ukázkový graf představující distribuci klíčových momentů a~cesty k~ním. Převzato z~článku \protect\textit{Gameplay Fundamentals Revisited: Harnessed Pacing \& Intensity} \protect\cite{pacingIntensity}.}
\label{fig:pacing}
\end{figure}
\section{Žánr, mechaniky, reference, platforma}
Důležité~je také rozmyslet si~vhodné umělecké a~technické aspekty hry. Například nebude moc zábavné hrát hlavní mechaniku farmářství, pokud hlavní žánr hry je~horor. Správná volba žánru a~mechanik je~tedy klíčová pro~vytvoření konzistentního a~poutavého herního zážitku.
\newpage
\paragraph{Žánr} Žánr hry určuje její základní atmosféru, pravidla a~často i~cílovou skupinu hráčů. Většinou se~dnes setkáváme s~hybridními žánry, které dokážou poskytnout hráči více obsahu a~tím pádem i~více možné zábavy.
Při výběru žánru je~důležité vzít v~úvahu preferované herní mechaniky a~jejich složitost. Například hra zaměřená na~rychlou a~dynamickou akci bude pravděpodobně obsahovat prvky střílečky nebo bojové hry, zatímco narativně založená hra může využívat prvky adventury či~RPG.
\paragraph{Herní mechaniky} Mechaniky jsou základní interaktivní prvky, které hráč využívá k~postupu ve~hře. Spravný návrh mechanik zajistí, že~hra bude plynulá, intuitivní a~zábavná.
Při jejich návrhu je~třeba zvážit: jak~mechaniky podporují zvolený žánr, jak~se~budou vyvíjet v průběhu hry a~jak~se~kombinují s~ostatními prvky hry. Například v~hororové hře bude dobře fungovat správa omezených zdrojů pro~zvětšení napětí, zatímco ve~strategické hře budou klíčové rozhodovací prvky a~řízení ekonomiky.
\paragraph{Platforma} Platforma ovlivňuje technické aspekty vývoje i~celkový dosah hry mezi hráči. Každá platforma má~své specifické a~občas i~náročné požadavky. Za~to~ale~odmění hráče vhodnějším ovládáním nebo~unikátním vizuálním zážitkem.
Při~výběru platformy je~nutné zvážit technická omezení a~očekávání hráčů na~dané platformě. Například mobilní hry často využívají dotykové ovládání a~krátké herní smyčky, zatímco hry pro~PC a~konzole mohou nabídnout komplexnější mechaniky a~delší herní dobu.
\paragraph{Kopírování} Kopírování cizích a~vlastních nápadů je~nedílnou součástí úspěšného vývoje. Vyplatí~se mít přehled ve~vybraném žánru a~mechanikách. Není nic špatného učit~se na~chybách a~úspěších jiných her. Důležité ale~je si~pamatovat, že~neexistuje deterministický vzorec, jak~vytvořit dokonalou kombinaci příběhů, žánrů a~mechanik tak, aby~hra získala oblibu hráčů.
\newpage
\paragraph{Minihry} Skvělou metodou, jak~rozptýlit hráče od~monotonie herního cyklu jsou~minihry. Přitom je~lze aplikovat kdykoliv. Minihry většinou buď poskytují odměnu, anebo slouží k~relaxaci mezi náročnějšími segmenty hry. Důležité~je, aby~jejich design byl v~souladu s~celkovým stylem hry a~nepůsobil rušivě. Například rytmická minihra ve~fantasy RPG může být zajímavým doplňkem, ale~v~realistické hororové hře by~působila nepatřičně.
\section{Engine}
Jakmile je~rozhodnuto, jak~bude hra vypadat, je~zapotřebí zvolit vhodné prostředí pro~její vývoj. Vývojář sice může vytvořit vlastní herní engine, avšak v~dnešní době to~zpravidla znamená jen~zbytečné komplikace. Proto jsou na~trhu dnes již~běžně dostupná hotová řešení, která~pokrývají většinu potřeb.
Základní funkce herních enginů obvykle zahrnují editor scény, přehrávače a~čtečky různých multimediálních či~digitálních formátů, simulaci fyziky, zpracování uživatelského vstupu a~zajištění kompatibility výstupu mezi různými operačními systémy a~hardwarem. Nad~rámec~toho většina enginů poskytuje i~vlastní univerzální implementaci herních objektů a~mechanik. Například primitivní chůze herní postavy, či~implementace renderingu obrazu a~grafických prvků jako~osvětlení, stíny, odrazy a~případně další. Tedy většinou se~jedná o~technologie, které~se~využívají poměrně často, ale~jejich implementace bývá časově náročná až~nevýhodná.
Vytvářet hru pomoci enginu může mít~i~své nevýhody. Některé technologie, zejména grafické, mohou~být vynucené, čili pevně svázané s~daným enginem, čímž~vynucují určité způsoby použití a~tím~pádem omezují kreativní svobodu. Kromě~toho většina enginů není distribuována zcela zdarma. Vývojáři buď musí předem uhradit licenční poplatky za~middleware, nebo~jsou vázáni na~procentuální odvody z~výdělků, což~je~dnes častější model.
Tato práce je~zamýšlena jako~vývoj 3D příběhové hry s~více žánry a~s~možností dynamického načítání nového obsahu za~běhu. Pro~tyto účely se~nabízí čtyři hlavní enginy na~trhu, přičemž výběr v předchozí práci padl na~Unreal Engine a proto táto navazujiící práce v tom pokračuje. Z~tohoto důvodu veškerý následující sekce, věnované technologickému rozboru či implementaci, se~zaměří výhradně na~možnosti, které~Unreal Engine nabízí.
\paragraph{Unity\protect\footnote{https://unity.com/}} Unity~je nejspíš stále nejpopulárnější volbou v~roce vzniku této práce. Lze na~něm vytvořit hru libovolného žánru a~rozsahu. Má~rozhodně největší komunitu a~rozsáhle návody, jednodušší programovací jazyk C\# a~skriptování herních objektů. Zároveň již~obsahuje možnost načítání obsahu za~běhu, zmíněnou v požadavcích.
Má ale~své problémy, které pozorný vývojář procití už~v~polovině vývoje jestli ne~dřív. Tvorba dobré grafiky často vyžaduje psaní vlastních HLSL shaderů, což~moc nekoreluje s~jednoduchostí C\#. Navíc grafika často vyžaduje psaní vlastních optimalizačních algoritmů nebo~manuální adaptaci cizích pluginů. Následovně i~samotný C\# vytváří komplikace s~rychlostí běhu programu, obsahem zabrané paměti a~přítomností garbage collectoru. Všechny tyto problémy lze~částečně opravit a~vylepšit, jen~je~potřeba mnoho pokročilých znalostí navíc. Detaily a~zkušenosti vývojářů lze~nalézt online, například~zde\cite{unityComparing}.
V~roce 2019, kdy~vzníkala předchozí práce, v~Unity byl také problém s~paralelizací hlavního cyklu samotného enginu a~renderovacích úloh. Byl používán triviální model herní smyčky, který~spouštěl logiku sekvenčně v~hlavním vlákně. Stejně~tak bylo triviální i~spouštění renderovacích úloh bez~dynamického clusteringu a~paralelizace. V celku Unity tehdy ještě nebyl tak~robustní a~nenabízel tolik vývojářských možností resp. oprav. V~den vydání této navazující práce je~pravděpododně nejlepší volbou pro~jednotlivce ale~i~malé týmy. Proto pro~tuto práci bychom dnes zvolili Unity, kdybychom už~neměli předchozí prototyp postavěný na~Unreal Engine.
Unity je~engine otevřený všem žánrům a~mnoha platformám jako~mobilní, VR a~další. Často je~použiván v~menších projektech a~menších týmech, například při~vývoji indie her, ale~taky i~při~vývoji velkých her.
\paragraph{Godot\protect\footnote{https://godotengine.org/}} Godot je~velmi diskutovaná novinka, která~se~celkem dobře šíří trhem. Hlavní výhoda je~jeho malá velikost a~že~je~úplně zdarma za~všech okolností. Godot je~totiž open source produkt vyvíjený komunitou a~dokonce jeho vývoj je~podpořen některými herními studii či~jinými firmami.
Má~podobné problémy jako~jiné enginy a~něco navíc nefunguje dobře nebo chybí. Například výchozí implementace fyziky a~kolizí není často dostačující nebo nepředvídatelně a~uživatelsky špatně řeší určité okamžiky. Je~ale~vskutku ohromující, co~vše~může nabídnout. I~když většinu nabízených technologií vývojář potřebuje přepsat vlastnoručně, jelikož často nefungují, jak~je~zapotřebí. Příklady jsou k~nahlédnutí online na~fórech\cite{godotRealityCheck} nebo~taky blozích\cite{godotRealityCheck2}.
V~době vzniku hry přiložené k~práci byl~Godot ještě příliš nový a~nevypadal nijak perspektivně. Dnes je solidní konkurent ve~2D~herních žánrech jako~platformery, logické hry či~mobilní hry.
\paragraph{Unreal Engine\protect\footnote{https://www.unrealengine.com/}} Unreal Engine verze 4 byl kdysi zvolen enginem pro~hru, z~které~potom vznikla tato práce. Jeho primární výhodou oproti konkurenci jsou vysoce standardizované postupy neboli pipelines, které~zlevňují nebo vůbec umožňují tvorby her ve~velkých týmech.
Nabízené možností jsou vskutku ohromující, když~se~snažíte vybrat budoucí stavební kámen pro vaši~hru. Je~ale~potřeba brát v~úvahu silnou nepřívětivost enginu k~nováčkům, kteří~chtějí udělat něco vlastního mimo již~existující návody. Stejné lze říct o~oficiální dokumentaci, která~je často a~velmi nedostačujicí -- jestli~vůbec existuje. Navíc při~snaze udělat něco kompletního pomocí nabízených pokročilých technologií, v~závěru vývojář musí dané technologie ovládnout na~velmi vysoké úrovni a~často i~modifikovat zdrojový kód enginu. V~některých případech technologie jako Nanite nebo Lumen nejde použit pro~dokonalé a~odladěné výsledky, proto se~prostě zahazují -- probereme v~další sekci.
Pokud ignorujeme chybějící dokumentaci, je~Unreal Engine stejný engine jako~ostatní. Některé technologie má nesrovnatelně lepší a~některé horší. Lze~najít návody a~neoficiální dokumentaci diky velké komunitě. Dokonce vývojář může samotný engine upravovat podle sebe, protože lze zcela zdarma dostat přístup ke~zdrojovým souborům. Velké týmy tuto nezávislost s~radostí využívají.
\newpage
Aktuálně se~UE orientuje na~3D~hry převážně s~grafikou vysoké kvality a~stejně jako Unity podporuje většinu aktuálních platforem. Taky se~skvěle hodí pro~tvorbu filmu, motion design a~realtime simulace. Navíc díky technologiím jako~Nanite a~Lumen začína přebírat trh architektonických rendererů.
\paragraph{CryEngine\protect\footnote{https://www.cryengine.com/}} CryEngine je velmi podobný Unreal Enginu za~výjimkou toho, že~se~specialuzuje jen na~vývoj her. Taky~již~není tolik univerzalní, dokumentace je~ještě míň, komunita je~velmi malá a~přívětivost je snad nejhorší možná. Je~to~dost úzce specializovaný engine, který potřebuje silné odborníky k~jeho ovládání.
Všechny známé hry na~CE~jsou zaměřené na~velmi propracovanou grafiku a~částo hry s~mechanikami boje nebo~střelby z~pohledu první osoby. Nedokázal jsem dohledat žádné 2D~hry nebo~indie, což~je~pochopitelné. 2D~hry není specializace CryEngine a~tvořit indie na~tomto enginu je~neefektivní až~nepřínosné. Taky~často vývojáři her na~CE se~přiznávají, že~je~nutné přizpůsobovat zdrojový kód enginu podle vlastních potřeb, což~ještě~víc odrazuje začátečníky.
\subsection{Programovácí jazyk}
Unreal Engine umožňuje programovat pomoci vizuálních bloků tzv. Blueprintů nebo textově v~jazyce C++. I~při~použití pouze jedné z~variant lze vyvinout celou hru. Veškerý potenciál se~ale~projevuje při jejich kombinaci. V~C++ se~skvěle programují komplexní a~nízkoúrovňové prvky, zatímco Blueprinty jsou skvělé pro~skriptování úrovní a~objektů pomocí high-level bloků. Samozřejmě samotné vizuální bloky lze~v~C++ vlastnoručně vytvořit.
Je~to~vše zároveň velmi obsáhlý aspekt Unreal Engine. Začátečníkovi bude celkem dlouho trvat než začne sám něco vymýšlet. Na~první pohled jednoduché vizuální programování je~ve~skutečností velmi komplexní už~samotnou téměř nekonečnou nabídkou funkcí.
\paragraph{Blueprinty} Blueprinty jsou skvělé pro~rychlé a~jednoduché skriptování. Umožňuje~to do~procesu programování hry zapojit členy týmu z~jiných méně technických odvětví. Potom například level designer může iterovat vlastní nápady mnohem rychleji a~nečekat na~programátora, tím~že~si~poskláda vlastní logiku a~hned ji~může vyzkoušet. Spolu s~jednoduchostí jsou zároveň velmi bezpečné. Nefunkční kód se~za~běhu jen~poznamená do~logů a~engine nebude havarovat.
Samozřejmě to~přináší nějaký overhead, hlavně když se~jedná o~práci s~velkými daty. Pokud~ale udržovat Blueprinty s~malým počtem funkcí a~používat reference místo kopírování dat, potom je~overhead zanedbatelný.
Největší nevýhodou je~překvapivě nepřehlednost kódu, která~nejčastěji značí špatný programátorský návrh nebo lenost autora. Totiž velký počet vizuálních bloků a~jejich propojení není možné umístit přehledně na~jednu obrazovku. To~potom vyúsťuje v~nepřehledný mix různých logických částí, které~jsou dost obtížné na~orientaci a~údržbu. Napravit~to nejde ani~rozdělením jedné funkce do~více funkcí v~samotném Blueprintu. Nepřehledný mix propojení bloků se~pouze změní na~nepřehledný mix oken s~ruzným kódem. Správný postup v~tomto případě je~ručně konvertovat logiku z~Blueprintu do~C++.
\paragraph{C++} Práce s~C++ v~Unreal Engine je podobná práci s~velkými frameworky, například Qt. Použití čistého C++ je~zcela povolené, ale~takový kód potom nelze použít v~blueprintech a~tedy i~editoru. Unreal Engine proto definuje speciální makra jako~třeba UCLASS a~UFUNCTION pro~možnost integrování kódu buď~přímo do~blueprintu nebo~aspoň systému reflexe. Makra se~potom zpracovávají ne~macro preprocessor, ale~Unreal Header Tool nebo~Unreal Build Tool, které~slouží jako~generatory kódu. Generatory potom sami generují potřebné funkce a~proměnné pro~systém reflexe a~editor.
V~C++ a~navíc s~otevřeným kódem celého enginu, má~vývojář plnou kontrolu nad~během programu nebo~jeho debugováním. Problém je~ale~použití assetů z~editoru nebo~reference objektů v~herním světě. Jsou~možnosti jak~to~obejít, například statické načtení assetu z~registru pomoci konstantní plné cesty k~assetu nebo~přeiterovat všechny objekty ve~světě. Editor samořejmě není schopen takové reference udržovat v~případě přemístění assetu a~časté iterování přes všechny objekty je~citelná zátěž. Proto ve~většíně případů je~potřeba zpřístupnít celou třídu do~Blueprintu a~v~editoru rovněž vytvořit Blueprint podtřídu, která~bude pouze přiřazovat potřebné reference.
\subsection{Grafika}
V~rukou máme taktéž širokou nabídku technologií a~nástrojů pro~tvorbu grafiky nebo~import do~hry grafického obsahu vytvořeného v~jiném softwaru. Je~ale~potřeba dát~si~záležet na~veškerých nastaveních enginu. Těch~nastavení je~velké množství a~rozhodně se~budou iterovat během celého vývoje hry. Výchozí nastavení totiž jsou~příliš univerzální a~nekompletní. Přestože i~v~základu s~nimi hra vypadá na~dostatečné úrovní, při~hraní bude stálý pocit nedokončenosti produktu nebo~kopírování cizího díla. Většina vývojářů si~totiž nedá zaležet, jak~jejich hra vypadá kvůli úspoře času nebo~technické náročnosti tohoto kroku. Proto se~mnoho her (postavených na~Unreal Engine) vizuálně a~``pocitově" podobá, což~je~mnoha hráčům nepříjemné.
\subsection*{- Materiály}
Materiál je~odborné označení souboru dat a~funkcí, které reprezentují výsledný vzhled objektu, efektu, světla nebo~post-processu vyrenderovaného snímku. Je~to~de-facto vysokourovňový shader, který,~i~přestože je~dost omezený, dokáže generovat skvělý a~kreativní výstup. Případně~lze zdrojový kód materiálu poskytnutého enginem rozšířit o~potřebné funkcionality a~v~případě potřeby napsat i~vlastní render pipeline, jak~to~často dělají nekterá studia.
\paragraph{Substrate\protect\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/overview-of-substrate-materials-in-unreal-engine}}Substrate je~nově vyvíjený systém materiálů, který~se~primárně chlubí jednoduchostí vrstvení materiálů a~celkového návrhu. Vrstvení textur a~materiálů je~jistě pohodlné a~podobá se~klasickému vrstvení v~grafických editorech. Umožňuje~to tvorbu komplexních a~nádherných povrchů za~relativně málo úsilí.
Problémem však je zjednodušenost systému se~zaměřením na~pohodlí generického grafického umělce. Vytváří to~ještě víc omezení pro~grafické a~technické možností a~téměř úplnou nepoužitelnost technických triků.
\paragraph{HLSL shadery} V~Unreal Engine lze napsat a~aplikovat HLSL shadery. Je~to~ale málo dokumentovaný aspekt a~zahrnuje spoustu práce okolo, narozdil od~toho, jak~lehce to~lze zprovoznit v~Unity.
\subsection*{- Osvětlení}
Unreal Engine vyniká bohatým výběrem možností provedení osvětlení. Lze~zde najít různé druhy přímých a~nepřímých zdrojů světel, technik odrazů a~stínů. Nebo taktéž velké množství objemných prostorů pro~ovlivňování světla jako~mlhy nebo~rozptyl a~paprsky. Všechno lze~relativně podrobně nastavit buď~pro~účely výkonu nebo~grafické estetiky.
\paragraph{Lumen\protect\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/lumen-global-illumination-and-reflections-in-unreal-engine}} Lumen je~zdánlivě revoluce v~realtime herním osvětlení. Jedná~se o~speciální režim osvětlení a~odrazů, který~umožňuje za~běhu počítat dynamické osvětlení bez~potřeby vytváření lightmap nebo~pracného nastavení ploch odrazů. Vytváří velice kvalitní osvětlení při~vynaložení minimálního úsili.
Nevýhodu, kterou ale~již~autoři UE neprezentují, není jen výrazně větší zátěž na~hardware, ale~i~šum vyrenderovaného osvětlení a~odrazů. Lumen totíž v~reálném čase generuje buffer s~odrazy a~osvětlením ve~velice malém rozlišení a~navíc vynechává náhodně zhruba polovinu pixelů. Potom se~výsledný buffer rescaluje na~potřebné rozlišení a~aplikuje. Celý tento systém se~spoléhá na~zhlazovací metodu Temporal Anti-Aliasing, která~akumuluje výsledky předchozích snímků a~interpoluje~je do~aktuálního. Tak~potom v~klidných scénach šum je~zdanlivě dobře potlačen i~když~ne~kompletně. Ale~v~dynamických scénach neboli rychlejším pohybu kamery, TAA vytváří ghosting efekt nejen na~hranach objektů ale~i~osvetlení s~odrazy, který~často hráčům je~nepřijemný.
\subsection*{- 3D}
Podporován je import 3D modelů z~různých formátů. Navíc k~tomu UE poskytuje dostatečné množství optimalizačních technik jako~např.:
\begin{itemize}
\item Render occlusion culling vykreslující objekty pouze pokud se~nachází v~zorném poli kamery, nebo
\item Level Of Details (LOD) vykreslující různě detailizované verze objektu v~závislosti na~jeho vzdalenosti od~hráče, protože není potřeba vykreslovat detaily, které~z~dálky nejsou vidět.
\end{itemize}
\paragraph{Nanite\protect\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/nanite-virtualized-geometry-in-unreal-engine}} Nanite je~další specialita Unreal~Engine~5, která umožňuje vykreslování a~instancování objektů s~miliony až~miliardami trojúhelníků v~reálném čase. Umožňuje tak~použití v~enginu extremně detailních objektů, získaných pomoci skenování objektů v~realitě tzv.~fotogrammetrie.
Technika je~založená na~clustarizaci objektů při~importu a~následně dynamickém streamování pouze viditelných trojúhelníků. Bohužel neumožňuje kompletní vynechání LOD~systému, jak~to~inzeruje tvůrce enginu. Nanite sice může ušetřit spoustu času modeláři, ale~reálný zisk ve~výkonu je~pouze ve~velmi náročných scénach obsahujících statické objekty. Proto~LOD stále zůstává nejefektivnější technikou zkrácení vykreslovacího času objektu.
\paragraph{Instancování} Instancování umožňuje zmenšení paměti potřebné pro~reprezentaci skupiny stejných objektů a~výsledně i~zkrácení renderovacího času. Je~postavená na~jednoduché myšlence, že~instance objektů drží v~paměti pouze transformaci, a~zbytek dat je~referencován z~jedíneho pravého objektu. Často se~tato technika používá pro~naplnění světa různými drobnými objekty (instancování) nebo~tvorbu vegetace (foliáž).
\subsection*{- Animace}
Veškeré potřeby pro~animaci libovolného druhu jsou~taktéž pokryté.
\paragraph{Skeleton} Skeleton animace je~založená doslovně na~animování kostry přivázané k~3D modelu. Skupiny trojúhelníků jsou~namapované na~určité kosti, tak~že~při~pohybu kosti je~stejným směrem interpolovaná pozice trojúhelníků. Daný druh 3D~animace může vytvářet velkou zátěž na~procesor zejména při~velkém počtu instancí, jelikož~ten~musí propočítávat pohyb každé kostí vůči hernímu světu a~až~potom odesílat renderovací požadavek na~grafiku. Přesto daná technika tvoří převážnou část všech animací ve~hrách díky jednoduchosti tvorby a~práci s~ní.
\paragraph{Shader} Shader animace je~exotická technika s~myšlenkou přeskočit krok s~výpočtem na~procesoru. Animace se~zakóduje do~textury a~následně je~aplikovaná ve~vertex shaderu jako~offset vrcholů. Výsledně lze~například velmi levně animovat velké hejno ptáků, které~nemusí mít kolizi ve~světě.
\subsection*{- Renderer}
Z~rendererů lze~vybrat mezi~Forward a~Deferred rendererem. Jsou~to~systémy, které~se~starají o~zpracování grafiky a~vykreslování scény. Zajišťují převod 3D~objektů a~jejich vlastností na~obraz, který~se~zobrazí na~monitoru. Renderer pracuje s~osvětlením, stíny a~materiály pro~dosažení realistické nebo~stylizované grafiky. V~Unreal Engine ovlivňuje také dostupné prostředky pro~post-processing.
\label{sec:forwardRenderer}
\paragraph{Forward rendering} Forward rendering je~metoda renderingu, kde~objekty se~renderují pro~každý zdroj světla zvlášť a~výsledné osvětlení je~součtem těchto průchodů. Je~vhodný pro~scény s~malým množstvím světel a~vyžaduje menší paměťovou náročnost. Dnes se~převážně používá v~mobilních a~VR aplikacích, kde~je~důležitá nízka latence. Nevýhodou je například nemožnost použití Screen Space vykreslovacích technik a~omezení na~maximalně 4~dynamických světel na~objekt -- 4~kanály resp.~RGBA.
\label{sec:deferredRenderer}
\paragraph{Deferred rendering} Deferred rendering odkládá aplikaci světelných efektů a~v~první fázi ukládá informace o~geometrii scény do~bufferu (G-buffer). Světla se~aplikují až~v~druhé fázi, což~umožňuje efektivnější práci s~větším množstvím dynamických světelných zdrojů. Tato~metoda se~používá především v~moderních AAA~hrách, kde~je~vyžadována vysoká vizuální kvalita. Je~to~výchozí renderer v~Unreal~Engine, který~navíc umožňuje použití technologií Nanite a~Lumen.
Nevýhodou je~nemožnost použití kvalitních zhlazovacích metod jako~Multisample Anti-Aliasing. MSAA funguje~tak, že~ukládá průměr více vzorků na~pixel během rasterizace, což~dobře funguje u~forward renderingu, kde~se~barva a~hloubka určují okamžitě. V~deferred renderingu se~však barvy a~osvětlení aplikují až~v~pozdější fázi, kdy~se~světelné výpočty provádějí na~pixelech na~základě uložených dat v~G\mbox{-}bufferu. Problém~je, že~MSAA by~muselo být aplikováno na~všechny jednotlivé buffery (normály, hloubku, albedo atd.), což~je~extrémně výpočetně náročné a~neefektivní. Proto se~místo MSAA často používají jiné metody zhlazování, jako~FXAA (Fast Approximate Anti-Aliasing) nebo~TAA (Temporal Anti-Aliasing). Ty~jsou podstatně méně kvalitní a~TAA dokonce způsobuje rozmazávání hran objektů v~dynamických scénach resp. ghosting efekt. SMAA (Subpixel Morphological Anti-Aliasing) je skvělá zhlazovací metoda pro deffered rendering, ale není podporováná v Unreal Engine.
Zároveň deferred shading není schopná poskytnout některé grafické techniky. Například transparentní materiály (např.~skla) nebo~subsurface scattering (rozptyl světla při~průchodu objektem nebo dopadu na~něj) se~musí renderovat na~konci ještě jedním průchodem tzv.~forward passem.
\label{sec:screenspace}
\subsection*{- Postprocessing}
Postprocessing je~technika dodatečného zpracování vyrenderovaného obrazu. Většinou se~jedná o~triviální manipulaci barev, ale~lze~tady dělat i~spoustu designových a~technickych triků. Např.~různé glitch efekty, efekty tepelného/nočního vidění~atd. získané pomocí procedurální nebo~statické modulace obrazu. V~deferred rendereru navíc lze~používat screen space techniky, které~používají vyrenderovaný snímek k~rychlé tvorbě odrazů (SSR - Screen Space Reflections) nebo~zastínění (SSAO - Screen Space Ambient Occlusion).
\subsection*{- 2D}
Je~více způsobů práce s~2D~grafikou, avšak udělat čistě 2D~hru by bylo problematické. V~oficiální nabídce je~rozhraní Paper~2D\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/paper-2d-overview-in-unreal-engine}, které~vývoj 2D~hry sice zjednodušuje, ale~přesto má pouze základní prvky 2D~enginu. Místy chybí optimalizace, protože soubory v~editoru jsou neracionálně velké a~ve~větších projektech engine začíná být náročný na~hardware. Proto se~pro~2D~hry Unreal~Engine moc nehodí a~je~doporučené rozhlédnout~se po~konkurenčních enginech.
\newpage
\paragraph{UI} UI~lze programovat v~C++ pomoci třídy Slate nebo~přímo pomoci Blueprintů v~editoru. V~Slate prostředí se~programuje nízkoúrovňově, tedy je stejné jako programování okenní aplikace pro Windows pomocí Win32~API bez~přímé vizualizace. Mnohem pohodlnější je práce v~editoru, kde~rovnou lze vidět výsledek. Celkově tvorba UI v~Unreal Engine je~jedna z~jeho nejsilnějších stránek mezi konkurenty, i~když se~o~ní~moc nemluví.
Pro~zobrazení UI~nebo jiných 2D~prvků ve~3D bylo vždy možné vytvořit klasickou plochu s~texturou/materiálem nebo~renderovat text do~3D~světa. Samotné renderování textu ve~3D je~implementováno pomoci 3D~objektu z~vektorového fontu, což~je často výkonnostně přehnané řešení neboť mesh texty jsou již součástí hotového modelu. Ještě lze použít renderování textu z~předgenerované průhledné rastrové textury fontu. Poslední způsob je~dost rychlý na~implementaci a~výkonnostně nejlepší, pokud~je pro~nás přijatelné rozmazání přiblíženého výstupu (kvůli pevnému rozlišení textury). Nejlepší možností je~generovat text vektorově v~UI a~následně ho promítnout do~3D~světa, což~je umožněno pomoci již~zmíněných UI~tříd.
\subsection{Zvuk}
Pro práci se~zvuky máme taktéž bohaté možností. Důležité je předem nastavit kompresi a~způsob streamování zvukových dat z~assetů hry. Ještě lepší je rozdělit zvuky do~menších spojitých balíčků assetů. Často totiž chceme zvukovou stopu použít hned v~okamžiku nějaké udalostí, a~je~důležité, aby~se~data co~nejrychleji načetla. Samozřejmě taky lze některé zvuky načíst předem a~držet v~paměti procesu. Ale~i~když se~nezdá, zvuky mohou obsadit poměrně velký kus paměti aplikace a~většinou zbytečně, což~také~většina vývojářů ignoruje.
\paragraph{Mixer a Cue} Cue je chytrým kontejnerem pro jeden a~více konkrétních zvuků, který~se chová jako~jeden samostatný zvuk. V~tomto kontejneru lze~zvuky mixovat nebo~větvit, modifikovat tonalitu, hlasitost, modulaci, dělat přechody a~mnoho dalšího. Navíc veškeré efekty a~jejich intenzitu lze~aplikovat staticky nebo~dynamicky. Dohromady vše~prochází přes~Mixer, který~funguje jako~zjednodušený mixážní pult. Nastavuje a~kombinuje přiřazené zvukové třídy a~může na~nich~aplikovat equalizer.
\paragraph{Dynamická hlasitost} Attenuation je struktura parametrů popisující modifikaci zvuku při~rozdílné vzdálenosti posluchače od~zdroje zvuku. Dohromady tak~popisuje, na~jakou vzdálenost lze~zvuk slyšet a~jak~bude znít ztlumení a~zesílení. Parametry podrobně upřesňují, jak~se~zvuk bude šířit, blokovat, odrážet a~splývat v~prostoru. Většinou je~postačující pouze první základní skupina parametrů popisující objem zvukového prostoru a~funkci, která provádí interpolaci hlasitosti.
\subsection{Hudba}
Během existence Unreal Engine 4 neexistoval téměř žádný oficiální nástroj pro~dynamickou ani~statickou kompozici hudebních linek. Proto~vzníkl jednočlenný tým, který~daný nástroj programoval a~dokonce byl dostupný v~alfa verzi ke~stažení. S~příchodem Unreal Engine 5 práce na~nástroji byla pozastavena a~tedy žádný oficiální nástroj stále neexistuje a~není v~plánu.
\newpage
Hlavní problém s~hudbou je~synchronizace linek. Hudba je~dost náchylná na~jakékoliv zpoždění neboli desynchronizaci linek, protože i~milisekunda rozdílu může přeměnit nádherně zkomponovanou hudbu v~neposlouchatelnou kaši. Proto~jednoduché přehrání linky v~potřebný okamžik nefunguje. Buď~se~zvukový data načtou pomalu nebo herní tik provede spuštění opožděně, protože~je závislý na~renderovácí frekvenci snímků (viz~\Cref{fig:musicLinking}).
\begin{figure}
\centering
\includegraphics[width=.6\linewidth]{img/musicLinking.pdf}
\caption{Diagram znázorňující opožděné spuštění navazující hudební linky z~důvodu závislosti spouštění na~snímkové frekvenci hry.}
\label{fig:musicLinking}
\end{figure}
\label{prg:fmod}
\paragraph{FMOD\protect\footnote{https://www.fmod.com/}} FMOD je middleware audio engine pro~hry poskytující velice silné rozhraní pro~práci se~zvuky nebo~jejich manipulaci. Nejčastěji se~k~němu přiklání pro~tvorbu dynamických hudebních doprovodů, což~vyplňuje hudební mezeru v~UE. V~populárních enginech má~integrovanou podporu nebo~poskytuje engine v~podobě samostatného procesu, který~potom může komunikovat s~procesem hry. FMOD~také poskytuje editor zvukových stop a~s~nimi spojených eventů, pro~jednoduché ovládání audia přímo ve~hře.
\subsection{Načítání obsahu}
V~Unreal~Engine načítání obsahu je~realizované v~podobě herních patchů. Umožnuje~to exportovat a~nahrát libovolný asset nebo~kód, což~je~potom znázorněno v~praktické části práce. Nevýhodou takového přístupu je~dlouha iterace a~aplikace patchů v~případě jejích většího množství -- oficiální dokumentace doporučuje nepřesahovat mez~100~patchů.
\paragraph{Zdlouhavé načítání} Načtení i~těch menších assetů může značně pozastavit hru. Proto~je~potřeba načítání nového obsahu provést hned při~načtení celé hry, nebo~zapracovat nad~vhodným streamingem dat po menších částech, který~nezpůsobí velkou zátěž na~hardware.
\paragraph{Kompatibilita} Kompatibilita nového a~starého kódu je~něco, co~může zhavarovat celou aplikaci. Naštěstí UE řeší havarijní stavy a~hra v~případě načtení nekompatibilního nebo~poškozeného obsahu poběží dál, ale~potřebné assety se~již~nenačtou. Nejvíc se tento problém projevuje s~klasickým kódem v~C++, kde~výsledný strojový kód očekává nějakou proměnnou nebo~funkci v~přesně daném místě paměti. O~něco lepší je~to~se~vším ostatním, protože~vše je propojeno a~voláno relativními nebo~globálními cestami a~názvy. Tak například funkce v~blueprintech jsou~vždy voláné pomoci názvů funkcí v~řetězcové podobě. Stejně~tak proměnné jsou uložené v pomocné třídě generované za běhu.
\newpage
Takové využití víceúrovňové reflexe, umožňuje ošetřit libovolný problém s~kompatibilitou a~zaručit bezpečný běh za~cenu trochu většího zatížení prostředků. Navíc stejnou reflexi v~C++ lze~jednoduše udělat pomoci maker, které~Unreal~Engine poskytuje. Ovšem ošetření kompatibility není~součástí této~práce.
\subsection{Umělá inteligence herních postav}
Nehratelné postavy resp.~NPC jsou~součástí většiny her, protože~pomáhají vyprávět příběh nebo~oživit prostředí. NPC~jako~každý herní prvek lze~napevno navrhnout a~naprogramovat, určit všechny potřebné varianty vzhledů a~použití. Ale~z~designových a~časových důvodů ve~většině případu chceme, aby~NPC~byli více univerzální. Chceme aby~se~mohli samostatně orientovat v~prostředí, pohybovat~se a~občas dokonce reagovat na~okolí a~ovlivňovat~ho.
Základní implementaci NPC pozorujeme spíše ve~2D a~textových hrách kvůli jednoduchosti problému. Jedná~se o~strom podmínek IF-ELSE, který~je snadný na~implementaci, ale~hůře se~udržuje a~škáluje.
\paragraph{Behavior tree} Strom pravidel neboli Behavior tree je~nejčastěší způsob kódování chování NPC. Takový strom umožňuje efektivní rozhodování a~řízení chování umělé inteligence. Hlavní výhodou oproti jiným přístupům, jako~například konečné automaty nebo~plánování, je~modularita, škálovatelnost, snadná údržba a~současně přehlednost. Samozřejmě má~i~nevýhody, mezi~které zejména patří optimalizace a~náročný návrh složitých víceúrovňových chování.
NPC začíná rozhodování v~kořenu stromu, od~kterého postupuje k~vrcholům s~pravidly. Listy jsou vždy akční vrcholy a,~jak~napovídá~název,~určují akci, kterou~objekt provede. Cestu od~kořene k~listům vytváří řídicí vrcholy, každý~z~nich určuje pořadí a~podmínky přechodu na podřízené vrcholy. Nejčastější jsou:
\begin{itemize}
\item Sequence, který~cyklicky spouští své~podřízené vrcholy postupně, dokud některý nevrátí přerušení,
\item Selector, vybírá první podřízený vrchol, který~v~zadaném pořadí má~pozitivně zhodnocené pravidlo,
\item Parallel, který~spouští podřízené vrcholy současně,
\item a~podmínkové vrcholy, které~rozhodují, zda~pokračovat v~dané větvi, nebo~se~vrátit ke~kořenu.
\end{itemize}
Pomocí těchto pravidel lze~popsat mnoho různých chování postav neboli objektů. UE~navíc poskytuje užitečné systémy pro~pokročilé chování ``inteligentních" objektů, jako~například systémy koordinace pohybu. Postava se tak může řídít navigační síti (navmesh), která~napovídá objektům místo a~způsob obcházení překážek. K~tomu~jsou k~dispozici i~pokročilejší implementace reakcí chytrých objektů na~zvuky, obraz a~jiné objekty.
\newpage
\section{Umělá inteligence pro tvorbu obsahu}
V~současné době díky výkonnostním pokrokům se~rozšířují hranice použitelností umělé inteligence neboli~neuronových sítí (dále jako~NS). NS~ukazují skvělé výsledky v~generování obsahu různého charakteru v~poměru lidského času a~ceny. Nejúniverzálnější z~NS jsou Large Language Models~(LLM) pro~generování textu. Právě pomocí textu dnes předáváme informaci nejen od~člověka k~člověku, ale~i~od~člověka k~počítači. Proto~můžeme tvořit textové modely, které~umí ovládat systémy s~textovým vstupem (příkazové rozhraní OS, kompilátory programovacích jazyků) nebo~generovat textové datové struktury (JSON, XML) (viz~\textit{Language Models are~Unsupervised Multitask Learners} \cite{gptPaper}).
Již~dnes se~objevují hry, které~integrují danou technologii. NPC~tak~umí poměrně realisticky a~nekonečně držet konverzaci s~hráčem v~textové a~dokonce i~hlasové podobě s~definovaným typem osobnosti. Možnosti generování textur a~spritů jsou~na~pohled snad nekonečné. Vývojáři mohou poměrně rychle vygenerovat jednoduchý kód nebo~velké konfigurační soubory a~struktury. Navíc již~existuje a~zdokonaluje se~generování 3D~objektů, videí a~hudby. V~teorii stejná umělá inteligence je~schopná generovat popis a~rozmístění objektů v~herním světě nebo~vyprávět příběh.
Celé toto téma je~technicky a~odborně velice zkrácené s~ohledem na~rozsah bakalářské práce. Jednotlivé modely a~práce s~nimi nejsou součástí této~práce. Tato~práce zakládá pouze potřebný koncept pro~integraci umělé inteligence. Pro~jednoduchost se~zaměřím pouze na~univerzální~LLM.
\paragraph{Udržení kontextu} Udržení kontextu je~největší problém této technologie. Nejvíce se~to~projevuje při~generování videí, kde~je~zřetelné jak~model má~potíže udržet konkrétní obsah nebo~myšlenku jednotlivých scén a~následně i~vzhled vizuálních objektů. LLM~s~každou další iteraci má poměrně vysokou šanci změnit směr ``myšlenky''. A~to~proto, že~LLM nemyslí, LLM~je pouze násobení velkého množství matic pravděpodobnostní tzv.~váhové transformery. Tak~například LLM nevytváří logicky souvislý text ale~pouze predikuje další pravděpodobnostně nejvhodnější sekvence textu na~základě trénovacích dat.
Proto zásadní chybou je~použití LLM k~úplné tvorbě nového obsahu. A~správné je~používat LLM pouze jako~nástroj buď pro~tvorbu počáteční verze obsahu nebo~vedlejší obohacení již~existujícího díla. Právě s~touto myšlenkou byl~doprovázen vznik této~práce, díky~níž bude možné otestovat, jak~dobře LLM bude obohacovat již~hotovou počítačovou hru.
\paragraph{Halucinace} Další významnou slabinou LLM jsou halucinace. Jedná~se o~situace, kdy~model generuje nesprávné, zavádějící nebo~zcela smyšlené informace. V~kontextu počítačových her tak~může docházet například k~halucinacím při~generování herních dialogů, příběhu nebo~vizuálních prvků, kde~model vymýšlí neexistující herní mechaniky, postavy či~události, které~nepatří do~hry. Kořen tohoto problému je~stejný jak~v~udržení kontextu, kde~navíc se~to~prohlubuje slabým natrenováním modelu.
\newpage
Řešení halucinací nejsou dokonalá, ale~mohou výrazně zlepšit stav problémů. K~dispozici je~větší množství metod a~některé dokonce proprietární. V~teorii se~ale~většinou jedná o~metody:
\begin{itemize}
\item retrieval-augmented generation (RAG), která~kombinuje model s~databází obsahující ověřené informace,
\item jemné doladění modelu resp.~fine-tuning, které~spočívá v~dotrenování modelu na~specifických datech (na~datech naši~hry),
\item a~omezení generativní volnosti pomocí pravidel a~pevně definovaných scénářů, které~se~zároveň kryjí s~kontrolními mechanismy a~pomocí validace výstupů.
\end{itemize}
\section{Rozvoj předchozího konceptu hry}
Původně drobné demo hry, na které tato práce navazuje, bylo vytvořené za~účelem obhajoby maturitní práce. Předchozí práce ale~měla globálně jinou myšlenku a~motivaci. Aktuálně je~hra přeportovaná na~Unreal~Engine~verze~5 a~k~tomu nabyla konzistentního game designu a~příběhu. Stejně tak byl~předělán veškerý kód a~architektura herní logiky. Od~původní prace zbyly pouze:
\begin{itemize}
\item 3D modely s~animacemi (přibližně desetina současného obsahu),
\item některé UI elementy a~textury (přibližně čtvrtína současného obsahu),
\item level design prvního herního levelu~a
\item koncept herního světa a~hlavní téma příběhu.
\end{itemize}
Aktuální práce značně rozvíjí příběh a~přidává mnoho různých herních mechanik a~systémů, grafických a~zvukových assetů spolu s~API pro~načítání nového obsahu za~běhu.

437
ch2.tex
View File

@ -1,437 +0,0 @@
\chapter{Vývoj hry}
\label{chap:main}
\paragraph{Koncept} Hra je postavená z pěti úrovní s pohledem převážně z první osoby.
\begin{itemize}
\item První level představuje thriller a horror adventuru.
\item Druhý level je postaven na průzkumu menšího otevřeného světu s hraním miniher.
\item Třetí level sestává z tří nezávislých hlavolamů s vlastním prostředím a mechanikami.
\item Čtvrtý level představuje arkádový stealth.
\item Pátý level představuje hardcorový top-down shooter.
\end{itemize}
Každý z levelů vyžaduje společné nebo i specifické ``systémy", které si popíšeme dále v této kapitole. Výjimkou je pátá úroveň, která nebyla dokončena.
\section{Přenos starého obsahu}
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~odstraně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é) rozhraní PhysX\footnote{PhysX je open-source fyzický engine s hardwarovou akcelerací pro grafiky s CUDA architekturou (GPU společnosti NVIDIA).}, 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:
\newpage
\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í, dynamické modifikátory a~triggery 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í skoku herní postavy). Předtím se muselo toto a mnoho dalších částí 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. Bohuž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 mnohem více, 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, jak~kompilovat a~exportovat projekt, jsou~popsány 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 zásadám UE~C++ (guidelines) pro~pohodlí a~rychlost vývoje. Proto~často třídy manažerů systémů, game~modů, instance hráče a~další využívají návrhový vzor Singleton. Přináší~to nejen zmíněné pohodlí, ale~navíc šetří tři až~deset 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ýkon 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<Class>(). A~blueprinty disponují zkrácenou verzí GetPlayerPawn(index)\textrightarrow Cast<Class>(). 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.
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~jednu 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 Programování), 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ěta~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 obsáhlého a~repetitivního nastavení každého objektu, který~chceme zapojit do~mechaniky interakce.
Navrhl jsem 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}
\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 hráčem viditelné 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} na další stránce).
\newpage
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 jehlanu 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í.
\newpage
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}
Běžně pod~pojmem herní dialog rozumíme způsob vyprávění příběhu hráči v~nějaké mediální podobě. Existující ``dialogový" systém v~UE je de-facto IF-ELSE kontejner, který řeší pouze přepínání cílové věty odesílatele na~základě stavu příjemce. Tedy ``dialogy" představené v~UE jsou~pouze samostatné věty, nikoliv posloupnost vět. O~nedostatku systému pro~tvorbu a~řízení dialogů svědčí návody na~tvorbu vlastních dialogů nebo~vývojářský obchod plný hotových řešení.
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.~posloupnost 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é úrovně 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 doplněny o~konečnou grafiku a~optimalizovány pro~zábavnost. Každá z~miniher je~adaptace na~již existující známou hru.
\newpage
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. Po~dohrání nebo~po~předčasném ukončení minihra zobrazí skóre a~vrátí ovládání hráči.
Dostupné zkušební implementace:
\begin{itemize}
\item Adaptace 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, která je popsaná v programatorské dokumentaci). Hráč ovládá minihru pomicí~UI, kde~nakupuje jednotky typu lišící se útočnou silou, vzdáleností útoku a obranou. 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 Adaptace mobilní hry 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 předmětu důležitého pro~příběh. 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 Obdoba počítačové rytmické hry Osu!. Hráč má~za~úkol klikat na~objevující~se hvězdy na~obloze v~souladu s~rytmem hudby (v~pořadí ve~kterém se~objevily). Aktuálně ``hvězdy'' jsou~v~podobě čtverečků, ale~hudba je~zcela hotova. Již~teď lze vyzkoušet klikání během prvních 10~sekund doprovodu.
\item Adaptace hry Frogger. Hráč pomocí pohybu dopředu, 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 hrami). 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ši (zóna kvadraticky zrychluje/zpomaluje vzhledem k délce držení/puštění tlačítka). V~implementaci chybí zvukové assety a~vyváženost složitosti, ale~je k~dispozici kompletní~UI a~mechanika lovu.
\end{itemize}
\newpage
\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, když~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á enginem nabízenou 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í).
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.
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~API 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{itemize}
\item První 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 Druhý 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 Třetí 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 Čtvrtý level umožňuje vyzkoušet generování sekvencí chodeb. Chodby by~musely obsahovat hlídače a~kryty~tak, aby~hráč dokázal nenápadně projít mezi hlídači.
\item Pátý level bude testovat schopnost navržení herních nepřátel, jejich logiku a~rozmístění na~úrovni.
\end{itemize}
\subsection{Návrh architektury}
Tato práce popisuje pouze návrh generovací pipeline a~její~využití. Aktuálně je k~dispozici pouze systém stahování a~načítání objektů. Generované assety jsou~nahrazeny ručně tvořenými~tak, aby~předvedly načítání libovolného obsahu (interakční objekt, dialog a~kompletní instance nezávislé úrovni) a~integraci obsahu (změna příběhového předmětu v~třetí úrovní). Implementace byla tvořena s~ohledem na~širokou univerzalitu a~nezávislost na~stavu aplikace, aby~v~budoucnu vyžadovala minimální úpravy.
Návrh architektury generování obsahu pro tento projekt je~založený na~použití zřetězení různých modelů a~kontrolních mechanismů. Řetězení modelů resp.~jejich výstupů je dnes běžný koncept, který~slouží k~přírozenému rozkladu komplexních úkolů na~menší kousky. Již~můžeme najít příklady využití takových řetězců pro~nějaké tvůrčí programy, kde~AI pomocník umí pomocí vstupu od~uživatele vygenerovat prototyp požadovaného objektu, nebo~aspoň napovědět, jak~jej~dosáhnout. Například generování popisu množiny 3D~modelů a~jejich následné jednotné generování. Nebo~iterativní parsování webových stránek do~datových struktur a~následné zpracování dat.
Jelikož je plánované generování herních assetů bez~řízení a~úpravy člověkem, bude~zapotřebí navrhnout automatické kontrolní mechanismy. Nejdůležitější pro~nás není~kvalita výstupů modelů, ale~především technická koherence a~funkčnost takových výstupů, které~nám zaručí bezpečný běh programu a~umožní objektu plnit účel v~herním světě.
\newpage
Navrhovaný je nasazování kompletních instancí řetězců modelů na~soukromých serverech, které~v~různých intervalech nezávisle produkují nové assety. Po~generování budou hotové soubory přemístěny na~veřejné úložiště, odkud~hra ihned~po~spuštění stáhne několik~``náhodných'' assetů (přesnou definici výběru obsahuje \Cref{par:contentSharing}).
\paragraph{Fine-tuning} Většina potřebných druhů modelů je~k~dispozici v~podobě open-source a~tedy můžeme je dotrénovat na~vlastních datech. Pro~nás bude zásadní tvorba generativního modelu, 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í.
Dotrénování může~mít více~podob. Nejspíš by~se~jednalo o~fine-tuning jazykového LLM modelu, který~je schopen výstupu v~jazyce C++. Takový model bychom ``doučili" potřebnou syntaxi Unreal Enginu nebo~tvorbu textového popisu, ze~kterého~by~bylo možné zkonstruovat graf 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. U~Blueprintů díky jednodušší ``syntaxi" (předem definované nody a~jejich možností propojení) lze snáze ověřit správnost vygenerovaného výstupu, 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í nějakého algoritmu se~vybere příslušná množina dalších generovácích modelů, kontrolních mechanismů a~konverzních nástrojů. Asset bude~postupně procházet takovým řetězcem, až~nabude 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~je zároveň natrénovaný na~kontextu naše~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 a~smoke testy, pro~které v~UE existuje API. 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ě. 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} Při~sdílení obsahu je zapotřebí přemýšlet o~zabezpečení~tak, aby~především nedošlo k~poškození majetku hráče a~následně i~našeho majetku. V~takovém procesu útočník může napadnout všechny tři části procesu, tedy:
\begin{itemize}
\item naše zařízení, které odesílá nějaká data,
\item data na cestě k příjemci,
\item a zařízení příjemce.
\end{itemize}
Zařízení hráče a~naše servery mohou být napadeny různými způsoby, které~se~odvíjí od~účelů útočníků. Zabezpečení zařízení hráče ponecháváme na~něm a~jeho okolí. Zabezpečení našich zařízení provedeme přísným krytím za~aktivními a~pasivními ochrannými systémovými a~síťovými prvky. Z~důvodu zaměření práce, analýza a~provedení zabezpečení zařízení jsou vynechány, jelikož v~aplikační části můžeme pracovat pouze s~procesem přenosu a~příjmu dat.
Skrytí místa a~způsobu stahování dat pouze zpomalí jejich odhalení a~zvýší nároky na~údržbu. Tedy nejsou zapotřebí žádné autentikační nebo~šifrovací vrstvy pro~obfuskaci (ztěžování analýzy) procesu. Vždy~by~zůstala~možnost zpětnou analýzou (reverse-engineeringem\footnote{Reverse-engineering je~metoda analýzy hotového produktu (v~našem~případě binárního souboru), pro~získání neveřejných informací popisujících funkčnost produktu.}) rozluštit a~napodobit proces. Když~se~nad~tím zamyslíme, volný přístup k~generovaným assetům nám nijak nevadí, je~jednoduchý na~implementaci a~údržbu.
\newpage
Opravdový problém by~mohl nastat, až~když útočník vymění data během přenosu a~hráč by~mohl spustit ve~hře nebezpečný obsah. Proto~při~komunikaci mezi serverem a~uživatelem použijeme připojení pomocí HTTPS\footnote{Hypertext Transfer Protocol Secure je~protokol pro~šifrovaný přenos dat využívaný pro~poskytování webových serverů.}, které~nás ochrání před~man-in-the-middle útokem\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.}. Navíc pro~případ, kdy~útočník přes~naše snahy přesto~prolomí zabezpečení komunikace nebo~serveru zodpovědného pro~odeslání dat, budeme assety posílat s~digitálním podpisem. Podpis se~bude vytvářet na~izolovaných generativních workerech pomocí prvního asymetrického klíče a~ověřovat přímo ve~hře pomocí předinstalovaného druhého klíče. Takovým způsobem vždy ověříme, že~data, které~chceme načíst do~hry, pochází opravdu od~nás a~ručíme za~jejich bezpečnost.
Ve~výsledku hra automaticky zahájí stahování pomocí API a~aktivuje obsah před~začátkem nové hry. Pokud~ověření dat selže, pak~je zahodíme a~zastavíme veškeré připojení. Assety jsou~vybírány náhodně, nebo~se~používá hodnocení získané od~hráčů.
\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. Pokud~bychom neměli žádnou autentikaci, volné~hodnocení nemusí fungovat. Kdokoliv by~mohl 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~ztíží útočníkům práci.
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~lze 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žaduje 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 si~můžeme vystačit 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 algoritmus k-DOP\footnote{k-DOP (k-Discrete Oriented Polytope) je~jeden z~postupů obalování složitých 3D~objektu do~jednodušších tvarů.} dostupný~v~UE.
\end{itemize}
\section{Grafika}
\label{sec:graphics}
\subsection{Statické objekty}
Engine disponuje modely základních tvarů (krychle, koule, válec) a~navíc lze zdarma vzít libovolné assety z~balíčku Starter Content\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/starter-content-in-unreal-engine} nebo~assety použité v~demo projektech společnosti Epic~Games. Přestože assety mají souvislý styl, většinou jsou~zaměřeny na~konkrétní prostředí, a~proto~v~další~hře nemusí najít využití. Zřejmě lze nahrát vlastní modely, které~lze~ručně vytvořit nebo~obstarat na~libovolné online platformě.
V~Unreal Engine verze~5 navíc přidali funkčně bohatý editor 3D~modelů. Tvůrci propagují editor tak, že~v~něm lze vytvářet vlastní modely, protože~množina funkcí dovoluje tvořit hardsurface a~sculpting modely, ale~aktuální provedení není~dostačující ve~srovnání s~dedikovaným softwarem. Drobné editovací funkce na~druhou stranu jsou~užitečné a~šetří čas. Ty~umožňují například editování UV~map, normálových vektorů plošek nebo~změnu středového bodu modelu. ``Best practice'' je~využití tohoto editoru pouze v~případě nouze (například časová výhoda nebo~neexistence původního souboru), jinak~je~v~dlouhodobém měřítku prospěšné editovat původní verzovaný soubor.
\paragraph{Použití cizích assetů} Rychlejší a~občas jednodušší je~získání assetů třetí strany. K~tomu~existují různé volně dostupné webové platformy. Jednou z~takových platform je~FAB\footnote{https://www.fab.com/}, která~navíc má přímou integraci s~UE~5. Objektivně FAB nemá dostatečně velký výběr assetů, jelikož nemá ani~dostatečnou popularitu vývojářů a~tvůrců.
\newpage
Příčinou jsou~hlavně větší platformní marže z~prodeje a~sice jednoduché, ale~přesto nevýhodné licencování produktů pro~kupující stranu. Tyto a~další problémy popisují i~jiní uživatelé na~fórech\cite{fabRealityCheck}.
Z~finančních důvodů, v~této praci byly využity pouze produkty dostupné zdarma. Neznamená~to, že~vše~končí pouhým stahováním souborů a~vložením do~editoru. Často (v~této práci všech~100\%) assety nevykazují známky optimalizace nebo~profesionální tvorby. Modely tak~mají některé normálové vektory plošek invertované\footnote{Invertované normály plošek jsou při~tvorbě objektů běžné a~triviálně řešitelný problém, který~často způsobuje, že~ploška ve~scéně není vidět, jelikož~se~vykresluje pouze ve~viditelném směru normálového vektoru a~tedy vytváří ``díry'' v~objektu.}, středové body jsou~nesmyslně mimo, textury a~UV~mapy je~potřeba kompletně předělat. Nejhorší jsou primitivní objekty, které~mají bezdůvodně velké množství vrcholů. V~praxi se~nachází i~náhodné vrcholy bezúčelně existující v~prostoru modelu.
\paragraph{Vlastní tvorba} Vlastnoručně jsou tvořeny modely ze~staré verze hry a~během vývoje této práce se~pouze upravovaly nebo tvořily textury. Standardem v~oboru jsou~obecně Maya\footnote{https://www.autodesk.com/products/maya/overview} nebo~3ds~Max\footnote{https://www.autodesk.com/products/3ds-max/overview} pro~víceúčelové zpracování a~úpravy, ZBrush\footnote{https://www.maxon.net/en/zbrush} pro~sculpting a~Substance~Painter\footnote{https://www.adobe.com/products/substance3d/apps/painter.html} pro~texturování objektu. V~tomto projektu byl použit výhradně Blender\footnote{https://www.blender.org/} a~software pro~editaci obrázkových formátů, které~jsou k~dispozici na~internetu zdarma. Výsledný model lze často bez~problémů rovnou využít v~enginu.
\paragraph{Modeling a Sculpting} Nejprve se~vytváří tvar modelu. Toho se~docílí pomocí modelování polygonů nebo~sculptingu. Obě~metody jsou velmi odlišné a~stejně~tak mají odlišný výstup.
Sculpting se~provádí především přes~grafický tablet, kde~pomocí různých 3D~štětců se~natahují nebo~smršťují vrcholy a~celý proces napodobuje tvorbu sochy z~plastického materiálu. Především takový přístup se~používá pro~tvorbu organických modelů nebo~modelů s~měkkým povrchem jako~například živé bytosti, rostliny nebo~oblečení. Modeling na~druhou stranu je obecnější zpracování vrcholů, hran a~ploch. Tady se~manuálně přidávají resp.~odebírají a~posouvají vrcholy. Navíc toto~prostředí obsahuje funkce umožňující různé druhy efektivního instancování, množinových operací mezi objekty a~zjednodušených simulací vrcholů. V~takovém prostředí se~tvoří především komplexní resp.~hybridní nebo~tvrdé povrchy jako~například nábytek, architektura nebo~scény se~sculpting modely.
Specifickou sculpting instancí v~enginu je Landscape\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/landscape-overview}, de-facto síť vrcholů předem určené hustoty, kterou~můžeme v~editoru sculptovat a~napodobovat křivý resp.~různě vysoký terén. Manuální sculpting je pomalý a~přináší slabé až~nevyhovující výsledky. Proto místo sculptingu se~používá výšková neboli height~mapa, což~je textura odstínů šedi, kde~každý pixel kóduje výšku v~3D prostoru. Potom stačí naskenovat nějaký povrch v~reálném světě a~získat skvělé výsledky. Stejné height~mapy lze používat i~jako~štětce v~běžném sculptingu, pro~specifické detalizace povrchů, a~samotné height mapy lze získat na~některých online platformách dokonce zdarma.
\newpage
Ukázka landscapu je k~dispozici ve~druhé úrovni, kde~povrch terénu jsem vytvořil pomocí textury výšek a~hory jsem tvořil ručně základními štětci.
\paragraph{Animace} Animace se~tvoří v~dalším kroku modelingu. Pokud jsme předtím vytvořili model pomocí sculptingu, potřebujeme ho importovat do~modeling prostředí. Začíná~se tvorbou umělé kostry z~tzv.~kostí a~kloubů.
Klouby slouží pouze ke~specifikaci hierarchie mezi kostmi tak, že~kost propaguje vlastní otočení a posun na~všechny následující. Navíc specifikují střed rotačního bodu.
Kosti jsou samostatné abstraktní označení pro~nosič prostorových transformací, pro~který~můžeme přiřadit množinu vrcholů. Potom v~logice animace stačí pouze posouvat určité kosti a~předrenderovácí engine bude souvislé modifikovat přiřazené vrcholy. Navíc kosti často modifikují vrcholy podle předem určené váhy pro~každý vrchol, čímž~lze škálovat a~skládat posuny různých kostí na~určitých vrcholech. Jen~je~potřeba brát v~úvahu, že~skeleton animace neboli modifikace provedené předrenderovacím enginem jsou spuštěné na~CPU, jelikož jsou řízeny logikou herního světa. Naštěstí moderní procesory s~instrukčními sadami AVX a~více jádry v~takových úlohách dokážou předvádět poměrně skvělé až~nadbytečné výkony.
V~Unreal~Engine~5 přidaly rozhraní pro~tvorbu skeleton animací přímo v~editoru. Předtím bylo možné pouze hotové animace naimportovat. Uvnitř editoru je příliš mnoho způsobů jak~režírovat animace (myšleno přehrávání, slepení přechodů, modifikace, skládání atd.) a~lze se~v~tom jednoduše ztratit. V~základu je předpokládaná tvorba stavového automatu, který~bude přehrávat a~cyklit jednotlivé animace v~závislosti na~větvení grafu a~podmínkách hran.
Tato práce obsahuje pouze jednoduché animace postav, které~byly přeneseny ze~staré verze. Animace hráče navíc disponuje imersivním\footnote{Imersivita je označení pro~větší stupeň uživatelské odezvy nebo~pocit přítomností a~ponoření do~děje hráčem.} otáčením trupu a~animace nohou jsou přitahovány k~podlaze pomocí inverzní kinematické metody\footnote{Inverzní kinematická metoda umožňuje procedurální modifikaci skeleton animace. Obvykle se jedná o dopočítání pozice kloubů po cestě (např. loktu nebo kolena) pro určenou pozici "listů" (např. dlaně nebo chodidla)}.
Tráva viditelná v~první a~druhé úrovní je animovaná pomocí offsetů vrcholů. V~reálném čase pod~hráčem se~generují částice s~barevným gradientem kódující offset v~prostoru. Takové~částice jsou viditelné pouze pro~speciální render target menší velikosti -- snímá~se pouze blízké okolí hráče. Materiál trávy následný render target interpretuje jako~texturu, kterou~interpoluje spolu s~texturou jednoduchého procedurálního shaderu větru dostupného v~enginu. Výsledkem je~výkonná procedurální animace reakce na~vítr a~chůzi hráče v~okolí objektu obsahující velké množství instancí resp.~vrcholů.
\paragraph{Texturování} Za~účelem texturování nejdřív potřebujeme objektu určit jedinečnou UV~mapu, která~bude mapovat plošky 3D~modelu na normalizovaný prostor 2D~obrázku. Často tvůrci mají na~začátku problém pochopit, o~co~se~vlastně jedná a~jak~model rozložit. K~tomu může napomoci myšlenka s~rozlepováním resp.~slepováním hran papírové figurky. Celý koncept UV~mappingu je totožný se~zpětným procesem tvorby například papírové krychle, kde~rozbalenou krychli skládáme z~jednoho uceleného kousku materiálu.
Když máme hotové mapování, můžeme volně přiřazovat textury, které~mohou určovat barvu vrcholů, modifikovat jejich normálový vektor, lesk, matnost, průhlednost a~případně další. Přibližně do~roku~2014, kdy~vznikl Substance Painter (program na~procedurální tvorbu materiálů a texturování) a~dnes i~jeho alternativy, jediný způsob texturování objektu bylo manuální kreslení navrch vytvořené mapy. Dnes existují uživatelsky příjemné programy, kde~stačí kreslit rovnou komplexní materiály na~povrch 3D~modelu a~aplikace sama obstará data všech textur.
V~tomto projektu většina objektů používá pouze jednobarevné textury pro~vybarvení určitých skupin plošek. Přesto jsou často využívané normal mapy nebo~masky průhlednosti. Bohužel se~musely zahodit mapy pro~tesselaci\footnote{Teselace je technika podrozdělení a~modifikace plošek za~účelem zvětšení detalizace objektu.} povrchů používané v~staré verzi projektu, jelikož s~příchodem UE~5 tvůrci odebrali celou podporu tesselace kvůli technologii Nanite.
\paragraph{Exportování a Importování}
Workflow nebo~pipeline exportu jsou standardizované v~profesionálních softwarech jako~3ds~Max. Blender má pouze základní možnosti exportu, které~je potřeba nejdřív přizpusobit specifickému hernímu enginu. Potřebné minimum je zajištění správné interpretace dopředního a~vrchního vektorů\footnote{Dopřední "forward" a~vrchní "up" vektory určují, jak~program interpretuje osy ve~3D prostoru. Ve~většině programů dopřední vektor odpovídá ose~Z a~vrchní ose~Y, ale~v~UE je~to obrácené.} celého modelu. Taky se~vyplatí:
\begin{itemize}
\item nastavit šablonu pro~všechny budoucí projekty, tak~aby~modelovací program a~herní editor sdíleli měřítko jednotek,
\item vyzkoušet, jak~se~chová exportovaná hierarchie modelů v~jednom souboru,
\item před exportem ověřit, že~všechny plošky modelu mají správně natočený normálový vektor (očekává~se směr mířící ven z~objektu).
\end{itemize}
Unreal Engine je standardem herního oboru a~proto verze~5 implementuje systém importovacích pipelines. Jedná~se o~mocný nástroj, který~citelně zrychluje a~sjednocuje postupy importování různých assetů nebo~dokonce stejných assetů podle specifických filtrů (adresář assetu, typ, obsah, podřetězce názvu atd.). Subjektivně největší výhodou je předání zodpovědnosti specifického importu pouze osobám v~týmu s~odpovídajícími znalostmi. V~praxi týmový senior založí pipelines pro~často využívané importy~tak, aby~odpovídaly vnitřním firemním politikám a~proto celý tým nemá žádné starosti při importu assetů.
\paragraph{Optimalizace} I~když objekty jsou statické, stále vyžadují optimalizace. Takové lze najít i~v~tomto projektu:
\begin{itemize}
\item Instancování se~využívá k~tvorbě prostorů hustých na~specifické modely. V~UE se~jedná o~editovací prostředek sousedící vedle Landscape. Umožňuje pokročilé nastavení různých množin instancí a~jejich parametry náhodného umístění.
\item Optimální topologie objektu pro~minimalizaci vrcholů potřebných k~vykreslování. Převážná většina modelů -- patří sem i~získané od~třetích stran -- mají mnou ručně přepracované topologie. Jedná~se nejen~o~jednoduchou redukci nepotřebných vrcholů, ale~taky použití létající neboli floating geometrie.
\newpage
Tato~metoda spočívá v~protínání plošek, místo skutečného propojení vrcholů někde uprostřed, jelikož takové propojení by~vyžadovalo podrozdělení plošek, což~by~vedlo ke~zbytečnému zvětšení počtu vrcholů (viz \Cref{fig:FloatingGeometry}). Taktéž objekty mají redukovanou k-DOP kolizní topologii, pro~urychlení výpočtů fyzických simulací.
\item Modely náročné na~vykreslování nebo~použité v~instancování používají LOD~technologii (viz \Cref{fig:LodShowcase} na~další stránce). Nanite v~práci nebyl využit, jelikož~máme vypnutý deferred renderer (viz \Cref{sec:deferredRenderer}).
\end{itemize}
\begin{figure}
\centering
\includegraphics[width=1\linewidth]{img/FloatingGeometry.pdf}
\caption{Floating geometrie využitá v~modelu okna. Vlevo je výsledný vzhled, uprostřed floating geometrie (48~vrcholů a~52~trojúhelníků) a~napravo běžná naivní topologie (64~vrcholů a~152~trojúhelníků).}
\label{fig:FloatingGeometry}
\end{figure}
\begin{figure}
\centering
\includegraphics[width=1\linewidth]{img/LodShowcase.pdf}
\caption{Ukázka LOD instancí kytky.}
\label{fig:LodShowcase}
\end{figure}
Optimalizace textur je zajištěná pouze hlídáním rozumných rozlišení. Jinak některé textury je určitě možné seskupit do~jedné a~výběr instance řídit pomocí UV~mapy, což~zrychlí přístup k~datům.
Jiná grafická optimalizace není řešená. Modely použité v~instancování občas mohou vyvolat snížení výkonu, což~by~bylo potřeba už~řešit nahrazením plnohodnotných modelů za~kolekce průhledných textur (billboard metoda popsaná v~další podsekci).
\newpage
\subsection{Dynamické a procedurální objekty}
\paragraph{Sequencer} Běžná dynamická animace se~vytváří přímo v~editoru objektu Sequencer\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-sequencer-movie-tool-overview}. Taková animace dokáže modifikovat parametry objektů na~úrovni a~volat funkce v~určité okamžiky. Objekty mohou~být určené předem, nebo~Sequencer umí dynamicky vyhledat jejich reference před~spuštěním. Právě v~tomto prostředí se~tvoří cutscény nebo~cyklické animace objektů na~úrovni.
\paragraph{Procedurální generování} V~předchozí verzi hry model trávy byl vytvořen pomocí billboard metody, kde~místo vykreslování 3D~geometrie vegetace se~vykresluje průnik ploch s~texturou vegetace a~průhledným pozadím. Tato~technika je~standardem ve~videohrách, přesto nestačila ke~splnění dizajnových účelů projektu. Buď~vegetace musela být řídká, nebo~vyžadovala nesmyslně mnoho hardwarových prostředků a~občas vzniklo i~drobné zmrazení aplikace.
Za~tímto účelem jsem implementoval nástroj pro~editor, který~je schopen na základě určitých parametrů vygenerovat náhodnou a~hustou trávu z~trojúhelníků. Uživatel může specifikovat oblast generování a~cílový Landscape objekt společně s~materiálem, na~kterém má~být tráva generována. K~tomu lze specifikovat hustotu, variabilitu velikostí, minimální a~maximální velikost. Generování se~skládá ze~tří kroků:
\begin{itemize}
\item Rozložíme oblast na mřížku definované hustoty.
\item Z~každé buňky v~mřížce vyšleme kolizní paprsek směrem k~Landscape povrchu, čímž~získáme střed pro~budoucí stéblo.
\item V~prostoru každé buňky náhodně umístíme dva vrcholy ve~výšce středu a~jeden uprostřed s~náhodnou výškou, čímž~získáme trojúhelník, kterému~říkáme stéblo. Z~pozic vrcholů stébla dopočítáme normálové vektory (potřebujeme ke~správnému stínování stébel ve~světě) a~UV~mapu (pokud chceme určit stéblu texturu, např.~gradientu s~přechodem od~tmavé do~světlé zelené).
\end{itemize}
Výsledný objekt má několikanásobně více geometrických dat než~billboard metoda, přesto~má skvělý výkon a~navíc vegetace působí mnohem hustěji, má kvalitnější vzhled a~lépe reaguje na~offset vrcholů v~shaderech (viz \Cref{fig:GrassShowcase} na~další stránce).
Trik~je v~přenesení velké texturové zátěže s~převýpočty průhledností na~vykreslování jednotné a~jednoduché 3D~geometrie. K~tomu generativní přístup umožňuje kvalitnější pokrytí ploch, jako~například v~tomto projektu, kde~tráva se~generuje pouze v~oblastech určité velikosti a~jestli jsou pokryté určitým materiálem, tedy~tráva se~negeneruje na~cestičkách a~mezi povolenou a~zakázanou plochou je pozvolný přechod ve~velikosti jednotlivých stébel. Takový přístup byl inspirován hrou Ghosts~of~Tsushima od~studia Sucker~Punch~Productions, kde~autoři si~vytvořili podobný proprietární nástroj, jelikož~chtěli dosáhnout husté kinematické a~stylistické vegetace na~konzolích.
\begin{figure}
\centering
\includegraphics[width=1\linewidth]{img/GrassShowcase.pdf}
\caption{Ukázka procedurální~(vlevo) a~billboard~(vpravo) metody pro~vykreslování vegetace. Procedurální metoda má přibližně 6-krát menší render time a~paměťové požadavky.}
\label{fig:GrassShowcase}
\end{figure}
\subsection{Osvětlení}
Téměř každý objekt osvětlení sdílí podobné parametry, které~mohou definovat~to, jak~světlo vypadá nebo~ovlivňuje prostředí. Vedle běžných dizajnových parametrů nechybí ani~široká škála technických triků a~úskalí.
\paragraph{Forward shading} Jelikož celá hra je v~režimu forward shading (viz \Cref{sec:forwardRenderer}), některé technologie jsou značně omezené nebo~nefungují. Například není podporován Rect Light (světelný zdroj ve tvaru obdelníku), který~ale~můžeme napodobit~tak, že~Point Light (světelný zdroj ve tvaru kruhu) zdroji přiřadíme IES~texturu, která~nám specifikuje způsob šíření světla neboli~tvar světla v~herním světě. Stejně~tak lze~vytvořit vlastní Light Function, což~je~materiál definující, co~a~jak světelný zdroj vyzařuje. Navíc je potřeba pamatovat na~technická omezení enginu pro~forward shadingu, jako~nejvýše tři~zdroje světla na~jeden objekt a~nedostatek SSAO nebo~SSR (viz \Cref{sec:screenspace}). S~čímž~stále si~můžeme poradit. Pokud~je potřeba víc zdrojů světel ve~scéně, můžeme specifikovat tři~různé kanály pro~objekt a~zdroje zvlášť.
\newpage
Jestli~nutně potřebujeme ambientní okluzi můžeme použít Lightmass Volume\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/cpu-lightmass-global-illumination-in-unreal-engine} pro~jeho simulaci a~stejně tak~můžeme použít Planar~Reflections\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/planar-reflections-in-unreal-engine} pro simulaci odrazů.
\paragraph{Základy osvětlení} Kromě bodových světel na~úrovní téměř vždy chceme přidat globální osvětlení, které~sestává z~Directional~Light a~Sky~Light.
Directional zdroj funguje jako~jeden velký nekonečně vzdálený zdroj pro~celou scénu, který~napodobuje funkci slunce a~slouží primárně k~vykreslování stínů. Zdroj typu Sky~Light také~může ovlivňovat stíny, ale~primárně zobrazuje Skybox texturu a~modifikuje ambient složku celého osvětlení.
Navíc pokud chceme zobrazit venkovní prostory, je dobré použít nějakou formu mlhy, jako~je Ambient~Fog. Mlha přidá pocit velkého a~neomezeného prostoru i~když ve~skutečnosti je malý a~uzavřený. Navíc mlha výborně skryje a~tedy~umožní horší detailizaci objektů v~dálce, čímž~efektivně zkrátíme dobu vykreslování snímku.
Nakonec se~lze odchýlit k~použití mnoha různých Volume objektů, které~z~důvodů rozsahu práce nebudou podrobně probrány. Pomocí těchto prostorů lze~specifikovat oblastí s~určitými parametry, které~budou napovídat enginu potřebné optimalizace, nebo~zapínat výkonnostně náročné vykreslovací technologie. Pro~představu Lightmass~Importance~Volume\footnote{https://dev.epicgames.com/documentation/en-us/unreal-engine/lightmass-basics-in-unreal-engine} specifikuje oblast, kde~je potřeba propočítat větší počet odrazů paprsků světla při ``zapekání" statických stínů\footnote{Zapekání světla neboli~light map baking je proces náročného předpočítání osvětlení a stínů tvořených statickými objekty na~statickém povrchu do~formátu textury.}.
\subsection{Post-Processing}
Post-processing jsou funkce, které~pracují s~již vyrenderovaným snímkem před~jeho zobrazením. Tímto způsobem lze např.~napadobit rozmazání/rozostření (depth-of-field), mlhu nebo~efekty popsané níže. Post-Processing lze~definovat přímo v~kameře nebo~v~již zmíněných Volume objektech. Každá~definice je de-facto materíál (v~kontextu~UE), který~lze vrstvit mezi sebou. PP~vyžaduje hlubší grafické znalosti, aby~bylo možné vytvořit něco užitečnějšího než~barevnou korekci. Zároveň kvůli tématice práce pouze nastíním, jak~jsem naimplementoval PP~materiály (viz~\Cref{fig:PPShowcase} na~další stránce), které~mají gamedizajnový důvod, ale~se~nestihli použít.
\begin{figure}
\centering
\includegraphics[width=1\linewidth]{img/PPShowcase.pdf}
\caption{Ukázka post-process materiálů ve~hře. Efekt deště jsem nedokázal rozumně zachytit, aby~byl vidět na~statickém obrázku.}
\label{fig:PPShowcase}
\end{figure}
\begin{enumerate}
\item Plovoucí obrazovka - UV~prostor obrazu se~lehce zakřiví pomocí animované šumové textury.
\item Bezpečnostní kamera - obraz rozložíme na~trochu sesunuté proužky dle~rozlišení výstupu a~zároveň tyto~proužky střídavě obarvíme. Nakonec proužky animujeme posunem nahoru nebo~dolu.
\item Slepota - výstupní obraz nahradíme vlastním, ve~kterém zobrazujeme pouze ohraničení objektů s~efektem emise. Ohraničení lze dosáhnout různými způsoby a~v~tomto projektu je~implementováno pomocí drobného posunu hloubkové textury ve~všech směrech. Mezi posuny se~provede rozdíl s~originální hloubkou a~sloučením rozdílů získáme obrysy objektů.
\item Pixelizace - obraz rozložíme na~potřebnou mřížku dle~rozlišení a~modifikujeme UV~prostor výstupního obrazu.
\item Námraza - obraz interpolujeme s~animavanou texturou. Nejlépe použít nějaký gradient uprostřed jako~masku průhlednosti, aby~hráč měl čistší vidění.
\item Tužka a~papír - výstupní obraz nahradíme texturou ambient occlusion.
\item Tavení pixelů - vytvoříme netriviální vertikální gradient s~více přechody. Výsledek poškodíme zaokrouhlováním a~násobením dat, zpixelizujeme vzorkováním na~mřížku a~výsledek použijeme k~modifikaci UV~prostoru výstupního obrazu a~barevné korekci.
\item Déšť - obraz rozložíme na~jemnou mřížku a~v~blocích vygenerujeme různé kapky pomocí složení dvou turbulencí, každá~z~nich bude mít animovanou lehce odlišnou rychlost posunu, aby~kapky nebyly stále stejné. Paralelně k~tomu znovu rozložíme obraz, ale~teď na~hrubou mřížku, kde~animujeme svislé pády bloků s~gradientním ocasem. Oba~výstupy složíme~tak, že~hrubá mřížka představuje animovanou masku průhlednosti, která~nám bude v~různý okamžik otevírat pouze některé kapky. Nakonec přidáme trochu distortion a~výsledek použijeme jako modifikátor UV~výstupního obrazu.
\end{enumerate}
\subsection{Materiály a shadery}
Materiál v~UE je high-level programovátelný objekt popisující vizuální reprezentaci povrchu objektu. Materiál se~programuje pomocí odpovídajících Blueprintů, které~engine převede nejdřív do~HLSL a~potom kompiluje jako~fragment/pixel a~vertex shader.
Přestože materiály jsou omezené shadery, stále lze pomocí nich definovat mnoho různých a~komplexních grafických funkcí. Základem jsou jednoduché barevné výstupy s~triviálními parametry lesku, matnosti a~emise. Může záležet na druhu objektu, pro~který~materiály tvoříme, tedy~potřebujeme správně nastavit i~druh materiálu, čímž~následně dostaneme další, předtím uzavřené, výstupy a~vstupy. Například za~účelem optimalizace můžeme přepnout materiál ze~základního režimu osvětlení neboli~Default~Lit do~neosvětleného režimu Unlit, čímž~budeme moci definovat barvu objektu pouze emisní složkou, ale~zmenšíme vykreslovací čas potřebný pro~materiál.
V~UE materiály resp.~shadery mají mnoho globálních(uniform) proměnných, z~kterých můžeme získat cenné údaje o~enginu, scéně, vykreslovaném objektu, render buffrech atd. Dokonce můžeme definovat vlastní globální nebo~lokální parametry a~měnit jejich hodnoty v~logice světa. Použití takových proměnných lze často vidět v~již~zmíněných post-procesech, které~přebírají a~modifikují hodnoty výstupního zobrazení nebo~jsou animované pomocí sinusové funkce s~globálním parametrem herního času jako~vstup.
Stojí~za~to zmínit, že~některé materiály se~hodí pouze na~určitý druh objektů podle velikosti a~umístění ve~světě. Jedním z~příkladů v~této hře je materiál skla. Původně navržený shader, který~simuluje zalamování a~vnitřní objem, skvěle funguje na~drobných objektech jako lahve nebo~skleněné střepy. Při~použití na~velkých skleněných plochách jako~jsou~okna, takové simulace vytváří nežádané artefakty. Pro takové situace byl přidán duplicitní shader skla, který~primárně vykresluje poloprůhlednou barvu na~povrchu objektu.
\paragraph{Funkce} V~materiálech se~lze zbavit duplicitního kódu, čímž~se~zároveň zrychlí kompilace a~běh shader variací. Implementoval~jsem funkce:
\begin{itemize}
\item Škálování vstupní hodnoty podle vzdálenosti objektu od~kamery.
\item Uniformní škálování a~tiling textury nezávislé na~velikosti objektu.
\item Získání obrysů objektů v~podobě masky.
\item Rotace objektu ve~směru kamery.
\end{itemize}
\subsection{Uživatelské rozhraní}
Uživatelské rozhraní neboli UI je sada 2D~prvků vykreslených na~vyrenderováný obraz 3D~scény. Běžně se~jedná o~menu, titulky nebo~popisky ovládání. Před~Unreal~Engine~5 téměř každé~UI byl rastrový obrázek a~v~minulosti to~ani~nebyl problém. Stačilo vytvořit mip-mapy pro~menší množinu nejrozšířenějších rozlišení (HD, WSXGA a~Full~HD) a~k~tomu škálovat mip~texturu menšího rozlišení na~potřebný lehce větší výstup. Předtím hry nevypadaly zaostřeně takže nemuselo ani~UI a~dokonce to~rozostření rastrového obrazu nebylo tak~viditelné na~displejích menší velikosti v~té~době. Dnes rastrové~UI vytváří příliš komplikací při~tvorbě a~vykreslování. Je potřeba mnoho mip-map ve~velkých rozlišeních pro~ostrý obraz na~každém displeji, které~vyžadují velké množství paměti a~hlavně velkou propustnost při~čtení dat, což~se~nejvíc projevuje u~rastrových animací.
Jelikož původní projekt vznikal ve~čtvrté verzi enginu, ale~v~době již~velkých rozlišení, nebylo realistické pro~dva vývojáře vypracovat přijatelné rastrové~UI. Proto jsem tehdy a~teď vytvořil všechny prvky pomocí černobílých poloprůhledných vektorových čtverců s~transformacemi. Rastrové textury se~používají pouze v~podobě masek nebo gradientů, při~použití~kterých nejsou zřejmé škalovací artefakty.
Všechny kořenové UI~prvky (overlay, kontejner questů, kontejner nápověd ovládání, menu~atd.) spravuje mnou implementována třída Widget~Manager. Tato~třída slouží nejen jako~high-level~API pro~všechny kořenové prvky resp.~kontejnery, ale~primárně přehledně udržuje reference na~takové prvky. Bez~manuálního udržování reference, po~instancování libovolného UI~prvku ho~již~nelze získat a~tedy nemůžeme prvek ani~odstranit z~obrazovky.
Každý prvek se~instancuje na~začátku a~udržuje~se v~paměti po~celou dobu. Důvodem stálého udržování prvků v~paměti je jejich naplňování daty, které~občas může trvat déle a~tak při~dynamickém instancování vyvolávat zaseknutí aplikace.
\paragraph{Texty a překlady} V~enginu je více druhů řetězců:
\begin{itemize}
\item FString - běžný řetězec pro~reprezentaci UTF-16 se~stejnou množinou funkcí jako~u~std::string. Je optimalizovaný pro~konkatenace.
\item FName - pouhý ukazatel na~tabulku triviálních unikátních bajtových řetězců. Používá~se pro~pojmenování konstant v~kódu nebo~tagování objektů a~je~to doporučený textový formát pro~přenos přes internet.
\item FText - komplexní řetězec schopný překládat obsah podle tabulky nebo~formátovat čísla podle pravidel jazyka.
\end{itemize}
Engine při~instancování určitého FText nebo~FString se~snaží najít již~existující instanci v~paměti, čímž~se~výrazně redukuje duplicita dat zejména v~blueprintech.
Při~tvorbě projektu jsem~si~dal záležet, aby~veškerý text viditelný hráčem byl překladatelný. Zároveň jsem dbal na~zachování unikátností řetězců, aby~se~v~tabulce překladů nevyskytovaly duplicitní záznamy. Engine pochopitelně takové záznamy nemůže eliminovat sám a~ani to~nechceme, protože~každá stejná slova v~jednom jazyce, mohou~být již různá v~jiném jazyce v~závisloti na~gramatice a~kontextu.
\paragraph{Načítací obrazovka} Načítací obrazovka je povinná z~důvodů licenčních podmínek některých knihoven a~programů. Zejména Unreal~Engine a~FMOD vyžadují, aby~produkt obsahoval načítací obrazovku s~logem jejich softwaru. Tato~zdánlivě triviální problematika ve~skutečnosti zahrnuje netriviální množství časové investice a~rozboru startovací sekvence enginu, což~vyúsťuje v~nekompetentní řešení začínajících i~pokročilých vývojářů. Přesně se~jedná~o:
\begin{itemize}
\item úplné vynechání celé funkcionality a~tedy porušování licenčních podmínek,
\item nebo~simulaci načítaní~tak, že~po již plném načtení enginu se~otevře speciální scéna obsahující pouze UI s~animaci načítání s~předem definovanou délkou zobrazování.
\end{itemize}
Ve~své práci pro~mě bylo zásadní vytvářet věci technicky správně a~tedy vyhýbat~se programátorským workaroundům nebo~technickému ``lhaní'' hráči. Proto~jsem~si~dal záležet i~na~správném provedení načítací obrazovky.
Postup tvorby načítací obrazovky vývojáři enginu nedokumentují a~běžně dostupné návody třetích stran jsou již zmíněné nekvalitní simulace. Dokázal jsem najít pár funkčních ukázek u~kolegů z~Číny\Cite{chinaLoadingScreen} a~Japonska\Cite{japanLoadingScreen}, které~mi~umožnily se~zorientovat v~základech a~následně provést reverse engineering celé problematiky. K~mému překvapení jedná~se o~důkladně propracovaný systém, který~je podrobně přizpůsoben specifikům různých platforem.
Engine při~načítaní nepodporuje UI vytvořený v~blueprintech, jelikož blueprinty jsou assety s~hlubokou reflexí, kterou~engine teprve~načítá (po~načtení již~lze zobrazit blueprint načítací obrazovky mezi úrovněmi). Proto~jsem~musel vytvořit navíc UI~v~nízkoúrovňovém Slate.
\section{Audio}
\label{sec:audio}
V~tomto projektu jsem~se~zaměřil primárně na~zprovoznění všech technologií potřebných k~dokončení uceleného produktu a~proto~je ve~hře značný nedostatek audia. Přesto je připravené široké technické zázemí, které~obsahuje drobné ukázky:
\begin{itemize}
\item nastavení a~ukládání hlasitostí různých kategorií audia,
\item prostorové přehrávání,
\item dynamický hudební doprovod
\item a~možnost dabování dialogů spolu s~hotovým procesem generování hlasů.
\end{itemize}
\newpage
Optimalizace audia nepatřila mezi cíle této práce, avšak~základní systematická pravidla byla určena.
\begin{itemize}
\item Použít streaming a~kompresi dat kdekoliv to~bude možné,
\item hudební doprovod je~ve~formátu~MP3,
\item hlasy a~jiné zvuky jsou~ve~formátu~WAV.
\end{itemize}
V~budoucnu by~také pomohlo zabalit všechny hlasy a~jiné audio do~samostatných datových balíčků neboli~chunků. Aktuálně všechny herní assety jsou automaticky zabalené do~pár ucelených balíčků, což~sice může vyvolat drobné zpomalení načtení assetů, ale~stále zásadně ovlivnit audio zážitek. Tomu~tak~je, protože uši jsou mnohem ``časově citlivější" než~oči. Zatímco pro~vnímání plynulosti obrazu často stačí vyšší desítky snímků za~sekundu\Cite{videoSampling}, pro~zachycení všech slyšitelných zvukových frekvencí je potřeba nad~40~tisíc vzorků za~sekundu\Cite{audioSampling}. Navíc i~drobné záseky nebo~vypadnutí několika vzorků jsou snadno slyšet.
\subsection{Dynamický hudební doprovod}
Když~mluvíme o~dynamickém doprovodu ve~hrách, často myslíme právě~dynamické přepínání částí skladby v~závislosti na~proměnných světa. Pří~vývoji jsem se~uchýlil k~použití zvukového enginu~FMOD (viz~\Cref{prg:fmod}) a~hudbu jsem skládal sám bez~použití samplů, tedy~pomocí~VST (Virtual~Studio~Technology) hudebních nástrojů. Častí hotových kompozic za~účelem dynamiky by~měly~být nerušivě zacyklené, na~což~jsem kladl největší důraz. Bohužel kvůli~omezenému času jsem~nemohl věnovat dostatečnou pozornost rozmanitosti a~komplexitě hudebních kompozic. Prototypy dynamického doprovodu lze již~zaslechnout v~průběhu třetí úrovně, tedy postupné vrstvení zvukových stop při~propojování kabelů a~adaptivní hudební progrese napříč částmi bludiště.
\subsection{Dabing dialogů}
Jelikož hra by~měla poskytnout prostor pro~AI generovaný obsah, dialogy jsou již~nadabované pomocí~AI. Původně jsem začínal s~Python knihovnou Coque~TTS\footnote{https://github.com/coqui-ai/TTS}, ale~dosáhnout v~ní aspoň dobrých výsledků bylo náročné. Proto~jsem~přešel na~knihovnu a~model Zonos\footnote{https://github.com/Zyphra/Zonos}, který~již v~základu poskytuje vynikající výsledky a~navíc má~prostředky pro~udržování kontextu nebo~parametry zabarvení hlasu.
V~modulu VoiceGenerator v~repozitáři hry je~k~dispozici skript pro~jednoduchou instalaci prostředí. Z~časových důvodů jsem~nestihl vytvořit skript, který~by jednoduše generoval množiny resp.~sekvence dialogů přímo z~jednoho textového souboru. Aktuálně je~potřeba ručně generovat každou větu jednotlivě přes~webové rozhraní, které~je~součástí knihovny, ale~naprogramovat klienta, který~bude pro~každou textovou linku volat stejné generující~API a~ukládat výsledky, by~nemělo~být složité.
Ukázkové dialogy lze již~zaslechnout v~průběhu třetí úrovně. Původně jsem~taky~plánoval vytvořit robotický hlas ve~třetí úrovni pomocí modifikace základního hlasu v~novém pro~UE5 zvukovém systému MetaSound. Ten~dokáže komplexně modifikovat zvukový signál za~běhu, ale~na~začlenění takové technologie do~hry nezbýval čas.
\newpage
\section{Co se~nestihlo nebo~změnilo}
Přestože do~práce jsem~vložil mnoho času a~úsilí, nepodařilo se~mi splnit všechny mnou stanovené cíle. Místo herního dema práce představuje spíš demo technické, neboli~jsem~úspěšně vytvořil technické zázemí, ale~nestihl naplnít hru obsahem. Třetí úroveň nějakým obsahem disponuje a~dohromady lze tuto úroveň považovat za~hru. Jinak~všechny úrovně resp.~celá hra trpí nedostatkem nebo~neobsahuje vůbec:
\begin{itemize}
\item grafické prvky jako~animace postav, efekty, 3D modely,
\item zvukové prvky jako~hudební doprovod, zvuky~interakce se~světem a~UI,
\item příběhové dialogy, cutscény a~dokončený level design,
\item balancování herních mechanik a~doladění ovládání.
\end{itemize}
Nepodařilo~se~mi vytvořit poslední pátou úroveň z~časových důvodů. Zároveň jsem~se~rozhodl změnit žánr této úrovně z~first-person shooter na~top-down shooter. Důvodem změny posloužila analýza náročnosti tvorby obsahu pro~takový žánr. Přestože~first-person shooter se~může zdát jako~jednoduchý koncept, ve~skutečnosti pro~hezký herní zážitek je~potřeba vložit mnoho úsilí a~času. Pro~tento~žánr je~nutné pečlivě odladit všechny prvky hry a~hlavně animace, které~jsou má slabá stránka. Na~druhou stranu top-down shooter neklade tak~vysoké nároky a~dokonce umožňuje skrytí od~hráče nedostačující animace.
\subsection{Obsah mimo hru}
Projekt není~tvořen pouze technickým demo hry, ale~také zahrnuje nasazení a~údržbu sítě s~veřejnou ip~adresou, webového a~Git\footnote{https://git-scm.com/} serveru. Postupy nasazení a~údržby vzhledem k~zaměření práce nejsou zveřejněny. Zvolil jsem údržbu vlastní sítě a~zařízení převážně z~finančních důvodů. Vlastní Git server je zapotřebí z~důvodu nadstandardní velikosti repozitáře, kterou~veřejné platformy jako~GitHub\footnote{https://github.com/} a~Gitlab\footnote{https://about.gitlab.com/} již~zpoplatňují. Webový server slouží jako~rozhraní pro~poskytování assetů hráči v~podobě běžné indexovací složky se~soubory, kterou~poskytuje základní implementace serveru Nginx\footnote{https://nginx.org/}.

23
ch3.tex
View File

@ -1,23 +0,0 @@
\chapter{Uživatelská dokumentace}
\section{Hardwarové požadavky a instalace}
Minimální hardwarové požadavky (nejnižší otestované pro~FullHD min.~60FPS bez~MSAA):
\begin{itemize}
\item CPU: AMD Ryzen 5 5500
\item GPU: NVIDIA GTX 1050 Ti
\item RAM: 2 GB
\item Místo na disku: 2 GB
\item Operační systém: Windows 10 nebo Windows 11
\item Připojení k Internetu: 1 MB/s (pouze pro~stahování nového obsahu a~instalaci knihoven, jinak~není nutný)
\end{itemize}
Součástí přilohy je hra (Builds/Lost\_Edge). Před~spuštěním hry (soubor Builds/Lost\_Edge/Lost\_Edge.exe) je doporučeno spustit instalaci knihoven potřebných k~fungování hry tvořené v~Unreal~Engine~5 (soubor Builds/Lost\_Edge/Redist/UEPrereqSetup\_x64.exe). Při~instalaci knihoven je potřeba mít připojení k~internetu.
\section{Menu a nastavení hry}
Po spuštění programu se~uživateli otevře testovací úroveň. Pro~otevření/zavření menu je potřeba stisknout klávesu Escape. V~menu pomocí levého tlačítka myši lze program vypnout, nebo~nastavit parametry zobrazení aplikace (rozlišení, omezení snímků, zobrazení FPS, zhlazovací metoda), hlasitost audia nebo~citlivost pohybu herní kamery.
\newpage
\section{Ovládání, zahájení a průběh hry}
Ve hře je k dispozici debug nabídka, kterou~lze otevřít klávesou TAB (lze v~ní přeskočit minihru). Jinak hra využívá klasické ovládání pro~3D~hry, tedy klávesy WASD pro~chůzi, držení Shift pro~běh, mezerník pro~skok a~pohyb myší pro~pohyb kamery. Během hry v~závislosti na~kontextu se~objevují další ovládací prvky a~nápovědy k~ním. Nápovědy mohou slovně nebo~pomocí animací vyzývat stisknutí, nebo~podržení určitých kláves. Některé pohyblivé objekty simulují fyzické chování, pro~které je zapotřebí objekty pustit při~posunu, nebo~narážet do~sebe (například hod objektem pomocí rychlého posunu kamerou a~jeho puštění v~okamžiku švihu).
Příběhový režim hry se~zahájí aktivací panelu s~nápisem ``Start game" v~testovací úrovni (úplně první panel, který~vidí hráč po~spuštění hry). Příběh se~skládá ze~čtyř úrovní se~žánry po~pořadě horror, minigame adventura, puzzle a~stealth. Průměrná délka hry je 5~až~10 minut.

View File

@ -1,15 +0,0 @@
\chapwithtoc{Závěr}
Cílem této práce bylo:
\begin{enumerate}
\item navrhnout způsob tvorby a využití AI generativního obsahu pro hry
\item a vytvořit kostru příběhové 3D počítačové hry s podporou načítání nového obsahu za~běhu, která~bude schopná pojmout různé herní žánry a~situace.
\end{enumerate}
Práce zahrnuje popis, analýzu a~řešení problémů spojených s~návrhem her, jejich tvorbou v~Unreal~Engine a~jejich AI~generováním, stahováním a~načítáním přímo do~hry. Jsou pokryty i~technologie a~systémy potřebné pro~pokročilou tvorbu a~práci s~2D a~3D grafikou a~se~zvuky a~hudbou.
Z~důvodu rozsahu práce nebyl dodán veškerý plánovaný obsah netechnického charakteru. Text práce nastiňuje reálnou implementaci, ale~nezabíhá do~hlubších detailů, které~jsou lépe popsané v~(programátorské) dokumentaci. Výsledek práce splňuje všechny stanovené cíle a~navádí na~možná vylepšení. Absence audiovizuálního obsahu a~jedné z~pěti úrovní nezasahuje do~funkčnosti ani~hratelnosti kostry hry. Bakalářská práce obsahuje v~příloze programátorskou dokumentaci, která~umožňuje jednodušší začátek práce se~zdrojovým kódem.
Výsledná hra nyní slouží jako bohatá platforma pro~zkoušení AI~generativní tvorby podle analýzy v~Sekci~\ref{sec:contentGenerationAndIntegration}. Avšak~jsou k~dispozici široké možnosti dalšího vývoje.
Především, jak je zmíněno v návrhu, potřebujeme doladit existující textový AI~model, aby~byl schopný programovat v~prostředí Unreal~Enginu. S~takovým modelem bychom mohli implementovat aspoň základní generátory (různých typů obsahu) a~začít testovat možností a~vliv generativní tvorby ve~hrách. V~průběhu psaní práce již~jeden podobný model vznikl, ale~je placený a~značně omezený (viz~Ludus~AI\footnote{https://ludusengine.com/}).
Také hře chybí ladění na~optimalizaci "herního zážitku" a~mnoho audiovizuálního obsahu, který~by zpestřil zážitek ze~hry a~zároveň poskytl více dat a~tedy i~kvalitnější AI~generativní výstupy. V~okamžiku odevzdání této práce se již na~tomto bodě pracuje a~jsou plánována budoucí rozšíření a~vylepšení stávající hry.

View File

@ -1,23 +0,0 @@
FROM debian:testing-slim
RUN apt-get -qq update && apt-get install -y \
biber \
texlive-bibtex-extra \
texlive-fonts-extra \
texlive-fonts-recommended \
texlive-formats-extra \
texlive-lang-czechslovak \
texlive-lang-english \
texlive-latex-extra \
texlive-latex-recommended \
texlive-luatex \
texlive-pictures \
texlive-publishers \
texlive-science \
texlive \
ghostscript \
latexmk \
make
RUN rm -fr /var/lib/apt /var/cache/apt

View File

@ -1,10 +0,0 @@
\chapwithtoc{Přílohy}
Přiložený balíček ZIP obsahuje:
\begin{itemize}
\item kopii této práce,
\item designovou dokumentaci, popis příběhu, popis úrovní, programátorskou dokumentaci a kopii uživatelské dokumentace (složka Documentation),
\item zdrojové kódy (C++ textové soubory a Blueprint assety v~projektech), mediální soubory (audio, 2D~a~3D grafické soubory) a~projekty pro~Unreal Engine použité k~vývoji této~práce (Lost\_Edge) a~její předchozí verze (Lost\_Edge\_Legacy), na~které je práce založená (složka Data),
\item aktuální přeložená, hratelná verze této práce (Lost\_Edge) a~její předchozí verze (Lost\_Edge\_Legacy), na~které je práce založená (složka Builds),
\item textový rozcestník ke~složce ``Data" s~odkazem na~stránku s~aktuálním repozitářem projektu (README.txt).
\end{itemize}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,17 +0,0 @@
\chapwithtoc{Úvod}
Příběhové hry jsou běžně navrhnuté předem a~zůstávají neměnné. Existují ale~i~výjimky, například hry žánru rogue-like, kde~je generování obsahu založeno na~použití speciálně vytvořeného a~odladěného algoritmu. Tento algoritmus různé složitosti používá pouze prostředky předem navržené a~odladěné vývojáři. To~vše má podstatný důvod, jelikož vývojáři mají za~úkol vytvořit tzv.~dobrý herní zážitek a~zaručit, že~hra bude umělecky správně interpretovaná hráčem. Bohužel nezávisle na~kvalitě potenciál opakovaného hraní hry je omezený a~v~horším případě ani~hra k~druhému zahrání neláká.
Tento problém v~branži příběhových her je řešen různými druhy tzv.~komunitních modů neboli modifikací hry, jako~například grafické, kódové nebo~další úpravy. Buď~samotní vývojáři hry poskytují potřebné prostředky pro~podporu a~tvorbu modů, nebo~i~technicky zdatní autoři modů dokáží přímo upravovat soubory hry, nebo~vyvíjet nástroje, které~s~nimi pracují. V~každém případě modifikace značně zvyšují potenciál znovuzahrání hry, kde~klasickým příkladem je~hra The Elder Scrolls: Skyrim od~studia Bethesda.
Přestože toto (komunitní) řešení zdánlivě funguje, spoléhá~se na~ochotu samotných hráčů mody vytvářet. Pokud hra nebude mít dostatek hráčů, potom~také nebude mít dostatek nového fanouškovského obsahu a~pak počet znovuzahrání neroste. Nedávným příkladem je~hra Starfield od~již zmíněného studia Bethesda. Navíc kromě technických omezení samotných modů musí~mít hráči nejen ochotu, ale~i~být technicky a~umělecky zdatní, aby~něco vytvořili, nebo~nainstalovali.
Tato práce se~zaměřuje na~tvorbu hry a~návrh systému, který~umožní výše popsaný lidský faktor a~nedostatky omezit. Přináší příběh rozdělený na~pět žánrově odlišných úrovní a~zavádí high-level API pro~Unreal~Engine na~stahování a~načítání obsahu do~hry přímo za~běhu. Specifický příběh snižuje ludonarativní disonanci\footnote{Nesouvislost resp.~logické odpojení herního světa, příběhu a~gameplaye.} při~vzniku nového obsahu ve~hře a~přítomnost více žánrů umožňuje otestovat, jestli toto řešení v~každém z~nich dostatečně funguje. Tato práce přenechává samotné generování obsahu pomocí AI modelů a~testování výsledků~jako další rozšíření. Primárně se~zaměřuje na~kostru samotné hry, aby~byl prostor, kam nový obsah začlenit.
Hlavní témata na~které se~práce zaměřuje:
\begin{itemize}
\item ukázkové příklady tvorby herních systémů a~mechanik pro~Unreal~Engine (\cref{sec:systemsAndMechanics}),
\item návrh tvorby generativního obsahu a~jeho načítaní v~Unreal Engine (\cref{sec:contentGenerationAndIntegration}),
\item postupy tvorby grafiky v~UE (3D a 2D, animace, post-processing) (\cref{sec:graphics}) a
\item postupy tvorby zvuků a~hudby pro~hry (\cref{sec:audio}).
\end{itemize}

View File

@ -1,113 +0,0 @@
% use this for typesetting a chapter without a number, e.g. intro and outro
\def\chapwithtoc#1{\chapter*{#1}\addcontentsline{toc}{chapter}{#1}}
% If there is a line/figure overflowing into page margin, this will make the
% problem evident by drawing a thick black line at the overflowing spot. You
% should not disable this.
\overfullrule=3mm
% The maximum stretching of a space. Increasing this makes the text a bit more
% sloppy, but may prevent the overflows by moving words to next line.
\emergencystretch=1em
\ifEN
\theoremstyle{plain}
\newtheorem{thm}{Theorem}
\newtheorem{lemma}[thm]{Lemma}
\newtheorem{claim}[thm]{Claim}
\newtheorem{defn}{Definition}
\theoremstyle{remark}
\newtheorem*{cor}{Corollary}
\else
\theoremstyle{plain}
\newtheorem{thm}{Věta}
\newtheorem{lemma}{Lemma}
\newtheorem{claim}{Tvrzení}
\newtheorem{defn}{Definice}
\theoremstyle{remark}
\newtheorem*{cor}{Důsledek}
\fi
\newenvironment{myproof}{
\par\medskip\noindent
\textit{\ifEN Proof \else Důkaz \fi}.
}{
\newline
\rightline{$\qedsymbol$}
}
% real/natural numbers
\newcommand{\R}{\mathbb{R}}
\newcommand{\N}{\mathbb{N}}
% asymptotic complexity
\newcommand{\asy}[1]{\mathcal{O}(#1)}
% listings and default lstlisting config (remove if unused)
\DeclareNewFloatType{listing}{}
\floatsetup[listing]{style=ruled}
\DeclareCaptionStyle{thesis}{style=base,font={small,sf},labelfont=bf,labelsep=quad}
\captionsetup{style=thesis}
\captionsetup[algorithm]{style=thesis,singlelinecheck=off}
\captionsetup[listing]{style=thesis,singlelinecheck=off}
% Customization of algorithmic environment (comment style)
\renewcommand{\algorithmiccomment}[1]{\textcolor{black!25}{\dotfill\sffamily\itshape#1}}
% Uncomment for table captions on top. This is sometimes recommended by the
% style guide, and even required for some publication types.
%\floatsetup[table]{capposition=top}
%
% (Opinionated rant:) Captions on top are not "compatible" with the general
% guideline that the tables should be formatted to be quickly visually
% comprehensible and *beautiful* in general (like figures), and that the table
% "head" row (with column names) should alone communicate most of the content
% and interpretation of the table. If you just need to show a long boring list
% of numbers (because you have to), either put some effort into showing the
% data in an attractive figure-table, or move the data to an attachment and
% refer to it, so that the boredom does not impact the main text flow.
%
% You can make the top-captions look much less ugly by aligning the widths of
% the caption and the table, with setting `framefit=yes`, as shown below. This
% additionally requires some extra markup in your {table} environments; see the
% comments in the example table in `ch2.tex` for details.
%\floatsetup[table]{capposition=top,framefit=yes}
\ifEN\floatname{listing}{Listing}
\else\floatname{listing}{Výpis kódu}\fi
\lstset{ % use this to define styling for any other language
language=C++,
tabsize=2,
showstringspaces=false,
basicstyle=\footnotesize\tt\color{black!75},
identifierstyle=\bfseries\color{black},
commentstyle=\color{green!50!black},
stringstyle=\color{red!50!black},
keywordstyle=\color{blue!75!black}}
% Czech versions of the used cleveref references (It's not as convenient as in
% English because of declension, cleveref is limited to sg/pl nominative. Use
% plain \ref to dodge that.)
\ifEN\relax\else
\crefname{chapter}{kapitola}{kapitoly}
\Crefname{chapter}{Kapitola}{Kapitoly}
\crefname{section}{sekce}{sekce}
\Crefname{section}{Sekce}{Sekce}
\crefname{subsection}{sekce}{sekce}
\Crefname{subsection}{Sekce}{Sekce}
\crefname{subsubsection}{sekce}{sekce}
\Crefname{subsubsection}{Sekce}{Sekce}
\crefname{figure}{obrázek}{obrázky}
\Crefname{figure}{Obrázek}{Obrázky}
\crefname{table}{tabulka}{tabulky}
\Crefname{table}{Tabulka}{Tabulky}
\crefname{listing}{výpis}{výpisy}
\Crefname{listing}{Výpis}{Výpisy}
\floatname{algorithm}{Algoritmus}
\crefname{algorithm}{algoritmus}{algoritmy}
\Crefname{algorithm}{Algoritmus}{Algoritmy}
\newcommand{\crefpairconjunction}{ a~}
\newcommand{\crefrangeconjunction}{ a~}
\fi

View File

@ -1,91 +0,0 @@
%%% Choose a language %%%
\newif\ifEN
%\ENtrue % uncomment this for english
\ENfalse % uncomment this for czech
%%% Configuration of the title page %%%
\def\ThesisTitleStyle{mff} % MFF style
%\def\ThesisTitleStyle{cuni} % uncomment for old-style with cuni.cz logo
%\def\ThesisTitleStyle{natur} % uncomment for nature faculty logo
\def\UKFaculty{Faculty of Mathematics and Physics}
%\def\UKFaculty{Faculty of Science}
\def\UKName{Charles University in Prague} % this is not used in the "mff" style
% Thesis type names, as used in several places in the title
\def\ThesisTypeTitle{\ifEN BACHELOR THESIS \else BAKALÁŘSKÁ PRÁCE \fi}
%\def\ThesisTypeTitle{\ifEN MASTER THESIS \else DIPLOMOVÁ PRÁCE \fi}
%\def\ThesisTypeTitle{\ifEN RIGOROUS THESIS \else RIGORÓZNÍ PRÁCE \fi}
%\def\ThesisTypeTitle{\ifEN DOCTORAL THESIS \else DISERTAČNÍ PRÁCE \fi}
\def\ThesisGenitive{\ifEN bachelor \else bakalářské \fi}
%\def\ThesisGenitive{\ifEN master \else diplomové \fi}
%\def\ThesisGenitive{\ifEN rigorous \else rigorózní \fi}
%\def\ThesisGenitive{\ifEN doctoral \else disertační \fi}
\def\ThesisAccusative{\ifEN bachelor \else bakalářskou \fi}
%\def\ThesisAccusative{\ifEN master \else diplomovou \fi}
%\def\ThesisAccusative{\ifEN rigorous \else rigorózní \fi}
%\def\ThesisAccusative{\ifEN doctoral \else disertační \fi}
%%% Fill in your details %%%
% (Note: \xxx is a "ToDo label" which makes the unfilled visible. Remove it.)
\def\ThesisTitle{Vícežánrová příběhová počítačová hra s podporou načítání nového obsahu za běhu}
\def\ThesisAuthor{Oleg Petruny}
\def\YearSubmitted{2025}
% department assigned to the thesis
\def\Department{Katedra softwaru a výuky informatiky}
% Is it a department (katedra), or an institute (ústav)?
\def\DeptType{Katedra}
\def\Supervisor{Mgr. Martin Mirbauer}
\def\SupervisorsDepartment{Katedra softwaru a výuky informatiky}
% Study programme and specialization
\def\StudyProgramme{Informatika (B0613A140006)}
\def\StudyBranch{IPP6 (0613RA1400060010)}
\def\Dedication{%
Rozhodně děkuji svému vedoucímu Mgr. Martinu Mirbauerovi za jeho čas, ochotu, trpělivost a cenné rady. Velký dík patří také mnoha dalším lidem uvedeným v titulcích hry za jejich pomoc, testování a podporu. Bez všech těchto lidí by tato práce buď vůbec nevznikla, nebo by nedosáhla takového rozsahu a kvality.
}
\def\AbstractEN{%
The thesis deals with the creation of a multi-genre narrative computer game with support for loading new content on~the~fly in~Unreal Engine~5. It~includes an~analysis and~design of~a~complex system for~AI generation of~game content and~its downloading and~loading (in~the~game client) (during the~game). The~text provides an~introduction and the~use of~many technologies used to~create a~complete modern game. The~result is~a~demo that~contains examples of~all systems and~has the~possibility of~expansion in~subsequent works.
}
\def\AbstractCS{%
Práce se~zabývá tvorbou vícežánrové příběhové počítačové hry s~podporou načítání nového obsahu za~běhu v~Unreal Engine~5. Součástí je rozbor a~návrh komplexního systému pro~AI generování herního obsahu a~jeho stahování a~načítání (v~herním klientovi) (při~hře). Text obsahuje úvod a~nastínění použití mnoha technologií používaných pro~tvorbu kompletní a~moderní hry. Výsledkem je demo, které~obsahuje ukázky všech systémů a~disponuje možností rozšíření v~navazujících pracích.
}
% 3 to 5 keywords (recommended), each enclosed in curly braces.
% Keywords are useful for indexing and searching for the theses by topic.
\def\Keywords{%
{Počítačová hra} {Unreal Engine} {dynamické načítání obsahu} {3D grafika}
}
% If your abstracts are long and do not fit in the infopage, you can make the
% fonts a bit smaller by this setting. (Also, you should try to compress your abstract more.)
% Alternatively, consider increasing the size of the page by uncommenting the
% geometry modification in thesis.tex.
\def\InfoPageFont{}
%\def\InfoPageFont{\small} %uncomment to decrease font size
\ifEN\relax\else
% If you are writing a czech thesis, you additionally need to fill in the
% english translation of the metadata here!
\def\ThesisTitleEN{Multi-genre game with support for loading new content in real-time}
\def\DepartmentEN{Department of Software and Computer Science Education}
\def\DeptTypeEN{Department}
\def\SupervisorsDepartmentEN{Department of Software and Computer Science Education}
\def\StudyProgrammeEN{Computer Science (B0613A140006)}
\def\StudyBranchEN{IPP6 (0613RA1400060010)}
\def\KeywordsEN{%
{Computer game} {Unreal Engine} {dynamic content loading} {3D graphics}
}
\fi

25
pdfa.sh
View File

@ -1,25 +0,0 @@
#!/bin/bash
# Use this script to convert random PDFs to PDF/A (e.g. figures).
# Unfortunately, ghostscript cannot retain the PDF/A metadata. In result, if
# you use this on the thesis, it _will_ become PDF/A compliant (and SIS will
# accept it), but won't contain the magic PDF/A "stamp" and will show only as
# normal PDF-1.4. :(
gs -dPDFA=1 \
-dBATCH \
-dNOPAUSE \
-sProcessColorModel=DeviceCMYK \
-sColorConversionStrategy=UseDeviceIndependentColor \
-sDEVICE=pdfwrite \
-dPDFACompatibilityPolicy=3 \
-sOutputFile="pdfa-$1" \
"$1"
# Notes:
#
# PDFACompatibilityPolicy=3 actually doesn't exist. A bug in ghostscript
# interprets it as something between 1 and 2, without unnecessarily failing on
# various dumb errors.
#
# Add -dNoOutputFonts if you absolutely totally need to get rid of fonts in a
# figure PDF. Do not do that for the whole thesis though-- a thesis with
# removed font glyphs is not submittable!

View File

@ -1,85 +0,0 @@
@book{schreier2017blood,
title={Blood, Sweat, and Pixels: The Triumphant, Turbulent Stories Behind How Video Games Are Made},
author={Schreier, J.},
isbn={9780062651242},
lccn={2017034583},
url={https://books.google.cz/books?id=-bK-DQAAQBAJ},
year={2017},
publisher={HarperCollins}
}
@misc{pacingIntensity,
title = {Gameplay Fundamentals Revisited: Harnessed Pacing \& Intensity [online]},
author = {Mike Lopez},
year = 2018,
note = {[cit. 2025-04-01]. Dostupné z: \url{https://www.gamedeveloper.com/design/gameplay-fundamentals-revisited-harnessed-pacing-intensity}}
}
@misc{unityComparing,
title = {Objectively comparing Unity and Unreal Engine},
author = {Sirawat Pitaksarit},
year = 2019,
note = {[cit. 2025-04-01]. Dostupné z: \url{https://gametorrahod.com/objectively-comparing-unity-and-unreal-engine/}}
}
@misc{godotRealityCheck,
title = {What are the worst parts/issues of Godot in your experience?},
author = {Reddit/Godot},
year = 2024,
note = {[cit. 2025-04-01]. Dostupné z: \url{https://www.reddit.com/r/godot/comments/1ewrkey/what_are_the_worst_partsissues_of_godot_in_your/}}
}
@misc{godotRealityCheck2,
title = {Godots 3D Workflow Issues, Inconsistencies, and Confusion},
author = {Alfred Reinold Baudisch},
year = 2023,
note = {[cit. 2025-04-01]. Dostupné z: \url{https://alfredbaudisch.com/blog/gamedev/godot-engine/godots-3d-confusing-workflow-inconsistencies-conflicting-behaviours-and-annoyances/}}
}
@article{gptPaper,
author = {Radford, Alec and Wu, Jeffrey and Child, Rewon and Luan, David and Amodei, Dario and Sutskever, Ilya},
biburl = {https://www.bibsonomy.org/bibtex/233e4b003b64b1060334660fbf6db1f3f/albinzehe},
interhash = {b926ece39c03cdf5499f6540cf63babd},
intrahash = {33e4b003b64b1060334660fbf6db1f3f},
journal = {OpenAI},
keywords = {gpt gpt2 languagemodelling transferlearning transformer},
note = {[cit. 2025-07-01]. Dostupné z: \url{https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf}},
timestamp = {2024-11-15T12:44:17.000+0100},
title = {Language Models are Unsupervised Multitask Learners},
year = 2019
}
@misc{fabRealityCheck,
title = {FAB - Review (Disaster for Customers and Sellers)},
author = {Unreal Engine Forums},
year = 2024,
note = {[cit. 2025-07-01]. Dostupné z: \url{https://forums.unrealengine.com/t/fab-review-disaster-for-customers-and-sellers/2092291}}
}
@misc{chinaLoadingScreen,
title = {PreLoadScreen and LoadingScreen in Unreal Engine 4 (Translated)},
author = {AGuner58 (Translated)},
year = 2023,
note = {[cit. 2025-07-01]. Dostupné z: \url{https://zhuanlan.zhihu.com/p/608502007}}
}
@misc{japanLoadingScreen,
title = {[UE4] Display an image immediately after launching the app using EarlyStartupScreen (Translated)},
author = {Ogura (Translated)},
year = 2021,
note = {[cit. 2025-07-01]. Dostupné z: \url{https://historia.co.jp/archives/19862/}}
}
@misc{videoSampling,
title = {How to Use Frame Rates in Your Videos},
author = {Daniela Bowker},
year = 2024,
note = {[cit. 2025-07-01]. Dostupné z: \url{https://artlist.io/blog/how-to-use-frame-rates/}}
}
@misc{audioSampling,
title = {Digital audio basics: audio sample rate and bit depth},
author = {Ian Stewart},
year = 2024,
note = {[cit. 2025-07-01]. Dostupné z: \url{https://www.izotope.com/en/learn/digital-audio-basics-sample-rate-and-bit-depth}}
}

Binary file not shown.

View File

@ -1,145 +0,0 @@
\documentclass[12pt,a4paper]{report}
\let\openright=\clearpage
\setlength\textwidth{145mm}
\setlength\textheight{247mm}
\setlength\oddsidemargin{7.1mm}
\setlength\evensidemargin{7.1mm}
\setlength\topmargin{0mm}
\setlength\headsep{0mm}
\setlength\headheight{0mm}
\input{metadata}
\usepackage[a-2u]{pdfx}
\ifEN\else\usepackage[czech,shorthands=off]{babel}\fi
% See https://en.wikipedia.org/wiki/Canons_of_page_construction before
% modifying the size of printable area. LaTeX defaults are great.
% If you feel it would help anything, you can enlarge the printable area a bit:
%\usepackage[textwidth=390pt,textheight=630pt]{geometry}
% The official recommendation expands the area quite a bit (looks pretty harsh):
%\usepackage[textwidth=145mm,textheight=247mm]{geometry}
%%% TYPICAL FONT CHOICES (uncomment what you like) %%%
% Recommended combo: Libertinus (autoselects Biolinum for sans) and everything
% else (math+tt) comes from Latin Modern)
\usepackage{lmodern}
\usepackage[mono=false]{libertinus}
% For the "classic" LaTeX fonts (very good for pure math theses), simply
% comment out the libertinus package above.
% IBM Plex font suite: nice, but requires us to fine-tune the sizes and does
% not directly support small caps (\textsc):
%\usepackage[usefilenames,RM={Scale=0.88},SS={Scale=0.88},SScon={Scale=0.88},TT={Scale=0.88},DefaultFeatures={Ligatures=Common}]{plex-otf}
% TeX Gyre combo (Pagella+Heros+Cursor)
%\usepackage{fontspec}
%\setmainfont{TeX Gyre Pagella}
%\setsansfont{TeX Gyre Heros}
%\setmonofont{TeX Gyre Cursor}
% some useful packages
\usepackage{microtype}
\usepackage{amsmath,amsfonts,amsthm,bm}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{booktabs}
\usepackage{caption}
\usepackage{floatrow}
% Bibliography formatting.
% CHECK THE REQUIREMENTS OF YOUR DEPARTMENT AND FACULTY ON THE CITATION FORMAT!
%
% These are relatively "safe" default options that most people use:
\usepackage[natbib,style=numeric,sorting=none]{biblatex}
% alternative with alphanumeric citations (more informative than numbers, and
% more common in computer science journals):
%\usepackage[natbib,style=alphabetic]{biblatex}
%
% ALTERNATIVES THAT CONFORM TO ISO690
% ISO690 is not the greatest citation format ever, but may be formally
% required at Charles University, depending on your faculty and department.
%\usepackage[natbib,style=iso-numeric,sorting=none]{biblatex}
%\usepackage[natbib,style=iso-alphabetic]{biblatex}
% You might want to add extra options such as `maxbibnames=6,maxcitenames=2`
% here to further conform to some of the formatting requirements (see below for
% details). Again, consult your faculty rules.
%
% Additional option choices:
% - add `giveninits=true` to typeset "E. A. Poe" instead of full Edgar Allan
% - `terseinits=true` additionaly shortens it to nature-like "Poe EA"
% - add `maxnames=10` to limit (or loosen) the maximum number of authors in
% bibliography entry before shortening to `et al.` (useful when referring to
% book collections that may have hundreds of authors)
% - use `maxcitenames=2` to finetune the amount of authors listed in text-cite
% commands (\citet). Corresponding option that only affects the bibliography
% is `maxbibnames=10`.
% - `sorting=none` causes the bibliography list to be ordered by the order of
% citation as they appear in the text, which is usually the desired behavior
% with numeric citations. Additionally you can use a style like
% `numeric-comp` that compresses the long lists of citations such as
% [1,2,3,4,5,6,7,8] to simpler [1--8]. This is especially useful if you plan
% to add tremendous amounts of citations, as usual in life sciences and
% bioinformatics.
% - if you don't like the "In:" appearing in the bibliography, use the
% extended style (`ext-numeric` or `ext-alphabetic`), and add option
% `articlein=false`.
%
% possibly reverse the names of the authors with the default styles:
%\DeclareNameAlias{default}{family-given}
% load the file with bibliography entries
\addbibresource{refs.bib}
% remove this if you won't use fancy verbatim environments
\usepackage{fancyvrb}
% remove this if you won't typeset TikZ graphics
\usepackage{tikz}
\usetikzlibrary{positioning} %add libraries as needed (shapes, decorations, ...)
% remove this if you won't typeset any pseudocode
\usepackage{algpseudocode}
\usepackage{algorithm}
% remove this if you won't list any source code
\usepackage{listings}
\hypersetup{unicode}
\hypersetup{breaklinks=true}
\usepackage[noabbrev]{cleveref}
\input{todos} % remove this before compiling the final version
\input{macros} % use this file for various custom definitions
% setup urls
\usepackage{xurl}
\begin{document}
\include{title}
\tableofcontents
\include{intro}
\include{ch1}
\include{ch2}
\include{ch3}
\include{conclusion}
\include{bibliography}
\addcontentsline{toc}{chapter}{Seznam obrázků}
\listoffigures
\appendix
\include{howto}
% if your attachments are complicated, describe them in a separate appendix
%\include{attachments}
\openright
\end{document}

View File

@ -1,7 +0,0 @@
% Metadata to be stored in PDF, see documentation of the pdfx package for more details.
\Author{Oleg Petruny}
\Title{Vícežánrová příběhová počítačová hra s podporou načítání nového obsahu za běhu}
\Keywords{Počítačová hra\sep Unreal Engine\sep dynamické načítání obsahu\sep 3D grafika}
\Subject{Abstract of thesis}
\Publisher{Charles University}

165
title.tex
View File

@ -1,165 +0,0 @@
% the layout is mandatory, edit only in dire circumstances
\pagestyle{empty}
\hypersetup{pageanchor=false}
\begin{center}
% top part of the layout, this actually differs between faculties
\def\ThesisTitleXmff{%
\ifEN
\centerline{\mbox{\includegraphics[width=166mm]{img/logo-en.pdf}}}
\else
\centerline{\mbox{\includegraphics[width=166mm]{img/logo-cs.pdf}}}
\fi
\vspace{-8mm}\vfill%
{\bf\Large\ThesisTypeTitle}
\vfill%
{\LARGE\ThesisAuthor}\par
\vspace{15mm}%
{\LARGE\bfseries\ThesisTitle}
\vfill%
\Department}
\def\ThesisTitleCuniLogo#1{%
{\large\UKName\par\medskip\par\UKFaculty }
\vfill%
{\bf\Large\ThesisTypeTitle}
\vfill%
\includegraphics[width=70mm]{#1}
\vfill%
{\LARGE\ThesisAuthor}\par
\vspace{15mm}%
{\LARGE\bfseries\ThesisTitle}
\vfill%
\Department\par}
\def\ThesisTitleXcuni{\ThesisTitleCuniLogo{img/uklogo.pdf}}
\def\ThesisTitleXnatur{\ThesisTitleCuniLogo{img/naturlogo.pdf}}
% choose the correct page and print it
\csname ThesisTitleX\ThesisTitleStyle\endcsname
% latex corner: X is the new @
\vfill
{
\centerline{\vbox{\halign{\hbox to 0.45\hsize{\hfil #}&\hskip 0.5em\parbox[t]{0.45\hsize}{\raggedright #}\cr
\ifEN Supervisor of the \ThesisGenitive thesis:
\else Vedoucí \ThesisGenitive práce: \fi
& \Supervisor \cr
\noalign{\vspace{2mm}}
\ifEN Study programme: \else Studijní program: \fi
& \StudyProgramme \cr
\noalign{\vspace{2mm}}
\ifEN Study branch: \else Studijní obor: \fi
& \StudyBranch \cr
}}}}
\vfill
\ifEN Prague \else Praha \fi
\YearSubmitted
\end{center}
\newpage
% remember to sign this!
\openright
\hypersetup{pageanchor=true}
\pagestyle{plain}
\pagenumbering{roman}
\vglue 0pt plus 1fill
\ifEN
\noindent
I declare that I carried out this \ThesisAccusative thesis on my own, and only with the cited sources, literature and other professional sources. I understand that my work relates to the rights and obligations under the Act No. 121/2000 Sb., the Copyright Act, as amended, in particular the fact that the Charles University has the right to conclude a license agreement on the use of this work as a school work pursuant to Section 60 subsection 1 of the Copyright Act.
\else
\noindent
Prohlašuji, že jsem tuto \ThesisAccusative práci vypracoval(a) samostatně a~výhradně s~použitím citovaných pramenů, literatury a~dalších odborných zdrojů. Beru na vědomí, že se na moji práci vztahují práva a~povinnosti vyplývající ze zákona č.~121/2000 Sb., autorského zákona v platném znění, zejména skutečnost, že Univerzita Karlova má právo na uzavření licenční smlouvy o~užití této práce jako školního díla podle § 60 odst. 1 autorského zákona.
\fi
\vspace{10mm}
\ifEN
\hbox{\hbox to 0.5\hsize{%
In \hbox to 6em{\dotfill} date \hbox to 6em{\dotfill}
\hss}\hbox to 0.5\hsize{\dotfill\quad}}
\smallskip
\hbox{\hbox to 0.5\hsize{}\hbox to 0.5\hsize{\hfil Author's signature\hfil}}
\else
\hbox{\hbox to 0.5\hsize{%
V \hbox to 6em{\dotfill} dne \hbox to 6em{\dotfill}
\hss}\hbox to 0.5\hsize{\dotfill\quad}}
\smallskip
\hbox{\hbox to 0.5\hsize{}\hbox to 0.5\hsize{\hfil Podpis autora\hfil}}
\fi
\vspace{20mm}
\newpage
% dedication
\openright
\noindent
\Dedication
\newpage
% mandatory information page
\openright
\vbox to 0.49\vsize{\InfoPageFont
\setlength\parindent{0mm}
\setlength\parskip{5mm}
\ifEN Title: \else Název práce: \fi
\ThesisTitle
\ifEN Author: \else Autor: \fi
\ThesisAuthor
\DeptType:
\Department
\ifEN Supervisor: \else Vedoucí \ThesisGenitive práce: \fi
\Supervisor, \SupervisorsDepartment
\ifEN Abstract: \AbstractEN \else Abstrakt: \AbstractCS \fi
\ifEN Keywords: \else Klíčová slova: \fi
\Keywords
\vss}\ifEN\relax\else\nobreak\vbox to 0.49\vsize{\InfoPageFont
\setlength\parindent{0mm}
\setlength\parskip{5mm}
Title:
\ThesisTitleEN
Author:
\ThesisAuthor
\DeptTypeEN:
\DepartmentEN
Supervisor:
\Supervisor, \SupervisorsDepartmentEN
Abstract:
\AbstractEN
Keywords:
\KeywordsEN
\vss}
\fi
\newpage
\openright
\pagestyle{plain}
\pagenumbering{arabic}
\setcounter{page}{1}

View File

@ -1,5 +0,0 @@
% various forms of TODOs (you should remove this before submitting)
\usepackage[textsize=tiny, backgroundcolor=yellow!25, linecolor=black!25]{todonotes}
\newcommand{\xxx}[1]{\textcolor{red!}{#1}}