← Zpět na přehled VGA / 03 Úvod

Úvod

Architektura her a herní entity

Architektura, návrhové vzory, entity, kompozice a ECS.

Autorské ukázky kódu jsou fragmenty a pseudokód určené k výkladu. Nejsou vydávány za spustitelný projekt. Historická tvrzení zůstávají tvrzeními přednášky.

Původní snímek · 1Původní PDF strana 1

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 1

Architektura

Architektura

Původní snímek · 2Původní PDF strana 2

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 2

Architektura

Co (a proč) je softwarová architektura?

Může-li se něco pokazit, pokazí se to. – Edward Aloysius Murphy Jr.

The software needs to be built in such a way that it is able to adapt to unexpected changes in features. – Martin Fowler

Architektura software je promyšlený přístup k návrhu software, který umožňuje jej rozvíjet a reagovat na nečekané změny.

Původní snímek · 3Původní PDF strana 3

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 3

Architektura

Nečekané změny při vývoji hry

Obsah hry.

Herní mechaniky a systémy.

Zacílení hry (cílová skupina, způsob hraní hry).

Platformy, hardware, operační systémy, aplikační rozhraní.

Vývojářský tým, rozpočet na vývoj…

Volba nevhodné (nebo žádné) architektury prodraží implementaci změn.

Původní snímek · 4Původní PDF strana 4

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 4

Architektura

Architektura je investice do budoucna.

Původní snímek · 5Původní PDF strana 5

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 5

Architektura

Jak reagujeme na možné změny v obsahu hry?

class OldSoldier : public NPC {
    public:
        OldSoldier() : NPC("Hans", 100, ...) {}
}
NPC * old_soldier = new OldSoldier();

Zvolíme vhodnou abstrakci a přesuneme detaily do datových souborů:

[ { type: "npc", source: "hans.json", pos: ... } ]
...
{ name: "Hans", hp: "100", ... }
LoadSceneFromFile('level.json');
Původní snímek · 6Původní PDF strana 6

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 6

Architektura

Data > Kód

Původní snímek · 7Původní PDF strana 7

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 7

Architektura

Jak reagujeme na možné změny v herních mechanikách a systémech?

if(player_pressed_movement_keys()) {
  move_player();
}
else if(player_pressed_light_switch) {
  handle_light_switch();
}
else if ...

Využijeme OOP, zavedeme moduly.

for(auto system : systems) {
  system->tick();
}
Původní snímek · 8Původní PDF strana 8

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 8

Architektura

❤️ OOP

Původní snímek · 9Původní PDF strana 9

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 9

Architektura

Jak reagujeme na možné změny v platformě?

for(nYPos = 0; nHeight > nYPos; nYPos++) {
    pAddress = (unsigned char *)(0xC000+((nY/8u)*80u)+((nY%8u)*2048u)+nX);
    memcpy(pAddress, pSprite, nWidth);
    pSprite += nWidth;
    nY++;
}

Zavedeme vrstvy / služby, které lze měnit.

auto drawing = Engine->GetDrawingService();
drawing->addSprite(...);
...
drawing->finish();
Původní snímek · 10Původní PDF strana 10

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 10

Architektura

Lidé, vrstvěte!

Původní snímek · 11Původní PDF strana 11

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 11

Architektura

Jak reagujeme na možné změny ve složení vývojářského týmu?

Typické rizikové situace:

Zdvojnásobení velikosti týmu.

Nečekaný odchod klíčového člena týmu.

Čitelný a přehledný kód (a nejen ten) je základ.

Dokumentace.

Nově příchozí vývojáři se potřebují zorientovat a co nejdříve začít pracovat.

Stávající vývojáři potřebují zaznamenat a vysvětlit svá rozhodnutí a různé podivnosti v kódu, datech, procesech, dokumentech…

Původní snímek · 12Původní PDF strana 12

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 12

Architektura

Dobře zdokumentovaný projekt přežije i větší změny v týmu.

Původní snímek · 13Původní PDF strana 13

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 13

Architektura

Na co si dát pozor?

Každé architektonické opatření něco stojí a to, co získáme, nemusí vyvážit náklady.

Vytváření abstrakcí a datových formátů versus dělba práce.

Vytváření objektů a modulů versus jejich počet.

Vytváření vrstev versus režie komunikace mezi nimi.

Obsáhlost dokumentace versus pracnost její údržby.

Elegance versus run-time režie.

Neexistuje univerzálně vhodná architektura.

Pracujeme s omezeným prostorem nečekaných změn a architekturu volíme podle něj.

Původní snímek · 14Původní PDF strana 14

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 14

Architektura

Různé pohledy na herní architekturu

Živá databáze

Ve hře se nacházejí herní entity, které mohou vznikat a zanikat.

Tyto herní entity interagují mezi sebou.

Hra komunikuje s okolním prostředím, zejména s hráčem.

Hra = databáze + interakce + komunikační rozhraní.

Propojení služeb

Jádrem hry je její simulace.

Aby hra fungovala, potřebuje řadu podpůrných služeb.

Hra = simulace + služby (vykreslování, zvučení, vstup, síť, logování atd.)

K architektuře her jako celku se vrátíme někdy příště.

Původní snímek · 15Původní PDF strana 15

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 15

Návrhové vzory

Návrhové vzory

Původní snímek · 16Původní PDF strana 16

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 16

Návrhové vzory

Definice návrhového vzoru

Obecné řešení problému využívané při návrhu počítačových programů.

Problémem se zde nemyslí algoritmus.

Typické řešené problémy:

Úspora kódu.

Čitelnost kódu.

Udržovatelnost kódu.

Rozšiřitelnost kódu.

Oddělení zodpovědností.

Úspora zdrojů počítače (procesor, paměť, datové sběrnice…).

Tyto problémy často nejsou zřejmé na začátku vývoje, chceme jim ale předejít.

Návrhové vzory vypozorovány v praxi a popsány jako good/best practices → rozšíření návrhových vzorů do praxe.

Původní snímek · 17Původní PDF strana 17

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 17

Návrhové vzory

Trocha historie

Pojem design pattern poprvé použil Christopher Alexander v 1966; avšak v kontextu architektury a urbanismu, nikoliv software.

Poprvé v kontextu software Ward Cunningham a Kent Beck, v 1987 na konferenci OOPSLA. Předpřipravené vzory pro začátečníky v jazyce Smalltalk.

V roce 1991 vznikla skupina Gang of Four (GoF) – Erich Gamma, Richard Helm, Ralph Johnson a John Vlissides.

Původní snímek · 18Původní PDF strana 18

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 18

Návrhové vzory

Popis návrhového vzoru (podle knihy Design Patterns od GoF)

Název návrhového vzoru – jednoznačný název vzoru

Zařazení návrhového vzoru – creational, structural, behavioral, concurrency…

Cíl – kvůli čemu vzor vznikl

Další názvy – pod jakými dalšími názvy je vzor znám v praxi

Motivace vzoru – jaký problém vzor řeší

Použití – kontext použití vzoru

Struktura – grafické znázornění vzoru (typicky UML diagram)

Účastníci – třídy a objekty, které tento vzor používá

Spolupráce – popis, jak spolu účastníci komunikují

Důsledky – popis výsledků, vedlejších efektů a případných problémů plynoucích z použití

Implementace, ukázkový kód, příklady známých použití

Související vzory

Původní snímek · 19Původní PDF strana 19

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 19

Návrhové vzory

Důležité knihy a doporučené zdroje

Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994). Design Patterns: Elements of Reusable Object-Oriented Software.

Buschmann, Frank; Meunier, Regine; Rohnert, Hans; Sommerlad, Peter (1996). Pattern- -Oriented Software Architecture, Volume 1: A System of Patterns.

Schmidt, Douglas C.; Stal, Michael; Rohnert, Hans; Buschmann, Frank (2000). Pattern- -Oriented Software Architecture, Volume 2: Patterns for Concurrent and Networked Objects.

Fowler, Martin (2002). Patterns of Enterprise Application Architecture.

Hohpe, Gregor; Woolf, Bobby (2003). Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions.

Freeman, Eric T.; Robson, Elisabeth; Bates, Bert; Sierra, Kathy (2004). Head First Design Patterns.

Nystrom, Robert (2014). Game Programming Patterns.

Předměty BI-SWI, BI-OOP, ANI-ADP.

Původní snímek · 20Původní PDF strana 20

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 20

Herní entity

Základní návrhové vzory pro hry

Původní snímek · 21Původní PDF strana 21

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 21

Herní entity

Herní smyčka

void Game::run() {
    while (true)
    {
        processInput();
        update();
        render();
    }
}

Přesná realizace tohoto vzoru závisí na použité platformě.

Jaké problémy má výše uvedený kód?

Původní snímek · 22Původní PDF strana 22

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 22

Herní entity

Scéna

Prostředí hry obsahující herní entity

Je oživena herní smyčkou

Entity můžeme reprezentovat různými způsoby (viz dále)

(Velmi) naivní příklad:

struct Ball {
    int x, y, vx, vy;
};
struct Scene {
    Paddle player, otherPlayer;
    Ball ball;
    ScoreDisplay scoreDisplay;
};

Jaký má tento příklad problém a jaký problém by mohl řešit?

Původní snímek · 23Původní PDF strana 23

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 23

Herní entity

Herní smyčka s abstraktní scénou

class Scene {
public:
    virtual void processInput() = 0;
    virtual void update() = 0;
    virtual void render() = 0;
}
void Game::run() {
    while (true)
    {
        currentScene->processInput();
        currentScene->update();
        currentScene->render();
    }
}

Jak řešit přepínání scén? A jaké problémy přetrvávají?

Původní snímek · 24Původní PDF strana 24

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 24

Herní entity

Abstraktní entity

class Entity { ... };
class Paddle : public Entity { ... };
class Scene {
    std::vector<std::unique_ptr<Entity>> entities;
}

Na entitách využíváme polymorfismus. Podle použitého jazyka může mít různou realizaci (dědičnost a virtuální metody v C++, enums a/nebo dyn traits v Rust, tagged unions a/nebo function pointers v C…).

Jaké vzniknou problémy?

Původní snímek · 25Původní PDF strana 25

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 25

Herní entity

Abstraktní entity – problém horké smyčky

for(auto & entity : entities) {
    entity->draw();
}

Rozpočet snímku (příklad):

16 ms celkem (60 fps)

10 ms vykreslování na GPU

5 ms simulace

1 ms režie engine

Příklad ze zdroje · hypotetická režie draw()
EntitRežie
15 ns
1 0005 μs
1 000 0005 ms

Existují různá řešení, lze je kombinovat.

Původní rozpočet 16 ms je zaokrouhlený příklad; přesná perioda 60 Hz je 16,67 ms. Uvedených 5 ns na volání je předpoklad ukázky, nikoli naše měření.

Původní snímek · 26Původní PDF strana 26

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 26

Herní entity

Abstraktní entity – problém polymorfismu

Kam patří CDracula?

Pokud nás zradí dědičnost, zkusme kompozici.

Jan Matoušek, původní ilustrace nebo diagram, PDF strana 27
Jan Matoušek · původní ilustrace · PDF 27
Původní snímek · 27Původní PDF strana 27

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 27

Herní entity

Dědičnost versus kompozice – Godot engine

Druhy entit jsou obecnější (nejsou zde druhy nepřátel apod.).

Dokumentace doporučuje využívat kompozici, ale je na vývojáři, jak si ji zařídí.

Jan Matoušek, původní ilustrace nebo diagram, PDF strana 28
Jan Matoušek · původní ilustrace · PDF 28
Původní snímek · 28Původní PDF strana 28

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 28

Herní entity

Dědičnost versus kompozice – Unity engine (nikoliv DOTS)

Herní entity jsou složené z komponent.

Typické komponenty:

renderovatelný mesh,

fyzikální kolize,

poloha,

světlo,

…

programátorem dopsané chování

Jan Matoušek, původní ilustrace nebo diagram, PDF strana 29
Jan Matoušek · původní ilustrace · PDF 29
Původní snímek · 29Původní PDF strana 29

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 29

Herní entity

Kompozice v entitě

class Component { ... };
class RenderableMesh : public Component { ... };
class Entity { std::vector<std::unique_ptr<Component>> components; };

Problém? Dynamické vazby, pomalé dohledávání potřebných komponent.

class Entity {
    std::unordered_map<std::type_index, std::unique_ptr<Component>> components;
    template<typename A>
    A& getComponent() { return dynamic_cast<A>(components.at(typeid(A))); }
};

Problém (např. v Unity)? Zůstává míchání datových komponent a skriptů chování, skákání po ukazatelích (nelokalita paměti, častý cache miss), prostorová režie velkého množství hash map.

Původní snímek · 30Původní PDF strana 30

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 30

Herní entity

ECS – Entity component system

Každá entita má sama o sobě pouze identifikátor (typicky celé číslo)

Data jsou v komponentách

Kód je v systémech

Každý systém oživuje 1 nebo více druhů komponent

Paralelizovatelné přes komponenty (1 vlákno zapisuje, nebo N vláken čte)

Paralelizovatelné na GPU (zejména zvládneme-li mít data některého druhu komponenty výhradně v paměti grafické karty)

Jan Matoušek, původní ilustrace nebo diagram, PDF strana 31
Jan Matoušek · původní ilustrace · PDF 31
Původní snímek · 31Původní PDF strana 31

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 31

Herní entity

ECS – historie

1963, Ivan Sutherland, Sketchpad

Jan Matoušek, původní ilustrace nebo diagram, PDF strana 32
Jan Matoušek · původní ilustrace · PDF 32
Původní snímek · 32Původní PDF strana 32

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 32

Herní entity

ECS – Thief: The Dark Project (1998)

První použití ECS v počítačové hře.

Na stejném engine následoval System Shock 2.

Jan Matoušek, původní ilustrace nebo diagram, PDF strana 33
Jan Matoušek · původní ilustrace · PDF 33
Původní snímek · 33Původní PDF strana 33

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 33

Herní entity

ECS – příklad

Komponenty: poloha, světlo, pevné těleso, AI nepřítel, NPC, ovládání, quest…

Entity: hrdina, pochodeň, mlynář, quest unesené dcery, goblin, ohnivák, Dracula…

Systémy: fyzika, vykreslování, AI, vstup od hráče, questový systém…

Hrdina

Poloha · Pevné těleso · Ovládání

Pochodeň

Poloha · Světlo

Mlynář

Poloha · Pevné těleso · NPC

Únos dcery

Quest

Goblin

Poloha · Pevné těleso · AI nepřítel

Ohnivák

Poloha · Světlo · Pevné těleso · AI nepřítel

Dracula

Poloha · Pevné těleso · AI nepřítel · NPC

Jan Matoušek, původní ilustrace nebo diagram, PDF strana 34
Jan Matoušek · původní ilustrace · PDF 34
Původní snímek · 34Původní PDF strana 34

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 34

Herní entity

ECS – příklad

Které komponenty používá který systém?

Hrdina

Poloha · Pevné těleso · Ovládání

Pochodeň

Poloha · Světlo

Mlynář

Poloha · Pevné těleso · NPC

Únos dcery

Quest

Goblin

Poloha · Pevné těleso · AI nepřítel

Ohnivák

Poloha · Světlo · Pevné těleso · AI nepřítel

Dracula

Poloha · Pevné těleso · AI nepřítel · NPC

Původní snímek · 35Původní PDF strana 35

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 35

Herní entity

ECS – zjednodušená implementace

Každý druh komponenty se nachází v samostatné mapě indexované identifikátorem entity.

std::unordered_map<int, Position> positions;
std::unordered_map<int, Light> lights;
...

Každý systém potom prochází příslušné hash mapy, např.:

void lighting_system(...) {
    for(auto & [ entity_id, light ] : lights) {
        auto posIt = positions.find(entity_id);
        if(posIt == positions.end()) continue;
        auto & position = posIt->second;
        ...
    }
}
Původní snímek · 36Původní PDF strana 36

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 36

Herní entity

ECS – typická implementace

Všechny hash mapy bývají v jednom registru komponent.

K procházení registru komponent se používají tzv. dotazy/pohledy (queries/views), které zpřehledňují různé požadavky systémů (typicky: potřebuji všechny entity, které mají komponenty A a zároveň B, potřebuji komponentu C od entity s daným identifikátorem atd.).

Příklady viz knihovny EnTT (C++), Bevy (Rust) a další.

struct position { float x, y; };
struct velocity { float dx; float dy; }
void update(entt::registry &registry) {
    auto view = registry.view<const position, velocity>();
    for(auto [entity_id, pos, vel]: view.each()) {
        // ...
    }
}
Původní snímek · 37Původní PDF strana 37

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 37

Herní entity

Problém: kufr v grafu scény

Problém: Nehráčská postava přinese kufr,

položí jej na stůl a odejde.

V kufru jsou různé věci.

Původní snímek · 38Původní PDF strana 38

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 38

Herní entity

Graf scény

Scéna může být poskládána z entit hierarchicky

Můžeme schovat entity, které jsou v hierarchii pod (předměty v kufru, interiér domu).

Umožňuje mít hierarchie transformací a pohybu.

Obvyklá reprezentace: odkazy na nadřazenou entitu.

Jan Matoušek, původní ilustrace nebo diagram, PDF strana 39
Jan Matoušek · původní ilustrace · PDF 39
Původní snímek · 39Původní PDF strana 39

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 39

Herní entity

Space partitioning

Některé mechaniky vyžadují nalezení herních entit v blízkosti nějakých souřadnic.

Pro velké množství entit nebo velké množství hledání naivní postup nestačí – 𝑂(𝑛2)

Základní princip: Rozděl a panuj.

Existuje velké množství řešení:

Mřížky

Spatial hashing

Octree, quadtree

Bounding volume hierarchy

KD tree, BSP tree

Detaily necháme na jindy (přednáška o světech velkých a malých).

Původní snímek · 40Původní PDF strana 40

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 40

Herní entity

Vazby mezi entitami

Mohli bychom používat adresy / pointery. Problémy?

Invalidace odkazů při přesunech paměti (např. při realokaci pole).

Skákání po pointerech, časté cache miss.

Problematické určení platnosti, pokud odkazovaný objekt zanikne.

– Šlo by používat kombinace shared a weak pointerů.

Mít očíslované entity je pragmatičtější přístup.

Je potřeba řešit, zda řada čísel musel musí být souvislá.

Pokud ano, jak entity při změnách přečíslovávat.

Pokud ne, zda nám čísla rychle nedojdou.

S tím trochu souvisí object pooling (příště).

Původní snímek · 41Původní PDF strana 41

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 41

Herní entity

Životní cyklus entit

Scéna je během hry málokdy statická, entity vznikají a zanikají.

Načtení / uvolnění levelu.

Spawning nepřátel, střílení a dopady projektilů…

Problémy se vznikem entit:

Přidělení identifikátoru, dynamická alokace, realokace polí…

Napojení vazeb

Výlučný přístup ke scéně, vhodný okamžik přidání

Zánik entit:

Zrušení vazeb

Výlučný přístup ke scéně, vhodný okamžik odebrání

Původní snímek · 42Původní PDF strana 42

Jan Matoušek · Podklad a export 8. 10. 2026 · PDF, strana 42

Obsah přednášky

Poznámky

Původní text PDF

ECS: dotaz na komponenty · GRAFIT

Systém vyžaduje všechny vybrané komponenty

Didaktický doplněk GRAFIT podle příkladu v PDF. Výběr je průnik množin komponent; změna registru mění výsledek dotazu. Všechny vypnuté podmínky vrací všechny existující entity. Model neimplementuje produkční ECS, paralelní vykonávání, alokátor ani měření výkonu; zjednodušené okamžité odebrání je oddělené od probíhajícího průchodu systému.