A tegnap új vidiót tettem fel a játék készüléséről.
Idén mindössze két vidiót termeltem, nem valami sok, de dolgozni azért dolgoztam eleget, most egy kicsit hosszabban fogok írni, mert idén már nem fogok többet dolgozni és talán az sem árt, ha egy kicsit jobban kiöntöm a lelkem a témában.
Szóval még mindig a pályageneráláson dolgozom. Amikor a projekt kezdete előtt végig gondoltam a teendőket, úgy gondoltam, hogy nagyjából két hónap alatt befejezem ezt a dolgot. Nos, 2022 július 22-én tettem fel az utolsó vidiót aminek nem volt köze a procedurális generáláshoz, tehát olyan 17 hónapot dolgoztam rajta. Persze, még az sem biztos, hogy befejeztem, de erről később.
Szóval miért is kell nekem procedurális pálya generálás? Bizonyára 17 hónap alatt tervezhettem volna kézzel is 20-30 pályát és akkor már sokkal előbb lennék, talán a játék is be lenne már fejezve. Nos, ez így igaz, de ez a projekt nekem egy kicsit arról is szól, hogy ami nagyon érdekel, arra szánok időt, hogy felfedezzem, vagy megértsem. Márpedig a pálya generálás egy olyan dolog, ami régóta érdekelt, de sosem tudtam beleásni magam. Most szerencsémre lehetőség adódott, hogy addig ássak amíg kedvem tartja és hát jó mélyre sikerült leásnom. Bizonyára ha kézzel terveztem volna meg azokat a pályákat, abból is sokat tanultam volna, de az automatikus generáláson dolgozva is sokat tanultam, ráadásul azért így is szükség lesz arra, hogy sok mindent kézzel csináljak.
Van azért egy másik ok is. Ha írok egy jó pályagenerálót, akkor elvileg végtelen mennyiségű pályát generálhatok, ami jó pályák esetén egy jó dolog. Ha unalmasak lesznek a pályák, akkor fölösleges a végtelen számú, senki sem fog többel játszani mint 2-3. Egyelőre még nem túl jók a pályák, de nem is tettem túl magasra a lécet, ebben az első kísérletben csak egyszerű téglalap alakú szobák összeillesztéséből készült pályákat gyártottam, főként a Wolfenstein 3D-t használva inspirációnak. Igazából még csak nem is érik el azt a szintet a pályáim, mert tényleg csak véletlenszerűen vannak összeillesztve a téglalapok, mert már ezzel is volt elég gondom. Persze, készítettem néhány kisebb tesztet néhány bonyolultabb struktúra (mint mondjuk egy nxn-es cellákból álló fix szobaméretű labirintus, vagy egy 2xn-es szoba elhelyezés középen folyosóval, vagy csillag alakú berendezés) elkészítésével és azok mentek a kis tesztben, de a véletlenszerűen generált illesztések jobban feladták a leckét. Ugyanis már a munka elején kezdtem aggódni, hogy hogyan is fogom megoldani a rövidítések problémáját, ugyanis ahogy én a kifejezéseimet kiértékelem mélységi sorrendben, nem tudnak egymásról az egyes primitívek a különböző kiértékelési ágakon, csak annyit tudnak, hogy elkerüljék egymást. Semmiképpen nem akartam azt, hogy keresgéljek a térben kapcsolódási pontokat, mert az nagyon lassú és egy csomó gonddal is járna. Ezért sokat gondolkodtam ezen a problémán, találtam is rá néhány potenciális megoldást, de egyik sem volt elég jó, a mostani módszer sem olyan nagyon jó, de azt hiszem, megteszi. Azért van szükség a kiértékelési fa ágainak a kommunikációjára, mert ezzel tudom összekötni a szétágazó szobákat és arra meg azért van szükség, hogy rövidítéseket hozzon létre két térben közeli szoba között, azaz ha mondjuk van egy elágazás (azaz egy szobából két ajtó nyílik, (két különböző falon, de akár egy hosszú falon két ajtó is nyílhat, ha van hely)), akkor az egyik ajtót választva és végig küzdve a soron következő szobákat, ne kelljen már visszamenni az elágazásig, mert az unalmas, ugyanis már mind kiöltük ott a szörnyikéket. Inkább lehessen a másik elágazásra átmenni valahol és onnan folytatni a gyilkolászást, persze ha valaki mindent meg akar keresni a pályán, akkor valószínűleg muszáj lesz visszamennie már látogatott részekre, de az már az ő dolga, hogy betanulja, hogy milyen sorrendben érdemes választani az elágazásokban az irányokat, hogy a lehető leggyorsabban bejárhassa a pályát. Szóval úgy érzem, ilyen rövidítések nélkül eléggé nehéz fenntartani az adrenalin szintet, ezért mindenképpen meg kellett oldani. A mostani megoldás egyébként valami olyasmi, hogy a kiértékelés során a már kiértékelt részekre át lehet küldeni egy referenciát a kiértékelés alatti szabályba és az végezhet néhány egyszerű műveletet, pl. kereshet egy bizonyos címkével ellátott primitívek közül a lehető legközelebbit vagy legtávolabbit, meg megpróbálhatja összeadni a térfogataikat (esetleg a falakra elhelyezett markereknek) és megnézni, hogy van-e hely az összeadott térfogatnak is, sőt még kérhet ajtó nyitást is a már létező primitív falára. Lehet, hogy egyszer oda is el fogok jutni, hogy enumerálnom kell a címkézett primitíveket és ezt az enumerációra ki kell terjesztenem a backtrackinget is, ezen is gondolkodom most.
Egyébként nagyon érdekes játék ez, hogy mit tudjon a rendszer, néha úgy érzem, hogy már elég mindent tud, ha van valami problémám, akkor inkább próbáljam megoldani a létező dolgokkal, máskor meg minden ami eszembe jut, bekerül. Az elején, csak három primitívre gondoltam, az alap formák, a szabályok, amelyek mindig formával indulnak (hogy fixáljam azt, hogy a térben hol is fogom kiértékelni, de időközben ezek a formák lehetnek átlátszóak is, szóval ez nem túl erős megkötés) és a változók, amelyek véletlenszerűen felvehetik egy szabály vagy egy forma értékét. Na, most már van vagy 20 ilyen primitív, majd ha véget ér a fejlesztés, mindenképpen fogok készíteni egy vidiót arról, hogy mire is képes a rendszer, mindenesetre mindenféle dolgokra lett szükségem. Időközben rájöttem, hogy én nagyon programozó szemmel nézem még mindig ezeket a feladatokat, szóval még végrehajtási feltételeket is tettem be, olyanokat mint pl ha sikerült egy al-szabályban létrehozni egy primitívet, akkor érjen véget ez a szabály sikerrel (ez egy fajta "if", de van ennél sokkal explicitebb "if" is) vagy a büdzsé ha nem merült ki, akkor érjen véget a szabály sikertelenséggel amikor újra belép a backtracking és megpróbálja kielégíteni a szabályt, meg ilyenek. Azt kell mondjam, hogy igazán élvezem is ennek a szabályrendszernek a pofozgatását, pedig nem egy túl vicces dolog, általában tépem a hajam, hogy miért nem mennek úgy a dolgok ahogy szeretném, aztán mindig találok egy esetet amire nem megy az algoritmusom. Odáig jutottam, hogy kénytelen voltam debuggolási funkciókat beépíteni, egészen pontosan, brékpontot, meg lépésenkénti végrehajtást, hogy lássam pontosan mi történik. Sajnos nem volt valami jó döntés ez a szerkesztő amit írtam, jobb lett volna, ha inkább forráskódszerű valamit írok, még ha nem is imperatív nyelven, hanem deklaratívon, de nagyon hiányzik a teljes forrás átlátása, meg a keresés és kicserélés. Kommenteket kell már fűzzek gyakran a szabályok primitívjeihez, mert erőst felejtek és persze már meta-programozásra is szükség van, ami nagyjából csak annyit csinál, hogy kicserél primitíveket, vagy változókat, vagy szabályokat.
Szóval nem mondanám, hogy jól mennek a dolgok, de azért kitartok már ennél a procedurális generálásnál, mert lehetővé tesz még egy dolgot azon kívül, hogy rengeteg pályát lehet generálni. Mégpedig azt, hogy minőségileg másfajta pályák generálását teszi lehetővé, ugyanis a klasszikus pályaszerkesztésben az ember kénytelen koncentrálni egyetlen helyes bejárási útvonalra, mert olyan munkás a processz. Ha generáljuk a pályákat, akkor elvileg akárhány útvonalat generálhatunk a pályán belül, ami sokkal inkább megfelel a valóságnak, ugyanakkor persze ennek az az ára, hogy az egyes útvonalak nem annyira jól tervezhetőek és nem is annyira szépek és részletesek. De ezzel én már rég kibékültem, a falaknak még mintázata sem lesz, csak egy fix színe (legalábbis amíg meg nem gondolom megint magam), szerintem úgyis a geometria és a világítás adja a pálya érdekességét, nem az, hogy mi van a falon. Persze amíg NaissanceE klónt akartam írni, ez jól adta is magát, ugyanis ott is egyszínűek a falak. De megint megváltoztattam a tervet, mégsem sétáló-szimulátort írok először, mivel oda valami nagyon egyedi pályák dukálnának, inkább megmaradok az fps-ek világában, ahol nem csak a világ számít, hanem a szörnyikék is, akik benépesítik. Persze ezeket vásárolni fogom, az nagyon nem az én asztalom, hogy készítsek is ilyeneket, bár gondolkodtam egy kicsit generált robotokon (petscii robots mintára).
Hmm, én eredetileg arról akartam írni, hogy milyen jó, hogy a saját fejem után mehetek ebben a kérdésben is, de megint elvesztem a technikai részletekben. Fogok még filózni itt eleget, főként ha véget ér a fejlesztés. :)