Game Maker: Optimalizace kódu

Během několika posledních let, kdy výrazná část mé tvorby vznikala právě v tomto vývojovém prostředí, jsem nalezl řadu cest jak poměrně razantně snížit výkonnostní náročnost výsledné aplikace
a touto formou Vám nyní chci nabídnout některé z těchto mých poznatků. Upozorňuji, že níže uvedené postupy jsou vyzkoušeny pouze v GM 8.1, nicméně věřím, že jejich uplatnění je možné i v GM 8 a GM 7. V GM Studiu žádný z těchto postupů s největší pravděpodobností neplatí (Studio funguje naprosto jinak, než předešlé verze). Každý z postupů jsem pro větší přehlednost přibližně ohodnotil několika atributy (hodnota je od -5 🙁  do 5 🙂 ). Hodnota ukazuje jaký maximální potenciál daný postup zhruba má.

 

Pohledy, myš a klávesy
Snížení nároků: 🙂 🙂 🙂
Obtížnost použití: 🙁
Přehlednost kódu: 🙂 🙂 🙂

Pokud v jedné iteraci častěji zjišťujete, zda byla stisknuta nějaká klávesa (např. v menu), tlačítko myši nebo pracujete s pozicí pohledu (případně myši). Je velice výhodné nepoužívat předpřipravené funkce GM (mouse_y, mouse_check_button_pressed, view_xview…). Mě osobně se nejvíce osvědčilo v Begin step uložit do mých proměnných (deklarovaných v Create) všechny tyto informace, ale předpokládám, že většina z vás bude chtít použít více než jeden či dva objekty a proto v příkladu použiji globální proměnné (v příkladu jsou použity jen vlastnosti myši, ale princip je zřejmý i pro ostatní zmíněné věci). Výhodné je to i v tom, že se zpřehlední kód.

GM funkce: Stahujte zde.
Proměnné: Stahujte zde.

 

CleanMem
Velkým neduhem GM je práce s pamětí RAM. Zejména obrázky ukládané do paměti zaberou zcela zbytečně obrovské množství prostoru (nejvíce zarážející je ovšem fakt, že ani v GM studiu s tím nikdo nic neudělal). Tento problém do značné míry řeší úžasná knihovna zvaná CleanMem, která je dokonce zdarma i pro komerční použití. Informace zde: http://gmc.yoyogames.com/index.php?showtopic=438215.

 

Předčasné ukončení kódu
Snížení nároků: 🙂 🙂 🙂
Obtížnost použití: 🙁 🙁 🙁
Přehlednost kódu:

Tohle bude celkem rychlé. 🙂 Jednoduše, pokud víte, že v určitém momentu už kód pokračuje zbytečně, ukončete jej pomocí exit. Např. pokud máte v menu vytvořená tlačítka, která kontrolují pozici myši (najedete na tlačítko myší a to vykreslí jiný obrázek), můžete hned jak zjistíte, že je myš nad jedním tlačítkem, kontrolu ukončit (nad dalšími tlačítky už být myš nemůže).

 

Switch nebo if?
Snížení nároků: 🙂 🙂
Obtížnost použití: 🙁 🙁 🙁
Přehlednost kódu: 🙂 🙂

Nelze říci, co je lepší, protože obojí funguje jinak. Nicméně pokud situace dovoluje použít switch rozhodně jej použijte.
Někdo může namítat, že bude mít jen těžko 3000 podmínek ve svém projektu jako je tomu v příkladu. Inu, pokud je Váš projekt tak maličký, nemusíte se s tím pravděpodobně trápit. Je, ale podstatné si uvědomit, kolik podmínek skutečně v projektu máte.

if: Stahujte zde.
switch: Stahujte zde.

 

Samotný kód x Scripty x Externě uložený kód
Snížení nároků: 🙂 🙂
Obtížnost použití:
Přehlednost kódu: 🙁

Zde je funkční příklad zbytečný. Chci jen upozornit na nemalé rozdíly v rychlosti vykonávání těchto tří věcí. Jednoznačně nejrychlejší je bez debat samotný kód, těsně za ním jsou volané scripty a těžce na konci se belhá kód externě uložený. Scripty je bez pochyby výhodné používat, nicméně je třeba používat je také s rozumem. Obecně doporučuji nikdy nevytvářet jednořádkové scripty, práci vám to nijak markantně neulehčí, ale nároky přibudou. Také je dobré rozmyslet si, jak bude script strukturovaný, viz níže příklad s oknem s nastavením.
Př.:

Tohle je pomalejší:
scr_okno:
if(zobrazNastaveni){
//vykresli tlacitka, posuvniky, text…
}
Draw:
src_okno();

Tohle už je hezčí:
scr_okno:
//vykresli tlacitka, posuvniky, text…
Draw:
if(zobrazNastaveni){
src_okno();
}

Hlavní rozdíl je v tom, že pokud okno nemá být zobrazeno, nemusí hra hledat daný script -> je to rychlejší.
Poslední možnost, externě uložený kód, doporučuji nepoužívat vůbec. Jedná se o velmi pomalou záležitost a nedaří se mi vymyslet případ, kdy by to bylo potřeba.

 

Řízené vykreslování
Snížení nároků: 🙂 🙂 🙂 🙂 🙂
Obtížnost použití: 🙁 🙁 🙁 🙁
Přehlednost kódu: 🙁 🙁

To nejzajímavější nakonec. 🙂 Pomocí řízeného vykreslování můžete nároky hry snížit klidně na desetinu 🙂 (takže můžete dosahovat až na pár tisíc FPS).
GM ze základu překresluje obrazovku každou jednu iteraci, což je poměrně dost zbytečné, zejména v některých případech. Abychom tedy toto překreslování vypnuli, vypneme vykreslování barvy pozadí (background_showcolor = 0;) a vykreslování barvy okna (nějak se mi nedaří vzpomenout si na kód 😛 , ale lze to vypnout v nastavení views v okně s room). Deklarujeme si proměnnou, která bude kontrolovat vykreslování (0 – nekresli, 1 – kresli) a tuhle proměnnou dáme do podmínky všude, kde chceme řídit vykreslování. Vykreslování jednoduše vždy spustíte tam, kde potřebujete (např. myš najede nad tlačítko). Nakonec vytvoříte objekt, jenž bude vždy na konci iterace vykreslování vypínat.
Celé to lze samozřejmě ještě výrazně zlepšovat (Např. tak, aby se překreslila jen oblast, která se skutečně mění. Nebo napsat kód tak, aby se vždy vše vykreslilo jen jednou – v našem příkladě se bude tlačítko překreslovat jen pokud na něj najedete myší), ale myslím, že princip je jasný a vylepšení na konkrétní projekt či situaci si už každý musí udělat sám.
Jelikož jsem líný :-P, jako příklad jsem jen upravil aplikaci, která vykresluje tlačítka (viz výše). Přestože se jedná o příklad, kde nárůst FPS bude minimální (u mě na PC zvýšení cca o 300 FPS), je na něm stejně dobře vidět, jak to celé funguje. 🙂

Řízené vykreslování: Stahujte zde.
Klasické vykreslování: Stahujte zde.

 

Většina toho, co jsem sem napsal jsou věci použitelné zejména v konkrétních situacích. Aby jste byly skutečně schopni svůj projekt krásně optimalizovat, je nutné znát vnitřní fungování vývojového prostředí, které používáte, fungování samotného hardware a rozhodně není na škodu chápat jak funguje systém pro který vyvíjíte (jak pracuje s vaším kódem atp.). Můj názor je takový, že pokročilým programátorem v daném jazyce se stáváte až tehdy, kdy znáte tohle vše (o nějakém „mistrovství“ ani nemluvě), protože pak teprve umíte skutečně používat funkce, scripty, třídy atp., prostě to, co vámi používaný jazyk nabízí.