Ako vznikal snehuliak?
game-dev; 21. 1. 2023
Steam Počas roku 2022 som mal v hlave dosť dlhú dobu myšlienku vrátiť sa k projektu erLett a reštartovať ho. Popri práci na Repeate som vytváral veľmi malé skúšobné aplikácie, kde som pracoval s Vulkan API. Išlo o úplne základné veci ako vykreslenie trojuholníku alebo neskôr funkčná replika Asteroidov. Tieto testy ma časom postavili do pozície, keď som sa sám seba brzdil aby som projekt nereštartoval s tým, že by som ho implementoval mimo enginu, a sústredil sa radšej na obsahovú časť. Myšlienka ma ale čoraz viac dráždila: predsa nemôže byť až tak zložité integrovať externý fyzický engine do renderingu, ktorý mi už fungoval. Podobné myšlienky ma prenasledovali až do novembra.
V novembri som sa rozhodol, že nechcem reštartovať erLett, ale skúsiť niečo, čo je reálnejšie dokončiť do zimy, ideálne v okolí Vianoc. Tento časový rámec bol kľúčový krok k dokončeniu projektu. Téma bolo pohľadnica alebo novoročné prianie. Rozsah bol jasný:
- iterácia grafiky z projektu v-obrazoch
- kamera z prvej osoby
- cieľom hry je postaviť snehuliaka
- na snehuliaka môžeš pridávať rôzne objekty
- k niektorým objektom sa dostaneš za pomoci snehových gúľ (toto sa do hry nedostalo)
- celá hra je implementovaná v jazyku Odin, využíva Vulkan API priamo, bez grafického či herného enginu
Po tomto začal asi mesiac práce na editore. Osobne si myslím, že tento krok nebol až tak potrebný ale niektoré časti vo výsledku uľahčil. Bolo by totiž viac než reálne hru vytvoriť len v blenederi a následne importovať celú scénu, ktorá by reprezentovala herný svet. Hlavným dôvodom, prečo som sa rozhodol pre vlastný editor bol špecifický vizuál. V editore som totižto editoval scénu tak ako vyzerala aj v hre. Časom bol editor užitočný aj pri práci s collidermi.
Časti kódu boli portované z projektu v-obrazoch. Dobrý príklad je napríklad ovládanie kamery. Grafické rozhranie editoru využíva veľmi používanú knižnicu v game-deve: ImGUI. Projekt však tento krát vznikal v jazyku Odin. Na rozdiel od toho bol projekt v-obrazoch písaný v c++. Takže vývoj sprevádzal ako preklad c++ do Odin, tak vytváranie väzobného kódu pre niektoré knižnice ako spomenté ImGUI. Práve pre ImGUI som vytvoril vlastný generátor. Detaily prečo som sa tak rozhodol popisujem na jeho Github stránke: https://github.com/foxik0169/imgui-odin. ImGUI bolo použité iba pre editor a nie je dostupné vo vydanej hre.
Jazyk Odin sledujem už dlhšiu dobu. V stručnosti ide o jednoduchý procedurálny jazyk, ktorý má za cieľ poskytovať modernejšiu alternatívu k C. Teda nepracuje s OOP. Zároveň nemá žiadne automatické spravovanie pamäte. Človek musí pracovať s rôznymi alokátormy a spravovať si pamäť ručne. V snehuliakovi sa to až tak neprejavuje, nakoľko je hra naozaj malá. Na rozdiel od C disponuje základnými dátovými štruktúrami ako hashmap, dynamické pole či slice (v podstate štruktúra obsahujúca smerník a dĺžku, avšak jazyk disponuje špecifickou syntaxou, ktorá s týmito typmi uľahčuje prácu).
Na fyzickú simuláciu som použil knižnicu Bullet Physics 3\. Práca s knižnicou bol väčší oriešok ako napr. ImGUI práve preto, že pre Bullet neexistuje C API, na ktoré by sa dal väzobný kód napísať. Samozrejme existuje spôsob ako viazať c++ kód na iné jazyky, ale táto cesta mi prišla neúnosná v mojich časových limitoch. Preto som sa rozhodol vytvoriť c++ knižnicu, ktorá zverejňovala C API pre volanie z môjho Odin programu. Knižnica obsahuje len funkcie, ktoré som potreboval a nekopíruje API Bullet Physics
Čo sa týka ďalších knižníc, spočiatku som myslel, že na zvuk použijem FMOD. Avšak, po tom čo som ručne vytvoril väzobný kód :), som sa rozhodol knižnicu vymeniť za opensource alternatívu OpenAL-soft. Iste, knižnice majú úplne odlišné úrovne vlastností a komplexity ale pre tak jednoduchý projekt mi prišlo fajn využiť túto možnosť a vďaka tomu nemať povinnosť zobraziť logo firmy v tiráži. Nakoniec sa aj tak na hudbu nedostalo a hra zostala len so zvukmi.
Vizuálna stránka
Princíp vizuálnej stránky vznikal práve pre projekt v-obrazoch ešte za môjho štúdia a za finančnej podpory fakulty. Vrcholy objektov sú v reálnom čase (v shaderi) posunuté na najbližší predpočítaný náhodný bod vrámci obrazovky.
Nakoľko vizuál, ktorý vznikal týmto procesom bol v kamere z prvej osoby príliš intenzívny, do implementácie som pridal jednoduché váženie na základe vzdialenosti vrcholu od kamery. Tj. na vzdialené objekty je efekt aplikovaný s nižšou intenzitou ako na tie blízke. K tomuto zásahu mi pomohla aj komunita Indie herných vývojárov na fórach redditu, kde som zdieľal ukážky z aktuálneho stavu, ktorý som mal pod rukami.
Zároveň je v aktuálnej verzií pridaný jednoduchý cel-shading - dvoj-úrovňové tieňovanie. Pridal som ho práve preto, že bez akéhokoľvek tieňovania objekty boli len animujúca sa silueta a teda bolo relatívne zložité sa v nich zorientovať.
Stopy hráča a snehových gúľ
Hre na charaktere dosť pridávajú aj stopy chôdze a snehových gúľ. Stopy hráča sú implementované inštancovanou geometriou: do GPU sa posiela len model jednej stopy, a transformačné matice každého kroku. Stopy snehových gúľ sú vytvorené celé na CPU ako samostatný model, pre každú guľu zvlášť.
Záver
Projekt hodnotím pozitívne. Portovanie OpenGL kódu do Vulkan, učenie sa Vulkan API a celé to zaobaliť projektom, ktorý má začiatok a koniec bolo dobré rozhodnutie. Určite existujú jednoduchšie cesty, ako využiť nejakú abstrakčnú knižnicu alebo jednoduchšie API ako napríklad DX11 či práve OpenGL. Skúsenosť to bola dobrá a ak sa nájde niekto, koho nízko úrovňový kód zaujíma, určite odporúčam práve skúsiť vytvoriť projekt, ktorý má koniec.
Vulkan API je veľmi podrobné a manuálne, čo môže vyvolávať na prvý dojem odpor. V niektorých prípadoch sa s ním avšak pracuje lepšie, práve pre validačné vrstvy, ktoré sú dostupné vo Vulkan SDK. Taktiež neobsahuje veľa konceptov z hardvéru, ktorý je dnes už zastaralý. Na druhú stranu, tým, že Vulkan smeruje na veľkú škálu zariadení (mobilné - konzoly - pc), tak existuje šanca, že kód, ktorý napíšete, nebude na niektorej z nich fungovať.