Povídání o tvorbě herních enginů a představení RetroRPG Engine.

Zdravím zdejší komunitu i náhodného čtenáře.

V tomto článku budu psát o snad zajímavém tématu – implementaci vlastního herního enginu. Ač by se mohlo zdát, že půjde o povídání pouze pro programátory, snad se něco zajímavého dozví i herní vývojáři –  v tomto případě koncoví uživatelé. Často slyším stížnosti na ten, či onen uzavřený engine, proč jsou limity takové a makové. I této problematice se budu v článku věnovat. Přeji příjemné čtení.

Velmi dlouho jsem chtěl vytvořit textovou hru, běžící na konzoli, ASCII tabulka a 16 barev, jediné možnosti exprese. Návrat do osmdesátých let a hold titánům jako NetHack. Protože jsem nenašel engine, vyhovující mým požadavkům, přišel nápad na sepsaní vlastního. Jazykem projektu se stal můj oblíbený C#, vytyčil jsem cíle a tvorba mohla započít.

Spoustu let jsem pracoval v nástroji GameMaker a následně jeho následníkovi GM:S. Odtud jsem se rozhodl převzít objektový model. Hra se skládá z místností, ty obsahují instance, což jsou potomci jejich vzorů – herních entit. Výchozím modelem všech herních objektů je třída GameObject, která obsahuje sdílené hodnoty všech entit – kupříkladu každý objekt potřebuje proměnné pro své souřadnice, grafickou reprezentaci (v mém případě znak a jeho barvu). Instance vyvolávají a reagují na události, čímž přenášejí k okolí informace o svém stavu. Dále je třeba postarat se o vykreslení herní obrazovky, které musí být rozvrstveno tak, aby byl přístup k událostem před vykreslení, při vykreslení a po něm. Záznam o všech instancích uchovávají generické kolekce, patřící třídě GameWorld. Zhruba takové byly moje představy o vnitřním fungování enginu.

Pustil jsem se směle do mírně naivní implementace a záhy narazil na spoustu problémů, které bylo potřeba vyřešit. Začít můžu hned u herní mapy. Na začátku vývoje byla mapa velmi prostá. Tvořila se v libovolném textovém editoru a vypadala nějak takto:

RetroMapa č.1

Můžeme udělat analýzu formátu a jeho možnosti. V hlavičce mapy jsou párové tagy, připomínající strukturou jednoduché XML (nicméně bezparametrické), které poskytují parsující třídě extra informace. Další znaky určují entitu, která bude na jejich místě v mapě vytvořena (# = zeď, P = hráč, E = soupeř). Tady narážíme na první velkou limitaci. K popsání celého chování entity mám k dispozici v mapě jediný znak, tím pádem můžu pouze přímo referencovat objekt, ale ne specifikovat jeho chování. Problém je markantní např. v této situaci: chci na souřadnici umístit zlatou minci a určit její hodnotu. Je snad patrné že značení Q = mince s hodnotou 1, W = mince s hodnotou 2 je nesmyslné, nedostatečné a brzo by mi došly znaky. Řešením je konstruktor instance, kterou budu parsovat. Vznikl proto první editor map, mapa v něm vypadala asi takto:

 

Bezejmenný

[Další stránky textu naleznete pod medailonkem autora]