Compare commits

...

3 Commits

Author SHA1 Message Date
Martin Slachta dc354d3a17 grammar mistakes + game description 2026-08-05 22:41:42 +02:00
Martin Slachta bb43a5bf77 fix: grammar mistakes 2026-08-05 20:03:14 +02:00
Martin Slachta 22abb9b1c3 Annotation translation 2026-08-05 14:45:36 +02:00
20 changed files with 1612 additions and 1184 deletions
+3
View File
@@ -16,3 +16,6 @@ dist:
@rm -f kidiplom.zip
@zip -r kidiplom.zip kidiplom
@rm -r -f kidiplom
fix:
sed -i -E 's/\b([ksvzaiouKSVZAIOU]) /\1~/g' kidiplom.tex
+95
View File
@@ -0,0 +1,95 @@
# Soubory
Adresář obsahuje soubory se zdrojovými kódy, sestavené spustitelné aplikace a zdrojový kód pro textovou část diplomové práce. Doporučujeme použít už sestavené soubory, které jsou připravené pro "čistou" instalaci `ubuntu-desktop-24.04.ova`.
# Sestavení
Veškeré spustitelné soubory jsou pro Linux. Už sestavené soubory jsou v adresáři `build/`. Zdrojové kódy jsou v adresáři `src/`. Projekt lze sestavit klasicky lokálně nebo kompletně přes Docker.
## Lokálně
Pro standartní sestavení je potřeba Conan, CMake a moderní kompiler, jako CLang nebo GCC. Projekt využívá verzi C++23.
Conan slouží pro získání konkrétních verzí balíčků jako ProtoBuf a SDL3. Sestavení tak začíná tím, že Conan potřebné balíčky stáhne a vytvoří konfigurační soubory pro CMake. Lze použít tento příkaz, který konfigurační soubory umístí do adresáře `./build/`.
```bash
$ conan install . --output-folder=build --build=missing -s build_type=Debug
```
Poté je potřeba adresář `build/` připravit pro CMake.
```bash
$ cmake -S . -B ./build -DCMAKE_TOOLCHAIN_FILE="build/conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Debug
```
Nakonec lze projekt sestavit pomocí:
```bash
$ cmake --build ./build
```
## Docker
Druhou variantou je použít Docker. V adresáři zdrojových kódů je podadresář `docker/`. Ten obsahuje Dockerfile pro sestavení i export spustitelných souborů. Pro sestavení nás zajímá jeho fáze `builder`. Sestavíme obraz `tw_builder` s tagem `jammy` pomocí příkazu:
```
$ docker build -f docker/Dockerfile --target builder -t tw_builder:jammy .
```
Pro získání sestavených souborů z Docker obrazu je nejjednodušší použít poslední fázi `export` Dockerfile a definovat `--output`. Konkrétně v tomto případě budou soubory vyexportovány do podadresáře `./dist/`.
```
$ docker build -f docker/Dockerfile --target export --output type=local,dest=dist .
```
# Spuštění
Pro spuštění již připravených spustitelných souborů v adresáři `build/`, není třeba na připravené "čisté" instalaci Ubuntu 22 nic měnit.
## Server
Pro hru více hráčů je nutné mít spuštěný `tw_server`. Ten také najdeme v adresáři `build/`. Pro jeho spuštění je třeba mít nainstalovanou knihovnu `libpq5`. V připravené instalaci Ubuntu 22 stačí tento balíček nainstalovat.
```
# apt install libpq5
```
Server po spuštění vypíše port, který pro hráče otevřel. Příklad výstupu po spuštění:
```
[2026-08-05 16:28:09.874] [info] quicr-port=8101 cluster-port=8102 timescaledb=disabled
[2026-08-05 16:28:10.034] [info] Running on port: 8101
[2026-08-05 16:28:10.035] [info] ZoneClusterLink listening on port 8102
[2026-08-05 16:28:10.063] [info] Registered as zone 1 (-5000,-5000) (0,5000)
```
Zajímá nás řádek s `Running on port`.
V adresáři `src/` je připraven Docker compose, kterým lze spustit databázový server s TimescaleDB a Grafanu. Pro spuštění obou lze použít příkaz:
```
$ docker compose up grafana timescaledb
```
Aby server věděl, jak se má k databázi připojit, je nutné definovat proměnnné `TIMESCALEDB_HOST` a `TIMESCALEDB_PASSWORD`. Pokud jste spustili TimescaleDB pomocí našeho Docker compose, pak heslo je `mmo`.
```
$ TIMESCALEDB_HOST=127.0.0.1 TIMESCALEDB_PASSWORD=mmo ./tw_server
```
Webovou aplikaci Grafana najdete na `localhost:3000` s heslem `admin` a uživatelským jménem `admin`. Pro vytvoření datové zdroje pro spuštěnou databázi je nutné použít doménové jméno v Docker compose. Tedy adresa databáze bude `timescaledb:5432`. Metriky jsou v tabulce `ZoneMetrics`.
## Klient
Aplikace klienta je `tw_client`. Po spuštění uvidíte textové pole pro zadání adresy serveru, včetně portu. Klikněte na `Connect` pro připojení na server. Pokud se podaří, dostanete se do hry a uvidíte hráče jako červené kostky.
## Stress-testing
V adresáři `build/` je připravený i spustitelný soubor pro stress-testing, který naváže a simuluje určitý počet připojení na konkrétní server. Simulovaní hráči se i pohybují. Příklad testu pro server na 127.0.0.1:8101 s 300 simulovanými hráči.
```
$ ./tw_mock_client 300 127.0.0.1 8101
```
+33 -2
View File
@@ -40,8 +40,8 @@ urldate = {2026-08-03},
isbn = {978-0128182000}
}
@ONLINE{interpolation,
author = {Fiedler, Glenn},
@ONLINE{interpolation1,
author = {Glenn Fiedler},
title = {Snapshot Interpolation},
year = {2015},
url = {https://www.gafferongames.com/post/snapshot_interpolation/},
@@ -49,6 +49,15 @@ isbn = {978-0128182000}
hyphenation = {english}
}
@ONLINE{interpolation2,
author = {Gabriel Gambetta},
title = {Entity Interpolation},
year = {2026},
url = {https://www.gabrielgambetta.com/entity-interpolation.html},
urldate = {2026-08-03},
hyphenation = {english}
}
@ONLINE{evolveheirachy,
author = {West, Mick},
title = {Evolve Your Hierarchy},
@@ -95,3 +104,25 @@ isbn = {978-0128182000}
urldate = {2026-08-03},
hyphenation = {english}
}
% https://www.tigerdata.com/docs/learn/deep-dive/whitepaper
@ONLINE{timescaledb,
author = {TimescaleDB},
title = {Tiger Data architecture for real-time analytics},
year = {2026},
url = {https://www.tigerdata.com/docs/learn/deep-dive/whitepaper},
urldate = {2026-08-03},
hyphenation = {english}
}
@INPROCEEDINGS{assiotis06mmorpg,
author = {Assiotis, Marios and Tzanov, Velin},
title = {A Distributed Architecture for MMORPG},
booktitle = {NETGAMES '06: Proceedings of the 5th Workshop on Network and System Support for Games},
year = {2006},
location = {Singapore},
publisher = {ACM},
url = {https://www.comp.nus.edu.sg/~bleong/hydra/related/assiotis06mmorpg.pdf},
urldate = {2026-08-05},
hyphenation = {english}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

+156 -136
View File
@@ -9,39 +9,31 @@
\providecommand\HyField@AuxAddToCoFields[2]{}
\providecommand\BKM@entry[2]{}
\abx@aux@refcontext{none/global//global/global/global}
\BKM@entry{id=1,open,dest={6B693A7061706572},srcline={148}}{5C3337365C3337375C3030304D5C303030655C303030745C3030306F5C303030645C303030795C3030305C3034305C3030306F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030705C3030315C3133315C303030655C3030306E5C3030306F5C303030735C303030755C3030305C3034305C303030645C303030615C303030745C3030305C3034305C303030765C3030305C3034305C303030645C303030695C303030735C303030745C303030725C303030695C303030625C303030755C3030306F5C303030765C303030615C3030306E5C3030305C3335315C3030306D5C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303075}
\BKM@entry{id=2,open,dest={6B693A7469746C65},srcline={148}}{5C3337365C3337375C303030545C303030695C303030745C303030755C3030306C5C3030306E5C3030305C3335355C3030305C3034305C303030735C303030745C303030725C303030615C3030306E5C30303061}
\providecommand\@newglossary[4]{}
\@newglossary{main}{glg}{gls}{glo}
\@newglossary{acronym}{alg}{acr}{acn}
\@newglossary{index}{ilg}{ind}{idx}
\providecommand\@glsorder[1]{}
\providecommand\@istfilename[1]{}
\@istfilename{kidiplom.ist}
\@glsorder{word}
\BKM@entry{id=1,open,dest={6B693A7061706572},srcline={144}}{5C3337365C3337375C3030304D5C303030655C303030745C3030306F5C303030645C303030795C3030305C3034305C3030306F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030705C3030315C3133315C303030655C3030306E5C3030306F5C303030735C303030755C3030305C3034305C303030645C303030615C303030745C3030305C3034305C303030765C3030305C3034305C303030645C303030695C303030735C303030745C303030725C303030695C303030625C303030755C3030306F5C303030765C303030615C3030306E5C3030305C3335315C3030306D5C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303075}
\BKM@entry{id=2,open,dest={6B693A7469746C65},srcline={144}}{5C3337365C3337375C303030545C303030695C303030745C303030755C3030306C5C3030306E5C3030305C3335355C3030305C3034305C303030735C303030745C303030725C303030615C3030306E5C30303061}
\babel@aux{czech}{}
\BKM@entry{id=3,open,dest={6B693A616E6F746174696F6E},srcline={148}}{5C3337365C3337375C303030415C3030306E5C3030306F5C303030745C303030615C303030635C30303065}
\BKM@entry{id=4,open,dest={6B693A746F63},srcline={148}}{5C3337365C3337375C3030304F5C303030625C303030735C303030615C30303068}
\BKM@entry{id=5,open,dest={73656374696F6E2E31},srcline={159}}{5C3337365C3337375C303030315C3030305C3034305C3030305C3333325C303030765C3030306F5C30303064}
\BKM@entry{id=3,open,dest={6B693A616E6F746174696F6E},srcline={144}}{5C3337365C3337375C303030415C3030306E5C3030306F5C303030745C303030615C303030635C30303065}
\BKM@entry{id=4,open,dest={6B693A746F63},srcline={144}}{5C3337365C3337375C3030304F5C303030625C303030735C303030615C30303068}
\BKM@entry{id=5,open,dest={73656374696F6E2E31},srcline={155}}{5C3337365C3337375C303030315C3030305C3034305C3030305C3333325C303030765C3030306F5C30303064}
\@writefile{toc}{\contentsline {section}{\numberline {1}Úvod}{8}{section.1}\protected@file@percent }
\BKM@entry{id=6,open,dest={73656374696F6E2E32},srcline={214}}{5C3337365C3337375C303030325C3030305C3034305C303030445C303030695C303030735C303030745C303030725C303030695C303030625C303030755C3030306F5C303030765C303030615C3030306E5C3030305C3335315C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303079}
\BKM@entry{id=7,open,dest={73756273656374696F6E2E322E31},srcline={222}}{5C3337365C3337375C303030325C3030302E5C303030315C3030305C3034305C303030505C3030306F5C3030315C3031355C3030305C3335355C303030745C303030615C3030315C3031355C3030306F5C303030765C3030305C3334315C3030305C3034305C303030735C3030305C3335355C3030315C313435}
\BKM@entry{id=6,open,dest={73656374696F6E2E32},srcline={210}}{5C3337365C3337375C303030325C3030305C3034305C303030445C303030695C303030735C303030745C303030725C303030695C303030625C303030755C3030306F5C303030765C303030615C3030306E5C3030305C3335315C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C30303079}
\BKM@entry{id=7,open,dest={73756273656374696F6E2E322E31},srcline={218}}{5C3337365C3337375C303030325C3030302E5C303030315C3030305C3034305C303030505C3030306F5C3030315C3031355C3030305C3335355C303030745C303030615C3030315C3031355C3030306F5C303030765C3030305C3334315C3030305C3034305C303030735C3030305C3335355C3030315C313435}
\@writefile{toc}{\contentsline {section}{\numberline {2}Distribuované systémy}{9}{section.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Počítačová síť}{9}{subsection.2.1}\protected@file@percent }
\newlabel{sec:NetworkCommunication}{{2.1}{9}{Počítačová síť}{subsection.2.1}{}}
\BKM@entry{id=8,open,dest={73756273756273656374696F6E2E322E312E31},srcline={231}}{5C3337365C3337375C303030325C3030302E5C303030315C3030302E5C303030315C3030305C3034305C3030304B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C30303065}
\BKM@entry{id=9,open,dest={73756273756273656374696F6E2E322E312E32},srcline={244}}{5C3337365C3337375C303030325C3030302E5C303030315C3030302E5C303030325C3030305C3034305C3030304D5C3030306F5C303030645C303030655C3030306C5C303030795C3030305C3034305C303030705C303030725C3030306F5C3030305C3034305C3030306B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C30303069}
\BKM@entry{id=8,open,dest={73756273756273656374696F6E2E322E312E31},srcline={227}}{5C3337365C3337375C303030325C3030302E5C303030315C3030302E5C303030315C3030305C3034305C3030304B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C30303065}
\BKM@entry{id=9,open,dest={73756273756273656374696F6E2E322E312E32},srcline={240}}{5C3337365C3337375C303030325C3030302E5C303030315C3030302E5C303030325C3030305C3034305C3030304D5C3030306F5C303030645C303030655C3030306C5C303030795C3030305C3034305C303030705C303030725C3030306F5C3030305C3034305C3030306B5C3030306F5C3030306D5C303030755C3030306E5C303030695C3030306B5C303030615C303030635C30303069}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.1.1}Komunikace}{10}{subsubsection.2.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.1.2}Modely pro komunikaci}{10}{subsubsection.2.1.2}\protected@file@percent }
\BKM@entry{id=10,open,dest={73756273656374696F6E2E322E32},srcline={265}}{5C3337365C3337375C303030325C3030302E5C303030325C3030305C3034305C303030415C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C303030795C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C3030315C313537}
\BKM@entry{id=11,open,dest={73756273756273656374696F6E2E322E322E31},srcline={272}}{5C3337365C3337375C303030325C3030302E5C303030325C3030302E5C303030315C3030305C3034305C303030535C3030306F5C303030665C303030745C303030775C303030615C303030725C3030306F5C303030765C3030305C3334315C3030305C3034305C303030615C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303061}
\BKM@entry{id=10,open,dest={73756273656374696F6E2E322E32},srcline={261}}{5C3337365C3337375C303030325C3030302E5C303030325C3030305C3034305C303030415C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C303030795C3030305C3034305C303030735C303030795C303030735C303030745C3030305C3335315C3030306D5C3030315C313537}
\BKM@entry{id=11,open,dest={73756273756273656374696F6E2E322E322E31},srcline={268}}{5C3337365C3337375C303030325C3030302E5C303030325C3030302E5C303030315C3030305C3034305C303030535C3030306F5C303030665C303030745C303030775C303030615C303030725C3030306F5C303030765C3030305C3334315C3030305C3034305C303030615C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303061}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Architektury systémů}{11}{subsection.2.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.1}Softwarová architektura}{11}{subsubsection.2.2.1}\protected@file@percent }
\BKM@entry{id=12,open,dest={73756273756273656374696F6E2E322E322E32},srcline={288}}{5C3337365C3337375C303030325C3030302E5C303030325C3030302E5C303030325C3030305C3034305C303030535C303030795C303030735C303030745C3030305C3335315C3030306D5C3030306F5C303030765C3030305C3335315C3030305C3034305C303030615C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303079}
\BKM@entry{id=12,open,dest={73756273756273656374696F6E2E322E322E32},srcline={284}}{5C3337365C3337375C303030325C3030302E5C303030325C3030302E5C303030325C3030305C3034305C303030535C303030795C303030735C303030745C3030305C3335315C3030306D5C3030306F5C303030765C3030305C3335315C3030305C3034305C303030615C303030725C303030635C303030685C303030695C303030745C303030655C3030306B5C303030745C303030755C303030725C30303079}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.2}Systémové architektury}{12}{subsubsection.2.2.2}\protected@file@percent }
\newlabel{sec:system_architecture}{{2.2.2}{12}{Systémové architektury}{subsubsection.2.2.2}{}}
\BKM@entry{id=13,open,dest={73656374696F6E2E33},srcline={303}}{5C3337365C3337375C303030335C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C30303079}
\BKM@entry{id=14,open,dest={73756273656374696F6E2E332E31},srcline={319}}{5C3337365C3337375C303030335C3030302E5C303030315C3030305C3034305C303030525C3030306F5C303030645C303030695C3030306E5C303030615C3030305C3034305C303030705C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030315C3135375C3030305C3034305C303030545C303030435C303030505C3030302F5C303030495C30303050}
\BKM@entry{id=13,open,dest={73656374696F6E2E33},srcline={299}}{5C3337365C3337375C303030335C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C30303079}
\BKM@entry{id=14,open,dest={73756273656374696F6E2E332E31},srcline={315}}{5C3337365C3337375C303030335C3030302E5C303030315C3030305C3034305C303030525C3030306F5C303030645C303030695C3030306E5C303030615C3030305C3034305C303030705C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030315C3135375C3030305C3034305C303030545C303030435C303030505C3030302F5C303030495C30303050}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Vrstvená architektura}}{13}{figure.1}\protected@file@percent }
\newlabel{fig:layer_architecture}{{1}{13}{Vrstvená architektura}{figure.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3}Protokoly}{13}{section.3}\protected@file@percent }
@@ -50,176 +42,204 @@
\abx@aux@segm{0}{0}{computer_networks}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Komunikace vrstev TCP/IP}}{14}{figure.2}\protected@file@percent }
\newlabel{fig:tcpip}{{2}{14}{Komunikace vrstev TCP/IP}{figure.2}{}}
\BKM@entry{id=15,open,dest={73756273656374696F6E2E332E32},srcline={358}}{5C3337365C3337375C303030335C3030302E5C303030325C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C303030795C3030305C3034305C303030765C3030305C3034305C303030615C303030705C3030306C5C303030695C3030306B5C303030615C3030315C3031355C3030306E5C3030305C3335355C3030305C3034305C303030765C303030725C303030735C303030745C303030765C3030315C303333}
\BKM@entry{id=16,open,dest={73756273756273656374696F6E2E332E322E31},srcline={362}}{5C3337365C3337375C303030335C3030302E5C303030325C3030302E5C303030315C3030305C3034305C303030485C303030545C303030545C30303050}
\BKM@entry{id=15,open,dest={73756273656374696F6E2E332E32},srcline={354}}{5C3337365C3337375C303030335C3030302E5C303030325C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C303030795C3030305C3034305C303030765C3030305C3034305C303030615C303030705C3030306C5C303030695C3030306B5C303030615C3030315C3031355C3030306E5C3030305C3335355C3030305C3034305C303030765C303030725C303030735C303030745C303030765C3030315C303333}
\BKM@entry{id=16,open,dest={73756273756273656374696F6E2E332E322E31},srcline={358}}{5C3337365C3337375C303030335C3030302E5C303030325C3030302E5C303030315C3030305C3034305C303030485C303030545C303030545C30303050}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Protokoly v aplikační vrstvě}{15}{subsection.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.1}HTTP}{15}{subsubsection.3.2.1}\protected@file@percent }
\BKM@entry{id=17,open,dest={73756273756273656374696F6E2E332E322E32},srcline={383}}{5C3337365C3337375C303030335C3030302E5C303030325C3030302E5C303030325C3030305C3034305C303030485C303030545C303030545C303030505C3030302F5C30303033}
\BKM@entry{id=18,open,dest={73756273656374696F6E2E332E33},srcline={409}}{5C3337365C3337375C303030335C3030302E5C303030335C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C303030795C3030305C3034305C303030765C3030305C3034305C303030745C303030725C303030615C3030306E5C303030735C303030705C3030306F5C303030725C303030745C3030306E5C3030305C3335355C3030305C3034305C303030765C303030725C303030735C303030745C303030765C3030315C303333}
\BKM@entry{id=19,open,dest={73756273756273656374696F6E2E332E332E31},srcline={415}}{5C3337365C3337375C303030335C3030302E5C303030335C3030302E5C303030315C3030305C3034305C303030545C303030435C30303050}
\BKM@entry{id=17,open,dest={73756273756273656374696F6E2E332E322E32},srcline={379}}{5C3337365C3337375C303030335C3030302E5C303030325C3030302E5C303030325C3030305C3034305C303030485C303030545C303030545C303030505C3030302F5C30303033}
\BKM@entry{id=18,open,dest={73756273656374696F6E2E332E33},srcline={405}}{5C3337365C3337375C303030335C3030302E5C303030335C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C303030795C3030305C3034305C303030765C3030305C3034305C303030745C303030725C303030615C3030306E5C303030735C303030705C3030306F5C303030725C303030745C3030306E5C3030305C3335355C3030305C3034305C303030765C303030725C303030735C303030745C303030765C3030315C303333}
\BKM@entry{id=19,open,dest={73756273756273656374696F6E2E332E332E31},srcline={411}}{5C3337365C3337375C303030335C3030302E5C303030335C3030302E5C303030315C3030305C3034305C303030545C303030435C30303050}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.2}HTTP/3}{16}{subsubsection.3.2.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Protokoly v transportní vrstvě}{16}{subsection.3.3}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Vizualizace HTTP/2 blokování}}{17}{figure.3}\protected@file@percent }
\newlabel{fig:http_blocking}{{3}{17}{Vizualizace HTTP/2 blokování}{figure.3}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.1}TCP}{17}{subsubsection.3.3.1}\protected@file@percent }
\BKM@entry{id=20,open,dest={73756273756273656374696F6E2E332E332E32},srcline={429}}{5C3337365C3337375C303030335C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030555C303030445C30303050}
\BKM@entry{id=21,open,dest={73756273756273656374696F6E2E332E332E33},srcline={437}}{5C3337365C3337375C303030335C3030302E5C303030335C3030302E5C303030335C3030305C3034305C303030515C303030555C303030495C30303043}
\BKM@entry{id=20,open,dest={73756273756273656374696F6E2E332E332E32},srcline={427}}{5C3337365C3337375C303030335C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030555C303030445C30303050}
\BKM@entry{id=21,open,dest={73756273756273656374696F6E2E332E332E33},srcline={435}}{5C3337365C3337375C303030335C3030302E5C303030335C3030302E5C303030335C3030305C3034305C303030515C303030555C303030495C30303043}
\abx@aux@cite{0}{quic}
\abx@aux@segm{0}{0}{quic}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.2}UDP}{18}{subsubsection.3.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.3}QUIC}{18}{subsubsection.3.3.3}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces QUIC handshake}}{20}{figure.4}\protected@file@percent }
\newlabel{fig:quic_handshake}{{4}{20}{QUIC handshake}{figure.4}{}}
\BKM@entry{id=22,open,dest={73656374696F6E2E34},srcline={577}}{5C3337365C3337375C303030345C3030305C3034305C303030485C303030725C30303061}
\BKM@entry{id=23,open,dest={73756273656374696F6E2E342E31},srcline={592}}{5C3337365C3337375C303030345C3030302E5C303030315C3030305C3034305C303030455C3030306E5C303030675C303030695C3030306E5C30303065}
\BKM@entry{id=22,open,dest={73656374696F6E2E34},srcline={575}}{5C3337365C3337375C303030345C3030305C3034305C303030485C303030725C30303061}
\BKM@entry{id=23,open,dest={73756273656374696F6E2E342E31},srcline={581}}{5C3337365C3337375C303030345C3030302E5C303030315C3030305C3034305C303030455C3030306E5C303030675C303030695C3030306E5C30303065}
\abx@aux@cite{0}{peekingvalorant}
\abx@aux@segm{0}{0}{peekingvalorant}
\BKM@entry{id=24,open,dest={73756273756273656374696F6E2E342E312E31},srcline={615}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030465C303030795C3030307A5C303030695C303030635C3030306B5C3030305C3337355C3030305C3034305C303030655C3030306E5C303030675C303030695C3030306E5C30303065}
\@writefile{toc}{\contentsline {section}{\numberline {4}Hra}{21}{section.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Engine}{21}{subsection.4.1}\protected@file@percent }
\BKM@entry{id=24,open,dest={73756273756273656374696F6E2E342E312E31},srcline={626}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030465C303030795C3030307A5C303030695C303030635C3030306B5C3030305C3337355C3030305C3034305C303030655C3030306E5C303030675C303030695C3030306E5C30303065}
\BKM@entry{id=25,open,dest={73756273756273656374696F6E2E342E312E32},srcline={634}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030565C303030795C3030306B5C303030725C303030655C303030735C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.1}Fyzický engine}{21}{subsubsection.4.1.1}\protected@file@percent }
\BKM@entry{id=25,open,dest={73756273756273656374696F6E2E342E312E32},srcline={623}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030565C303030795C3030306B5C303030725C303030655C303030735C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\BKM@entry{id=26,open,dest={73756273756273656374696F6E2E342E312E33},srcline={631}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030455C3030306E5C303030745C303030695C303030745C303030795C3030302D5C303030435C3030306F5C3030306D5C303030705C3030306F5C3030306E5C303030655C3030306E5C303030745C3030302D5C303030535C303030795C303030735C303030745C303030655C3030306D}
\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Architektura hry pro jednoho hráče}}{22}{figure.5}\protected@file@percent }
\newlabel{fig:single_player_game}{{5}{22}{Architektura hry pro jednoho hráče}{figure.5}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.1}Fyzický engine}{22}{subsubsection.4.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.2}Vykreslování}{22}{subsubsection.4.1.2}\protected@file@percent }
\BKM@entry{id=26,open,dest={73756273756273656374696F6E2E342E312E33},srcline={642}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030455C3030306E5C303030745C303030695C303030745C303030795C3030302D5C303030435C3030306F5C3030306D5C303030705C3030306F5C3030306E5C303030655C3030306E5C303030745C3030302D5C303030535C303030795C303030735C303030745C303030655C3030306D}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.3}Entity-Component-System}{23}{subsubsection.4.1.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.3}Entity-Component-System}{22}{subsubsection.4.1.3}\protected@file@percent }
\newlabel{code:entt}{{1}{23}{Příklad použití knihovny Entt}{lstlisting.1}{}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {1}Příklad použití knihovny Entt}{23}{lstlisting.1}\protected@file@percent }
\BKM@entry{id=27,open,dest={73756273756273656374696F6E2E342E312E34},srcline={683}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030345C3030305C3034305C303030495C3030306D5C303030475C303030755C30303069}
\BKM@entry{id=27,open,dest={73756273756273656374696F6E2E342E312E34},srcline={672}}{5C3337365C3337375C303030345C3030302E5C303030315C3030302E5C303030345C3030305C3034305C303030495C3030306D5C303030475C303030755C30303069}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.4}ImGui}{24}{subsubsection.4.1.4}\protected@file@percent }
\BKM@entry{id=28,open,dest={73656374696F6E2E35},srcline={702}}{5C3337365C3337375C303030355C3030305C3034305C303030485C303030725C303030615C3030305C3034305C303030765C3030305C3335355C303030635C303030655C3030305C3034305C303030685C303030725C3030305C3334315C3030315C3031355C3030315C313537}
\BKM@entry{id=29,open,dest={73756273656374696F6E2E352E31},srcline={723}}{5C3337365C3337375C303030355C3030302E5C303030315C3030305C3034305C303030535C303030655C303030725C303030765C303030655C30303072}
\BKM@entry{id=28,open,dest={73656374696F6E2E35},srcline={691}}{5C3337365C3337375C303030355C3030305C3034305C303030485C303030725C303030615C3030305C3034305C303030765C3030305C3335355C303030635C303030655C3030305C3034305C303030685C303030725C3030305C3334315C3030315C3031355C3030315C313537}
\BKM@entry{id=29,open,dest={73756273656374696F6E2E352E31},srcline={712}}{5C3337365C3337375C303030355C3030302E5C303030315C3030305C3034305C303030535C303030655C303030725C303030765C303030655C30303072}
\@writefile{toc}{\contentsline {section}{\numberline {5}Hra více hráčů}{25}{section.5}\protected@file@percent }
\BKM@entry{id=30,open,dest={73756273756273656374696F6E2E352E312E31},srcline={733}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030525C303030655C303030675C303030695C303030735C303030745C303030725C3030305C3034305C3030306B5C3030306C5C303030695C303030655C3030306E5C303030745C3030315C313537}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Server}{25}{subsection.5.1}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Architektura hry pro více hráčů}}{26}{figure.6}\protected@file@percent }
\newlabel{fig:multi_player_game}{{6}{26}{Architektura hry pro více hráčů}{figure.6}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Server}{26}{subsection.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.1}Registr klientů}{26}{subsubsection.5.1.1}\protected@file@percent }
\BKM@entry{id=31,open,dest={73756273756273656374696F6E2E352E312E32},srcline={739}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030525C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\BKM@entry{id=32,open,dest={73756273756273656374696F6E2E352E312E33},srcline={743}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030535C303030705C303030725C3030305C3334315C303030765C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\BKM@entry{id=33,open,dest={73756273656374696F6E2E352E32},srcline={753}}{5C3337365C3337375C303030355C3030302E5C303030325C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C30303074}
\BKM@entry{id=34,open,dest={73756273756273656374696F6E2E352E322E31},srcline={757}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030315C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C303030745C3030305C3034305C303030525C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\BKM@entry{id=35,open,dest={73756273756273656374696F6E2E352E322E32},srcline={761}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030325C3030305C3034305C303030495C3030306E5C303030745C303030655C303030725C303030705C3030306F5C3030306C5C303030615C303030635C30303065}
\BKM@entry{id=30,open,dest={73756273756273656374696F6E2E352E312E31},srcline={722}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030525C303030655C303030675C303030695C303030735C303030745C303030725C3030305C3034305C3030306B5C3030306C5C303030695C303030655C3030306E5C303030745C3030315C313537}
\BKM@entry{id=31,open,dest={73756273756273656374696F6E2E352E312E32},srcline={728}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030535C303030655C303030725C303030765C303030655C303030725C3030305C3034305C303030525C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\BKM@entry{id=32,open,dest={73756273756273656374696F6E2E352E312E33},srcline={732}}{5C3337365C3337375C303030355C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030535C303030705C303030725C3030305C3334315C303030765C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.1}Registr klientů}{27}{subsubsection.5.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.2}Server Replikátoru}{27}{subsubsection.5.1.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.1.3}Správa zájmů}{27}{subsubsection.5.1.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Klient}{27}{subsection.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.1}Klient Replikátoru}{27}{subsubsection.5.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.2}Interpolace}{27}{subsubsection.5.2.2}\protected@file@percent }
\BKM@entry{id=36,open,dest={73756273756273656374696F6E2E352E322E33},srcline={769}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030335C3030305C3034305C303030525C3030306F5C3030306C5C3030306C5C303030625C303030615C303030635C3030306B}
\BKM@entry{id=37,open,dest={73756273656374696F6E2E352E33},srcline={779}}{5C3337365C3337375C303030355C3030302E5C303030335C3030305C3034305C303030505C3030306F5C303030735C3030305C3335355C3030306C5C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=38,open,dest={73756273756273656374696F6E2E352E332E31},srcline={790}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030315C3030305C3034305C3030304B5C3030305C3336335C303030645C3030306F5C303030765C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.3}Rollback}{28}{subsubsection.5.2.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}Posílání zpráv}{28}{subsection.5.3}\protected@file@percent }
\BKM@entry{id=39,open,dest={73756273756273656374696F6E2E352E332E32},srcline={798}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030495C3030306D5C303030705C3030306C5C303030655C3030306D5C303030655C3030306E5C303030745C303030615C303030635C30303065}
\BKM@entry{id=40,open,dest={73756273756273656374696F6E2E352E332E33},srcline={802}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030335C3030305C3034305C303030445C303030655C303030745C303030655C3030306B5C303030635C303030655C3030305C3034305C303030615C3030305C3034305C3030306E5C3030305C3334315C303030705C303030725C303030615C303030765C303030615C3030305C3034305C303030635C303030685C303030795C30303062}
\BKM@entry{id=41,open,dest={73756273656374696F6E2E352E34},srcline={809}}{5C3337365C3337375C303030355C3030302E5C303030345C3030305C3034305C303030535C303030655C303030725C303030695C303030615C3030306C5C303030695C3030307A5C303030615C303030635C30303065}
\BKM@entry{id=33,open,dest={73756273656374696F6E2E352E32},srcline={742}}{5C3337365C3337375C303030355C3030302E5C303030325C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C30303074}
\BKM@entry{id=34,open,dest={73756273756273656374696F6E2E352E322E31},srcline={746}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030315C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C303030745C3030305C3034305C303030525C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\BKM@entry{id=35,open,dest={73756273756273656374696F6E2E352E322E32},srcline={750}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030325C3030305C3034305C303030495C3030306E5C303030745C303030655C303030725C303030705C3030306F5C3030306C5C303030615C303030635C30303065}
\abx@aux@cite{0}{interpolation1}
\abx@aux@segm{0}{0}{interpolation1}
\abx@aux@cite{0}{interpolation2}
\abx@aux@segm{0}{0}{interpolation2}
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Graf interpolace}}{28}{figure.7}\protected@file@percent }
\newlabel{fig:interpolation}{{7}{28}{Graf interpolace}{figure.7}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Klient}{28}{subsection.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.1}Klient Replikátoru}{28}{subsubsection.5.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.2}Interpolace}{28}{subsubsection.5.2.2}\protected@file@percent }
\BKM@entry{id=36,open,dest={73756273756273656374696F6E2E352E322E33},srcline={767}}{5C3337365C3337375C303030355C3030302E5C303030325C3030302E5C303030335C3030305C3034305C303030525C3030306F5C3030306C5C3030306C5C303030625C303030615C303030635C3030306B}
\BKM@entry{id=37,open,dest={73756273656374696F6E2E352E33},srcline={777}}{5C3337365C3337375C303030355C3030302E5C303030335C3030305C3034305C303030505C3030306F5C303030735C3030305C3335355C3030306C5C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=38,open,dest={73756273756273656374696F6E2E352E332E31},srcline={788}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030315C3030305C3034305C3030304B5C3030305C3336335C303030645C3030306F5C303030765C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.2.3}Rollback}{29}{subsubsection.5.2.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}Posílání zpráv}{29}{subsection.5.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.1}Kódování zpráv}{29}{subsubsection.5.3.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.2}Implementace}{29}{subsubsection.5.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.3}Detekce a náprava chyb}{29}{subsubsection.5.3.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Serializace}{29}{subsection.5.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}cpp}{30}{lstlisting.2}\protected@file@percent }
\BKM@entry{id=42,open,dest={73756273656374696F6E2E352E35},srcline={843}}{5C3337365C3337375C303030355C3030302E5C303030355C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\BKM@entry{id=43,open,dest={73756273756273656374696F6E2E352E352E31},srcline={856}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030315C3030305C3034305C303030525C3030305C3334315C3030306D5C303030635C30303065}
\BKM@entry{id=39,open,dest={73756273756273656374696F6E2E352E332E32},srcline={796}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030495C3030306D5C303030705C3030306C5C303030655C3030306D5C303030655C3030306E5C303030745C303030615C303030635C30303065}
\BKM@entry{id=40,open,dest={73756273756273656374696F6E2E352E332E33},srcline={800}}{5C3337365C3337375C303030355C3030302E5C303030335C3030302E5C303030335C3030305C3034305C303030445C303030655C303030745C303030655C3030306B5C303030635C303030655C3030305C3034305C303030615C3030305C3034305C3030306E5C3030305C3334315C303030705C303030725C303030615C303030765C303030615C3030305C3034305C303030635C303030685C303030795C30303062}
\BKM@entry{id=41,open,dest={73756273656374696F6E2E352E34},srcline={807}}{5C3337365C3337375C303030355C3030302E5C303030345C3030305C3034305C303030535C303030655C303030725C303030695C303030615C3030306C5C303030695C3030307A5C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.2}Implementace}{30}{subsubsection.5.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.3}Detekce a náprava chyb}{30}{subsubsection.5.3.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Serializace}{30}{subsection.5.4}\protected@file@percent }
\BKM@entry{id=42,open,dest={73756273656374696F6E2E352E35},srcline={840}}{5C3337365C3337375C303030355C3030302E5C303030355C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\newlabel{code:entity_spawn_message}{{2}{31}{cpp}{lstlisting.2}{}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}cpp}{31}{lstlisting.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.5}Protokol QUICr}{31}{subsection.5.5}\protected@file@percent }
\BKM@entry{id=44,open,dest={73756273756273656374696F6E2E352E352E32},srcline={869}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030325C3030305C3034305C303030485C303030615C3030306E5C303030645C303030735C303030685C303030615C3030306B5C30303065}
\BKM@entry{id=45,open,dest={73756273756273656374696F6E2E352E352E33},srcline={903}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030335C3030305C3034305C303030535C303030705C3030306F5C3030306C5C303030655C303030685C3030306C5C303030695C303030765C3030306F5C303030735C30303074}
\BKM@entry{id=43,open,dest={73756273756273656374696F6E2E352E352E31},srcline={853}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030315C3030305C3034305C303030525C3030305C3334315C3030306D5C303030635C30303065}
\BKM@entry{id=44,open,dest={73756273756273656374696F6E2E352E352E32},srcline={866}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030325C3030305C3034305C303030485C303030615C3030306E5C303030645C303030735C303030685C303030615C3030306B5C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.1}Rámce}{32}{subsubsection.5.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.2}Handshake}{32}{subsubsection.5.5.2}\protected@file@percent }
\newlabel{sec:quicr_handshake}{{5.5.2}{32}{Handshake}{subsubsection.5.5.2}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.3}Spolehlivost}{32}{subsubsection.5.5.3}\protected@file@percent }
\newlabel{sec:quicr_reliability}{{5.5.3}{32}{Spolehlivost}{subsubsection.5.5.3}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Stavový stroj QUICr handshake}}{33}{figure.7}\protected@file@percent }
\newlabel{fig:quicr_handshake}{{7}{33}{Stavový stroj QUICr handshake}{figure.7}{}}
\BKM@entry{id=46,open,dest={73756273756273656374696F6E2E352E352E34},srcline={925}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030345C3030305C3034305C303030455C3030306E5C3030306B5C3030306F5C303030645C3030305C3335315C30303072}
\BKM@entry{id=47,open,dest={73756273756273656374696F6E2E352E352E35},srcline={933}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030355C3030305C3034305C303030545C303030655C303030735C303030745C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\BKM@entry{id=45,open,dest={73756273756273656374696F6E2E352E352E33},srcline={900}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030335C3030305C3034305C303030535C303030705C3030306F5C3030306C5C303030655C303030685C3030306C5C303030695C303030765C3030306F5C303030735C30303074}
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Stavový stroj QUICr handshake}}{33}{figure.8}\protected@file@percent }
\newlabel{fig:quicr_handshake}{{8}{33}{Stavový stroj QUICr handshake}{figure.8}{}}
\BKM@entry{id=46,open,dest={73756273756273656374696F6E2E352E352E34},srcline={922}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030345C3030305C3034305C303030455C3030306E5C3030306B5C3030306F5C303030645C3030305C3335315C30303072}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.3}Spolehlivost}{34}{subsubsection.5.5.3}\protected@file@percent }
\newlabel{sec:quicr_reliability}{{5.5.3}{34}{Spolehlivost}{subsubsection.5.5.3}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.4}Enkodér}{34}{subsubsection.5.5.4}\protected@file@percent }
\BKM@entry{id=48,open,dest={73756273656374696F6E2E352E36},srcline={974}}{5C3337365C3337375C303030355C3030302E5C303030365C3030305C3034305C303030485C3030306F5C303030725C303030695C3030307A5C3030306F5C3030306E5C303030745C3030305C3334315C3030306C5C3030306E5C3030305C3335355C3030305C3034305C3030315C3134315C3030306B5C3030305C3334315C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\BKM@entry{id=49,open,dest={73756273656374696F6E2E352E37},srcline={994}}{5C3337365C3337375C303030355C3030302E5C303030375C3030305C3034305C303030565C3030305C3337355C303030735C3030306C5C303030655C303030645C3030306E5C3030305C3334315C3030305C3034305C303030685C303030725C30303061}
\BKM@entry{id=47,open,dest={73756273756273656374696F6E2E352E352E35},srcline={930}}{5C3337365C3337375C303030355C3030302E5C303030355C3030302E5C303030355C3030305C3034305C303030545C303030655C303030735C303030745C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\BKM@entry{id=48,open,dest={73756273656374696F6E2E352E36},srcline={971}}{5C3337365C3337375C303030355C3030302E5C303030365C3030305C3034305C303030485C3030306F5C303030725C303030695C3030307A5C3030306F5C3030306E5C303030745C3030305C3334315C3030306C5C3030306E5C3030305C3335355C3030305C3034305C3030315C3134315C3030306B5C3030305C3334315C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.5}Testování}{35}{subsubsection.5.5.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.6}Horizontální škálování}{35}{subsection.5.6}\protected@file@percent }
\newlabel{fig:zone_cluster_architecture}{{5.6}{36}{Horizontální škálování}{subsection.5.6}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Architektura systému s zone clusterem}}{36}{figure.8}\protected@file@percent }
\BKM@entry{id=49,open,dest={73756273656374696F6E2E352E37},srcline={991}}{5C3337365C3337375C303030355C3030302E5C303030375C3030305C3034305C303030565C3030305C3337355C303030735C3030306C5C303030655C303030645C3030306E5C3030305C3334315C3030305C3034305C303030685C303030725C30303061}
\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Architektura systému s zone clusterem}}{36}{figure.9}\protected@file@percent }
\newlabel{fig:zone_cluster_architecture}{{9}{36}{Architektura systému s zone clusterem}{figure.9}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.7}Výsledná hra}{36}{subsection.5.7}\protected@file@percent }
\newlabel{fig:lobby_ui}{{5.7}{37}{Výsledná hra}{subsection.5.7}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Uživatelské rozhraní v lobby}}{37}{figure.9}\protected@file@percent }
\newlabel{fig:ui_showcase}{{5.7}{37}{Výsledná hra}{figure.9}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Uživatelské rozhraní v klientovi}}{37}{figure.10}\protected@file@percent }
\BKM@entry{id=50,open,dest={73656374696F6E2E36},srcline={1018}}{5C3337365C3337375C303030365C3030305C3034305C3030304D5C3030315C3033335C3030315C3133315C3030315C3033335C3030306E5C3030305C333535}
\BKM@entry{id=51,open,dest={73756273656374696F6E2E362E31},srcline={1022}}{5C3337365C3337375C303030365C3030302E5C303030315C3030305C3034305C3030304D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\BKM@entry{id=52,open,dest={73756273756273656374696F6E2E362E312E31},srcline={1030}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030505C3030306F5C303030735C303030745C303030675C303030725C303030655C303030535C303030515C3030304C}
\BKM@entry{id=53,open,dest={73756273756273656374696F6E2E362E312E32},srcline={1034}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030545C303030695C3030306D5C303030655C303030735C303030635C303030615C3030306C5C303030655C303030445C30303042}
\BKM@entry{id=54,open,dest={73756273756273656374696F6E2E362E312E33},srcline={1038}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030475C303030725C303030615C303030665C303030615C3030306E5C30303061}
\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Uživatelské rozhraní v lobby}}{37}{figure.10}\protected@file@percent }
\newlabel{fig:lobby_ui}{{10}{37}{Uživatelské rozhraní v lobby}{figure.10}{}}
\BKM@entry{id=50,open,dest={73656374696F6E2E36},srcline={1016}}{5C3337365C3337375C303030365C3030305C3034305C3030304D5C3030315C3033335C3030315C3133315C3030315C3033335C3030306E5C3030305C333535}
\BKM@entry{id=51,open,dest={73756273656374696F6E2E362E31},srcline={1020}}{5C3337365C3337375C303030365C3030302E5C303030315C3030305C3034305C3030304D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\BKM@entry{id=52,open,dest={73756273756273656374696F6E2E362E312E31},srcline={1028}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030505C3030306F5C303030735C303030745C303030675C303030725C303030655C303030535C303030515C3030304C}
\newlabel{fig:ui_showcase}{{5.7}{38}{Výsledná hra}{figure.10}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces Uživatelské rozhraní v klientovi}}{38}{figure.11}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {6}Měřění}{38}{section.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Metriky}{38}{subsection.6.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.1}PostgreSQL}{38}{subsubsection.6.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.2}TimescaleDB}{38}{subsubsection.6.1.2}\protected@file@percent }
\BKM@entry{id=55,open,dest={73756273756273656374696F6E2E362E312E34},srcline={1050}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030345C3030305C3034305C303030545C303030725C303030615C303030635C30303079}
\BKM@entry{id=56,open,dest={73756273756273656374696F6E2E362E312E35},srcline={1080}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030355C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C303030745C303030735C3030306B5C3030305C3334315C3030305C3034305C303030615C303030705C3030306C5C303030695C3030306B5C303030615C303030635C30303065}
\BKM@entry{id=57,open,dest={73756273656374696F6E2E362E32},srcline={1084}}{5C3337365C3337375C303030365C3030302E5C303030325C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces Příklad Grafana dashboardu}}{39}{figure.11}\protected@file@percent }
\newlabel{fig:grafana}{{11}{39}{Příklad Grafana dashboardu}{figure.11}{}}
\BKM@entry{id=53,open,dest={73756273756273656374696F6E2E362E312E32},srcline={1032}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030545C303030695C3030306D5C303030655C303030735C303030635C303030615C3030306C5C303030655C303030445C30303042}
\abx@aux@cite{0}{timescaledb}
\abx@aux@segm{0}{0}{timescaledb}
\BKM@entry{id=54,open,dest={73756273756273656374696F6E2E362E312E33},srcline={1036}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030475C303030725C303030615C303030665C303030615C3030306E5C30303061}
\BKM@entry{id=55,open,dest={73756273756273656374696F6E2E362E312E34},srcline={1048}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030345C3030305C3034305C303030545C303030725C303030615C303030635C30303079}
\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces Příklad Grafana dashboardu}}{39}{figure.12}\protected@file@percent }
\newlabel{fig:grafana}{{12}{39}{Příklad Grafana dashboardu}{figure.12}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.1}PostgreSQL}{39}{subsubsection.6.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.2}TimescaleDB}{39}{subsubsection.6.1.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.3}Grafana}{39}{subsubsection.6.1.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.4}Tracy}{39}{subsubsection.6.1.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.5}Klientská aplikace}{39}{subsubsection.6.1.5}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces Jeden snímek v Tracy}}{40}{figure.12}\protected@file@percent }
\newlabel{fig:frame_in_tracy}{{12}{40}{Jeden snímek v Tracy}{figure.12}{}}
\BKM@entry{id=56,open,dest={73756273756273656374696F6E2E362E312E35},srcline={1078}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030355C3030305C3034305C3030304B5C3030306C5C303030695C303030655C3030306E5C303030745C303030735C3030306B5C3030305C3334315C3030305C3034305C303030615C303030705C3030306C5C303030695C3030306B5C303030615C303030635C30303065}
\BKM@entry{id=57,open,dest={73756273656374696F6E2E362E32},srcline={1082}}{5C3337365C3337375C303030365C3030302E5C303030325C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Jeden snímek v Tracy}}{40}{figure.13}\protected@file@percent }
\newlabel{fig:frame_in_tracy}{{13}{40}{Jeden snímek v Tracy}{figure.13}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.4}Tracy}{40}{subsubsection.6.1.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.5}Klientská aplikace}{40}{subsubsection.6.1.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.2}QUICr}{40}{subsection.6.2}\protected@file@percent }
\newlabel{kod:tc}{{3}{40}{Příklad volání TC}{lstlisting.3}{}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Příklad volání TC}{40}{lstlisting.3}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Porovnání odezvy TCP a QUICr}}{41}{figure.13}\protected@file@percent }
\newlabel{fig:latencycomparison}{{13}{41}{Porovnání odezvy TCP a QUICr}{figure.13}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Porovnání integrace TCP a QUICr}}{41}{figure.14}\protected@file@percent }
\newlabel{fig:integrationcomparison}{{14}{41}{Porovnání integrace TCP a QUICr}{figure.14}{}}
\BKM@entry{id=58,open,dest={73756273656374696F6E2E362E33},srcline={1131}}{5C3337365C3337375C303030365C3030302E5C303030335C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030725C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces 301 připojených hráčů}}{42}{figure.15}\protected@file@percent }
\newlabel{fig:playerbenchmark}{{15}{42}{301 připojených hráčů}{figure.15}{}}
\newlabel{fig:tracyreplicator}{{6.3}{42}{Optimalizace replikátoru}{subsection.6.3}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces Analýza replikátoru}}{42}{figure.16}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Porovnání odezvy TCP a QUICr}}{41}{figure.14}\protected@file@percent }
\newlabel{fig:latencycomparison}{{14}{41}{Porovnání odezvy TCP a QUICr}{figure.14}{}}
\newlabel{kod:tc}{{3}{41}{Příklad volání TC}{lstlisting.3}{}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Příklad volání TC}{41}{lstlisting.3}\protected@file@percent }
\BKM@entry{id=58,open,dest={73756273656374696F6E2E362E33},srcline={1129}}{5C3337365C3337375C303030365C3030302E5C303030335C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030725C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces Porovnání integrace TCP a QUICr}}{42}{figure.15}\protected@file@percent }
\newlabel{fig:integrationcomparison}{{15}{42}{Porovnání integrace TCP a QUICr}{figure.15}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.3}Optimalizace replikátoru}{42}{subsection.6.3}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_01}{{6.3}{43}{Optimalizace replikátoru}{figure.16}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{43}{figure.17}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_02}{{6.3}{43}{Optimalizace replikátoru}{figure.17}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces 301 připojených hráčů}}{42}{figure.16}\protected@file@percent }
\newlabel{fig:playerbenchmark}{{16}{42}{301 připojených hráčů}{figure.16}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Analýza replikátoru}}{43}{figure.17}\protected@file@percent }
\newlabel{fig:tracyreplicator}{{17}{43}{Analýza replikátoru}{figure.17}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {18}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{43}{figure.18}\protected@file@percent }
\BKM@entry{id=59,open,dest={73756273656374696F6E2E362E34},srcline={1186}}{5C3337365C3337375C303030365C3030302E5C303030345C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C3030306D5C303030615C3030306E5C303030615C3030315C3137365C303030655C303030725C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\newlabel{fig:ecs_optimization_tracy_01}{{18}{43}{Analýza optimalizace replikátoru pro ECS}{figure.18}{}}
\BKM@entry{id=59,open,dest={73756273656374696F6E2E362E34},srcline={1184}}{5C3337365C3337375C303030365C3030302E5C303030345C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C3030306D5C303030615C3030306E5C303030615C3030315C3137365C303030655C303030725C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\@writefile{lof}{\contentsline {figure}{\numberline {19}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{44}{figure.19}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_02}{{19}{44}{Analýza optimalizace replikátoru pro ECS}{figure.19}{}}
\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Porovnání serializátorů}}{44}{table.1}\protected@file@percent }
\newlabel{t:serialization_comparison}{{1}{44}{Porovnání serializátorů}{table.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.4}Optimalizace manažera zájmů}{44}{subsection.6.4}\protected@file@percent }
\BKM@entry{id=60,open,dest={73756273656374696F6E2E362E35},srcline={1214}}{5C3337365C3337375C303030365C3030302E5C303030355C3030305C3034305C303030505C303030655C303030655C303030725C3030302D5C303030745C3030306F5C3030302D5C303030705C303030655C303030655C30303072}
\BKM@entry{id=60,open,dest={73756273656374696F6E2E362E35},srcline={1212}}{5C3337365C3337375C303030365C3030302E5C303030355C3030305C3034305C303030505C303030655C303030655C303030725C3030302D5C303030745C3030306F5C3030302D5C303030705C303030655C303030655C30303072}
\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Porovnání algoritmů}}{45}{table.2}\protected@file@percent }
\newlabel{table:range_query_comparison}{{2}{45}{Porovnání algoritmů}{table.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.4}Optimalizace manažera zájmů}{45}{subsection.6.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.5}Peer-to-peer}{45}{subsection.6.5}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {19}{\ignorespaces Porovnání TCP a QUICr v peer-to-peer}}{46}{figure.19}\protected@file@percent }
\newlabel{fig:peer_to_peer}{{19}{46}{Porovnání TCP a QUICr v peer-to-peer}{figure.19}{}}
\BKM@entry{id=61,open,dest={73656374696F6E2A2E33},srcline={1253}}{5C3337365C3337375C3030305A5C3030305C3334315C303030765C3030315C3033335C30303072}
\abx@aux@cite{0}{quic}
\abx@aux@segm{0}{0}{quic}
\@writefile{toc}{\contentsline {section}{Z\'av\v er}{47}{section*.3}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {20}{\ignorespaces Porovnání TCP a QUICr v peer-to-peer}}{47}{figure.20}\protected@file@percent }
\newlabel{fig:peer_to_peer}{{20}{47}{Porovnání TCP a QUICr v peer-to-peer}{figure.20}{}}
\BKM@entry{id=61,open,dest={73656374696F6E2A2E33},srcline={1251}}{5C3337365C3337375C3030305A5C3030305C3334315C303030765C3030315C3033335C30303072}
\@writefile{toc}{\contentsline {section}{Z\'av\v er}{48}{section*.3}\protected@file@percent }
\babel@aux{czech}{}
\babel@aux{czech}{}
\BKM@entry{id=62,open,dest={73656374696F6E2A2E35},srcline={1262}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030635C3030306C5C303030755C303030735C303030695C3030306F5C3030306E5C30303073}
\@writefile{toc}{\contentsline {section}{Conclusions}{48}{section*.5}\protected@file@percent }
\BKM@entry{id=62,open,dest={73656374696F6E2A2E35},srcline={1260}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030635C3030306C5C303030755C303030735C303030695C3030306F5C3030306E5C30303073}
\@writefile{toc}{\contentsline {section}{Conclusions}{49}{section*.5}\protected@file@percent }
\babel@aux{english}{}
\babel@aux{czech}{}
\BKM@entry{id=63,open,dest={617070656E6469782E41},srcline={1269}}{5C3337365C3337375C303030415C3030305C3034305C303030505C303030725C303030765C3030306E5C3030305C3335355C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=64,open,dest={617070656E6469782E42},srcline={1272}}{5C3337365C3337375C303030425C3030305C3034305C303030445C303030725C303030755C303030685C3030305C3334315C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=65,open,dest={617070656E6469782E43},srcline={1277}}{5C3337365C3337375C303030435C3030305C3034305C3030304F5C303030625C303030735C303030615C303030685C3030305C3034305C303030655C3030306C5C303030655C3030306B5C303030745C303030725C3030306F5C3030306E5C303030695C303030635C3030306B5C3030305C3337355C303030635C303030685C3030305C3034305C303030645C303030615C30303074}
\@writefile{toc}{\contentsline {section}{\numberline {A}První příloha}{49}{appendix.A}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {B}Druhá příloha}{49}{appendix.B}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {C}Obsah elektronických dat}{49}{appendix.C}\protected@file@percent }
\newlabel{sec:ObsahData}{{C}{49}{Obsah elektronických dat}{appendix.C}{}}
\BKM@entry{id=63,open,dest={617070656E6469782E41},srcline={1273}}{5C3337365C3337375C303030415C3030305C3034305C3030304F5C303030625C303030735C303030615C303030685C3030305C3034305C303030655C3030306C5C303030655C3030306B5C303030745C303030725C3030306F5C3030306E5C303030695C303030635C3030306B5C3030305C3337355C303030635C303030685C3030305C3034305C303030645C303030615C30303074}
\abx@aux@nociteall
\BKM@entry{id=66,open,dest={73656374696F6E2A2E37},srcline={1354}}{5C3337365C3337375C3030304C5C303030695C303030745C303030655C303030725C303030615C303030745C303030755C303030725C30303061}
\@writefile{toc}{\contentsline {section}{\numberline {A}Obsah elektronických dat}{50}{appendix.A}\protected@file@percent }
\newlabel{sec:ObsahData}{{A}{50}{Obsah elektronických dat}{appendix.A}{}}
\BKM@entry{id=64,open,dest={73656374696F6E2A2E37},srcline={1337}}{5C3337365C3337375C3030304C5C303030695C303030745C303030655C303030725C303030615C303030745C303030755C303030725C30303061}
\@writefile{toc}{\contentsline {section}{Literatura}{51}{section*.7}\protected@file@percent }
\babel@aux{english}{}
\babel@aux{czech}{}
\abx@aux@read@bbl@mdfivesum{C3CBA72138B16E01160647867A8D8F99}
\abx@aux@read@bblrerun
\babel@aux{english}{}
\babel@aux{czech}{}
\babel@aux{english}{}
\babel@aux{czech}{}
\babel@aux{english}{}
\babel@aux{czech}{}
\babel@aux{english}{}
\babel@aux{czech}{}
\babel@aux{english}{}
\babel@aux{czech}{}
\babel@aux{english}{}
\babel@aux{czech}{}
\babel@aux{english}{}
\babel@aux{czech}{}
\babel@aux{english}{}
\babel@aux{czech}{}
\abx@aux@read@bbl@mdfivesum{4EA5A63E4195854FCFE02C3AE7D59DF9}
\abx@aux@defaultrefcontext{0}{computer_networks}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{quic}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{interpolation}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{peekingvalorant}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{interpolation1}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{interpolation2}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{timescaledb}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{distributed_systems}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{velky_pruvodce}{none/global//global/global/global}
\newlabel{LastPage}{{C}{51}{Obsah elektronických dat}{page.51}{}}
\gdef\lastpage@lastpage{51}
\gdef\lastpage@lastpageHy{51}
\abx@aux@defaultrefcontext{0}{evolveheirachy}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{gambettaclientserver}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{bleong}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{prdeving}{none/global//global/global/global}
\abx@aux@defaultrefcontext{0}{assiotis06mmorpg}{none/global//global/global/global}
\newlabel{LastPage}{{A}{52}{Obsah elektronických dat}{page.52}{}}
\gdef\lastpage@lastpage{52}
\gdef\lastpage@lastpageHy{52}
\gdef\svg@ink@ver@settings{{\m@ne }{inkscape}{\m@ne }}
\gdef \@abspage@last{51}
\gdef \@abspage@last{52}
+299 -7
View File
@@ -85,7 +85,39 @@
\verb https://www.rfc-editor.org/rfc/rfc9000.html
\endverb
\endentry
\entry{interpolation}{online}{}{}
\entry{peekingvalorant}{online}{}{}
\name{author}{1}{}{%
{{hash=ef652ce9122538bb5568a24a6c377e56}{%
family={{dewet, Matt and Straily, David}},
familyi={d\bibinitperiod}}}%
}
\strng{namehash}{ef652ce9122538bb5568a24a6c377e56}
\strng{fullhash}{ef652ce9122538bb5568a24a6c377e56}
\strng{fullhashraw}{ef652ce9122538bb5568a24a6c377e56}
\strng{bibnamehash}{ef652ce9122538bb5568a24a6c377e56}
\strng{authorbibnamehash}{ef652ce9122538bb5568a24a6c377e56}
\strng{authornamehash}{ef652ce9122538bb5568a24a6c377e56}
\strng{authorfullhash}{ef652ce9122538bb5568a24a6c377e56}
\strng{authorfullhashraw}{ef652ce9122538bb5568a24a6c377e56}
\field{sortinit}{3}
\field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
\field{title}{Peeking into VALORANT's Netcode}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2020}
\field{urldateera}{ce}
\verb{urlraw}
\verb https://www.riotgames.com/en/news/peeking-valorants-netcode
\endverb
\verb{url}
\verb https://www.riotgames.com/en/news/peeking-valorants-netcode
\endverb
\endentry
\entry{interpolation1}{online}{}{}
\name{author}{1}{}{%
{{hash=115b8af350e59a3a75d1e1601b157185}{%
family={Fiedler},
@@ -101,8 +133,8 @@
\strng{authornamehash}{115b8af350e59a3a75d1e1601b157185}
\strng{authorfullhash}{115b8af350e59a3a75d1e1601b157185}
\strng{authorfullhashraw}{115b8af350e59a3a75d1e1601b157185}
\field{sortinit}{3}
\field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{sortinit}{4}
\field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
@@ -119,6 +151,73 @@
\verb https://www.gafferongames.com/post/snapshot_interpolation/
\endverb
\endentry
\entry{interpolation2}{online}{}{}
\name{author}{1}{}{%
{{hash=1cf0f11213db40d088c94d74a6cb71b3}{%
family={Gambetta},
familyi={G\bibinitperiod},
given={Gabriel},
giveni={G\bibinitperiod}}}%
}
\strng{namehash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{fullhash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{fullhashraw}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{bibnamehash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{authorbibnamehash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{authornamehash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{authorfullhash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{authorfullhashraw}{1cf0f11213db40d088c94d74a6cb71b3}
\field{extraname}{1}
\field{sortinit}{5}
\field{sortinithash}{20e9b4b0b173788c5dace24730f47d8c}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
\field{title}{Entity Interpolation}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2026}
\field{urldateera}{ce}
\verb{urlraw}
\verb https://www.gabrielgambetta.com/entity-interpolation.html
\endverb
\verb{url}
\verb https://www.gabrielgambetta.com/entity-interpolation.html
\endverb
\endentry
\entry{timescaledb}{online}{}{}
\name{author}{1}{}{%
{{hash=7b05eae0c6e46f226fe3ae99a4b220f0}{%
family={TimescaleDB},
familyi={T\bibinitperiod}}}%
}
\strng{namehash}{7b05eae0c6e46f226fe3ae99a4b220f0}
\strng{fullhash}{7b05eae0c6e46f226fe3ae99a4b220f0}
\strng{fullhashraw}{7b05eae0c6e46f226fe3ae99a4b220f0}
\strng{bibnamehash}{7b05eae0c6e46f226fe3ae99a4b220f0}
\strng{authorbibnamehash}{7b05eae0c6e46f226fe3ae99a4b220f0}
\strng{authornamehash}{7b05eae0c6e46f226fe3ae99a4b220f0}
\strng{authorfullhash}{7b05eae0c6e46f226fe3ae99a4b220f0}
\strng{authorfullhashraw}{7b05eae0c6e46f226fe3ae99a4b220f0}
\field{sortinit}{6}
\field{sortinithash}{b33bc299efb3c36abec520a4c896a66d}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
\field{title}{Tiger Data architecture for real-time analytics}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2026}
\field{urldateera}{ce}
\verb{urlraw}
\verb https://www.tigerdata.com/docs/learn/deep-dive/whitepaper
\endverb
\verb{url}
\verb https://www.tigerdata.com/docs/learn/deep-dive/whitepaper
\endverb
\endentry
\entry{distributed_systems}{book}{}{}
\name{author}{2}{}{%
{{hash=0b5c695d6cb5456cde890afe3b8b2111}{%
@@ -148,8 +247,8 @@
\strng{authornamehash}{3bb62aa7088dd4fca7609074d4fac863}
\strng{authorfullhash}{3bb62aa7088dd4fca7609074d4fac863}
\strng{authorfullhashraw}{3bb62aa7088dd4fca7609074d4fac863}
\field{sortinit}{6}
\field{sortinithash}{b33bc299efb3c36abec520a4c896a66d}
\field{sortinit}{8}
\field{sortinithash}{a231b008ebf0ecbe0b4d96dcc159445f}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{edition}{4}
@@ -186,8 +285,8 @@
\strng{authornamehash}{ec7dfb56df78a368389190afb803eeb9}
\strng{authorfullhash}{ec7dfb56df78a368389190afb803eeb9}
\strng{authorfullhashraw}{ec7dfb56df78a368389190afb803eeb9}
\field{sortinit}{7}
\field{sortinithash}{108d0be1b1bee9773a1173443802c0a3}
\field{sortinit}{9}
\field{sortinithash}{0a5ebc79d83c96b6579069544c73c7d4}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{edition}{5}
@@ -200,6 +299,199 @@
\field{urldateera}{ce}
\true{nocite}
\endentry
\entry{evolveheirachy}{online}{}{}
\name{author}{1}{}{%
{{hash=10fad6d49e80589b09b0aea94ea7a215}{%
family={West},
familyi={W\bibinitperiod},
given={Mick},
giveni={M\bibinitperiod}}}%
}
\strng{namehash}{10fad6d49e80589b09b0aea94ea7a215}
\strng{fullhash}{10fad6d49e80589b09b0aea94ea7a215}
\strng{fullhashraw}{10fad6d49e80589b09b0aea94ea7a215}
\strng{bibnamehash}{10fad6d49e80589b09b0aea94ea7a215}
\strng{authorbibnamehash}{10fad6d49e80589b09b0aea94ea7a215}
\strng{authornamehash}{10fad6d49e80589b09b0aea94ea7a215}
\strng{authorfullhash}{10fad6d49e80589b09b0aea94ea7a215}
\strng{authorfullhashraw}{10fad6d49e80589b09b0aea94ea7a215}
\field{sortinit}{1}
\field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
\field{title}{Evolve Your Hierarchy}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2007}
\field{urldateera}{ce}
\true{nocite}
\verb{urlraw}
\verb https://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
\endverb
\verb{url}
\verb https://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
\endverb
\endentry
\entry{gambettaclientserver}{online}{}{}
\name{author}{1}{}{%
{{hash=1cf0f11213db40d088c94d74a6cb71b3}{%
family={Gambetta},
familyi={G\bibinitperiod},
given={Gabriel},
giveni={G\bibinitperiod}}}%
}
\strng{namehash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{fullhash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{fullhashraw}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{bibnamehash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{authorbibnamehash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{authornamehash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{authorfullhash}{1cf0f11213db40d088c94d74a6cb71b3}
\strng{authorfullhashraw}{1cf0f11213db40d088c94d74a6cb71b3}
\field{extraname}{2}
\field{sortinit}{1}
\field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
\field{title}{Fast-Paced Multiplayer (Part I): Client-Server Game Architecture}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2026}
\field{urldateera}{ce}
\true{nocite}
\verb{urlraw}
\verb https://www.gabrielgambetta.com/client-server-game-architecture.html
\endverb
\verb{url}
\verb https://www.gabrielgambetta.com/client-server-game-architecture.html
\endverb
\endentry
\entry{bleong}{online}{}{}
\name{author}{2}{}{%
{{hash=622067caaf563361af964542b4398a75}{%
family={Assiotis},
familyi={A\bibinitperiod},
given={Marios},
giveni={M\bibinitperiod}}}%
{{hash=587cd9a38a6b41a2f56f2577ee75b7df}{%
family={Tzanov},
familyi={T\bibinitperiod},
given={Velin},
giveni={V\bibinitperiod}}}%
}
\strng{namehash}{3c746d33e9efc1c464b250a836d32560}
\strng{fullhash}{3c746d33e9efc1c464b250a836d32560}
\strng{fullhashraw}{3c746d33e9efc1c464b250a836d32560}
\strng{bibnamehash}{3c746d33e9efc1c464b250a836d32560}
\strng{authorbibnamehash}{3c746d33e9efc1c464b250a836d32560}
\strng{authornamehash}{3c746d33e9efc1c464b250a836d32560}
\strng{authorfullhash}{3c746d33e9efc1c464b250a836d32560}
\strng{authorfullhashraw}{3c746d33e9efc1c464b250a836d32560}
\field{extraname}{1}
\field{sortinit}{1}
\field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
\field{title}{A Distributed Architecture for MMORPG}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2006}
\field{urldateera}{ce}
\true{nocite}
\verb{urlraw}
\verb https://www.comp.nus.edu.sg/~bleong/hydra/related/assiotis06mmorpg.pdf
\endverb
\verb{url}
\verb https://www.comp.nus.edu.sg/~bleong/hydra/related/assiotis06mmorpg.pdf
\endverb
\endentry
\entry{prdeving}{online}{}{}
\name{author}{1}{}{%
{{hash=6af606f933778fda1c81ddef1736a542}{%
family={PRDeving},
familyi={P\bibinitperiod}}}%
}
\strng{namehash}{6af606f933778fda1c81ddef1736a542}
\strng{fullhash}{6af606f933778fda1c81ddef1736a542}
\strng{fullhashraw}{6af606f933778fda1c81ddef1736a542}
\strng{bibnamehash}{6af606f933778fda1c81ddef1736a542}
\strng{authorbibnamehash}{6af606f933778fda1c81ddef1736a542}
\strng{authornamehash}{6af606f933778fda1c81ddef1736a542}
\strng{authorfullhash}{6af606f933778fda1c81ddef1736a542}
\strng{authorfullhashraw}{6af606f933778fda1c81ddef1736a542}
\field{sortinit}{1}
\field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
\field{title}{MMO Architecture}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2023}
\field{urldateera}{ce}
\true{nocite}
\verb{urlraw}
\verb https://prdeving.wordpress.com/2023/09/29/mmo-architecture-source-of-truth-dataflows-i-o-bottlenecks-and-how-to-solve-them/
\endverb
\verb{url}
\verb https://prdeving.wordpress.com/2023/09/29/mmo-architecture-source-of-truth-dataflows-i-o-bottlenecks-and-how-to-solve-them/
\endverb
\endentry
\entry{assiotis06mmorpg}{inproceedings}{}{}
\name{author}{2}{}{%
{{hash=622067caaf563361af964542b4398a75}{%
family={Assiotis},
familyi={A\bibinitperiod},
given={Marios},
giveni={M\bibinitperiod}}}%
{{hash=587cd9a38a6b41a2f56f2577ee75b7df}{%
family={Tzanov},
familyi={T\bibinitperiod},
given={Velin},
giveni={V\bibinitperiod}}}%
}
\list{location}{1}{%
{Singapore}%
}
\list{publisher}{1}{%
{ACM}%
}
\strng{namehash}{3c746d33e9efc1c464b250a836d32560}
\strng{fullhash}{3c746d33e9efc1c464b250a836d32560}
\strng{fullhashraw}{3c746d33e9efc1c464b250a836d32560}
\strng{bibnamehash}{3c746d33e9efc1c464b250a836d32560}
\strng{authorbibnamehash}{3c746d33e9efc1c464b250a836d32560}
\strng{authornamehash}{3c746d33e9efc1c464b250a836d32560}
\strng{authorfullhash}{3c746d33e9efc1c464b250a836d32560}
\strng{authorfullhashraw}{3c746d33e9efc1c464b250a836d32560}
\field{extraname}{2}
\field{sortinit}{2}
\field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{NETGAMES '06: Proceedings of the 5th Workshop on Network and System Support for Games}
\field{langid}{english}
\field{title}{A Distributed Architecture for MMORPG}
\field{urlday}{5}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2006}
\field{urldateera}{ce}
\true{nocite}
\verb{urlraw}
\verb https://www.comp.nus.edu.sg/~bleong/hydra/related/assiotis06mmorpg.pdf
\endverb
\verb{url}
\verb https://www.comp.nus.edu.sg/~bleong/hydra/related/assiotis06mmorpg.pdf
\endverb
\endentry
\enddatalist
\endrefsection
\endinput
+206
View File
@@ -0,0 +1,206 @@
% $ biblatex auxiliary file $
% $ biblatex bbl format version 3.3 $
% Do not modify the above lines!
%
% This is an auxiliary file used by the 'biblatex' package.
% This file may safely be deleted. It will be recreated by
% biber as required.
%
\begingroup
\makeatletter
\@ifundefined{ver@biblatex.sty}
{\@latex@error
{Missing 'biblatex' package}
{The bibliography requires the 'biblatex' package.}
\aftergroup\endinput}
{}
\endgroup
\refsection{0}
\datalist[entry]{none/global//global/global/global}
\entry{computer_networks}{book}{}{}
\name{author}{1}{}{%
{{hash=37a62308e9421abec940ea8aa6b08f60}{%
family={Peterson\bibnamedelimb Larry\bibnamedelima L.},
familyi={P\bibinitperiod\bibinitdelim L\bibinitperiod\bibinitdelim L\bibinitperiod},
given={Davie\bibnamedelimb Bruce\bibnamedelima S.},
giveni={D\bibinitperiod\bibinitdelim B\bibinitperiod\bibinitdelim S\bibinitperiod}}}%
}
\list{location}{1}{%
{Cambridge}%
}
\list{publisher}{1}{%
{Elsevier}%
}
\strng{namehash}{37a62308e9421abec940ea8aa6b08f60}
\strng{fullhash}{37a62308e9421abec940ea8aa6b08f60}
\strng{fullhashraw}{37a62308e9421abec940ea8aa6b08f60}
\strng{bibnamehash}{37a62308e9421abec940ea8aa6b08f60}
\strng{authorbibnamehash}{37a62308e9421abec940ea8aa6b08f60}
\strng{authornamehash}{37a62308e9421abec940ea8aa6b08f60}
\strng{authorfullhash}{37a62308e9421abec940ea8aa6b08f60}
\strng{authorfullhashraw}{37a62308e9421abec940ea8aa6b08f60}
\field{sortinit}{1}
\field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{edition}{6}
\field{isbn}{978-0128182000}
\field{title}{Computer networks: a system approach}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2022}
\field{urldateera}{ce}
\endentry
\entry{quic}{online}{}{}
\name{author}{1}{}{%
{{hash=868aea39c494d643af672b69a8024d46}{%
family={{QUIC Working Group}},
familyi={Q\bibinitperiod}}}%
}
\strng{namehash}{868aea39c494d643af672b69a8024d46}
\strng{fullhash}{868aea39c494d643af672b69a8024d46}
\strng{fullhashraw}{868aea39c494d643af672b69a8024d46}
\strng{bibnamehash}{868aea39c494d643af672b69a8024d46}
\strng{authorbibnamehash}{868aea39c494d643af672b69a8024d46}
\strng{authornamehash}{868aea39c494d643af672b69a8024d46}
\strng{authorfullhash}{868aea39c494d643af672b69a8024d46}
\strng{authorfullhashraw}{868aea39c494d643af672b69a8024d46}
\field{sortinit}{2}
\field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{RFC 9000: QUIC: A UDP-Based Multiplexed and Secure Transport}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2021}
\field{urldateera}{ce}
\verb{urlraw}
\verb https://www.rfc-editor.org/rfc/rfc9000.html
\endverb
\verb{url}
\verb https://www.rfc-editor.org/rfc/rfc9000.html
\endverb
\endentry
\entry{interpolation}{online}{}{}
\name{author}{1}{}{%
{{hash=115b8af350e59a3a75d1e1601b157185}{%
family={Fiedler},
familyi={F\bibinitperiod},
given={Glenn},
giveni={G\bibinitperiod}}}%
}
\strng{namehash}{115b8af350e59a3a75d1e1601b157185}
\strng{fullhash}{115b8af350e59a3a75d1e1601b157185}
\strng{fullhashraw}{115b8af350e59a3a75d1e1601b157185}
\strng{bibnamehash}{115b8af350e59a3a75d1e1601b157185}
\strng{authorbibnamehash}{115b8af350e59a3a75d1e1601b157185}
\strng{authornamehash}{115b8af350e59a3a75d1e1601b157185}
\strng{authorfullhash}{115b8af350e59a3a75d1e1601b157185}
\strng{authorfullhashraw}{115b8af350e59a3a75d1e1601b157185}
\field{sortinit}{3}
\field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{langid}{english}
\field{title}{Snapshot Interpolation}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2015}
\field{urldateera}{ce}
\verb{urlraw}
\verb https://www.gafferongames.com/post/snapshot_interpolation/
\endverb
\verb{url}
\verb https://www.gafferongames.com/post/snapshot_interpolation/
\endverb
\endentry
\entry{distributed_systems}{book}{}{}
\name{author}{2}{}{%
{{hash=0b5c695d6cb5456cde890afe3b8b2111}{%
family={Steen},
familyi={S\bibinitperiod},
given={M.},
giveni={M\bibinitperiod},
prefix={van},
prefixi={v\bibinitperiod}}}%
{{hash=92bc8f2b5a926e6cc80dfae03d2751e5}{%
family={Tanenbaum},
familyi={T\bibinitperiod},
given={A.S.},
giveni={A\bibinitperiod}}}%
}
\list{location}{1}{%
{Praha}%
}
\list{publisher}{1}{%
{distributed-systems.net}%
}
\strng{namehash}{3bb62aa7088dd4fca7609074d4fac863}
\strng{fullhash}{3bb62aa7088dd4fca7609074d4fac863}
\strng{fullhashraw}{3bb62aa7088dd4fca7609074d4fac863}
\strng{bibnamehash}{3bb62aa7088dd4fca7609074d4fac863}
\strng{authorbibnamehash}{3bb62aa7088dd4fca7609074d4fac863}
\strng{authornamehash}{3bb62aa7088dd4fca7609074d4fac863}
\strng{authorfullhash}{3bb62aa7088dd4fca7609074d4fac863}
\strng{authorfullhashraw}{3bb62aa7088dd4fca7609074d4fac863}
\field{sortinit}{6}
\field{sortinithash}{b33bc299efb3c36abec520a4c896a66d}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{edition}{4}
\field{isbn}{978-1543057386}
\field{title}{Distributed Systems}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2023}
\field{urldateera}{ce}
\true{nocite}
\endentry
\entry{velky_pruvodce}{book}{}{}
\name{author}{1}{}{%
{{hash=ec7dfb56df78a368389190afb803eeb9}{%
family={KABELOVÁ},
familyi={K\bibinitperiod},
given={Libor},
giveni={L\bibinitperiod},
suffix={Alena\bibnamedelimb a\bibnamedelima DOSTÁLEK},
suffixi={A\bibinitperiod\bibinitdelim a\bibinitperiod\bibinitdelim D\bibinitperiod}}}%
}
\list{location}{1}{%
{Brno}%
}
\list{publisher}{1}{%
{Computer Press, a.s.}%
}
\strng{namehash}{ec7dfb56df78a368389190afb803eeb9}
\strng{fullhash}{ec7dfb56df78a368389190afb803eeb9}
\strng{fullhashraw}{ec7dfb56df78a368389190afb803eeb9}
\strng{bibnamehash}{ec7dfb56df78a368389190afb803eeb9}
\strng{authorbibnamehash}{ec7dfb56df78a368389190afb803eeb9}
\strng{authornamehash}{ec7dfb56df78a368389190afb803eeb9}
\strng{authorfullhash}{ec7dfb56df78a368389190afb803eeb9}
\strng{authorfullhashraw}{ec7dfb56df78a368389190afb803eeb9}
\field{sortinit}{7}
\field{sortinithash}{108d0be1b1bee9773a1173443802c0a3}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{edition}{5}
\field{isbn}{978-80-251-2236-5}
\field{title}{Velký průvodce protokoly TCP/IP a systémem DNS}
\field{urlday}{3}
\field{urlmonth}{8}
\field{urlyear}{2026}
\field{year}{2008}
\field{urldateera}{ce}
\true{nocite}
\endentry
\enddatalist
\endrefsection
\endinput
+5 -2
View File
@@ -2159,8 +2159,11 @@
<bcf:section number="0">
<bcf:citekey order="1" intorder="1">computer_networks</bcf:citekey>
<bcf:citekey order="2" intorder="1">quic</bcf:citekey>
<bcf:citekey order="3" intorder="1">quic</bcf:citekey>
<bcf:citekey order="4" intorder="1" nocite="1">*</bcf:citekey>
<bcf:citekey order="3" intorder="1">peekingvalorant</bcf:citekey>
<bcf:citekey order="4" intorder="1">interpolation1</bcf:citekey>
<bcf:citekey order="5" intorder="1">interpolation2</bcf:citekey>
<bcf:citekey order="6" intorder="1">timescaledb</bcf:citekey>
<bcf:citekey order="7" intorder="1" nocite="1">*</bcf:citekey>
</bcf:section>
<!-- SORTING TEMPLATES -->
<bcf:sortingtemplate name="none">
+29
View File
@@ -2157,3 +2157,32 @@
<bcf:datasource type="file" datatype="bibtex">bibliografie.bib</bcf:datasource>
</bcf:bibdata>
<bcf:section number="0">
<bcf:citekey order="1" intorder="1">computer_networks</bcf:citekey>
<bcf:citekey order="2" intorder="1">quic</bcf:citekey>
<bcf:citekey order="3" intorder="1">peekingvalorant</bcf:citekey>
<bcf:citekey order="4" intorder="1">interpolation1</bcf:citekey>
<bcf:citekey order="5" intorder="1">interpolation2</bcf:citekey>
<bcf:citekey order="6" intorder="1">quic</bcf:citekey>
<bcf:citekey order="7" intorder="1" nocite="1">*</bcf:citekey>
</bcf:section>
<!-- SORTING TEMPLATES -->
<bcf:sortingtemplate name="none">
<bcf:sort order="1">
<bcf:sortitem order="1">citeorder</bcf:sortitem>
</bcf:sort>
<bcf:sort order="2">
<bcf:sortitem order="1">intciteorder</bcf:sortitem>
</bcf:sort>
</bcf:sortingtemplate>
<!-- DATALISTS -->
<bcf:datalist section="0"
name="none/global//global/global/global"
type="entry"
sortingtemplatename="none"
sortingnamekeytemplatename="global"
labelprefix=""
uniquenametemplatename="global"
labelalphanametemplatename="global"
namehashtemplatename="global">
</bcf:datalist>
</bcf:controlfile>
+12 -12
View File
@@ -1,14 +1,14 @@
[0] Config.pm:328> INFO - This is Biber 2.21
[0] Config.pm:331> INFO - Logfile is 'kidiplom.blg'
[43] biber:342> INFO - === Mon Aug 3, 2026, 20:00:10
[55] Biber.pm:421> INFO - Reading 'kidiplom.bcf'
[91] Biber.pm:999> INFO - Using all citekeys in bib section 0
[101] Biber.pm:4487> INFO - Processing section 0
[108] Biber.pm:4678> INFO - Looking for bibtex file 'bibliografie.bib' for section 0
[109] bibtex.pm:1713> INFO - LaTeX decoding ...
[113] bibtex.pm:1519> INFO - Found BibTeX data source 'bibliografie.bib'
[161] UCollate.pm:68> INFO - Overriding locale 'cs_CZ' defaults 'variable = shifted' with 'variable = non-ignorable'
[161] UCollate.pm:68> INFO - Overriding locale 'cs_CZ' defaults 'normalization = NFD' with 'normalization = prenormalized'
[162] Biber.pm:4307> INFO - Sorting list 'none/global//global/global/global' of type 'entry' with template 'none' and locale 'cs_CZ'
[167] bbl.pm:676> INFO - Writing 'kidiplom.bbl' with encoding 'UTF-8'
[169] bbl.pm:779> INFO - Output to kidiplom.bbl
[45] biber:342> INFO - === Wed Aug 5, 2026, 20:53:02
[56] Biber.pm:421> INFO - Reading 'kidiplom.bcf'
[92] Biber.pm:999> INFO - Using all citekeys in bib section 0
[102] Biber.pm:4487> INFO - Processing section 0
[109] Biber.pm:4678> INFO - Looking for bibtex file 'bibliografie.bib' for section 0
[110] bibtex.pm:1713> INFO - LaTeX decoding ...
[116] bibtex.pm:1519> INFO - Found BibTeX data source 'bibliografie.bib'
[185] UCollate.pm:68> INFO - Overriding locale 'cs_CZ' defaults 'normalization = NFD' with 'normalization = prenormalized'
[185] UCollate.pm:68> INFO - Overriding locale 'cs_CZ' defaults 'variable = shifted' with 'variable = non-ignorable'
[185] Biber.pm:4307> INFO - Sorting list 'none/global//global/global/global' of type 'entry' with template 'none' and locale 'cs_CZ'
[192] bbl.pm:676> INFO - Writing 'kidiplom.bbl' with encoding 'UTF-8'
[195] bbl.pm:779> INFO - Output to kidiplom.bbl
+13 -43
View File
@@ -1,24 +1,23 @@
# Fdb version 4
["biber kidiplom"] 1777641420.71466 "kidiplom.bcf" "kidiplom.bbl" "kidiplom" 1785873458.8564 2
"kidiplom.bcf" 1785873458.70234 100697 0d278831f58b22e288d3858fcb2c1fe5 "pdflatex"
["biber kidiplom"] 1777641420.71466 "kidiplom.bcf" "kidiplom.bbl" "kidiplom" 1785962472.28568 2
"kidiplom.bcf" 1785962472.17566 100912 ee0f657cd8a3d7d773754f1b6b31bd61 "pdflatex"
(generated)
"kidiplom.bbl"
"kidiplom.blg"
(rewritten before read)
["makeindex kidiplom.idx"] 1777641420.69393 "kidiplom.idx" "kidiplom.ind" "kidiplom" 1785873458.85161 0
"kidiplom.idx" 1785873456.43831 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
["makeindex kidiplom.idx"] 1777641420.69393 "kidiplom.idx" "kidiplom.ind" "kidiplom" 1785962472.28226 0
"kidiplom.idx" 1785962470.42564 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
(generated)
"kidiplom.ilg"
"kidiplom.ind"
(rewritten before read)
["pdflatex"] 1785873455.47714 "/home/martin/projects/kidiplom/kidiplom.tex" "kidiplom.pdf" "kidiplom" 1785873458.85184 2
"/home/martin/projects/kidiplom/kidiplom.tex" 1785873455.29029 129638 c58f042e3489e766c0b8250bfdd4b881 ""
["pdflatex"] 1785962470.18848 "/home/martin/projects/kidiplom/kidiplom.tex" "kidiplom.pdf" "kidiplom" 1785962472.2825 2
"/home/martin/projects/kidiplom/kidiplom.tex" 1785962470.11264 131748 9018b0f2e3da319eeb87bfa46139a24d ""
"/usr/share/texmf-dist/fonts/enc/dvips/base/8r.enc" 1775415801 4850 80dc9bab7f31fb78a000ccfed0e27cab ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ec.enc" 1775415801 2375 baa924870cfb487815765f9094cf3728 ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathit.enc" 1775415801 2405 5dcf2c1b967ee25cc46c58cd52244aed ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathsy.enc" 1775415801 2840 216e6e45ad352e2456e1149f28885bee ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-rm.enc" 1775415801 2327 9d6df24f9c4f7368395224341a95523a ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ts1.enc" 1775415801 3031 6c4d3515bf7115d8518af1c9ab97ca44 ""
"/usr/share/texmf-dist/fonts/map/fontname/texfonts.map" 1775415801 3524 cb3e574dea2d1052e39280babc910dc8 ""
"/usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrb8r.tfm" 1775415801 1292 3059476c50a24578715759f22652f3d0 ""
"/usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrb8t.tfm" 1775415801 1384 87406e4336af44af883a035f17f319d9 ""
@@ -39,7 +38,6 @@
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr7.tfm" 1775415801 12064 09aa3eeac96bf141d673bb1b0385ce55 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr8.tfm" 1775415801 12064 a35db870f0b76c338d749c56dc030ef5 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmri12.tfm" 1775415801 17144 271aaf9ebb339934b04110dc5211fba4 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmri8.tfm" 1775415801 17152 c8240fef851c4991afefdae37a539ee1 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmex10.tfm" 1775415801 992 ce925c9346c7613270a79afbee98c070 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmmi10.tfm" 1775415801 1528 6d36b2385e0ca062a654de6ac59cb34f ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/lmmi12.tfm" 1775415801 1524 753b192b18f2991794f9d41a8228510b ""
@@ -58,7 +56,6 @@
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr6.tfm" 1775415801 11836 e3b6ce3e601aec94f64a536e7f4224d5 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr7.tfm" 1775415801 11852 5a9022f105fd1ee2797df861e79ae9a0 ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/rm-lmr8.tfm" 1775415801 11864 309fd7f43e4a0ba39f6f7644d76e8edf ""
"/usr/share/texmf-dist/fonts/tfm/public/lm/ts1-lmr12.tfm" 1775415801 1596 1d4548788e389ded56d0b01b28377882 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmbx10.pfb" 1775415801 121021 1bf809ce4a594679006bd72263eba59b ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmbx12.pfb" 1775415801 116908 1fca96723793882c2e0160350c192fc8 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmmi12.pfb" 1775415801 30696 2654571912f9cd384da9f7cb8a60c568 ""
@@ -68,7 +65,6 @@
"/usr/share/texmf-dist/fonts/type1/public/lm/lmr7.pfb" 1775415801 121145 68312a933e2c689ed40ec0aba373e279 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmr8.pfb" 1775415801 122174 a7a08406857c9530a0320a2517f60370 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmri12.pfb" 1775415801 109265 32320cb6133d4d76bf83e27b5eb4009b ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmri8.pfb" 1775415801 109952 3dd76c0c5c680d519bb6d59a066c0826 ""
"/usr/share/texmf-dist/fonts/type1/public/lm/lmsy10.pfb" 1775415801 27863 09ce3735688ffde955e72da27c95b61a ""
"/usr/share/texmf-dist/fonts/type1/urw/courier/ucrb8a.pfb" 1775415801 50493 4ed1f7e9eba8f1f3e1ec25195460190d ""
"/usr/share/texmf-dist/fonts/type1/urw/courier/ucrr8a.pfb" 1775415801 45758 19968a0990191524e34e1994d4a31cb6 ""
@@ -108,10 +104,7 @@
"/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex" 1775415801 30029 c49ea8f95207c46731469c614daf4e33 ""
"/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def" 1775415801 7067 11553488d1600cac6a0cfca012fca111 ""
"/usr/share/texmf-dist/tex/generic/stringenc/stringenc.sty" 1775415801 21514 b7557edcee22835ef6b03ede1802dad4 ""
"/usr/share/texmf-dist/tex/generic/tracklang/tracklang.tex" 1775415801 152705 c906707a12ed9475745f81566006dbd7 ""
"/usr/share/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty" 1775415801 7008 f92eaa0a3872ed622bbf538217cd2ab7 ""
"/usr/share/texmf-dist/tex/generic/xkeyval/xkeyval.tex" 1775415801 19299 c7c03646b32f5a7caaa137673b7e76d2 ""
"/usr/share/texmf-dist/tex/generic/xkeyval/xkvutils.tex" 1775415801 7787 7dfc2f158253fc82fd655393220e6620 ""
"/usr/share/texmf-dist/tex/latex/amscls/amsthm.sty" 1775415801 12594 0d51ac3a545aaaa555021326ff22a6cc ""
"/usr/share/texmf-dist/tex/latex/amsfonts/amsfonts.sty" 1775415801 5949 3f3fd50a8cc94c3d4cbf4fc66cd3df1c ""
"/usr/share/texmf-dist/tex/latex/amsfonts/amssymb.sty" 1775415801 13829 94730e64147574077f8ecfea9bb69af4 ""
@@ -146,21 +139,9 @@
"/usr/share/texmf-dist/tex/latex/csquotes/csquotes.cfg" 1775415801 7068 06f8d141725d114847527a66439066b6 ""
"/usr/share/texmf-dist/tex/latex/csquotes/csquotes.def" 1775415801 22135 0975a49eeaed232aa861e9425ffb2e7c ""
"/usr/share/texmf-dist/tex/latex/csquotes/csquotes.sty" 1775415801 62767 e79d6d7a989e7da62dcf3d0a65c1faee ""
"/usr/share/texmf-dist/tex/latex/datatool-english/datatool-english-utf8.ldf" 1775415801 3089 d52a4c355b25c3dd529891c3a45f909f ""
"/usr/share/texmf-dist/tex/latex/datatool-english/datatool-english.ldf" 1775415801 13644 e87d3e24e9d57f23552bacd982741384 ""
"/usr/share/texmf-dist/tex/latex/datatool/datatool-base.sty" 1775415801 300696 d64c0f6926b342caf0237aca7adc4565 ""
"/usr/share/texmf-dist/tex/latex/datatool/datatool-l3fp.def" 1775415801 8399 46cc9ec75e799cc8dab7047c95556626 ""
"/usr/share/texmf-dist/tex/latex/datatool/datatool-utf8.ldf" 1775415801 4460 214e95070da2307b91ff7e1a67406558 ""
"/usr/share/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty" 1775415801 13886 d1306dcf79a944f6988e688c1785f9ce ""
"/usr/share/texmf-dist/tex/latex/etoolbox/etoolbox.sty" 1775415801 46885 8953c67ffba03252c6090aa19568b8ba ""
"/usr/share/texmf-dist/tex/latex/geometry/geometry.sty" 1775415801 41601 9cf6c5257b1bc7af01a58859749dd37a ""
"/usr/share/texmf-dist/tex/latex/glossaries-english/glossaries-english.ldf" 1775415801 3656 cfd7063dcf1f89f4d3681b9a8bd5be4d ""
"/usr/share/texmf-dist/tex/latex/glossaries/base/glossaries.sty" 1775415801 263604 afa61de25e12f99bb1305606fa9e1ddf ""
"/usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-hypernav.sty" 1775415801 7346 20a6fbcba8f370c2b7d92a5a20321b54 ""
"/usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-list.sty" 1775415801 7729 7146f0a2bfdee482a9b65ea7004d6500 ""
"/usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-long.sty" 1775415801 9620 8591e606650ad0f162261aac7c7e8507 ""
"/usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-super.sty" 1775415801 10639 48c47d2eadf7b08958cc1dd323db6849 ""
"/usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-tree.sty" 1775415801 96632 7b39c1bccbc94c2cff19084b6ff5ed7e ""
"/usr/share/texmf-dist/tex/latex/graphics-cfg/color.cfg" 1775415801 1213 620bba36b25224fa9b7e1ccb4ecb76fd ""
"/usr/share/texmf-dist/tex/latex/graphics-cfg/graphics.cfg" 1775415801 1224 978390e9c2234eab29404bc21b268d1e ""
"/usr/share/texmf-dist/tex/latex/graphics-def/pdftex.def" 1775415801 19626 23e2822b9b2b5005f4c549ca98b9334d ""
@@ -206,17 +187,13 @@
"/usr/share/texmf-dist/tex/latex/lm/omxlmex.fd" 1775415801 568 a5494d810f2680caf10205cd1226c76c ""
"/usr/share/texmf-dist/tex/latex/lm/ot1lmr.fd" 1775415801 1882 28c08db1407ebff35a658fd141753d16 ""
"/usr/share/texmf-dist/tex/latex/lm/t1lmr.fd" 1775415801 1867 996fe743d88a01aca041ed22cc10e1bb ""
"/usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd" 1775415801 1914 884882d7ebb0fd65cea93fca77ff6f5a ""
"/usr/share/texmf-dist/tex/latex/logreq/logreq.def" 1775415801 1620 fb1c32b818f2058eca187e5c41dfae77 ""
"/usr/share/texmf-dist/tex/latex/logreq/logreq.sty" 1775415801 6187 b27afc771af565d3a9ff1ca7d16d0d46 ""
"/usr/share/texmf-dist/tex/latex/mfirstuc/mfirstuc.sty" 1775415801 18640 ecc51f3cc513cfff843ce5d9f457c3b9 ""
"/usr/share/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty" 1775415801 443 8c872229db56122037e86bcda49e14f3 ""
"/usr/share/texmf-dist/tex/latex/pgf/utilities/pgfrcs.sty" 1775415801 325 f9f16d12354225b7dd52a3321f085955 ""
"/usr/share/texmf-dist/tex/latex/psnfss/t1pcr.fd" 1775415801 798 d5895e9edc628f2be019beb2c0ec66df ""
"/usr/share/texmf-dist/tex/latex/refcount/refcount.sty" 1775415801 9878 9e94e8fa600d95f9c7731bb21dfb67a4 ""
"/usr/share/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty" 1775415801 9684 a33a14b82ce60d6e77cb9be689d79ee6 ""
"/usr/share/texmf-dist/tex/latex/savesym/savesym.sty" 1775415801 2076 969b46b87cb8b982a532fc328300998e ""
"/usr/share/texmf-dist/tex/latex/supertabular/supertabular.sty" 1775415801 16217 4373543ac84bc0161205d94fecd4b8bf ""
"/usr/share/texmf-dist/tex/latex/svg/svg.sty" 1775415801 43468 671ae75b3a15019004495eff4c0911e8 ""
"/usr/share/texmf-dist/tex/latex/thmtools/aliasctr.sty" 1775415801 2547 a5a59eb03f587b4c267981c894cde4cb ""
"/usr/share/texmf-dist/tex/latex/thmtools/parseargs.sty" 1775415801 1696 0b33b5336cb99d15b904405f9c077915 ""
@@ -231,15 +208,11 @@
"/usr/share/texmf-dist/tex/latex/tools/longtable.sty" 1775415801 16014 dfa4b4d4e04a78a3f05a90c19711737a ""
"/usr/share/texmf-dist/tex/latex/tools/multicol.sty" 1775415801 33142 efe8f4750fc02524935e7423b4bdef69 ""
"/usr/share/texmf-dist/tex/latex/tools/shellesc.sty" 1775415801 4121 d611256e8b768e99aa5a680aad44990d ""
"/usr/share/texmf-dist/tex/latex/tracklang/tracklang.sty" 1775415801 10062 6009a67f1c2bd376a9f34880dc509a07 ""
"/usr/share/texmf-dist/tex/latex/translator/translator.sty" 1775415801 8765 56d370785f0143111ff9898b5adfe08e ""
"/usr/share/texmf-dist/tex/latex/transparent/transparent-nometadata.sty" 1775415801 4218 953818299bf47dea89e603d2b8a390d8 ""
"/usr/share/texmf-dist/tex/latex/transparent/transparent.sty" 1775415801 1797 4ef4500488e0ea48fd76f41e2a351a2e ""
"/usr/share/texmf-dist/tex/latex/trimspaces/trimspaces.sty" 1775415801 1380 971a51b00a14503ddf754cab24c3f209 ""
"/usr/share/texmf-dist/tex/latex/url/url.sty" 1775415801 12796 8edb7d69a20b857904dd0ea757c14ec9 ""
"/usr/share/texmf-dist/tex/latex/xcolor/xcolor.sty" 1775415801 55384 b454dec21c2d9f45ec0b793f0995b992 ""
"/usr/share/texmf-dist/tex/latex/xfor/xfor.sty" 1775415801 2689 44855b72da58344b1c1d9b3087bce6ca ""
"/usr/share/texmf-dist/tex/latex/xkeyval/xkeyval.sty" 1775415801 5006 d7e899bb5d9717c7f214e9bc0284de7b ""
"/usr/share/texmf-dist/web2c/texmf.cnf" 1775415801 43569 fd570f2fa160877d211e859f687312ba ""
"/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map" 1780904047 5382322 468d3831690fd9b5e3d16d5c22dbf17a ""
"/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1780904038 2352582 86b484c6b78c2a90b481750cbf03de22 ""
@@ -255,6 +228,7 @@
"graphics/http2.pdf" 1785767496.10594 46800 91209613d245a76f155c3f9e6f79cdf6 ""
"graphics/http3.pdf" 1785767496.10594 79793 31bf8e82583c4435518e5143b8792c85 ""
"graphics/integrationcomparison.pdf" 1785767496.10694 21400 e9a5f98ce0119825ff32deab9aeb8849 ""
"graphics/interpolation.png" 1785951889.70366 17128 236f0c22113995d196ef39af0121366f ""
"graphics/kititle-cz-nofont.pdf" 1681557593 12762 4b9f69751f3c44debf721c7e80adffc7 ""
"graphics/latencycomparison.pdf" 1785767496.10694 20418 cce68df2d0a9cefe2fb78a48a6bd216b ""
"graphics/layer_architecture.pdf" 1785767496.10694 18700 76efc7ba73621fe471df54327abb2b71 ""
@@ -271,22 +245,18 @@
"iso-numeric.cbx" 1681557593 73 45828f8df9dead5135d2c8a727f5b601 ""
"iso.bbx" 1681557593 13233 9f9e9c852fe772bfe1efaacc6b415eb7 ""
"kibase.sty" 1681557593 23853 021ae8236751950ac5e18f6a5bcf1da7 ""
"kidiplom.aux" 1785873458.68234 33845 19588fd7bde7407d19fbd41d8c9fb7b0 "pdflatex"
"kidiplom.bbl" 1785780010.56994 7686 c3cba72138b16e01160647867a8d8f99 "biber kidiplom"
"kidiplom.aux" 1785962472.14966 34312 55704dae1776c65b762a3bfb7e806233 "pdflatex"
"kidiplom.bbl" 1785955982.8259 19352 4ea5a63e4195854fcfe02c3ae7d59df9 "biber kidiplom"
"kidiplom.cls" 1681557593 18598 7684b2d13ac67d7b017c4eea1e12fa0c ""
"kidiplom.glsdefs" 1777655247.6059 525 791a05cd0a9f8650067804d8f5ff3f41 ""
"kidiplom.ind" 1785767496.11494 0 d41d8cd98f00b204e9800998ecf8427e "makeindex kidiplom.idx"
"kidiplom.lot" 1785873458.70607 387 1ac32e7367846a270a0209a5b69d3838 "pdflatex"
"kidiplom.run.xml" 1785873458.70607 2535 4e001a965ee2f4de88dc6271855a61ea "pdflatex"
"kidiplom.tex" 1785873455.29029 129638 c58f042e3489e766c0b8250bfdd4b881 ""
"kidiplom.toc" 1785873458.70607 5374 8623b4d73b23c78b6a1b36c883daab52 "pdflatex"
"kidiplom.lot" 1785962472.17679 851 1e90215e2b35b4b3a868103c86c08a1f "pdflatex"
"kidiplom.run.xml" 1785962472.17679 2535 2737d3f684fc863fcc16a4e0d9d0a735 "pdflatex"
"kidiplom.tex" 1785962470.11264 131748 9018b0f2e3da319eeb87bfa46139a24d ""
"kidiplom.toc" 1785962472.17679 5690 f33555679ec284868227f9912a31c7ca "pdflatex"
(generated)
"kidiplom.acn"
"kidiplom.aux"
"kidiplom.bcf"
"kidiplom.glo"
"kidiplom.idx"
"kidiplom.ist"
"kidiplom.log"
"kidiplom.lot"
"kidiplom.pdf"
+17 -78
View File
@@ -128,70 +128,6 @@ INPUT /usr/share/texmf-dist/tex/generic/iftex/ifpdf.sty
INPUT /usr/share/texmf-dist/tex/generic/iftex/ifpdf.sty
INPUT /usr/share/texmf-dist/tex/latex/base/ifthen.sty
INPUT /usr/share/texmf-dist/tex/latex/base/ifthen.sty
INPUT /usr/share/texmf-dist/tex/latex/savesym/savesym.sty
INPUT /usr/share/texmf-dist/tex/latex/savesym/savesym.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/base/glossaries.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/base/glossaries.sty
INPUT /usr/share/texmf-dist/tex/latex/xkeyval/xkeyval.sty
INPUT /usr/share/texmf-dist/tex/latex/xkeyval/xkeyval.sty
INPUT /usr/share/texmf-dist/tex/generic/xkeyval/xkeyval.tex
INPUT /usr/share/texmf-dist/tex/generic/xkeyval/xkvutils.tex
INPUT /usr/share/texmf-dist/tex/latex/mfirstuc/mfirstuc.sty
INPUT /usr/share/texmf-dist/tex/latex/mfirstuc/mfirstuc.sty
INPUT /usr/share/texmf-dist/tex/latex/xfor/xfor.sty
INPUT /usr/share/texmf-dist/tex/latex/xfor/xfor.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsgen.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsgen.sty
INPUT /usr/share/texmf-dist/tex/latex/supertabular/supertabular.sty
INPUT /usr/share/texmf-dist/tex/latex/supertabular/supertabular.sty
INPUT /usr/share/texmf-dist/tex/latex/tracklang/tracklang.sty
INPUT /usr/share/texmf-dist/tex/latex/tracklang/tracklang.sty
INPUT /usr/share/texmf-dist/tex/generic/tracklang/tracklang.tex
INPUT /usr/share/texmf-dist/tex/generic/tracklang/tracklang.tex
INPUT /usr/share/texmf-dist/tex/generic/tracklang/tracklang.tex
INPUT /usr/share/texmf-dist/tex/generic/tracklang/tracklang.tex
INPUT /usr/share/texmf-dist/tex/generic/tracklang/tracklang.tex
INPUT /usr/share/texmf-dist/tex/latex/translator/translator.sty
INPUT /usr/share/texmf-dist/tex/latex/translator/translator.sty
INPUT /usr/share/texmf-dist/tex/latex/translator/translator.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries-english/glossaries-english.ldf
INPUT /usr/share/texmf-dist/tex/latex/glossaries-english/glossaries-english.ldf
INPUT /usr/share/texmf-dist/tex/latex/glossaries-english/glossaries-english.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool/datatool-base.sty
INPUT /usr/share/texmf-dist/tex/latex/datatool/datatool-base.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsmath.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsmath.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsopn.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amstext.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amstext.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsbsy.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsbsy.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsopn.sty
INPUT /usr/share/texmf-dist/tex/latex/datatool/datatool-l3fp.def
INPUT /usr/share/texmf-dist/tex/latex/datatool/datatool-l3fp.def
INPUT /usr/share/texmf-dist/tex/latex/datatool/datatool-l3fp.def
INPUT /usr/share/texmf-dist/tex/latex/datatool/datatool-utf8.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool/datatool-utf8.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool/datatool-utf8.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool-english/datatool-english.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool-english/datatool-english.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool-english/datatool-english.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool-english/datatool-english-utf8.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool-english/datatool-english-utf8.ldf
INPUT /usr/share/texmf-dist/tex/latex/datatool-english/datatool-english-utf8.ldf
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-hypernav.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-hypernav.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-list.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-list.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-long.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-long.sty
INPUT /usr/share/texmf-dist/tex/latex/tools/longtable.sty
INPUT /usr/share/texmf-dist/tex/latex/tools/longtable.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-super.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-super.sty
INPUT /usr/share/texmf-dist/tex/latex/supertabular/supertabular.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-tree.sty
INPUT /usr/share/texmf-dist/tex/latex/glossaries/styles/glossary-tree.sty
INPUT /usr/share/texmf-dist/tex/latex/lm/lmodern.sty
INPUT /usr/share/texmf-dist/tex/latex/lm/lmodern.sty
INPUT /usr/share/texmf-dist/tex/latex/base/fontenc.sty
@@ -217,9 +153,6 @@ INPUT /usr/share/texmf-dist/tex/latex/csquotes/csquotes.def
INPUT /usr/share/texmf-dist/tex/latex/csquotes/csquotes.cfg
INPUT /usr/share/texmf-dist/tex/latex/csquotes/csquotes.cfg
INPUT /usr/share/texmf-dist/tex/latex/csquotes/csquotes.cfg
OUTPUT kidiplom.glo
OUTPUT kidiplom.acn
OUTPUT kidiplom.idx
INPUT /usr/share/texmf-dist/tex/latex/base/makeidx.sty
INPUT /usr/share/texmf-dist/tex/latex/base/makeidx.sty
INPUT /usr/share/texmf-dist/tex/latex/tools/multicol.sty
@@ -282,6 +215,16 @@ INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang3.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsmath.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsmath.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsopn.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amstext.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amstext.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsgen.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsgen.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsbsy.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsbsy.sty
INPUT /usr/share/texmf-dist/tex/latex/amsmath/amsopn.sty
INPUT /usr/share/texmf-dist/tex/latex/amscls/amsthm.sty
INPUT /usr/share/texmf-dist/tex/latex/amscls/amsthm.sty
INPUT /usr/share/texmf-dist/tex/latex/thmtools/thmtools.sty
@@ -324,6 +267,8 @@ INPUT /usr/share/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
INPUT /usr/share/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
INPUT /usr/share/texmf-dist/tex/latex/lipsum/lipsum.ltd.tex
INPUT /usr/share/texmf-dist/tex/latex/lipsum/lipsum.ltd.tex
INPUT /usr/share/texmf-dist/tex/latex/tools/longtable.sty
INPUT /usr/share/texmf-dist/tex/latex/tools/longtable.sty
INPUT /usr/share/texmf-dist/tex/latex/svg/svg.sty
INPUT /usr/share/texmf-dist/tex/latex/svg/svg.sty
INPUT /usr/share/texmf-dist/tex/latex/koma-script/scrbase.sty
@@ -383,9 +328,6 @@ INPUT /usr/share/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
INPUT /usr/share/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
INPUT /usr/share/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
OUTPUT kidiplom.pdf
INPUT ./kidiplom.glsdefs
INPUT ./kidiplom.glsdefs
INPUT kidiplom.glsdefs
INPUT ./czech-iso.lbx
INPUT ./czech-iso.lbx
INPUT czech-iso.lbx
@@ -469,7 +411,6 @@ INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm7.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmr10.tfm
OUTPUT kidiplom.ist
INPUT /var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ec.enc
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmbx10.tfm
@@ -480,7 +421,6 @@ INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msbm10.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmbx12.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmri12.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmri8.tfm
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ec-lmbx12.tfm
INPUT ./kidiplom.toc
INPUT ./kidiplom.toc
@@ -562,6 +502,11 @@ INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/multi_player_game.pdf
INPUT ./graphics/interpolation.png
INPUT ./graphics/interpolation.png
INPUT ./graphics/interpolation.png
INPUT ./graphics/interpolation.png
INPUT ./graphics/interpolation.png
INPUT ./graphics/quicr_handshake.pdf
INPUT ./graphics/quicr_handshake.pdf
INPUT ./graphics/quicr_handshake.pdf
@@ -629,11 +574,6 @@ INPUT ./graphics/peer_to_peer.pdf
INPUT ./graphics/peer_to_peer.pdf
INPUT ./graphics/peer_to_peer.pdf
INPUT ./graphics/peer_to_peer.pdf
INPUT /usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd
INPUT /usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd
INPUT /usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd
INPUT /usr/share/texmf-dist/fonts/tfm/public/lm/ts1-lmr12.tfm
INPUT /usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ts1.enc
INPUT kidiplom.aux
INPUT kidiplom.run.xml
OUTPUT kidiplom.run.xml
@@ -646,7 +586,6 @@ INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmr17.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmr7.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmr8.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmri12.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmri8.pfb
INPUT /usr/share/texmf-dist/fonts/type1/public/lm/lmsy10.pfb
INPUT /usr/share/texmf-dist/fonts/type1/urw/courier/ucrb8a.pfb
INPUT /usr/share/texmf-dist/fonts/type1/urw/courier/ucrr8a.pfb
+1 -1
View File
@@ -1,5 +1,5 @@
% makeindex style file created by the glossaries package
% for document 'kidiplom' on 2026-8-4
% for document 'kidiplom' on 2026-8-5
actual '?'
encap '|'
level '!'
+560 -731
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -7,3 +7,19 @@
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -41,7 +41,7 @@
>
]>
<requests version="1.0">
<internal package="biblatex" priority="9" active="1">
<internal package="biblatex" priority="9" active="0">
<generic>latex</generic>
<provides type="dynamic">
<file>kidiplom.bcf</file>
@@ -66,7 +66,7 @@
<file>czech-iso.lbx</file>
</requires>
</internal>
<external package="biblatex" priority="5" active="1">
<external package="biblatex" priority="5" active="0">
<generic>biber</generic>
<cmdline>
<binary>biber</binary>
Binary file not shown.
+128 -147
View File
@@ -65,7 +65,7 @@
% tables=false,
% theorems,
% sourcecodes,
glossaries,
% glossaries,
index
]{kidiplom}
@@ -106,11 +106,7 @@
%% práce). Jeden odstavec!
\annotation{V diplomové práci se zabýváme optimalizacemi datového přenosu v distribuovaných systémech. Konkrétně se zaměřujeme na systémy pro hry více hráčů. Analyzujeme a popisujeme jejich problematiku a specifika. Následně představujeme optimalizace, které jsme implementovali. Mezi hlavní části patří náš vlastní protokol transportní vrstvy a vývoj našeho vlastního herního enginu pro implementaci hry pro více hráčů.}
\annotation[english]{Sample text of thesis at the \kitextdepten,
\kitextfacultyen, \kitextuniven{} and, at the same time,
documentation of the \LaTeX{} style for the text. The source text in
\LaTeX{} is recommended to be used as a template for real student's
thesis text.}
\annotation[english]{In this theses we focus on optimization of the data transfer in distributed systems. We focus on systems for multiplayer games. We analyse and describe their issues and specifics. Then we show our implementation of those optimization. Main parts are our own protocol in the transport layer and development of our own game engine to create multiplayer game for showcase.}
\newcommand{\inlcpp}[1]{\kiinlinecode{cpp}{!}{#1}}
@@ -578,17 +574,8 @@ Všimněme si teď různých typů paketů: Initial, Handshake, 0-RTT a 1-RTT. L
\section{Hra}
V této kapitole představíme hru, kterou jsem vyvinuli pro demonstraci různých technik a jejich měření. Ve hře má každý hráč svou postavu, se kterou může volně pohybovat ve 3D prostoru. Hra simuluje na postavách hráčů realistickou fyziku. Pokud se do hry připojí více hráčů, tak se navzájem vidí. Každý hráč spustí program klienta, který zobrazuje stav hry a postavy hráčů v 3D prostoru. V další kapitole porovnáme plynulost pohybu a rychlost odezvy, které jsou pro hratelnost důležité.
V této kapitole představíme hru, kterou jsem vyvinuli pro demonstraci různých technik a jejich měření. Ve hře má každý hráč svou postavu, se kterou může volně pohybovat ve 3D prostoru. Hra simuluje na postavách hráčů realistickou fyziku. Pokud se do hry připojí více hráčů, vidí se navzájem. Každý hráč spustí program klienta, který zobrazuje stav hry a postavy hráčů v 3D prostoru. V této kapitole popíšeme obecnou architekturu hry a našeho enginu. V další kapitole rozšíříme a upravíme tento model pro hru více hráčů. Vytvoříme tak distribuovaný sysm.
V první části popíšeme architekturu hry a našeho enginu. Následně rozšíříme a jinak upravíme tento model pro hru více hráčů. Vytvoříme tak distribuovaný systém.
Naše první implementace využívá model klient-server, kde máme dva různé programy: server a klient. Podrobně popíšeme, které komponenty jsme přidali, které pouze přesunuli do programu serveru a které naopak ponechali v programu klienta.
Mezi hlavní prvky patří náš vlastní komunikační protokol transportní vrstvy: \uv{QUICr}. Je to obousměrný protokol pro posílání zpráv jako n-tic bytů, který se inspiruje protokolem QUIC, ale upravuje ho pro lepší využití pro hry. Náš protokol lépe zachycuje závislosti mezi zprávami a umožňuje i posílat zprávy nespolehlivě. Díky tomu se úplně zbavuje ahead-of-line blokování.
Zjistili jsme, že důležitým vylepšením je vlastní serializace primitivních zpráv. Pokud například obsahuje pouze seznam pozic, může být vlastní serializace rozdíl mezi hratelnou a nehratelnou odezvou. Popíšeme, jak jsme rychlost měřili a jaké metody jsme pro vlastní serializaci použili.
Nakonec představíme i architekturu peer-to-peer, kdy umožníme, aby v systému bylo více spolupracujících serverů, které si mezi sebou budou rozdělovat práci. Zároveň porovnáme i případ, kdy není žádný autoritativní server a hráči se mezi sebou synchronizují samovolně.
\subsection{Engine}
@@ -603,7 +590,7 @@ Pro hru jsme vyvinuli vlastní herní engine tak, abychom mohli celý systém do
% Vstup od hráče -> akce
% Co je herní stav, jak probíhá kolo?
Mezi hlavní komponenty patří \uv{stav} hry a \uv{řídící logika}. Stav obsahuje množinu entit, které jsou ve hře a jejich vlasnosti a atributy. Entity jsou objekty v herním světě, jako postava hráče, nepřátele nebo interaktivní prvky jako truhla s pokladem. Entita má přiřazené vlastnosti, které ji dávají stav. Entita nepřítele může mít vlastnost "množství životů" a truhla vlastnost "poklad", která definuje, co je v truhle obsaženo. Stavu hry se někdy říká pouze \uv{svět}.
Mezi hlavní komponenty patří \uv{stav} hry a \uv{řídící logika}. Stav obsahuje množinu entit, které jsou ve hře, jejich vlasnosti a atributy. Entity jsou objekty v herním světě, jako postava hráče, nepřátele nebo interaktivní prvky, například truhla s pokladem. Entita má přiřazené vlastnosti, které jí dávají stav. Entita nepřítele může mít vlastnost \uv{množství životů} a truhla vlastnost \uv{poklad}, která definuje, co je v truhle obsaženo. Stavu hry se někdy říká pouze \uv{svět}.
@@ -612,14 +599,14 @@ Mezi hlavní komponenty patří \uv{stav} hry a \uv{řídící logika}. Stav obs
% Stav hry reprezentujeme kompletně ve třídě \inlcpp{World}. Ta obsahuje registr z knihovny Entt. Řídící logika je ve třídě \inlcpp{WorldController}. Obsahuje smyčku, která v každé iteraci posbírá vstupy od hráče, převede je na akce a aplikuje je společně s další definovanout logikou. Například v naší hře má vstup: stisknutí klávesy W, definovaný příkaz: \uv{posuň dopředu}, která změní vektor zrychlení hráče. Dalšími prvky, které mění změnu stavu je například fyzický engine, který upravuje zrychlení podle nárazů a nebo vlivů sil, například gravitace.
Druhá část je řídící logika, která iterativně mění stav hry. Tato změna může být pouze na základě stavu světa, například posune objekt, který má nenulový vektor zrychlení. Mimo to může řídící logika reagovat na údalosti. Například stisk tlačítka W je událost, který vyvolá změnu vektoru zrychlení hráče, který tlačítko stiskl. V důsledku toho se postava hráče pohne.
Druhou část tvoří řídící logika, která iterativně mění stav hry. Tato změna může být pouze na základě stavu světa, například posun objektu, který má nenulový vektor zrychlení. Mimo to může řídící logika reagovat na údalosti. Například stisk tlačítka W je událost, který vyvolá změnu vektoru zrychlení hráče, který tlačítko stiskl. V důsledku toho se postava hráče pohne.
Každá iterace řídící logiky trvá přibližně stejně dlouho, většinou 1/60 sekundy nebo 1/24 sekundy. Vyšší frekvence znamená nižší odezvu a lepší plynulost. Nižší frekvence znamená menší výpočetní náročnost. Pro pomalejší hry bez rychlých akčních pasáží se využívá frekvence 24Hz a u kompetentních her i 120Hz
\footnote{Článek od Riot Games ukazuje, jak důležitá je odezva u kompetetivních her. U profesionálních hráčů je poznat i rozdíl mezi 120Hz a 240Hz. https://www.riotgames.com/en/news/peeking-valorants-netcode}.
Každá iterace řídící logiky trvá přibližně stejně dlouho, většinou 1/60 sekundy nebo 1/24 sekundy. Vyšší frekvence znamená nižší odezvu a lepší plynulost. Nižší frekvence znamená menší výpočetní náročnost. Pro pomalejší hry bez rychlých akčních pasáží se využívá frekvence 24Hz a u kompetetivních her i 120Hz
\footnote{Článek\cite{peekingvalorant} od Riot Games ukazuje, jak důležitá je odezva u kompetetivních her. U profesionálních hráčů je poznat i rozdíl mezi 120Hz a 240Hz.}.
\begin{figure}
\begin{center}
\includegraphics[width=0.5\textwidth]{graphics/single_player_game.pdf}
\includegraphics[width=0.8\textwidth]{graphics/single_player_game.pdf}
\end{center}
\caption{Architektura hry pro jednoho hráče}
\label{fig:single_player_game}
@@ -627,25 +614,25 @@ Každá iterace řídící logiky trvá přibližně stejně dlouho, většinou
\subsubsection{Fyzický engine}
Hra je 3D a chtěli jsme simulovat otevřený svět, ve kterém platí zákony fyziky. Pro simulaci jsme využili existující fyzický engine \uv{Jolt} a zabalili ho do modulu. Jolt je populární projekt, který je využíván například v Horizon: Forbidden West nebo Death Stranding 2.
Hra je ve 3D a cílem bylo simulovat otevřený svět, ve kterém platí zákony fyziky. Pro simulaci jsme využili existující fyzický engine \uv{Jolt} a zabalili jej do modulu. Jolt je populární projekt, který je využíván například v Horizon: Forbidden West nebo Death Stranding 2.
Pro použití jsme vytvořili instanci fyzického světa, do kterého naskládáme objekty a jejich vlastnosti, jako hmotnost a tvar. Zavoláním metody pro aktualizaci engine posune stav entit (zrychlení a pozice). Vše jsme obalili do \inlcpp{JoltPhysicsWorld}.
Simulace probíhá nad instancí fyzického světa, do kterého naskládáme objekty a jejich vlastnosti, jako hmotnost a tvar. Zavoláním metody pro aktualizaci engine posune stav entit (zrychlení a pozice). Vše jsme zapouzdřili do \inlcpp{JoltPhysicsWorld}.
Jolt umí využít více vláken procesoru a podporuje \uv{rollback}, který umožňuje vracet stav v historii simulace dozadu. Je to důležitá věc pro hry více hráčů a obecně distribuovaných systémů, pro řešení desynchronizace.
Jolt umí využít více vláken procesoru a podporuje \uv{rollback}, který umožňuje vrátit simulaci do některého z předchozích stavů. To je důležitá věc pro hry více hráčů a obecně distribuovaných systémů pro řešení desynchronizace.
\subsubsection{Vykreslování}
K vykreslování jsme použili náš vlastní engine. Pro vykreslení 3D objektu je potřeba popsat jeho povrch jako množinu polygonů. Této množině se říká \uv{mesh}. Vykreslení jednoho snímku lze v enginu popsat jako graf operací. Běžně bude obsahovat operaci, která seznam mesh vykreslí do obrázku. Tento celý proces lze shrnout jednou operací, protože o celý algoritmus a logiku se stará grafická karta. Vývojář jen popisuje mesh a například jakou má mít barvu apod.
K vykreslování jsme použili náš vlastní engine. Pro vykreslení 3D objektu je potřeba popsat jeho povrch jako množinu polygonů. Této množině se říká \uv{mesh}. Vykreslení jednoho snímku lze v enginu popsat jako graf operací. Běžně bude obsahovat operaci, která seznam mesh vykreslí do obrázku. Tento celý proces lze shrnout jednou operací, protože o celý algoritmus a logiku se stará grafická karta. Vývojář jen popisuje mesh a jeho vlastnosti, například jakou má mít barvu apod.
Mezi operacemi v grafu definujeme závislosti. Díky tomu můžeme definovat operaci, která vykreslí 3D mesh a druhou operaci, která je na ni závislá, a která přes obrázek vykreslí uživatelské rozhraní.
Mezi operacemi v grafu definujeme závislosti. Díky tomu můžeme definovat operaci, která vykreslí 3D mesh a druhou operaci, která je na ní závislá a přes obrázek vykreslí uživatelské rozhraní.
V našem případě máme právě operaci pro vykreslení statických objektů, jako povrchu, po kterém se hráči pohybují apod. Druhá operace vykreslí samotné hráče a jiné dynamické objekty. Poslední operaci vykreslí uživatelské rozhraní obsahující různé nástroje pro různé ladění programu.
V našem případě máme právě k dispozici operaci pro vykreslení statických objektů, jako například povrchu, po kterém se hráči pohybují. Druhá operace vykreslí samotné hráče a jiné dynamické objekty. Poslední operace vykreslí uživatelské rozhraní obsahující různé nástroje pro libovolné ladění programu.
\subsubsection{Entity-Component-System}
V programu využíváme architekturu entity-component-system, zkráceně ECS, která je pro hry běžná. Entity jsme popsali výše. Ke konkrétním entitám vážeme instance komponent, které entitě dají stav. Většinou je komponenta přiřazena právě jedné entitě. Poslední částí jsou systémy, které reprezentují řídící logiku. Systém je definován funkcí, která prochází entity, které splňují definovanou podmínku a mění stav její komponent. Tato podmínka většinou pouze omezuje na entity, které mají přiřazené komponenty pro určité typy. Systém může například simulovat fyziku, a to přičítáním zrychlení k pozici. K tomu definuje podmínku, která procházenou množinu omezí na entity, které mají potřebné komponenty. Těmi jsou komponenta transformace a komponenta zrychlení.
V programu využíváme pro hry běžnou architekturu entity-component-system, zkráceně ECS. Entity jsme již popsali výše. Ke konkrétním entitám vážeme instance komponent, které entitě dají stav. Většinou je komponenta přiřazena právě jedné entitě. Poslední částí jsou systémy, které reprezentují řídící logiku. Systém je definován funkcí, která prochází entity, které splňují definovanou podmínku a mění stav jejich komponent. Tato podmínka se většinou omezuje na entity, které mají přiřazené komponenty pro určité typy. Systém může například simulovat fyziku, a to přičítáním zrychlení k pozici. K tomu definuje podmínku, která procházenou množinu omezí na entity, které mají potřebné komponenty. Těmi jsou komponenta transformace a komponenta zrychlení.
Motivací této architektury je jednoduché skládání různých entit, které jsou pro rozmanité herní světy typické. Pomocí stromu dědičnosti bychom tyto různé scénáře hůře skládali. Další výhoda je zlepšení výkonu. Protože si engine může poskládat entity a jejich komponenty do paměti jak chce, může umístění optimalizovat pro definované systémy tak, aby iterování bylo co nejrychlejší. Tomuto se říká problém lokality.
Motivací této architektury je jednoduché skládání různých entit, které jsou pro rozmanité herní světy typické. Pomocí stromu dědičnosti bychom tyto různé scénáře hůře skládali. Další výhodou je zlepšení výkonu. Protože si engine může poskládat entity a jejich komponenty do paměti jak chce, může umístění optimalizovat pro definované systémy tak, aby iterování bylo co nejrychlejší. Tomuto se říká problém lokality.
@@ -666,7 +653,7 @@ Motivací této architektury je jednoduché skládání různých entit, které
});
\end{kicode}
Pro ECS využíváme knihovnu \uv{Entt}, která usnadňuje definici entit, přiřazování komponent a definici systémů. Entita je v této knihovně pouze unikátně identifikační číslo a komponenta je libovolný typ. V registru pak můžeme vytvářet \uv{pohledy} na n-tici typů komponent, které jsou seznam právě všech entit v registru, které všechny tyto komponenty mají. Ten můžeme procházet a libovolně měnit atributy komponent. Příklad použití vidíme v \ref{code:entt}, kde nejprve vytvoříme registr do kterého přidáme novou entity a přiřadíme ji komponentu typu Transform. Nakonec definujeme pohled na všechny entity, které mají komponentu obou typů: Transform i CharacterBody. Před tento pohled iterujeme a v každé iteraci kopírujeme. Představíme komponenty, které jsme pro hru definovali a proč:
Pro ECS využíváme knihovnu \uv{Entt}, která usnadňuje definici entit, přiřazování komponent a definici systémů. Entita je v této knihovně pouze unikátní identifikační číslo a komponenta je libovolný typ. V registru pak můžeme vytvářet \uv{pohledy} na n-tici typů komponent, které představují seznam právě všech entit v registru, které všechny tyto komponenty mají. Ten můžeme procházet a libovolně měnit atributy komponent. Příklad použití vidíme ve zdrojovém kódu \ref{code:entt}, kde nejprve vytvoříme registr do kterého přidáme novou entitu a přiřadíme jí komponentu typu Transform. Nakonec definujeme pohled na všechny entity, které mají komponentu obou typů: Transform i CharacterBody. Přes tento pohled iterujeme a v každé iteraci kopírujeme. Představíme komponenty, které jsme pro hru definovali a proč:
\begin{description}
@@ -674,7 +661,7 @@ Pro ECS využíváme knihovnu \uv{Entt}, která usnadňuje definici entit, při
Obsahuje transformační matici. Entity, které chceme zobrazit ve světě, tuto komponentu potřebují. Příkladem entity, která ji mít nebude, je zpráva v chatu.
\item[{Mesh}] \hfill \\
Obsahuje mesh, který má hra využít pro vykreslení entity. Mesh je n-tici bodů, které dohromady dávají 3D povrch objektu. Komponenta neobsahuje body, ale pouze odkaz na buffer, ve kterém je najdeme a kde. Systém, který entity vykresluje si vytvoří pohled na Mesh a Transform, protože je potřeba vědět kam entitu vykreslit.
Obsahuje mesh, který má hra využít pro vykreslení entity. Mesh je n-tice bodů, které dohromady dávají 3D povrch objektu. Komponenta neobsahuje body, ale pouze odkaz na buffer, ve kterém jsou uloženy a informaci o jejich umístění. Systém, který entity vykresluje si vytvoří pohled na Mesh a Transform, protože je potřeba vědět kam entitu vykreslit.
\item[{Rigidbody}] \hfill \\
Slouží pro fyzikální informace o entitě, jako hmotnost a zrychlení, které na entitu budeme aplikovat. Systém pro tuto komponentu bude ve fyzickém enginu.
@@ -684,9 +671,9 @@ Pro ECS využíváme knihovnu \uv{Entt}, která usnadňuje definici entit, při
\subsubsection{ImGui}
Některé metriky jsme chtěli zobrazit přímo v klientovi pro hru. Jsou to například příchozí a odchozí množství dat klienta. Tyto data neukládáme nikam do databáze a musíme si je spravovat lokálně. Proto jsme v klientovi potřebovali zobrazit základní uživatelské rozhraní. Zvolili jsme knihovnu ImGui a ImPlot, které se integrují přímo do vykreslovacího enginu. Pro knihovnu jsme přidali jednu novou úlohu do vykreslovacího grafu.
Některé metriky jsme chtěli zobrazit přímo v klientovi pro hru. Jsou to například příchozí a odchozí množství dat klienta. Tyto data neukládáme do databáze, ale musíme si je spravovat lokálně. Proto jsme v klientovi potřebovali zobrazit základní uživatelské rozhraní. Zvolili jsme knihovnu ImGui a ImPlot, které se integrují přímo do vykreslovacího enginu. Pro knihovnu jsme přidali jednu novou úlohu do vykreslovacího grafu.
S knihovnou se pracuje procedurálně, nikoliv objektově. Každý snímek je třeba definovat celé rozhraní znova. Pro definici voláme různé funkce, kde každá definuje v rozhraní některý z možných prvků. Například funkce \inlcpp{InputText} zobrazí vstup pro text. Důležitá je funkce \inlcpp{Begin("Název okna")}, která zobrazí okno, do kterého můžeme vložit další prvky, jako texty, textové vstupy, nebo tlačítka. Tento přístup je pro herní enginy a podobné kreativní aplikace ideální, protože umožňuje velmi snadno a rychle dělat dynamické uživatelské rozhraní.
S knihovnou se pracuje procedurálně, nikoliv objektově. Pro každý snímek je třeba definovat celé uživatelské rozhraní znovu. Pro definici voláme různé funkce, kde každá definuje v rozhraní některý z možných prvků. Například funkce \inlcpp{InputText} zobrazí vstup pro text. Důležitá je funkce \inlcpp{Begin("Název okna")}, která zobrazí okno, do kterého můžeme vložit další prvky, jako texty, textové vstupy, nebo tlačítka. Tento přístup je pro herní enginy a podobné kreativní aplikace ideální, protože umožňuje velmi snadno a rychle dělat dynamické uživatelské rozhraní.
@@ -705,17 +692,17 @@ S knihovnou se pracuje procedurálně, nikoliv objektově. Každý snímek je t
V předchozí části jsme představili základní implementaci hry pro jednoho hráče. V této části ukážeme, jak jsme hru rozšířili na síťový systém a umožnili hru více hráčů. To znamená, že více hráčů se může připojit do stejné instance hry a navzájem spolu interagovat.
Jako první jsme implementovali model klient-server. Diagram systému vidíme na obrázku \ref{fig:multi_player_game}. Stav hry řídí autoritativní server, který ho replikuje klientům posíláním snapshotů. Klient zobrazuje stav hry hráči, stejně jako v případě hry jednoho hráče. Autorita serveru zjednodušuje konzistenci a detekci podvádění. Klienti na server neposílají svůj stav, ale pouze akce, které chtějí provést. Příkladem může být akce pohybu dopředu, kterou vyvolal hráč. Server má možnost akce odmítnout a libovolně interpretovat, protože konečné slovo má právě server. Server rozesílá klientům zprávy zvané snapshoty, které obsahují aktuální stav hry (např. pozice entit) a události pro jednorázové akce (např. událost o konci hry).
Jako první jsme implementovali model klient-server. Diagram systému vidíme na obrázku \ref{fig:multi_player_game}. Stav hry řídí autoritativní server, který ho replikuje klientům posíláním snapshotů. Klient zobrazuje stav hry hráčovi, stejně jako v případě hry jednoho hráče. Autorita serveru zjednodušuje konzistenci a detekci podvádění. Klienti na server neposílají svůj stav, ale pouze akce, které chtějí provést. Příkladem může být akce pohybu dopředu, kterou vyvolal hráč. Server má možnost akce odmítnout a libovolně interpretovat, protože konečné slovo má právě server. Server rozesílá klientům zprávy zvané snapshoty, které obsahují aktuální stav hry (např. pozice entit) a události pro jednorázové akce (např. událost o konci hry).
Druhá varianta je model peer-to-peer. Ta je složitější z hlediska konzistence. Účastníci si mezi sebou posílají akce a každý si udržuje svůj stav, který ale nikomu nereplikuje. Každý se tak chová jako server v modelu klient-server. Je potřeba, aby každý účastník měl kompletní historii akcí všech ostatních v systému ve správném pořadí. Tomuto se říká \uv{event-sourcing}. V případě, že se historie liší, dochází k nekonzistenci.
Druhá komplikace peer-to-peer je, že aplikace stejné akce na stejný stav musí mít vždy stejný výsledek. Pokud by dva procesy ve stejném stavu po aplikaci stejné akce na stav dospěli do jiného stavu, dochází k desynchronizaci. Problémové oblasti jsou generování pseudo-náhodných čísel a integrace. Výsledek integrace je často závislý na frekvenci. Například fyzický engine postupně integruje pozice entit podle derivace, která je reprezentována vektorem zrychlení. Každá integrace musí definovat, o jak velký časový krok se jedná (tzv. delta-time) a všichni účastníci se na něm musejí shodnout. Různé délky by rychle způsobily desynchronizaci. Zároveň všechny pseudonáhodné generátory musejí mít stejný počáteční seed. Je třeba si dát pozor na aritmetriku s plovoucí desetinou čárkou, která na různých platformách může dopadnout trochu jinak. I malé rozdíly se mohou rychle projevit.
Druhá komplikace peer-to-peer je, že aplikace stejné akce na stejný stav musí mít vždy stejný výsledek. Pokud by dva procesy ve stejném stavu po aplikaci stejné akce dospěli do jiného stavu, dochází k desynchronizaci. Problémovou oblastí je generování pseudo-náhodných čísel a integrace. Výsledek integrace je často závislý na frekvenci. Například fyzický engine postupně integruje pozice entit podle derivace, která je reprezentována vektorem zrychlení. Každá integrace musí definovat, o jak velký časový krok se jedná (tzv. delta-time) a všichni účastníci se na něm musejí shodnout. Různé délky by rychle způsobily desynchronizaci. Zároveň všechny pseudonáhodné generátory musejí mít stejný počáteční seed. Je třeba si dát pozor na aritmetriku s plovoucí desetinou čárkou, která na různých platformách může dopadnout odlišně. I malé rozdíly se mohou rychle projevit.
Rozšířenou architekturu vidíme na obrázku \ref{fig:multi_player_game}. Hned si všimneme, že se svět rozdvojil na instanci na serveru a instanci na klientovi. Jsou to právě tyto dvě instance, které se snažíme posíláním zpráv synchronizovat. Řídící logiku jsme rozdělili na Server World Controller a Client World Controller. Všimněme si, že ovladač na klientovi ne nutně obsahuje systémy, které by měnili stav hry, ale pouze kopíruje to, co mu server poslal ve zprávě pro snapshot. Na druhou stranu posílá akce, které přečetl od hráče. Oba ovladače ale zapisují do své instance světa.
Rozšířenou architekturu vidíme na obrázku \ref{fig:multi_player_game}. Hned si všimneme, že se svět rozdvojil na instanci na serveru a instanci na klientovi. Jsou to právě tyto dvě instance, které se snažíme posíláním zpráv synchronizovat. Řídící logiku jsme rozdělili na Server World Controller a Client World Controller. Všimněme si, že ovladač na klientovi nutně neobsahuje systémy, které by měnily stav hry, ale pouze kopíruje to, co mu server poslal ve zprávě pro snapshot. Naopak posílá akce, které přečetl od hráče. Oba ovladače ale zapisují do své instance světa.
\begin{figure}
\begin{center}
\includegraphics[width=0.5\textwidth]{graphics/multi_player_game.pdf}
\includegraphics[width=1\textwidth]{graphics/multi_player_game.pdf}
\end{center}
\caption{Architektura hry pro více hráčů}
\label{fig:multi_player_game}
@@ -724,9 +711,9 @@ Rozšířenou architekturu vidíme na obrázku \ref{fig:multi_player_game}. Hned
\subsection{Server}
Představíme, jak vypadá architektura pro server a komponenty, ze kterých se skládá. Stejně jako hra jednoho hráče si ukládá stav hry, tedy instanci \inlcpp{World}. Navíc pro hru více hráčů jsou komponenty \uv{replikátor}. Ten posílá snapshoty a replikuje tak stav na serveru. Může posílat i jednorázové události.
Představíme, jak vypadá architektura pro server a komponenty, ze kterých se skládá. Stejně jako hra jednoho hráče si ukládá stav hry, tedy instanci \inlcpp{World}. Navíc pro hru více hráčů existuje komponenta \uv{replikátor}. Ta posílá snapshoty a replikuje tak stav na serveru. Může posílat i jednorázové události.
Replikátor pracuje pouze s entitami a komponentami. Proto můžeme snapshot zjednoduššit na seznam entit s komponentami. Dále bude obsahovat seznam entit, které jsou nové a které naopak už mají zmizet. Stará se jen o to, jak tento stav synchronizovat pomocí posílání zpráv.
Replikátor pracuje pouze s entitami a komponentami. Proto můžeme snapshot zjednoduššit na seznam entit s komponentami. Dále bude obsahovat seznam entit, které jsou nové, a seznam entit, které naopak už mají zmizet. Stará se jen o to, jak tento stav synchronizovat pomocí posílání zpráv.
Různé entity na serveru jsou pro některé hráče jinak důležité. Například ty, které jsou daleko, nemusíme synchronizovat, protože po vykreslení by nebyly vidět. Komponenta, která se o to stará je \uv{manažer zájmu}.
@@ -736,7 +723,7 @@ Obě tyto komponenty, společně se stavem a řídící logikou, jsou ve tříd
Komponenta, která spravuje a udržuje spojení s klienty hráčů, se nazývá \uv{registr klientů}. Slouží jako sifon pro všechny zprávy, které klienti odesílají. Zároveň z ní lze zjistit kdo se právě připojil a kdo odpojil. K tomu slouží metody: \inlcpp{popDisconnectedPlayers} a \inlcpp{popConnectedPlayers}. Udržuje seznam nových připojení od posledního zavolání \inlcpp{popConnectedPlayers}.
Třída si u každého klienta hlídá počet po sobě jdoucích selhání. Jakmile počet překročí určitou hranici, např. 5 chyb, relaci s klientem ukončí. Tato komponenty skrývá samotné připojení s klientem a zbytek systému tak odpojení a připojení nemusí řešit. Pro získání seznamu existuje metoda \inlcpp{getClients}.
Třída si u každého klienta hlídá počet po sobě jdoucích selhání. Jakmile počet překročí určitou hranici, např. 5 chyb, relaci s klientem ukončí. Tato komponenta skrývá samotné připojení s klientem a zbytek systému tak odpojení a připojení nemusí řešit. Pro získání seznamu existuje metoda \inlcpp{getClients}.
\subsubsection{Server Replikátoru}
@@ -744,9 +731,9 @@ Komponenta, která se snaží synchronizovat stav klientů s lokálním stavem n
\subsubsection{Správa zájmů}
Komponenta, která řeší důležitost entit pro jednotlivé hráče, je \uv{manažer zájmu}. Důležitost definujeme pro každou dvojici klienta a entity. Manažer zájmu podle definované logiky, například na základě vzdálenosti, určí důležitost entity pro klienta. V základní verzi jsme měli pouze dvě hodnoty: důležitá a nedůležitá. Synchronizovali jsme pouze důležité. Replikátor se dotazuje manažera zájmu v moment, kdy klientovi chce stav synchronizovat.
Komponenta, která řeší důležitost entit pro jednotlivé hráče, je \uv{manažer zájmu}. Důležitost definujeme pro každou dvojici klienta a entity. Manažer zájmu podle definované logiky, například na základě vzdálenosti, určí důležitost entity pro klienta. V základní verzi jsme měli pouze dvě hodnoty: důležitá a nedůležitá. Synchronizovali jsme pouze důležité. Replikátor se dotazuje manažera zájmu v okamžiku, kdy chce klientovi synchronizovat jeho stav.
Dotazu na všechny body, které jsou dostatečně blízko od konkrétního bodu, se říká `range-query`. Datové struktury které tuto operaci akcelerují jsou například fixní mřížka, dynamická mřížka nebo quad-tree.
Dotazu na všechny body, které jsou dostatečně blízko od konkrétního bodu, se říká \uv{range query}. Datové struktury které tuto operaci akcelerují, jsou například fixní mřížka, dynamická mřížka nebo quad-tree.
@@ -758,21 +745,30 @@ Program klienta se skládá z třídy \inlcpp{World}, která reprezentuje stav a
\subsubsection{Klient Replikátoru}
Abychom oddělili to, jak replikátor funguje, vytvořili jsme pro něj na straně klienta ovladač. To nám později umožnilo měnit protokol mezi klientem a server podle potřeby. Komponenta pouze přijme snapshot od serveru, provede autentizaci a pak podle něj změní stav na klientovi.
Abychom oddělili to, jak replikátor funguje, vytvořili jsme pro něj na straně klienta ovladač. To nám později umožnilo měnit protokol mezi klientem a serverem podle potřeby. Komponenta pouze přijme snapshot od serveru, provede autentizaci a pak podle něj změní stav na klientovi.
\subsubsection{Interpolace}
Když jsme začali systém měřit, zjistili jsme, že vysoká frekvence replikace až příliš zatěžuje síť. Graf s průměry pro počet hráčů vidíme na grafu. Snížili jsme proto frekvenci na 20Hz. To snížilo zátěž na třetinu. Hra potom nebyla plynulá. Klient vykresloval s frekvencí 60Hz, ale aktualizace pozice s frekvencí 20Hz způsobily neplynulý pohyb. Řešení je na klientovi interpolovat spojité proměnné, jako pozice nebo rotace.
Když jsme začali systém měřit, zjistili jsme, že vysoká frekvence replikace až příliš zatěžuje síť. Snížili jsme proto frekvenci na 20Hz. To snížilo zátěž na třetinu. Hra potom nebyla plynulá. Klient vykresloval s frekvencí 60Hz, ale aktualizace pozice s frekvencí 20Hz způsobila neplynulý pohyb. Řešení zůstává na klientovi, který může interpolovat\cite{interpolation1} \cite{interpolation2} spojité proměnné, jako je pozice nebo rotace.
\begin{figure}
\begin{center}
\includegraphics[width=1.0\textwidth]{graphics/interpolation.png}
\end{center}
\caption{Graf interpolace}
\label{fig:interpolation}
\end{figure}
Vytvořili jsme novou komponentu \uv{interpolátor}. Ta umožňuje zapsat pozici entity v konkrétní čas. Komponenta si udržuje časovou osu stavu pozice. Zároveň umožňuje číst pozici entity pro konkrétní čas. Pokud je vybraný čas na ose mezi dvěma body, tak vrátí mezi nimi interpolovanou pozici. Pokud je vybraný čas až po posledním známém bodě na ose, tak vrací poslední známou hodnotu.
Změnili jsme objekt, do kterého klient replikátoru zapisuje pozice entit na právě objekt interpolátoru. Do něj zapisuje původní sníženou frekvencí 20Hz. Řídící logika ale může z interpolátoru číst s vyšší frekvencí, například 60Hz. Aby čtecí funkce interpolátoru měla mezi čím interpolovat, není vhodné číst hned nejnovější hodnoty. Lepší je počkat, a interpolovat pozici určitý čas zpět. To má za následek zvýšení odezvy mezi vstupem od hráče a fyzickým posunem postavy hráče. Klient nejprve čeká na odpověď serveru a poté čeká ještě o jednu odpověď navíc. To není problém, pokud takto interpolujeme postavu, kterou neovládá přímo hráč. Rozdíl odezvy pár set milisekund bude zanedbatelný.
Změnili jsme objekt, do kterého klient replikátoru zapisuje pozice entit na právě objekt interpolátoru. Do něj zapisuje původní sníženou frekvencí 20Hz. Řídící logika ale může z interpolátoru číst s vyšší frekvencí, například 60Hz. Aby čtecí funkce interpolátoru měla mezi čím interpolovat, není vhodné číst hned nejnovější hodnoty. Lepší je počkat, a interpolovat pozici určitý čas zpět. To má za následek zvýšení odezvy mezi vstupem od hráče a fyzickým posunem postavy hráče. Klient nejprve čeká na odpověď serveru a poté čeká ještě o jednu odpověď navíc. Na obrázku \ref{fig:interpolation} vidíme graf interpolace. Modré body jsou pozice, které klient dostal od serveru. Zelený graf je plynulá interpolovaná pozice.
\subsubsection{Rollback}
Interpolace zlepšila plynulost, ale nepříjemně zvýšila odezvu mezi vstupem od hráče a vyvolanou změnou stavu. Možným řešením je simulovat řídící logiku i na klientovi, ale pouze pro konkrétní entitu, kterou hráč ovládá. Odezva bude v podstatě nulová.
Vytvořili jsme buffer, do kterého ukládáme konkrétní moment stavu, číslo iterace stavu a seznam akcí, která se v danou iteraci mají aplikovat. Pokud dostaneme snapshot pro snímek $x$ a z bufferu přečteme, jaký byl v iteraci stav. Pokud se neshodují, celý původní stav načteme a opravíme podle snapshotu. Následně znova aplikujeme všechny akce a přepíšeme tak náš buffer, až se dostaneme do aktuální iterace. Poté normálně pokračujeme s opraveným stavem.
Vytvořili jsme buffer, do kterého ukládáme konkrétní moment stavu, číslo iterace stavu a seznam akcí, které se v danou iteraci mají aplikovat. Uvažujme situaci, kdy dostaneme snapshot pro snímek $x$ a zároveň z bufferu přečteme, jaký byl v iteraci stav. Pokud se neshodují, celý původní stav načteme a opravíme podle snapshotu. Následně opět aplikujeme všechny akce a přepíšeme náš buffer, až se dostaneme do aktuální iterace. Poté normálně pokračujeme s opraveným stavem.
@@ -785,13 +781,13 @@ Vytvořili jsme buffer, do kterého ukládáme konkrétní moment stavu, číslo
% Měl by poskytovat možnost, jak posílat zprávy nespolehlivě.
% Zpráva přijde vždy buď celá, nebo vůbec.
V aplikační vrstvě jsme definovali middleware protokol, který umožňuje obousměrné posílání typovaných zpráv. Typ zprávy je definován čtyř bytovým kladným číslem. Protokol jsme umístili do modulu \inlcpp{message_protocol}. Protokol využívá TCP, ale později implementaci změníme tak, aby používal náš protokol. Koncové body v protokolu se chovají jako fronta příchozích a fronta odchozích zpráv. Pro koncový bod můžeme definovat tzv. \uv{dispečer}, definovaný typem zprávy a anonymní funkci, která každou příchozí zprávu tohoto typu zpracuje.
V aplikační vrstvě jsme definovali middleware protokol, který umožňuje obousměrné posílání typovaných zpráv. Typ zprávy je definován čtyř bytovým kladným číslem. Protokol jsme umístili do modulu \inlcpp{message_protocol}. Protokol využívá TCP, ale později implementaci změníme tak, aby používal náš protokol. Koncové body v protokolu se chovají jako fronta příchozích a fronta odchozích zpráv. Pro koncový bod můžeme definovat \uv{dispečer}, definovaný typem zprávy a anonymní funkci, která každou příchozí zprávu tohoto typu zpracuje.
% Popíšeme náš middleware pro posílání zpráv a jeho protokol založený na TCP. Poskytuje službu oboustranného peer-to-peer posílání zpráv na různé koncové body, které jsou identifikované čtyř bytovým číslem. Strana může pro libovolný identifikátor definovat handler, který se po získání takové zprávy spustí. Protokol zajišťuje spolehlivost na úrovni zpráv. To znamená, že zpráva dorazí buď celá, nebo vůbec. Později v kapitole \ref{sec:quicr} představíme náš protokol v transportní vrstvě, který umožňuje posílat zprávy spolehlivě i nespolehlivě.
\subsubsection{Kódování zpráv}
Middleware využívá TCP, které na rozhraní při čtení a zápisu pracuje s proudem bytů, který není logicky rozdělený. Jediné pevné body jsou začátek a konec proudu. UDP na druhou stranu zaručuje, že celý buffer dat odeslaný přes \inlcpp{write} operaci bude přečtený vždy právě jedním voláním \inlcpp{read} operace. Náš protokol definuje oddělení zpráv tak, aby šli v proudu najít.
Middleware využívá TCP, které na rozhraní při čtení a zápisu pracuje s proudem bytů, který není logicky rozdělený. Jediné pevné body jsou začátek a konec proudu. UDP na druhou stranu zaručuje, že celý buffer dat odeslaný přes \inlcpp{write} operaci bude přečtený vždy právě jedním voláním \inlcpp{read} operace. Náš protokol definuje oddělení zpráv tak, aby šly v proudu najít.
První čtyři byty každé zprávy jsou tzv. MAGIC číslo. Konstanta, která nemá jiný význam než záchytný bod při čtení. Dekodér v počátečním stavu hledá v proudu tuto hodnotu. Pokud ji do určitého počtu bytů nenajde, ukončí spojení z důvodu narušení protokolu. Když konstantu najde, přečte další čtyři byty, které reprezentují délku těla a další čtyři byty reprezentující ID koncového bodu.
@@ -810,26 +806,25 @@ Občas mohou nastat v proudu chyby, kdy zprávu nelze dekódovat, nebo nastane c
\subsection{Serializace}
Většinou nechceme používat middleware protokol, který na rozhraní používá n-tice bytů. Lepší je postavit obal, který umožní poslat zprávy reprezentované strukturou. Procesu, který ji převede na n-tici bytů se říká \uv{serializace}. Existují různé knihovny, které umí objekty serializovat. Některé umí serializovat přímo třídy definované v konkrétním programovacím jazyce. Jazyk C++ ale nemá runtime reflexi jako C\# nebo silná makra jako Rust, a tento způsob není možný. Druhá varianta je definovat tyto třídy ve speciálním jazyce pro definici schémat. Před sestavením programu z této definice vygenerujeme třídy v jazyce, který potřebujeme. Do tříd se vygenerují i metody pro serializaci. Tento přístup umožňuje například ProtoBuf, Cap'n'Proto a další. Velká motivace pro použití tohoto přístupu byla možnost reflexe, kterou tyto knihovny umožňují. Další výhoda je pro architekturu orientovanou na služby, kde každá služba je implementována v jiném jazyce, tak nemusíme definice lokalizovat.
Většinou nechceme používat middleware protokol, který na rozhraní používá n-tice bytů. Lepší je postavit obal, který umožní poslat zprávy reprezentované strukturou. Procesu, který ji převede na n~-~tici bytů se říká \uv{serializace}. Existují různé knihovny, které umí objekty serializovat. Některé umí serializovat přímo třídy definované v konkrétním programovacím jazyce. Jazyk C++ ale nemá runtime reflexi jako C\# nebo silná makra jako Rust, a tento způsob není možný. Druhá varianta je definovat tyto třídy ve speciálním jazyce pro definici schémat. Před sestavením programu z této definice vygenerujeme třídy v jazyce, který potřebujeme. Do tříd se vygenerují i metody pro serializaci. Tento přístup umožňuje například ProtoBuf, Cap'n'Proto a další. Velká motivace pro použití tohoto přístupu byla možnost reflexe, kterou tyto knihovny umožňují. Další výhoda je pro architekturu orientovanou na služby, kde každá služba je implementována v jiném jazyce, takže nemusíme definice lokalizovat.
Hned na začátku jsme se rozhodli nepoužít JSON nebo XML, protože jsou to textové formáty a jejich forma je často větší než binárních formátů. Například číslo 1 000 000 se v JSON zakóduje do 7 bytů, i když binární reprezentace stejného čísla se vleze do 4 bytů. Rozdíl je téměř dvojnásobný. Každý atribut objektu se v JSONu reprezentuje řetězcem, namísto identifikačním číslem o 2 bytech, které by bylo menší. Výhody formátu jsou především liberalní zpracování, kdy se schémata dvou koncových bodů mohou i trochu lišit, ale pokud má zpráva všechny potřebné atributy, tak se strany domluví.
Hned na začátku jsme se rozhodli nepoužít JSON nebo XML, protože jsou to textové formáty a jejich forma je často větší než binárních formátů. Například číslo 1 000 000 se v JSON zakóduje do 7 bytů, i když binární reprezentace stejného čísla se vleze do 4 bytů. Rozdíl je téměř dvojnásobný. Každý atribut objektu se v JSONu reprezentuje řetězcem, namísto identifikačním číslem o 2 bytech, které by bylo menší. Výhody formátu jsou především liberalní zpracování, kdy se schémata dvou koncových bodů mohou i mírně lišit, ale pokud má zpráva všechny potřebné atributy, tak se strany domluví.
Binární formáty tuto problematiku také řeší, například číslováním atributů, ale stále není řešení tak volné, jako u textových formátů. Obecně hrozí, že v binárním formátu je atribut navíc, nemusí se druhé straně podařit zprávu deserializovat. Proto se někdy JSON používá jako záložní formát, kdy dvě strany provedou handshake a domluví se na formátu. Pokud zjistí, že jedna strana používá starší definici schématu, mohou použít záložní JSON.
Binární formáty tuto problematiku také řeší, například číslováním atributů, ale stále není řešení tak volné, jako u textových formátů. Obecně hrozí, že když bude ve zprávě v binárním formátu atribut navíc, nemusí se druhé straně podařit zprávu deserializovat. Proto se někdy JSON používá jako záložní formát, kdy dvě strany provedou handshake a domluví se na formátu. Pokud zjistí, že jedna strana používá starší definici schématu, mohou použít záložní JSON.
Rozhodli jsme se začít velmi rozšířeným ProtoBuf formátem. Začneme definicí zpráv mezi serverem a klientem. Vytvořili jsme WorldServerMessages.proto soubor, do kterého budeme zprávy definovat. Trochu formát \inlcpp{.proto} představíme. V kódu \ref{code:entity_spawn_message} vidíme definici zprávy, která říká, že si příjemce má do svého stavu přidat novou entitu. Obsahuje tři atributy: ID pro navázání budoucích zpráv o entitě, příznak, jestli se jedná o hráče a jméno.
Rozhodli jsme se začít velmi rozšířeným ProtoBuf formátem. Začneme definicí zpráv mezi serverem a klientem. Vytvořili jsme WorldServerMessages.proto soubor, do kterého budeme zprávy definovat. Ve zkratce formát \inlcpp{.proto} představíme. V kódu \ref{code:entity_spawn_message} vidíme definici zprávy, která říká, že si příjemce má do svého stavu přidat novou entitu. Obsahuje tři atributy: ID pro navázání budoucích zpráv o entitě, dále příznak, zda se jedná o hráče a jméno.
\begin{kicode}{cpp}{}{cpp}
\begin{kicode}{cpp}{code:entity_spawn_message}{cpp}
message EntitySpawnMessage {
uint32 entity_id = 1;
bool is_player = 2;
string name = 3;
}
\label{code:entity_spawn_message}
\end{kicode}
Jazyk vypadá podobně jako C. Nejprve použijeme klíčové slovo \inlcpp{message} a název typu. Do těla píšeme atributy oddělené středníkem. Všimněme si, že pro každý atribut musíme definovat jeho unikátní číslo. To slouží při identifikaci a pomáhá při úpravách definice, abychom měli kontrolu nad tím, pod jakým klíčem se hodnota serializuje.
FlatBuffers je opět protokol od Googlu, který se vyvýjel pro použití v herních enginech pro hry více hráčů. Jeho výhoda je, že není třeba zprávu "deserializovat". Instanci třídy čte atributy přímo z n-tice bytů. V případě 60 zpráv za vteřinu zprávy od stovek hráčů, je rozdíl mezi deserializací a FlatBuffers znát.
FlatBuffers je opět protokol od Googlu, který se vyvíjel pro použití v herních enginech pro hry více hráčů. Jeho výhoda je, že není třeba zprávu \uv{deserializovat}. Instanci třídy čte atributy přímo z n-tice bytů. V případě 60 zpráv za vteřinu zprávy od stovek hráčů, je rozdíl mezi deserializací a FlatBuffers znát.
Posledním příkladem je Cap'n'Proto, čteno Captain Proto. Je to volně dostupný protokol, který nemá deserializaci, a je tak velmi rychlý. Jeho tvůrce navíc pracoval právě na ProtoBuf.
@@ -848,16 +843,16 @@ Naše hra používala ke komunikaci mezi vrcholy protokol TCP. Zmínili jsme ale
Upustili jsme od QUIC paketů a definovali jsme právě jeden typ, který má v hlavičce ID příjemce a ID odesílatele. Každý paket obsahuje rámce. Rámce jsme také rozdělili na dva typy: datové a ovládací. Ovládací slouží pro handshake, ukončení spojení nebo nastavení jiných parametrů spojení a budou vždy doručené spolehlivě. Datové rámce obsahují aplikační data a mohou definovat svou spolehlivost. Ty, které budou obsahovat pozice hráčů, tak budeme moct odesílat nespolehlivě, zatímco změny stavu, jako změna barvy postavy, posíláme spolehlivě. Implementace se skládá ze dvou tříd: \uv{koncový bod} a \uv{spojení}.
Objekt navázaného spojení je stavový stroj a fronta příchozích a fronta odchozích zpráv, podobně jako TCP spojení. Stavy se mění v reakci na příchozí ovládací rámce. Každý objekt spojení má přiřazeno alespoň jedno ID reprezentované osmi bytovým číslem. Tento objekt přímo nepracuje se socketem, ale poskytuje rozhraní, kterým dostává získané zprávy, které odeslala druhá strana. Právě tento objekt překládá n-tici bytů na rámce a postupně je zpracovává. Stavový stroj je důležitý hlavně v procesu handshake, který definujeme níže.
Objekt navázaného spojení je stavový stroj a fronty příchozích a odchozích zpráv, podobně jako TCP spojení. Stavy se mění v reakci na příchozí ovládací rámce. Každý objekt spojení má přiřazeno alespoň jedno ID reprezentované osmi bytovým číslem. Tento objekt přímo nepracuje se socketem, ale poskytuje rozhraní, kterým dostává získané zprávy, které odeslala druhá strana. Právě tento objekt překládá n-tici bytů na rámce a postupně je zpracovává. Stavový stroj je důležitý hlavně v procesu handshake, který definujeme níže.
Objekt pro koncový bod se stará o soket pro UDP: čtení a zápis na něj, a udržuje si registr objektů spojení. Při získání datagramu ze socketu ověří, že má správný formát. Podle protokolu by každý datagram měl obsahovat hlavičku s magickým číslem a ID spojení. Koncový bod přečte ID spojení a podle svého registru vyhledá objekt spojení, kterému tělo zprávy předá. Pokud v registru klíč pro získané ID není, koncový bod si objekt spojení vytvoří v počátečním stavu a začíná proces zvaný handshake. Tento proces popíšeme v podkapitole \ref{sec:quicr_handshake}.
Objekt pro koncový bod se stará o soket pro UDP: čtení a zápis na něj, a udržuje si registr objektů spojení. Při získání datagramu ze socketu ověří, že má správný formát. Podle protokolu by každý datagram měl obsahovat hlavičku s magickým číslem a ID spojení. Koncový bod přečte ID spojení a podle svého registru vyhledá objekt spojení, kterému předá tělo zprávy. Pokud v registru není klíč získaného ID, koncový bod si objekt spojení vytvoří v počátečním stavu a začíná proces zvaný handshake. Tento proces popíšeme v podkapitole \ref{sec:quicr_handshake}.
Nechtěli jsme, aby si implementace QUICr spravovala vlastní asynchronní kontext. Namísto toho jsme definovali metodu pro aktualizaci, která posbírá zprávy od jednotlivých navázaných spojení a pošle je. Následně přečte všechna data ze soketu a roztřídí je do navázaných spojení.
\subsubsection{Rámce}
Hlavním prvkem datového přenosu v protokolu jsou rámce. Jak už bylo nastíněno, dělíme je na kontrolní a datové. Pro využití nespolehlivosti jsme u každého datového rámce umožňili definovat, jestli je spolehlivý nebo nespolehlivý. O spolehlivost obecně se stará komponenta \inlcpp{ReliabilityUnit}, kterou podpobněji představíme v kapitole \ref{sec:quicr_reliability}.
Hlavním prvkem datového přenosu v protokolu jsou rámce. Jak už bylo nastíněno, dělíme je na kontrolní a datové. Pro využití nespolehlivosti jsme u každého datového rámce umožňili definovat, jestli je spolehlivý nebo nespolehlivý. O spolehlivost se obecně stará komponenta \inlcpp{ReliabilityUnit}, kterou podpobněji představíme v kapitole \ref{sec:quicr_reliability}.
Rámec je n-tice bytů, která se skládá z hlavičky a těla. V hlavičce máme ID cílového spojení a ID počátečního spojení.
@@ -870,7 +865,7 @@ Rámec je n-tice bytů, která se skládá z hlavičky a těla. V hlavičce mám
\subsubsection{Handshake} \label{sec:quicr_handshake}
Objekt navázaného spojení obsahuje stavový stroj a postupně mezi stavy přechází. Počáteční stav je \inlcpp{Closed}. Jedna strana musí začít a odeslat paket s \inlcpp{Hello} rámcem. Po obdržení se stavový stroj druhé strany přesune do \inlcpp{ReceivedHello} a spolehlivě odešle \inlcpp{Hello}. Když strana dostane rámec \inlcpp{Hello} tak ví, že v hlavičce paketu je cílové i lokální ID. Proto už touto výměnou se strany shodli na ID navázaného spojení, které budou používat. Poté už si vymění rámec \inlcpp{HandshakeDone} a spojení je navázané a připravené k posílání.C elý stavový diagram vidíme na obrázku \ref{fig:quicr_handshake}.
Objekt navázaného spojení obsahuje stavový stroj a postupně mezi stavy přechází. Počáteční stav je \inlcpp{Closed}. Jedna strana musí začít a odeslat paket s \inlcpp{Hello} rámcem. Po obdržení se stavový stroj druhé strany přesune do \inlcpp{ReceivedHello} a spolehlivě odešle \inlcpp{Hello}. Jakmile strana dostane rámec \inlcpp{Hello} tak ví, že v hlavičce paketu je cílové i lokální ID. Proto set už touto výměnou strany shodly na ID navázaného spojení, které budou používat. Poté už si vymění rámec \inlcpp{HandshakeDone} a spojení je navázané a připravené k posílání. Celý stavový diagram vidíme na obrázku \ref{fig:quicr_handshake}.
% Nové připojení projde všechny rámce v paketu. Měl by narazit na rámec Hello, který když najde, a je ve stavu `Initial`, tak z hlavičky zjistí unikátní ID druhé strany a uloží si ho. Reaguje na rámec tak, že druhé straně odešle přes koncový bod paket, který obsahuje: rámec ACK o tom, že paket s číslem přijal, a rámec Hello. ACK si pro začátek představme zakódovaný jako: první 4 byty reprezentují kladné celé číslo pro počet rámců, řekněme $n$, které chceme označit jako přijaté. Následně přečteme $4n$ bytů. Každé 4 byty představují číslo paketu, který označíme jako ACKed. Jednotce, která udržuje stav o tom, jaké pakety jsou potřeba oznámit jako ACK a které je třeba poslat znovu, budu říkat `RealiabilityUnit` a podrobněji ji rozeberu později.
@@ -879,16 +874,16 @@ Objekt navázaného spojení obsahuje stavový stroj a postupně mezi stavy pře
\begin{description}
\item[{Closed}] \hfill \\
Počátečním stavem je `Closed`. Zároveň se jedná o stav, do kterého se spojení dostane, pokud dlouho s druhou stranou nekomunikuje.
Počátečním stavem je \inlcpp{Closed}. Zároveň se jedná o stav, do kterého se spojení dostane, pokud dlouho s druhou stranou nekomunikuje.
\item[{SentHello}] \hfill \\
Po odeslání \texttt{Hello} rámce se spojení dostane do stavu \texttt{SentHello}. V tomto stavu čeká na \texttt{Hello} rámec od druhé strany.
Po odeslání \inlcpp{Hello} rámce se spojení dostane do stavu \inlcpp{SentHello}. V tomto stavu čeká na \inlcpp{Hello} rámec od druhé strany.
\item[{ReceivedHello}] \hfill \\
Jakmile strana dostane rámec \texttt{Hello}, přejde do stavu \texttt{ReceivedHello}. V ten moment čeká na potvrzení, že spojení bylo navázáno, tedy rámec \texttt{HandshakeDone}.
Jakmile strana dostane rámec \inlcpp{Hello}, přejde do stavu \inlcpp{ReceivedHello}. V ten moment čeká na potvrzení, že spojení bylo navázáno, tedy rámec \inlcpp{HandshakeDone}.
\item[{Established}] \hfill \\
Po odeslání HandshakeDone zprávy se klient dostane do stavy Established. Jakmile server přijme zprávu HandshakeDone, taky se dostává do stavu Established.
Po odeslání \inlcpp{HandshakeDone} zprávy se klient dostane do stavu \inlcpp{Established}. Jakmile server přijme zprávu \inlcpp{HandshakeDone}, taky se dostává do stavu \inlcpp{Established}.
\end{description}
@@ -906,7 +901,7 @@ Objekt navázaného spojení obsahuje stavový stroj a postupně mezi stavy pře
O spolehlivost doručení se protokol stará posíláním \inlcpp{Ack} rámců s číslem paketu, který získal. Navíc ale rozlišujeme spolehlivost na základě jednotlivých rámců. Pokud paket neobsahuje žádný spolehlivý rámec, nemusí pro něj příjemce posílat \inlcpp{Ack} rámec. Protokol v tento moment neřeší spolehlivost pořadí paketů. V našem případě posíláme například akce z klienta na server a u každé definujeme číslo snímku. Server si udržuje nejvyšší číslo snímku, které dostal, a všechny zprávy z nižších snímků zahazuje. Stejně to dělá klient se snapshoty. Proto neřešíme pořadí na transportní vrstvě.
Spolehlivost řeší komponenta \inlcpp{ReliabilityUnit}, která si udržuje frontu rámců, které je potřeba odeslat, čas, kdy je potřeba rámec odeslat a jejich spolehlivost. Čas slouží pouze pro prioritu a málokdy se stane, že se rámec odešle právě v tento čas. Objekt \inlcpp{QuicrEndpoint} se při ťiku dotazuje \inlcpp{QuicrConnection} na další datagram, který chce odeslat. Ten pomocí \inlcpp{ReliabilityUnit} začne datagram skládat z paketů. Když přijde rámec na řadu a je spolehlivý, hned se umístí na konec fronty a nastaví se mu čas odeslání. Většinou aktuální čas s přičteným konstantním intervalem. Pokud je nespolehlivý, do fronty se nevrátí. Krátce představíme rozhraní \inlcpp{ReliabilityUnit} objektu.
Spolehlivost řeší komponenta \inlcpp{ReliabilityUnit}, která si udržuje frontu rámců, které je potřeba odeslat, čas, kdy je potřeba rámec odeslat a jejich spolehlivost. Čas slouží pouze pro prioritu a málokdy se stane, že se rámec odešle právě v tento čas. Objekt \inlcpp{QuicrEndpoint} se při aktualizaci dotazuje \inlcpp{QuicrConnection} na další datagram, který chce odeslat. Ten pomocí \inlcpp{ReliabilityUnit} začne datagram skládat z paketů. Když přijde rámec na řadu a je spolehlivý, hned se umístí na konec fronty a nastaví se mu čas odeslání. Většinou aktuální čas s přičteným konstantním intervalem. Pokud je nespolehlivý, do fronty se nevrátí. Krátce představíme rozhraní \inlcpp{ReliabilityUnit} objektu.
\begin{description}
@@ -914,10 +909,10 @@ Spolehlivost řeší komponenta \inlcpp{ReliabilityUnit}, která si udržuje fro
Uloží si zakódovaný rámec a nastaví si u něj čas odeslání. Jakmile bude po deadline, jednotka se bude snažit dostat rámec do dalšího datagramu. Rámec se ukládá v zakódované podobě tak, aby byla předpovídatelná jeho velikost a snadno se odhadovalo, jestli se do dalšího datagramu vleze.
\item[\texttt{peek/pop\_reliable\_frames\_to\_send(packet\_number)}] \hfill \\
Vrátí rámce, které je potřeba v tomto okamžiku odeslat. Číslo paketu \texttt{packet\_number} si jednotka přiřadí jako verifikátor doručení rámce, který metoda vrátí. To znamená, že když toto číslo přijde v \texttt{Ack} rámci, bude jednotka vědět, který rámec může odebrat. Zároveň může mít vícero vazeb čísla paketu na jeden rámec. Libovolné číslo paketu smaže provázaný rámec. Důvod je, aby mohlo být v oběhu více paketů se stejným rámcem.
Vrátí rámce, které je potřeba v tomto okamžiku odeslat. Číslo paketu \inlcpp{packet\_number} si jednotka přiřadí jako verifikátor doručení rámce, který metoda vrátí. To znamená, že když toto číslo přijde v \inlcpp{Ack} rámci, bude jednotka vědět, který rámec může odebrat. Zároveň může mít vícero vazeb čísla paketu na jeden rámec. Libovolné číslo paketu smaže provázaný rámec. Důvod je, aby mohlo být v oběhu více paketů se stejným rámcem.
\item[\texttt{push\_ack(packet\_number)}] \hfill \\
Vloží do seznamu čísel paketů. Celý tento seznam se odešle v \texttt{Ack} rámci v dalším datagramu.
Vloží do seznamu čísel paketů. Celý tento seznam se odešle v \inlcpp{Ack} rámci v dalším datagramu.
\item[\texttt{peek/pop\_acks\_to\_send()}] \hfill \\
Vrátí seznam čísel paketů, které musí druhé straně oznámit jako doručené.
@@ -975,7 +970,7 @@ Při implementaci jsme zjistili, že je dobré začít testy, které definují j
\subsection{Horizontální škálování}
Při nárustu počtu hráčů už nemusí stačit jeden výpočetní server. Poté je nutné využít výkon více počítačů technikou zvanou \uv{horizontální škálování}. To znamená, že do systému přidáváme servery, které si tak rovnoměrně rozdělí práci. V případě naší hry jsme rozdělili herní svět na zóny a o každou se stará jiný server. Takový server je \uv{zone server} a dohromady tvoří \uv{zone cluster}. Do systému jsme dále přidali \uv{cluster koordinátora}, který říká, který zone server má jakou zónu. Model mezi koordinátorem a zone serverem je klient-server. Na druhou stranu zone servery mezi sebou komunikují přímo a využívají model peer-to-peer.
Při nárustu počtu hráčů už nemusí stačit jeden výpočetní server. Poté je nutné využít výkon více počítačů zároveň technikou zvanou \uv{horizontální škálování}. To znamená, že do systému přidáváme servery, které si tak rovnoměrně rozdělí práci. V případě naší hry jsme rozdělili herní svět na zóny a o každou se stará jiný server. Takový server je \uv{zone server} a dohromady tvoří \uv{zone cluster}. Do systému jsme dále přidali \uv{cluster koordinátora}, který říká, který zone server má jakou zónu. Model mezi koordinátorem a zone serverem je klient-server. Na druhou stranu zone servery mezi sebou komunikují přímo a využívají model peer-to-peer.
Představíme, jak spolu zone servery komunikují. Využijeme k tomu už existující komponenty: replikátor a manažera zájmu. Nejprve jsme stav hry, manažera zájmu a fyzický svět do třídy \inlcpp{ZoneManager}. Tuto třídu obalíme \inlcpp{ZoneServer} třídou. Ta bude obsahovat replikátor a \inlcpp{ZoneCoordinatorClient}. Manažer zón si bude udržovat registr sousedních zón a bude se k ním chovat jako klasickým klientům. Rozdíl bude ten, že klient má jako zájem definovaný pouze bod a manažer zájmu klientovi přiřadí do zájmu entity, které jsou od bodu v dostatečné vzdálenosti. Sousedi budou mít jako zájem definovanou celou jejich plochu. Manažer zájmu má nyní na rozhraní dvě metody: \inlcpp{register\_client\_interest(interest\_id, entity)} a \inlcpp{register\_zone\_interest(interest\_id, area)}. Každý zájem je definovaný unikátním ID. O to, jaké entity pak konkrétní zájem zajímají získáme voláním \inlcpp{get_interest(interest_id)}.
@@ -986,8 +981,8 @@ Systémovou architekturu vidíme na obrázku \ref{fig:zone_cluster_architecture}
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/zone_server_architecture.pdf}
\label{fig:zone_cluster_architecture}
\caption{Architektura systému s zone clusterem}
\label{fig:zone_cluster_architecture}
\end{figure}
@@ -995,17 +990,18 @@ Systémovou architekturu vidíme na obrázku \ref{fig:zone_cluster_architecture}
\subsection{Výsledná hra}
V této části výslednou hru popíšeme. Po spuštění klienta dostaneme možnost zadat IP adresu serveru. V tento moment je aplikace ve stavu \inlcpp{lobby}. Hlavní třída, která řídí chod včetně nekonečné smyčky, se nazývá \inlcpp{Runtime}. Ta se chová jako stavový stroj a umožňuje stavům vracet zprávy, podle kterých mezi stavy přechází. Po kliknutí na \uv{connect} se klient pokusí připojit na server.
V této části výslednou hru popíšeme. Po spuštění klienta dostaneme možnost zadat IP adresu serveru. Obrazovku vidíme na obrázku \ref{fig:lobby_ui}. V tento moment je aplikace ve stavu \inlcpp{lobby}. Po připojení hra přejde do stavu \inlcpp{game}. Hlavní třída, která řídí chod stavového stroje se nazývá \inlcpp{Runtime}. Chová jako stavový stroj a umožňuje stavům vracet zprávy, podle kterých mezi stavy přechází.
V případě že uspěje, přejde \inlcpp{Runtime} do stavu \inlcpp{game}. V něm už vidíme stav hry a uživatelské rozhraní, které se skládá z oken. Okna je možné skládat do sebe. TODO: Otevírání různých oken pro přehlednost.
Po kliknutí na \uv{connect} se klient pokusí připojit na server. V případě že uspěje, přejde \inlcpp{Runtime} do stavu \inlcpp{game}. V něm už vidíme stav hry a uživatelské rozhraní. Ve hře je možné se volně pohybovat pomocí kláves W, A, S a D. Další připojení hráči jsou vidět jako červené kostky. Pro zátěžové testování je možné použít program \inlcpp{tw_mock_client}, který umožňuje připojit a simulovat určitý počet entit specifikovaný CLI argumentem. Náš hráč se pohybuje téměř okamžitě po stisku klávesy. Ostatní hráče vidíme s odezvou, která závisí na síťových podmínkách.
V horní části okna vidíme panel s možností \uv{Windows}, která po rozkliknutí zobrazí okna, která lze otevřít. Příklad je okno pro síťové statistiky, které zobrazuje různé sbírané metriky, jako odchozí a příchozí množství bitů. Dalším užitečným oknem je seznam entit ve hře. Po rozkliknutí entity vidíme komponenty a informace k nim. Například transformační matici nebo interpolační buffer. Otevřená okno pro seznam entit a síťové statistiky vidíme na obrázku \ref{fig:ui_showcase}.
Po připojení je možné se volně pohybovat pomocí WASD. Do hry se může připojit více hráčů. Například je možné použít program \inlcpp{tw_mock_client}.
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/lobby_ui.png}
\label{fig:lobby_ui}
\caption{Uživatelské rozhraní v lobby}
\label{fig:lobby_ui}
\end{figure}
\begin{figure}
@@ -1019,27 +1015,27 @@ Po připojení je možné se volně pohybovat pomocí WASD. Do hry se může př
\newpage
\section{Měřění}
V této kapitole popíšeme, jaké testy jsme provedli a jejich výsledky. Nejprve představíme jak samotné metriky můžeme sbírat. Implementovali jsme jednoduchý systém pro sběr metrik, který je schopný je různě agregovat do oken dlouhých například jednu sekundu. Data jsme různě vizualizovali ve webovém rozhraní, tak i přímo v aplikaci klienta.
V této kapitole popíšeme, jaké testy jsme provedli a jejich výsledky. Nejprve představíme jak samotné metriky můžeme sbírat. Implementovali jsme jednoduchý systém pro sběr metrik, který je schopný je různě agregovat do oken dlouhých například jednu sekundu. Data jsme různě vizualizovali jak ve webovém rozhraní, tak i přímo v aplikaci klienta.
\subsection{Metriky}
Představíme metody měřění a metriky v systému, které jsme využili pro hledání potenciálních míst pro optimalizaci. Problém jde rozdělit na tří úlohy: jak metriky sbírat, jak je ukládat a jak je zobrazit. Pro sběr jsme definovali třídy \inlcpp{NetworkMetricsReporter}, který obsahuje metody pro přidávání nových vzorků a různé možnosti čtení daných metrik. Každá lze přečíst jako celá série s určitou historií. Příkladem metod jsou \inlcpp{report\_outbound} a \inlcpp{get\_outbound}.
Implementace si data ukládá pouze do paměti RAM a po ukončení programu jsou nenávratně ztracena. Druhý problém šel ale řešit i perzistentně. Existují databáze, které jsou pro rychlé vkládání vzorků s časovou známkou vhodné. Mezi využití takových databází patří logy nebo právě metriky. Náš výběr představíme.
Implementace si data ukládá pouze do paměti RAM a po ukončení programu jsou nenávratně ztracena. Druhý problém lze řešit i perzistentně. Existují databáze, které jsou pro rychlé vkládání vzorků s časovou známkou vhodné. Mezi využití takových databází patří logy nebo právě metriky. Náš výběr představíme.
Nakonec zbývalo metriky zobrazit. Rozhodli jsme se použít webové rozhraní pro rychlou inspekci stavu. Umožní rychle se podívat na množství hráčů nebo velikost datového toku. Metriky, které sbírá klient, zobrazujeme přímo v klientovi. Obě řešení ukážeme.
\subsubsection{PostgreSQL}
Pro perzistentní úložiště jsme vybrali populární relační databázový server PostgreSQL. Rozhodli jsme se právě pro ten, protože je to otevřený a svobodný software, který je zdarma. Databázi si lze snadno nasadit lokálně, ať už daemoném nebo jako Docker kontejner. Skrze rozšíření jako TimescaleDB lze přidat optimalizace pro rychlé vkládání dat o metrikách.
Pro perzistentní úložiště jsme vybrali populární relační databázový server PostgreSQL. Rozhodli jsme se tak, protože jde o otevřený a svobodný software, který je zdarma. Databázi si lze snadno nasadit lokálně, ať už daemoném nebo jako Docker kontejner. Skrze rozšíření jako TimescaleDB lze přidat optimalizace pro rychlé vkládání dat o metrikách.
\subsubsection{TimescaleDB}
Pro optimalizaci PostgreSQL pro časová data jsme zvolili TimescaleDB. Díky tomu, že se jedná o rozšíření, nemusíme spravovat jinou službu, než PostgreSQL. TimescaleDB umožňuje vytvářet \uv{hypertables}, které jsou rychlé vkládání optimalizované. Vytvořili jsme komponentu \inlcpp{TimescaleDbMetricsWriter}, která čte z \inlcpp{NetworkMetricsReporter} a postupně zapisuje metriky do databáze. Jedná se o konkrétní implementace pro TimescaleDB. Komponenty jsou tak oddělené a snadno lze přidat rozšíření pro další typy úložišť, jako CSV nebo jiný databázový server.
Pro optimalizaci PostgreSQL pro časová data jsme zvolili TimescaleDB. Díky tomu, že se jedná o rozšíření, není třeba spravovat jinou službu, než PostgreSQL. TimescaleDB umožňuje vytvářet tzv. \uv{hypertables}, které jsou optimalizované pro rychlé vkládání dat s časovou známkou\cite{timescaledb}. Vytvořili jsme komponentu \inlcpp{TimescaleDbMetricsWriter}, která čte z \inlcpp{NetworkMetricsReporter} a postupně zapisuje metriky do databáze. Jedná se o konkrétní implementaci pro TimescaleDB. Komponenty jsou tak oddělené a snadno lze přidat rozšíření pro další typy úložišť, jako CSV nebo jiný databázový server.
\subsubsection{Grafana}
Grafana je služba, která skrze webovou stránku poskytuje rozhraní pro vizualizaci metrik. Lze nastavit svůj dashboard a v něm různé grafy. Pro naše účely jsme vytvořili grafy pro odchozí a příchozí množství bytů. Služba slouží spíše pro sledování stavu a neumožňuje pokročilejší analýzu. Na obrázku \ref{fig:grafana} vidíme tři grafy. Horní graf ukazuje více metrik najednou, konkrétně množství odchozích a příchozích dat a počet hráčů. V tomto konkrétním případě jsme připojili 300 hráčů. Vidíme, že množství příchozích a odchozích dat se zvýšil. Množství odchozích dat se zvýšil očekávaně daleko více.
Grafana je služba, která skrze webovou stránku poskytuje rozhraní pro vizualizaci metrik. Lze nastavit vlastní dashboard a v něm různé grafy. Pro naše účely jsme vytvořili grafy pro odchozí a příchozí množství bytů. Služba slouží spíše pro sledování stavu a neumožňuje pokročilejší analýzu. Na obrázku \ref{fig:grafana} vidíme tři grafy. Horní graf ukazuje více metrik najednou, konkrétně množství odchozích a příchozích dat a počet hráčů. V tomto konkrétním případě jsme připojili 300 hráčů. Vidíme, že množství příchozích a odchozích dat se zvýšil. Množství odchozích dat se zvýšil očekávaně daleko více.
\begin{figure}
\begin{center}
@@ -1051,9 +1047,9 @@ Grafana je služba, která skrze webovou stránku poskytuje rozhraní pro vizual
\subsubsection{Tracy}
Pro měření a pokročilejší analýzu výkonu programu klienta nebo serveru používáme profiler Tracy. Program je zdarma, open-source, napsaný v C++ a pro vykreslování UI využívá ImGui. Poskytuje přesnost na nanosekundy, což je užitečné u serverů, na kterém může být miliony různých entity. Navíc umožňuje připojit se k programu, který měří, vzdáleně. Případně sbírat metriky do souboru, ten si ze serveru stáhnout a analyzovat později.
Pro měření a pokročilejší analýzu výkonu programu klienta nebo serveru používáme profiler Tracy. Program je zdarma, open-source, napsaný v C++ a pro vykreslování UI využívá ImGui. Poskytuje přesnost na nanosekundy, což je užitečné u serverů, na kterém může být miliony různých entity. Navíc umožňuje připojit se k měřícímu programu vzdáleně. Případně je možné sbírat metriky do souboru, ten si ze serveru stáhnout a analyzovat později.
V kódu umožňuje definovat jednotlivé iterace řídící logiky zvané snímky. Následně umožňuje definovat tzv. \uv{zóny}, které následně měří. Zóna může být průběh funkce nebo její konkrétní část. Na obrázku \ref{fig:frame_in_tracy} vidíme, jak taková analýza vypadá. Vidíme právě jeden snímek. V něm máme označené části replikátoru a manažera zájmu. Také vidíme dole zóny.
V kódu umožňuje definovat jednotlivé iterace řídící logiky zvané snímky. Následně umožňuje definovat tzv. \uv{zóny}, které poté měří. Zóna může být průběh funkce nebo její konkrétní část. Na obrázku \ref{fig:frame_in_tracy} vidíme, jak taková analýza vypadá. Vidíme právě jeden snímek. V něm máme označené části replikátoru a manažera zájmu. V dolní části také vidíme zóny.
\begin{figure}
\begin{center}
@@ -1085,7 +1081,7 @@ Přímo v hráčově klientské aplikaci jsme chtěli mít možnost vidět metri
\subsection{QUICr}
Protokol měl za cíl snížit odezvu na nespolehlivé síti a neblokovat zprávy. Vytvořili jsme test, který simuluje program hry. V testu jsou dvě vlákna, jedno pro klienta a druhé pro server. Oba mají svou vlastní smyčku, ve kterém iterují. Klient odesílá hodnotu derivace typu double. Server si udržuje stav hodnoty, nazvěme ji \uv{pozice}. Při obdržení derivace ji přičte k aktuálnímu stavu. Každý snímek server odesílá na klienta stav pozice, kterou si klient aplikuje.
Protokol měl za cíl snížit odezvu na nespolehlivé síti a neblokovat zprávy. Vytvořili jsme test, který simuluje program hry. V testu jsou dvě vlákna, jedno pro klienta a druhé pro server. Oba mají svou vlastní smyčku, ve které iterují. Klient odesílá hodnotu derivace typu double. Server si udržuje stav hodnoty, nazvěme ji \uv{pozice}. Při obdržení derivace ji přičte k aktuálnímu stavu. V každém snímku odesílá server klientovi stav pozice, kterou si klient aplikuje.
Pro nasimulování nespolehlivosti sítě jsme využili Linuxový nástroj \uv{tc}. Ten obsahuje \uv{network emulator} s různými nastaveními spolehlivosti sítě. Například kolik procent paketů má ztratit, jaká má být odezva nebo jak moc náhodné bude pořadí paketů. Budeme simulovat odezvu 200 milisekund s rozptylem 20ms, ztrátu 3\% paketů a 1\% paketů bude duplikovaných. Celý příkaz pro nastavení můžeme vidět v příkladu \ref{kod:tc}. Vidíme, že používáme pouze rozhraní \inlcpp{lo}, tedy loopback, které se týká posílání mezi programy na lokální adrese.
@@ -1107,7 +1103,7 @@ Pro nasimulování nespolehlivosti sítě jsme využili Linuxový nástroj \uv{t
\label{fig:latencycomparison}
\end{figure}
V prvním testu jsme pouze měřili odezvu mezi odesláním vstupu od klienta pro snímek $n$ a získáním jeho integrovaného stavu ze serveru. Na obrázku \ref{fig:latencycomparison} vidíme, že TCP obsahuje skoky a QUICr je stabilnější.
V prvním testu jsme měřili pouze odezvu mezi odesláním vstupu od klienta pro snímek $n$ a získáním jeho integrovaného stavu ze serveru. Na obrázku \ref{fig:latencycomparison} vidíme, že TCP obsahuje skoky a QUICr je stabilnější.
\begin{figure}
\begin{center}
@@ -1135,8 +1131,8 @@ Nakonec jsme integrovali protokol přímo do replikátoru. Vytvořili jsme simul
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/300playerstrace.png}
\label{fig:tracyreplicator}
\caption{Analýza replikátoru}
\label{fig:tracyreplicator}
\end{figure}
Test s 301 hráči odhalil nedostatečný výkon serveru. Pomocí Tracy jsme začali program analyzovat. Na obrázku \ref{fig:tracyreplicator} vidíme, že pouze aktualizace replikátoru trvá každý snímek kolem 100ms. Pro představu, pokud bychom chtěli, aby server integroval 20 krát za sekundu, museli bychom všechno, nejen aktualizaci replikátoru, stihnout do 50 milisekund. Proto je aktuální stav nepřijatelně dlouhá doba. Úzké hrdlo najednou nebyla síť, ale příprava smysluplných dat, kterými síť zatížíme. Soustředili jsme další optimalizace právě na replikátor.
@@ -1150,15 +1146,15 @@ Replikátor pro každého klienta zjistil jeho zájem a pro každou entitu v ně
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/ecs_optimization_tracy_01.png}
\label{fig:ecs_optimization_tracy_01}
\caption{Analýza optimalizace replikátoru pro ECS}
\label{fig:ecs_optimization_tracy_01}
\end{figure}
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/ecs_optimization_tracy_02.png}
\label{fig:ecs_optimization_tracy_02}
\caption{Analýza optimalizace replikátoru pro ECS}
\label{fig:ecs_optimization_tracy_02}
\end{figure}
\begin{table}
@@ -1175,7 +1171,7 @@ Replikátor pro každého klienta zjistil jeho zájem a pro každou entitu v ně
\end{center}
\end{table}
Replikátor jsme začali analyzovat do větších detailů. Na obrázku \ref{fig:ecs_optimization_tracy_02} vidíme, které jeho části zabrali jakou dobu. Zjistili jsme, že problém byl samotný ProtoBuf. Formát je podobně jako JSON dělaný pro složité struktury objektů. V našem případě je ale zpráva pro snapshot světa primitivní. Rozhodli jsme udělat porovnání s FlatBuffers. V testu jsme simulovali 100 snímků, tak, abychom si mohli dopředu alokovat všechnu potřebnou paměť, kterou můžeme mezi snímky využívat. Dopředu si vytvoříme vektor pozic, které v testu budeme serializovat. Tímto zajistíme, že nebudeme měřit čas včetně alokace paměti. Stejně jako v replikátoru používáme architekturu orientovanou na ECS a procházíme všechny pozice, ty pak umisťujeme do alokovaných bloků paměti pro každého klienta a simulujeme tak skládání rámců, které můžeme odesílat. Všimli jsme si, že v případě primitivní zprávy, jako je snapshot stavu světa, by nám stačila klasická funkce ze standartní C knihovny zvaná \inlcpp{memcpy} a do testu jsme ji zařadili. Výsledky vidíme v tabulce \ref{t:serialization_comparison}.
Replikátor jsme začali analyzovat do větších detailů. Na obrázku \ref{fig:ecs_optimization_tracy_02} vidíme, jak dlouho trvali jeho jednotlivé části. Zjistili jsme, že problém byl samotný ProtoBuf. Formát je podobně jako JSON dělaný pro složité struktury objektů. V našem případě je ale zpráva pro snapshot světa primitivní. Rozhodli jsme udělat porovnání s FlatBuffers. V testu jsme simulovali 100 snímků tak, abychom si mohli dopředu alokovat všechnu potřebnou paměť, kterou můžeme mezi snímky využívat. Dopředu si vytvoříme vektor pozic, které v testu budeme serializovat. Tímto zajistíme, že nebudeme měřit čas včetně alokace paměti. Stejně jako v replikátoru používáme architekturu orientovanou na ECS a procházíme všechny pozice. Ty pak umisťujeme do alokovaných bloků paměti pro každého klienta a simulujeme tak skládání rámců, které můžeme odesílat. Všimli jsme si, že v případě primitivní zprávy, jako je snapshot stavu světa, by nám stačila klasická funkce ze standartní C knihovny zvaná \inlcpp{memcpy} a do testu jsme ji zařadili. Výsledky vidíme v tabulce \ref{t:serialization_comparison}.
Zjistili jsme, že problémem byl ProtoBuf a FlatBuffers by nám nepomohl. Nepřekvapilo nás, že memcpy byl nejrychlejší. Rozhodli jsme se, že pro serializaci a deserializaci snapshotů světa budeme používat vlastní serializaci.
@@ -1187,9 +1183,9 @@ Zpráva obsahuje hlavičku, ve které je počet aktualizovaných entit a počet
\subsection{Optimalizace manažera zájmů}
Všimli jsme si, že replikátor trval každou iteraci kolem 60 milisekund. Nejprve jsme se rozhodli přidat datové struktury. Druhým cílem bylo zlepšit API, kterým se replikátor dotazuje, jestli je entita pro klienta zajímavá.
Všimli jsme si, že replikátor trval každou iteraci kolem 60 milisekund. Nejprve jsme se rozhodli přidat datové struktury. Druhým cílem bylo zlepšit API, kterou se replikátor dotazuje, zda je entita pro klienta zajímavá.
Jedna s datových struktur, která má nízkou složitost pro dotaz na seznam entit ve vzdálenosti maximálně, je klasická mřížka. Charakteristika hráčů ve hrách je, že se hodně pohybují. Mřížka nepotřebuje žádný přepočet, ale pouze vložit do předem alokovaného bufferu, nebo z něj naopak odebrat.
Jednou z datových struktur, která má nízkou složitost pro dotaz na seznam entit ve maximální vzdálenosti, je klasická mřížka. Charakteristikou hráčů ve hrách je, že se zpravidla často pohybují. Mřížka nepotřebuje žádný přepočet, ale pouze vložit do předem alokovaného bufferu, nebo z něj naopak odebrat.
\begin{table}
\begin{center}
@@ -1211,25 +1207,25 @@ Jedna s datových struktur, která má nízkou složitost pro dotaz na seznam en
\end{center}
\end{table}
Testovali jsme 4 implementace, z toho 3 různé datové struktury a naivní přístup. Simulovali jsme pohyb 100 000 různých entit po dobu 100 snímků. Všechny možnosti představíme. Naivní přístup využívá pouze Pythagorovu větu, aby získal vzdálenost dvou bodů. Jediná optimalizace je vynechat odmocninu a umocnit místo toho vzdálenost. Druhá a třetí implementace využívá mřížku a entity rozděluje do svých polí. První je fixní mřížka, která je vhodná pro světy, které nemění svou velikost, jako např. World of Warcraft. Naopak hashovací mřížka přiřazuje entity do polí pomocí hashe jejich pozice. Jsou tak ideální pro dynamické a potenciálně nekonečné světy, jako např. Minecraft. Poslední je quad tree. Jedná se o obdobu stromu, kde vrcholy mají právě 4 potomky nebo žádného potomka. V tabulce \ref{table:range_query_comparison} vidíme výsledky testu. Celkový čas je milisekundách. Ve třetím a čvrtém sloupci je změřená část vkládání a dotazování. Díky tomu vidíme, že Quad tree má rychlejší dotazování, ale delší vkládání. Nejrychlejší je fixní mřížka. Má ale vysokou paměťovou náročnost a při použití je tak nutné zvážit, jestli není hashovací mřížka vhodnější. Quad tree implementace se ukázala jako nevhodná. S přibývající hloubkou je navíc pomalejší. Ideální se ukázali varianty s fixní a hashovací mřížkou.
Testovali jsme 4 implementace, z toho 3 různé datové struktury a naivní přístup. Simulovali jsme pohyb 100 000 různých entit po dobu 100 snímků. Všechny možnosti představíme. Naivní přístup využívá pouze Pythagorovu větu, aby získal vzdálenost dvou bodů. Jediná optimalizace je vynechat odmocninu a umocnit místo toho vzdálenost. Druhá a třetí implementace využívá mřížku a entity rozděluje do svých polí. První je fixní mřížka, která je vhodná pro světy, které nemění svou velikost, jako např. World of Warcraft. Naopak hashovací mřížka přiřazuje entity do polí pomocí hashe jejich pozice. Jsou tak ideální pro dynamické a potenciálně nekonečné světy, jako např. Minecraft. Poslední je quad tree. Jedná se o obdobu stromu, kde vrcholy mají právě 4 potomky nebo žádného potomka. V tabulce \ref{table:range_query_comparison} vidíme výsledky testu. Celkový čas je milisekundách. Ve třetím a čvrtém sloupci je změřená část vkládání a dotazování. Díky tomu vidíme, že Quad tree má rychlejší dotazování, ale delší vkládání. Nejrychlejší je fixní mřížka. Má ale vysokou paměťovou náročnost a při použití je tak nutné zvážit, jestli není hashovací mřížka vhodnější. Quad tree implementace se ukázala jako nevhodná. S přibývající hloubkou je navíc pomalejší. Ideální se ukázaly varianty s fixní a hashovací mřížkou.
\subsection{Peer-to-peer}
Chtěli jsme změřit i hru s modelem peer-to-peer. Zároveň jsme chtěli dokázat, že náš protokol QUICr pomáhá i v tomto modelu. Vytvořili jsme proto program, který simuluje jednoho účastníka peer-to-peer systému, tzv. \uv{peer}. Na začátku program čeká, až se připojí a autentizují ostatní peer. Proto jsme definovali číslo hráčů, v základu rovno 2.
Hry peer-to-peer fungují podobně jako v modelu klient-server. Každý účastník si udržuje svůj svět a chová se jako server. Tedy pro něj je zdroj pravdy právě jeho stav. Následně je hra rozdělena na iterace. V každé iteraci všichni odešlou všem svou akci, kterou učinili. Jakmile peer v iteraci $i$ získá akce od všech ostatních pro iteraci $i$, tak si je lokálně aplikuje na svůj stav. Poté se posune do iterace $i+1$ a proces se opakuje. Tento způsob má nevýhodu v tom, že hra je stejně rychlá jako nejpomalejší peer. Pokud někomu bude dlouho trvat, než odešle svou akci, všichni ostatní jsou nuceni na něj čekat. Je totiž třeba žádnou akci nevynechat, jinak dojde k desynchronizaci.
Hry peer-to-peer fungují podobně jako v modelu klient-server. Každý účastník si udržuje svůj svět a chová se jako server. Tedy pro něj je zdroj pravdy právě jeho stav. Následně je hra rozdělena na iterace. V každé iteraci všichni odešlou všem svou akci, kterou učinili. Jakmile peer v iteraci $i$ získá akce od všech ostatních pro iteraci $i$, lokálně si je aplikuje na svůj stav. Poté se posune do iterace $i+1$ a proces se opakuje. Tento způsob má nevýhodu v tom, že hra je stejně rychlá jako nejpomalejší peer. Pokud někomu bude dlouho trvat, než odešle svou akci, všichni ostatní jsou nuceni na něj čekat. Je nutné nevynechat žádnou akci, protože jinak dojde k desynchronizaci.
Optimalizaci, kterou jsme implementovali, byl rollback. Ten umožňil, aby nebylo nutné čekat na všechny akce. Pokud peer $A$ v iteraci $i$ chybí akce pro peer $B$, tak peer $A$ zkusí udělat pro peer $B$ predikci. Pokud eventuélně akce od $B$ do $A$ pro iteraci $i$ dorazí a liší se od predikce, tak se peer $A$ vrátí v historii, akci změní a aplikuje znova.
Optimalizací, kterou jsme implementovali, byl rollback. Ten umožňil, aby nebylo nutné čekat na všechny akce. Pokud peer $A$ v iteraci $i$ chybí akce pro peer $B$, tak peer $A$ zkusí udělat pro peer $B$ predikci. Pokud nakonec akce od $B$ do $A$ pro iteraci $i$ dorazí a liší se od predikce, tak se peer $A$ vrátí v historii, akci změní a aplikuje znova.
Zde je nutné, aby peer posílal ne pouze poslední akci, ale celou historii svých akcí. Představme si, že akce pro iteraci $i$ chybí, takže peer iteraci predikuje a přejde do $i+1$. Akce pro iteraci $i$ se ztratila a už nedorazí. Jakmile ale dorazí akce pro $i+1$, tak obsahuje i akci pro $i$. Peer si tak může historii vrátit, nasimulovat správně a tím se synchronizovat. Díky tomu je synchronizace daleko plynulejší.
Zde je nutné, aby peer neposílal pouze poslední akci, ale celou historii svých akcí. Představme si, že akce pro iteraci $i$ chybí, takže peer iteraci predikuje a přejde do $i+1$. Akce pro iteraci $i$ se ztratila a už nedorazí. Jakmile ale dorazí akce pro $i+1$, tak obsahuje i akci pro $i$. Peer si tak může historii vrátit, nasimulovat správně a tím se synchronizovat. Díky tomu je synchronizace daleko plynulejší.
Účastníci nemusejí vždy posílat celou svou historii, ale pouze tu část, kterou druhá strana ještě nemá. To lze zjistit tak, že příjemce posílá zprávu o tom, které iterace už obdržel. Tento přístup sice stále iteruje rychlostí nejpomalejšího účastníka, ale alespoň řeší lehké záseky při ztrátě paketu. Používá se často v bojových hrách, kde je odezva hráčových vstupů kritická.
V testu jsou tedy dva hráči, každý má svou postavu s pozicí ve 3D prostoru. Výše zmíněným způsobem provedou $X$ iterací. Postupně v čase jsme pozice obou postav exportovali do CSV pro oba hráče. Udělali jsme dvě měření, jedno pro TCP a druhé pro QUICr. Na obrázku \ref{fig:peer_to_peer} vidíme naměřené hodnoty pozice postavy hráče 1 jak ji viděl hráč 2. V případě TCP hráč silně skákal, právě kvůli ahead-of-line blokování. To snižuje hratelnost. Protokol QUICr je plynulejší a tedy i hratelnější.
V testu jsou tedy dva hráči, každý má svou postavu s pozicí ve 3D prostoru. Výše zmíněným způsobem provedou $X$ iterací. Postupně v čase jsme pozice obou postav exportovali do CSV pro oba hráče. Udělali jsme dvě měření, jedno pro TCP a druhé pro QUICr. Na obrázku \ref{fig:peer_to_peer} vidíme naměřené hodnoty pozice postavy hráče 1 jak ji viděl hráč 2. V případě TCP hráč silně skákal, právě kvůli ahead-of-line blokování. To znepříjemňuje hratelnost. Protokol QUICr je plynulejší a tedy i hratelnější.
\begin{figure}
\centering
\includegraphics[width=0.5\textwidth]{graphics/peer_to_peer.pdf}
\includegraphics[width=1\textwidth]{graphics/peer_to_peer.pdf}
\caption{Porovnání TCP a QUICr v peer-to-peer}
\label{fig:peer_to_peer}
\end{figure}
@@ -1254,34 +1250,29 @@ V testu jsou tedy dva hráči, každý má svou postavu s pozicí ve 3D prostoru
\begin{kiconclusions}
V práci jsme představili problematiku distribuovaných systémů a soustředili jsme se na konkrétní využití pro hry více hráčů. Popsali jsme různé modely a architektury nejen systému, ale i programů v něm. Jednotlivé atributy, které systémy nebo komunikace mohou mít, jsme identifikovali a přenesli na náš konkrétní případ.
Vytvořili jsme si vlastní herní engine, který umožňuje vytvářet hry pro více hráčů. Programy jsme skládali jako modulární monolity a popisovali jejich architekturu a implementaci. Ukázali jsme, že náš přístup umožnil snadno herní engine rozšiřovat. Pro distribuovaný systém jsme vytvořili hned dva protokoly: jeden v transportní a druhý v aplikační vrstvě. První protokol zrychluje tempo, jakým se zprávy dostanou ke zpracování, oproti TCP. Jinými slovy eliminuje ahead-of-line blokování. Implementovali jsme různé vlastnosti jako handshake a spolehlivost. Druhý protokol umožňuje zprávy rozdělovat podle typu. Na koncových bodech je tak možné pro typ definovat funkci, která každou příchozí zprávu tohoto typu zpracuje. Pro snadnější práci se zprávami jsme přidali serializaci objektů. To znamená, že ve vrstvě, kde implementujeme herní logiku, nepracujeme se zprávami jako n-ticemi bytů, ale objekty.
Vytvořili jsme vlastní herní engine, který umožňuje vytvářet hry pro více hráčů. Programy jsme skládali jako modulární monolity a popisovali jejich architekturu a implementaci. Ukázali jsme, že náš přístup umožnil snadno herní engine rozšiřovat. Pro distribuovaný systém jsme vytvořili hned dva protokoly: jeden v transportní a druhý v aplikační vrstvě. První protokol zrychluje tempo, jakým se zprávy dostanou ke zpracování, oproti TCP. Jinými slovy eliminuje ahead-of-line blokování. Implementovali jsme různé vlastnosti jako handshake a spolehlivost. Druhý protokol umožňuje zprávy rozdělovat podle typu. Na koncových bodech je tak možné pro typ definovat funkci, která každou příchozí zprávu tohoto typu zpracuje. Pro snadnější práci se zprávami jsme přidali serializaci objektů. To znamená, že ve vrstvě, kde implementujeme herní logiku, nepracujeme se zprávami jako n-ticemi bytů, ale objekty.
Na konci jsme definovali, jaké metriky chceme měřit a jaké chceme optimalizovat. Představili jsme nástroje a možnosti měření, které jsme využili. Naše metriky se netýkali jen komunikace v síti, ale i výkonu jednolivých programů. Například jsme naměřili, že v případě stovek hráčů začala být problém serializace a obecně sestavení smysluplných zpráv, nikoliv samotné odesílání. Implementovali a popsali jsme naše řešení. Zároveň jsme dokázali, že implementované optimalizace jsou vhodné nejen pro model klient-server ale i peer-to-peer.
Nakonec jsme definovali, jaké metriky chceme měřit a jaké chceme optimalizovat. Představili jsme nástroje a možnosti měření, které jsme využili. Naše metriky se netýkaly jen komunikace v síti, ale i výkonu jednolivých programů. Například jsme naměřili, že v případě stovek hráčů začala být problém serializace a obecně sestavení smysluplných zpráv, nikoliv samotné odesílání. Implementovali a popsali jsme naše řešení. Zároveň jsme dokázali, že implementované optimalizace jsou vhodné nejen pro model klient-server ale i peer-to-peer.
Do budoucna by bylo dobré dokončit další vlastnosti QUICr protokolu, jako například sekvenční číslo zprávy. Bylo by nutné se zamyslet, do jaké hloubky by pořadí zpráv měl řešit QUICr. Aplikace sama nejlépe ví, jestli musí čekat na předchozí zprávu nebo ne, jako v našem případě snapshoty ze serveru. Možnost je definovat předchůdce pro kompletní odstranění ahead-of-line blokování. Protokol také neimplementuje dynamické změny datového toku. Ten je nutné snížit, když je síť zatížená.\cite{quic}
Do budoucna by bylo dobré dokončit další vlastnosti QUICr protokolu, jako například sekvenční číslo zprávy. Bylo by nutné se zamyslet, do jaké hloubky by pořadí zpráv měl řešit QUICr. Aplikace sama nejlépe ví, jestli musí čekat na předchozí zprávu nebo ne, jako v našem případě se snapshoty ze serveru. Možnost je definovat předchůdce pro kompletní odstranění ahead-of-line blokování. Protokol také neimplementuje dynamické změny datového toku. Ten je nutné snížit, jakmile je síť zatížená.
\end{kiconclusions}
\begin{kiconclusions}[english]
Thesis conclusions in \uv{English}.
In this thesis, we introduced the topic of distributed systems and focused on their specific use for multiplayer games. We described various models and architectures, not only of the system but also of the programs within it. We identified the individual attributes that systems or communication can have and applied them to our specific case.
We built our own game engine that enables the creation of multiplayer games. We structured the programs as modular monoliths and described their architecture and implementation. We showed that our approach made it easy to extend the game engine. For the distributed system, we created two protocols: one at the transport layer and one at the application layer. The first protocol speeds up the rate at which messages reach processing compared to TCP. It eliminates ahead-of-line blocking. We implemented various features such as handshaking and reliability. The second protocol allows messages to be split by type. At the endpoints, it is thus possible to define a handler function for each type that processes every incoming message of that type. To make working with messages easier, we added object serialization, meaning that at the layer where we implement game logic, we work with objects rather than tuples of bytes.
Finally, we defined which metrics we wanted to measure and optimize. We presented the tools and measurement options we used. Our metrics concerned not only network communication but also the performance of the individual programs. For example, we measured that with hundreds of players, serialization and, more generally, assembling meaningful messages became a bottleneck, rather than the sending itself. We implemented and described our solution. We also demonstrated that the implemented optimizations are suitable not only for the client-server model but also for peer-to-peer.
For future work, it would be good to complete additional features of the QUICr protocol, such as message sequence numbers. It would be necessary to consider how deeply QUICr itself should handle message ordering — the application itself best knows whether it needs to wait for a previous message or not, as in our case with server snapshots. One option is to define a predecessor to fully eliminate ahead-of-line blocking. The protocol also does not implement dynamic flow rate adjustment, which would be necessary to reduce throughput when the network is congested.
\end{kiconclusions}
%% Přílohy obsahu textu práce, za makrem \appendix.
\appendix
\section{První příloha}
Text první přílohy
\section{Druhá příloha}
Text druhé přílohy
%% Obsah elektronických dat. Poslední příloha. Upravte podle vlastní
%% práce!
\section{Obsah elektronických dat} \label{sec:ObsahData}
Na samotném konci textu práce je uveden stručný popis obsahu
elektronických dat odevzdaných v systému katedry informatiky spolu s
textem. Tato data jsou nedílnou součástí práce a tvoří (datovou)
přílohu textu práce. Povinné položky struktury dat jsou:
Práce se skládá z textové a praktické části. Přílohy jsme rozdělili do třech adresářů, které popíšeme.
\begin{description}
@@ -1289,56 +1280,46 @@ přílohu textu práce. Povinné položky struktury dat jsou:
Adresář s textem práce ve formátu PDF, vytvořený s~použitím
závazného stylu KI PřF UP v~Olomouci pro závěrečné práce, včetně
všech (textových) příloh, a~všechny soubory potřebné pro
bezproblémové vytvoření PDF dokumentu textu (případně v~ZIP
archivu), tj.~zdrojový text textu a příloh, vložené obrázky, apod.
bezproblémové vytvoření PDF dokumentu textu.
\item[\texttt{README.*}] \hfill \\
Textový soubor (s příponou např. \texttt{.txt}) s informacemi o
opakovatelném způsobu použití ostatních dat práce -- typicky plně
reprodukovatelný co nejúplnější funkční postup zprovoznění software
vytvořeného v~rámci práce, tzn. jeho případné instalace/nasazení a
spuštění, včetně uvedení všech požadavků pro bezproblémový provoz;
za zprovoznění software se nepovažuje zpřístupnění (např. po
Internetu) již někde zprovozněného software.
\item[\texttt{README.md}] \hfill \\
Textový soubor s informacemi o sestavení a spuštění programů vytvořených v rámci této práce.
\item[\texttt{*}] \hfill \\
Adresáře a soubory s veškerými ostatními autorskými daty práce
(případně v~ZIP archivu) -- typicky spustitelné a další soubory
software vytvořeného v rámci práce potřebné pro bezproblémový provoz
software, případně jeho instalační program, a kompletní zdrojové
texty software a další data nutná pro plně reprodukovatelné korektní
vytvoření spustitelných souborů.
\item[\texttt{build/}] \hfill \\
Adresář obsahuje už sestavené programy připravené pro použití. Obsahují tři spustitelné soubory pro server, klienta a testovacího klienta.
\item[\texttt{src/}] \hfill \\
Adresář se všemi zdrojovými kódy, včetně externích knihoven, které programy využívají. Instrukce pro sestavení jsou v README.md v kořenovém adresáři.
\end{description}
Dále mohou data obsahovat například:
\begin{itemize}
% \begin{itemize}
%\item[\texttt{data/}] \hfill \\
\item
ukázková a~testovací data použitá v~práci nebo pro potřeby posouzení
práce v rámci její obhajoby,
% \item
% ukázková a~testovací data použitá v~práci nebo pro potřeby posouzení
% práce v rámci její obhajoby,
%\item[\texttt{literature/}] \hfill \\
\item
položky bibliografie v elektronické podobě, příp.~jiná relevantní literatura
a dokumentace vztahující se k~práci,
% %\item[\texttt{literature/}] \hfill \\
% \item
% položky bibliografie v elektronické podobě, příp.~jiná relevantní literatura
% a dokumentace vztahující se k~práci,
%\item[\texttt{install/}] \hfill \\
\item
cizí data (software) potřebná pro bezproblémové použití autorských
dat práce (software), která nejsou standardní součástí
předpokládaného (softwarového) vybavení uživatele.
% %\item[\texttt{install/}] \hfill \\
% \item
% cizí data (software) potřebná pro bezproblémové použití autorských
% dat práce (software), která nejsou standardní součástí
% předpokládaného (softwarového) vybavení uživatele.
\end{itemize}
% \end{itemize}
U~veškerých cizích obsažených materiálů jejich
zahrnutí dovolují podmínky pro jejich veřejné šíření nebo přiložený souhlas
držitele práv k užití. Pro všechny použité (a~citované) materiály,
u~kterých toto není splněno a~nejsou tak obsaženy, je uveden
jejich zdroj, např.~webová adresa, v~bibliografii nebo textu práce
nebo souboru \texttt{README.*}.
% U~veškerých cizích obsažených materiálů jejich
% zahrnutí dovolují podmínky pro jejich veřejné šíření nebo přiložený souhlas
% držitele práv k užití. Pro všechny použité (a~citované) materiály,
% u~kterých toto není splněno a~nejsou tak obsaženy, je uveden
% jejich zdroj, např.~webová adresa, v~bibliografii nebo textu práce
% nebo souboru \texttt{README.*}.
%% -------------------------------------------------------------------
+37 -23
View File
@@ -18,52 +18,66 @@
\contentsline {subsubsection}{\numberline {3.3.3}QUIC}{18}{subsubsection.3.3.3}%
\contentsline {section}{\numberline {4}Hra}{21}{section.4}%
\contentsline {subsection}{\numberline {4.1}Engine}{21}{subsection.4.1}%
\contentsline {subsubsection}{\numberline {4.1.1}Fyzický engine}{22}{subsubsection.4.1.1}%
\contentsline {subsubsection}{\numberline {4.1.1}Fyzický engine}{21}{subsubsection.4.1.1}%
\contentsline {subsubsection}{\numberline {4.1.2}Vykreslování}{22}{subsubsection.4.1.2}%
\contentsline {subsubsection}{\numberline {4.1.3}Entity-Component-System}{23}{subsubsection.4.1.3}%
\contentsline {subsubsection}{\numberline {4.1.3}Entity-Component-System}{22}{subsubsection.4.1.3}%
\contentsline {subsubsection}{\numberline {4.1.4}ImGui}{24}{subsubsection.4.1.4}%
\contentsline {section}{\numberline {5}Hra více hráčů}{25}{section.5}%
\contentsline {subsection}{\numberline {5.1}Server}{26}{subsection.5.1}%
\contentsline {subsubsection}{\numberline {5.1.1}Registr klientů}{26}{subsubsection.5.1.1}%
\contentsline {subsection}{\numberline {5.1}Server}{25}{subsection.5.1}%
\contentsline {subsubsection}{\numberline {5.1.1}Registr klientů}{27}{subsubsection.5.1.1}%
\contentsline {subsubsection}{\numberline {5.1.2}Server Replikátoru}{27}{subsubsection.5.1.2}%
\contentsline {subsubsection}{\numberline {5.1.3}Správa zájmů}{27}{subsubsection.5.1.3}%
\contentsline {subsection}{\numberline {5.2}Klient}{27}{subsection.5.2}%
\contentsline {subsubsection}{\numberline {5.2.1}Klient Replikátoru}{27}{subsubsection.5.2.1}%
\contentsline {subsubsection}{\numberline {5.2.2}Interpolace}{27}{subsubsection.5.2.2}%
\contentsline {subsubsection}{\numberline {5.2.3}Rollback}{28}{subsubsection.5.2.3}%
\contentsline {subsection}{\numberline {5.3}Posílání zpráv}{28}{subsection.5.3}%
\contentsline {subsection}{\numberline {5.2}Klient}{28}{subsection.5.2}%
\contentsline {subsubsection}{\numberline {5.2.1}Klient Replikátoru}{28}{subsubsection.5.2.1}%
\contentsline {subsubsection}{\numberline {5.2.2}Interpolace}{28}{subsubsection.5.2.2}%
\contentsline {subsubsection}{\numberline {5.2.3}Rollback}{29}{subsubsection.5.2.3}%
\contentsline {subsection}{\numberline {5.3}Posílání zpráv}{29}{subsection.5.3}%
\contentsline {subsubsection}{\numberline {5.3.1}Kódování zpráv}{29}{subsubsection.5.3.1}%
\contentsline {subsubsection}{\numberline {5.3.2}Implementace}{29}{subsubsection.5.3.2}%
\contentsline {subsubsection}{\numberline {5.3.3}Detekce a náprava chyb}{29}{subsubsection.5.3.3}%
\contentsline {subsection}{\numberline {5.4}Serializace}{29}{subsection.5.4}%
\contentsline {subsubsection}{\numberline {5.3.2}Implementace}{30}{subsubsection.5.3.2}%
\contentsline {subsubsection}{\numberline {5.3.3}Detekce a náprava chyb}{30}{subsubsection.5.3.3}%
\contentsline {subsection}{\numberline {5.4}Serializace}{30}{subsection.5.4}%
\contentsline {subsection}{\numberline {5.5}Protokol QUICr}{31}{subsection.5.5}%
\contentsline {subsubsection}{\numberline {5.5.1}Rámce}{32}{subsubsection.5.5.1}%
\contentsline {subsubsection}{\numberline {5.5.2}Handshake}{32}{subsubsection.5.5.2}%
\contentsline {subsubsection}{\numberline {5.5.3}Spolehlivost}{32}{subsubsection.5.5.3}%
\contentsline {subsubsection}{\numberline {5.5.3}Spolehlivost}{34}{subsubsection.5.5.3}%
\contentsline {subsubsection}{\numberline {5.5.4}Enkodér}{34}{subsubsection.5.5.4}%
\contentsline {subsubsection}{\numberline {5.5.5}Testování}{35}{subsubsection.5.5.5}%
\contentsline {subsection}{\numberline {5.6}Horizontální škálování}{35}{subsection.5.6}%
\contentsline {subsection}{\numberline {5.7}Výsledná hra}{36}{subsection.5.7}%
\contentsline {section}{\numberline {6}Měřění}{38}{section.6}%
\contentsline {subsection}{\numberline {6.1}Metriky}{38}{subsection.6.1}%
\contentsline {subsubsection}{\numberline {6.1.1}PostgreSQL}{38}{subsubsection.6.1.1}%
\contentsline {subsubsection}{\numberline {6.1.2}TimescaleDB}{38}{subsubsection.6.1.2}%
\contentsline {subsubsection}{\numberline {6.1.1}PostgreSQL}{39}{subsubsection.6.1.1}%
\contentsline {subsubsection}{\numberline {6.1.2}TimescaleDB}{39}{subsubsection.6.1.2}%
\contentsline {subsubsection}{\numberline {6.1.3}Grafana}{39}{subsubsection.6.1.3}%
\contentsline {subsubsection}{\numberline {6.1.4}Tracy}{39}{subsubsection.6.1.4}%
\contentsline {subsubsection}{\numberline {6.1.5}Klientská aplikace}{39}{subsubsection.6.1.5}%
\contentsline {subsubsection}{\numberline {6.1.4}Tracy}{40}{subsubsection.6.1.4}%
\contentsline {subsubsection}{\numberline {6.1.5}Klientská aplikace}{40}{subsubsection.6.1.5}%
\contentsline {subsection}{\numberline {6.2}QUICr}{40}{subsection.6.2}%
\contentsline {subsection}{\numberline {6.3}Optimalizace replikátoru}{42}{subsection.6.3}%
\contentsline {subsection}{\numberline {6.4}Optimalizace manažera zájmů}{44}{subsection.6.4}%
\contentsline {subsection}{\numberline {6.4}Optimalizace manažera zájmů}{45}{subsection.6.4}%
\contentsline {subsection}{\numberline {6.5}Peer-to-peer}{45}{subsection.6.5}%
\contentsline {section}{Z\'av\v er}{47}{section*.3}%
\contentsline {section}{Z\'av\v er}{48}{section*.3}%
\babel@toc {czech}{}\relax
\babel@toc {czech}{}\relax
\contentsline {section}{Conclusions}{48}{section*.5}%
\contentsline {section}{Conclusions}{49}{section*.5}%
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\contentsline {section}{\numberline {A}První příloha}{49}{appendix.A}%
\contentsline {section}{\numberline {B}Druhá příloha}{49}{appendix.B}%
\contentsline {section}{\numberline {C}Obsah elektronických dat}{49}{appendix.C}%
\contentsline {section}{\numberline {A}Obsah elektronických dat}{50}{appendix.A}%
\contentsline {section}{Literatura}{51}{section*.7}%
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax
\babel@toc {english}{}\relax
\babel@toc {czech}{}\relax