FIT ČVUT

Adam Vesecký

NI-APH
Přednáška 3

Assety

Úvod do assetů

Co to jsou assety - různé definice

Vše, co je specifické pro danou hru (a není jen součástí enginu).

Všechna data, která jsou ve formátu podporovaném herním enginem.

Multimediální prvky, které jsou prezentovány hráči a chráněny copyrightem.

Co to jsou assety

  • mnoho her má podobné mechaniky ale odlišný vizuál - vizuální assety
Super Mario

Super Mario (1985)

Giana Sisters

Giana Sisters (1987)

World of Warcraft

World of Warcraft (2004)

Order and Chaos 2

Order and Chaos 2 (2015)

Assety

Binary assets

Binární data

Bytecode assets

Bytecode

Text assets

Textové soubory

Hybrid assets

Hybridní soubory

Assety
Assets diagram

Média

NES cartridge
NES cartridge
8kB - 1MB
Super Mario
GameBoy cartridge
Game Boy cartridge
256 kB - 8 MB
Pokémon Yellow
Floppy disk
Disketa
1.44 MB
Duke Nukem 1
Compact Disk
CD
700 MB
Half-Life
DVD disk
DVD
4.7 GB - 8.5 GB
GTA San Andreas
Bluray disk
Blu-ray
25 GB - 50 GB
Witcher 3
HDD
HDD + DLC
Jakákoliv velikost (bohužel)
Call of Duty: Warzone
Hra Super Mario zabírá méně KB než její screenshot!

Velikost herních assetů

Assets size in games

Typy assetů

Zvuky a hudba

  • AIFF, WAV, MP3, OGG

Obrázky / textury

  • PNG, JPG, TGA, SVG, EXR, PBR, MTLX

Video

  • MP4, MKV, AVI, MOV, MPG, WEBM

3D Modely

  • FBX, BLEND, DAE, 3DS, X3D, GLB, GLTF

Herní Data

  • ZIP, XML, JSON, CFG, BIN,...

Levely, Mapy

  • CAS, DAT, RPF, TIGER, WAD

Skripty

  • JS, LUA, PY, CS
HEX data

Resource Manager

Resource Manager

Poskytuje přístup ke všem zdrojům

  • meshe, materiály, shadery, animace, textury, klipy, levely
  • Resource Cache - používá se pro rychlejší přístup

Řídí životní cyklus každého zdroje

  • většina RM obsahuje nějaký registr

Garantuje, že vždy existuje pouze jedna kopie každého zdroje v paměti

  • resource GUID - jednoznačný identifikátor, možno použít cestu k souboru, neb je unikátní

Načítá požadované zdroje a uvolňuje ty, které už nejsou potřeba

  • načítání je mnohem jednodušší než uvolňování

Řeší streamování

  • u open-world her

Resource Manager

Resource Manager

Příklad: Godot Engine Resource Loader

1 RES ResourceLoader::_load(const String &p_path, const String &p_original_path,
2 const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads,
3 float *r_progress) {
4 bool found = false;
5
6 // Try all loaders and pick the first match for the type hint
7 for (int i = 0; i < loader_count; i++) {
8 if (!loader[i]->recognize_path(p_path, p_type_hint)) {
9 continue;
10 }
11 found = true;
12 RES res = loader[i]->load(p_path, p_original_path != String() ?
13 p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_no_cache);
14 if (res.is_null()) {
15 continue;
16 }
17
18 return res;
19 }
20
21 ERR_FAIL_COND_V_MSG(found, RES(), vformat("Failed loading resource: %s.", p_path));
22 }

Příklad: Godot Engine, dealokace textury

1 CameraTexture::~CameraTexture() {
2 if (_texture.is_valid()) {
3 RenderingServer::get_singleton()->free(_texture);
4 }
5 }
6
7 void TextureStorage::texture_free(RID p_texture) {
8 Texture *t = texture_owner.get_or_null(p_texture);
9 t->cleanup();
10 ...
11 texture_owner.free(p_texture);
12 }
13
14 void PoolAllocator::free(ID p_mem) {
15 mt_lock();
16 Entry *e = get_entry(p_mem);
17 bool index_found = find_entry_index(&entry_indices_pos, e);
18 ...
19 entry_count--;
20 free_mem += aligned(e->len);
21 e->clear();
22 mt_unlock();
23 }

Načítání dat

Level loading

  • načte se do paměti vždy daný level
  • vyžaduje loading screen či před-renderovanou cutscénu/video
  • použito ve hrách Tomb Raider, Doom, Quake,...

Air locky

  • air lock je malá scéna (místnost, výtah)
  • jakmile do ní hráč vkročí, načte se další část a airlock se otevře
  • použito ve hrách Half-Life, Portal (částečně)

World streams

  • engine uvolňuje prostředky týkajících se vzdálených regionů a načítá regiony, ke kterým hráč míří
  • 2D používá lazy loading
  • 3D používá LOD system - objekty blíže ke hráči se načtou ve větších detailech
  • použito ve hrách GTA, WoW, Arma a 2D scrollery

Příklad: Level Loading

Shadow of the Tomb Raider (2018)

Wolfenstein II: The New Colossus (2018), render

Příklad: Air Lock

Portal (2007)

Hellblade: Senua's Sacrifice (2017)

Příklad: World Streaming

World of Warcraft (2004)

Jazz Jackrabbit 2 (1998)

Příklad: Jazz Jackrabbit - event-based vykreslování

1 for (y = FTOT(viewY) - 5; y < ITOT(FTOI(viewY) + viewH) + 5; y++) {
2 for (x = FTOT(viewX) - 5; x < ITOT(FTOI(viewX) + canvasW) + 5; x++) {
3 if ((x >= 0) && (y >= 0) && (x < LW) && (y < LH) &&
4 grid[y][x].event && (grid[y][x].event < 121) &&
5 (eventSet[grid[y][x].event].difficulty <= game->getDifficulty())) {
6 while (event) {
7 if (event->isFrom(x, y)) break;
8 event = event->getNext();
9 }
10 if (!event) { // event not found -> create it
11 switch (getEvent(x, y)->movement) {
12 case 28:
13 events = new JJ1Bridge(x, y);
14 break;
15 case 41:
16 events = new MedGuardian(x, y);
17 ...
18 }
19 }
20 }
21 }
22 }

Multimediální assety

Hudební formáty

AIFF

  • Audio Interchange File Format
  • nekomprimovaná pulzně-kódovaná modulace
  • může obsahovat smyčky a samply

WAV

  • lineární pulzně-kódovaná modulace
  • používá se, když není čas čekat na dekompresi (krátké zvuky)

MP3

  • MPEG-1 Audio Layer III
  • ztrátová komprese

OGG

  • pokročilejší a lepší poměr kvalita/komprese než MP3
  • open-source (na rozdíl od MP3)
Music assets

Obrázkové formáty

JPEG

  • Joint Photographic Experts Group
  • pro digitální fotografii
  • nepodporuje alfa kanál
  • nepoužívat pro pixel-art

PNG

  • Portable Network Graphics
  • dobré výsledky u jednoduchých obrázků (pixel-art a vektory)

TGA

  • Truevision TGA
  • starší formát pro textury

SVG

  • Scalable Vector Graphics
  • formát pro vektorové obrázky
JPG image
PNG image
SVG image

Videa a cutscény

  • čím progresivnější hra, tím více cutscén
  • a) plně progresivní - video, in-game statické cutscény
  • b) částečně progresivní - např. skinovatelný avatar ve scéně
  • c) částečně emergentní - hráč se může pohybovat, ale nemůže do scény zasahovat
  • d) plně emergentní - generovaná cutscéna
  • 1980 - in-game cutscény
  • 1990 - předrenderované cutscény
  • 2000 - in-game cutscény
  • 2010 - předrenderované cutscény
  • 2020 - in-game cutscény
Warcraft cutsceneHellblade cutscene

Videa a cutscény

Another World cutscene

Another World (1991), in-game

The Last of us, Part I

The Last of Us, Part I (2022), in-game

Warcraft cutscene

Warcraft 3, in-game and cinematics

Warcraft reforged cutscene

Warcraft 3 Reforged, cinematics

Textury

  • bitmapa, která je vykreslená na objekt ve scéně
  • textury se obvykle konvertují do formátů, které jsou specifické pro dané grafické API

Typy

  • difúzní textura
  • displacement textura
  • normálová textura
  • volumetrická textura
  • dlaždicová (tile) textura
  • sprite atlas

Formáty

  • Desktop: BC6H, BC7, DXT1, DXT5
  • iOS: ATSC, PVRTC
  • Android: ASTC
Color texture

Difúzní

Displacement texture

Displacement

Normal texture

Normálová

Volumetric texture

Volumetrická

Tileable texture

Dlaždicová

Sprite animation

Sprite atlas

Sprity

Sprite

  • textura pro dynamický objekt
  • obvykle reprezentuje animované postavičky
  • engine umožňuje hýbat s každým spritem nezávisle na sobě
Braid spritesheet

Spritesheet

  • množina souvisejících spritů

Sprite atlas

  • obrázkový soubor, který obsahuje spritesheety

Billboard

  • textura, která je vždy natočená ke kameře
  • na rozdíl od spritů se objevuje i ve 3D hrách

3D Objekty

3D objects

Mesh

Materiály

Textury

3D formáty

  • obsahují geometrii, materiály, textury, animace,...
  • typy geometrií - aproximativní mesh, fixní (precise) mesh, CSG (constructive solid geometry)
  • BLEND - interní soubor Blenderu, podporovaný většinou enginů
  • COLLADA - .DAE soubor, pro CAD software
  • X3D - formát pro WEB
  • GLB, GLTF - formát především pro open-source webové enginy a knihovny
Appr. meshPrec. meshCSGBarvyMateriályTexturyKameraSvětla
STL
OBJ
FBX
DAE
3DS
STEP
X3D
BLEND
GLTF

Generické Assety

ZIP

  • mnoho her používá vlastní formáty, které jsou odvozeny od ZIPu

ZIP

  • bezztrátový formát pro archivaci
  • komprese: shrink, DEFLATE, bzip2, žádná
  • adresářová struktura

zlib

  • open-source knihovna
  • používá DEFLATE kompresi

Herní Data

Serializovaná data

  • XML, JSON, CSV, CFG,...
  • XML se hodí pro hierarchické struktury s větší hloubkou. Pro plošší struktury je tu JSON
  • některé jazyky (např. C++) nemají 1:1 serializační mechanismus
  • JSON je skvělý pro JavaScript, neb je to jeho přirozená notace

Databáze

  • web environment: Web storage (menší obsah dat), IndexedDB (větší obsah dat)
  • desktop/mobile: SQLite

Save data

  • destilát stavu hry, ze kterého je možno zrekonstruovat plný stav v daném čase/bodě
  • velikost obvykle jednotky MB

Web Storage

Local Storage

  • pro data menší velikosti (config, stav hry)
  • až 10MB, bez expirace
  • klíče a hodnoty jsou stringy
1 let myStorage = window.localStorage;
2
3 myStorage.setItem('player_state', player.stateId);
4 myStorage.removeItem('player_state');
5 myStorage.clear();

IndexedDB

  • object-oriented DB
  • low-level API pro strukturovaná data
1 await db.players.add({
2 name: 'Warrior',
3 avatar: await getBlob('sprite_warrior.png'),
4 key_mapping: 'default'
5 });
1 {
2 "player": {
3 "difficulty": "hard",
4 "scene": "mountains_02",
5 "posX" : 12,
6 "posY" : 56,
7 "inventory" : ["flashlight, lighter, candle"],
8 "stamina": 45,
9 "agility": 12
10 }
11 }

Příklad: OpenTTD Save format

OpenTTD save format
  • 3 datové vrstvy
  • velmi komplexní
Transport Tycoon Deluxe

Příklad: DOOM Save format

  • DSG soubory
  • hra načte level a načte stav hry tím, že iteruje přes všechny akce
  • prakticky znemožňuje hacknutí (kromě statů hráče)
  • Akce:
    • dveře, switche, výtahy, schody, světla
    • sebrané předměty
    • projektily, teleporty
    • animace, damage
    • linedefs na minimapě
    • kill counter
1 // p_saveg.c::P_UnArchiveThinkers
2 while (1) {
3 tclass = *save_p++;
4 switch (tclass) {
5 case tc_mobj:
6 PADSAVEP();
7 mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
8 memcpy (mobj, save_p, sizeof(*mobj));
9 save_p += sizeof(*mobj);
10 mobj->state = &states[(int)mobj->state];
11 mobj->target = NULL;
12 if (mobj->player) {
13 mobj->player = &players[(int)mobj->player-1];
14 mobj->player->mo = mobj;
15 }
16 P_SetThingPosition (mobj);
17 mobj->info = &mobjinfo[mobj->type];
18 P_AddThinker (&mobj->thinker);

Levely, mapy, dialogy

  • většinou proprietární formát jednotlivých knihoven/frameworků
  • TMX Mapy
    • XML formát používaný v aplikaci Tiled pro mapy 2D her
    • vrstvy, properties, objekty, animace, wangsety
  • Populární nástroje pro Unity
Tileset

Tilemapy

  • několik vrstev - dlaždice, sprity, další dlaždice, pozadí (např. pro parallax)
  • Dlaždice (Tile) - nejmenší statický objekt na mapě
  • Wang - související dlaždice (např. budova)
Zelda tilemap

Zelda (2004)

The Messenger screenshot

The Messenger (2018)

The Messenger tiles

Příklad: TMX file

1 <map version="1.0" orientation="orthogonal" renderorder="right-down" width="120" height="18" tilewidth="128"
2 tileheight="128" nextobjectid="1">
3 <tileset firstgid="1" name="gameart2d-desert" tilewidth="128" tileheight="128" tilecount="40" columns="5">
4 <image source="gameart2d-desert.png" width="640" height="1024"/>
5 <tile id="2">
6 <properties>
7 <property name="type" type="int" value="1"/>
8 </properties>
9 </tile>
10 <tile id="7">
11 <properties>
12 <property name="type" type="int" value="1"/>
13 </properties>
14 </tile>
15 </tileset>
16 <layer name="background" width="120" height="18">
17 <data encoding="csv">
18 0,23,25,25,36,37,36,23,23,37,25,23,25,......

Příklad: DOOM WAD file

  • "Where's All the Data"
  • Binární formát assetů hry Doom
    • Levely (zdi, podlahy, monstra)
    • Zvukové efekty, hudba
    • Barevná paleta, textury
  • Vytvořeno Johnem D. CarmackemDoom Map
Doom WAD format

Co jsme si řekli

  • Co to jsou herní assety
  • K čemu je Resource Manager
  • Jak se ve hrách řeší načítání
  • Rozdíl použití mezi PNG a JPEG formáty
  • Co je to cutscéna
  • Co je to sprite
  • Typy textur
  • Co je to tilemap

Hláška na závěr

Tuhle hru si pamatuju, protože jsem si kvůli ní musel pořídit nový počítač.90% hráčů