Az advcomp fordítóval lehet AdvGame JSON forrásfájlokat MEG-4 Kalandjátékokká konvertálni. Ezek klasszikus szöveges játékok (hívják őket Interaktív Fikciónak is), ahol a játékos mondatokat gépel be a játékban történő haladáshoz. Ezeket a mondatokat aztán igére és főnev(ek)re bontja, amikre keres. Ha talál szkriptet az aktuális ige és főnév kombinációhoz, akkor azt lefuttatja.
NOTE: Az advcomp
fordító képes kattintós felületű kalandjátékokat is fordítani pontosan ugyanazokból a JSON fájlokból. Habár a MEG-4
be tudja tölteni ezeket is, de közben sima szöveges kalandjátékká konvertálja őket, a point'n'click játékmód csak az advgame
programmal elérhető.
Korlátok:
A kalandjáték aktuális állapota egy 256 elemű bájttömben tárolódik. A legelső bájt az aktuális szoba száma, az utolsó 32 bájt a leltárnak van fenntartva, a többi szabadon felhasználható. Ezek lehetnek jelzőbitek, számlálók, bármi. A [szkriptek] ezen a 256 bájtnyi memórián végeznek műveleteket és ez az állapot elmenthető és visszatölthető játékmentésként.
A forrásfájl legfelső szintjén lennie kell egy "AdvGame"
JSON struktúrának, ami egyben a fájl azonosítója is. A mezői:
sprites
: sztring, 256 x 256 pixeles PNG szprájtlap elérési útja, a felső 32 sora üresmusic
: sztringtömb, Amiga MOD (.mod) vagy MIDI (.mid) zenefájlok elérési útjai (8 elemű)sounds
: sztringtömb, RIFF WAVE (.wav) formátumú fájlok elérési útjai (31 elemű)setup
: számtömb, a játék induló állapota (256 elemű, mind 0 és 255 közötti, az első szám az induló szoba)status
: számtömb, melyik játékállapotokat írja ki a státusz (2 elemig, többért lásd custom
)vars
: sztringtömb, a állapot indexek aliaszai, ún. "változók" (csak a JSON-ben használt)rooms
: sztringtömb, a szobaszámok aliaszai (csak a JSON-ben használt)verbs
: sztringtömb, a verb1
, verb2
, verb3
stb. aliaszai (csak a JSON-ben használt)nouns
: sztringtömb, a főnevek aliaszai (csak a JSON-ben használt)colors
: 5 elemű számtömb, intró háttér- és betű-, szoba háttér- és betű-, valamint promptszínpos
: szám, szöveg pozíciója pixelekben a képernyő tetejétől számítvacustom
: sztringtömb, plusz kusztom C kód a felhasználói felület megjelenítésére (első az intróé, a második a szobák kódja)logic
: sztringtömb, általános játék logika szkript, ami mindig minden parancs előtt lefutconfig0
: struktúra, fő játékkonfigurációconfig1
: struktúra, alternatív játékkonfiguráció (többnyelvűség támogatás)Alapesetben feltételezi, hogy a szprájtlap ketté van vágva: a felső 128 sor szobánként cserélődik, az alsó 128 sor állandó
(felhasználói felület elemei, ikonok stb. ez utóbbiak töltődnek be a sprites
-ról). Ha a textpos be van állítva, akkor az intrónál
és a szobáknál is textpos (de legfeljebb 96) sor a szprájtlap 32. sorától kezdődően megjelenik a szöveg fölött a képernyőn. A
kusztom felület C kóddal pedig akármilyen és akármennyi szprájt kirakható e helyett.
Van egy fő- és egy alternatív konfiguráció a többnyelvűség támogatásához. A mezőik:
lang
: sztring, kétbetűs nyelvkkódtext
: sztring, intró szövege (429 bájtig)answers
: 4 elemű sztringtömb, üzenetek (egyenként 63 bájtig): ismeretlen parancs, nem lehet arra menni, nem használható, játék elmentve.save
: sztringtömb, játékmentés igéi (15 bájtig, 8 szinoníma)load
: sztringtömb, játékbetöltés igéilist
: sztringtömb, leltárlistázás igéinorth
: sztringtömb, északra navigálás igéiwest
: sztringtömb, nyugatra navigálás igéieast
: sztringtömb, keletre navigálás igéisouth
: sztringtömb, délre navigálás igéiup
: sztringtömb, emeletre navigálás igéidown
: sztringtömb, alagsorba navigálás igéiverb1
: sztringtömb, 1-es akció igéi (a kulcs lehet valamenyik "verbs" aliasz is)verb2
: sztringtömb, 2-es akció igéiverb3
: sztringtömb, 3-as akció igéiverb32
: sztringtömb, 32-es akció igéinouns
: sztringtömb, tárgyak főnevei (255 sztringig)A parszolás során a három UNICODE karakternél rövidebb szavaknak teljes egészében, egyébként csak a szó elején kell egyeznie. Emiatt
ha például a verb1
-nek [ "kinyit" ]
, a nouns
-nak meg [ "lád" ]
van megadva, akkor fel fogja ismerni azt is, ha a játékos
kinyit láda
vagy kinyitom a ládát
parancsot gépeli be.
A szobák sorszáma 1 és 254 közötti lehet (a 0-ás szoba az intró illetve reset valamint nem járható irány navigációs parancsoknál, a 255-ös meg a mentett játékállás helye). Egy szoba struktúra mezői:
image
: sztring, egy PNG elérési útja, legfeljebb 256 x 96 pixelestext0
: sztringtömb, a config0
-hoz tartozó szövegek (32 sztringig, egyenként 255 bájt)text1
: sztringtömb, a config1
-hez tartozó szövegeknorth
: szám / sztring / sztringtömb, északi irány szkriptwest
: szám / sztring / sztringtömb, nyugati irány szkripteast
: szám / sztring / sztringtömb, keleti irány szkriptsouth
: szám / sztring / sztringtömb, déli irány szkriptup
: szám / sztring / sztringtömb, felfele irány szkriptdown
: szám / sztring / sztringtömb, lefele irány szkriptlogic
: szám / sztring / sztringtömb, a szobába lépéskor automatikusan lefutó szkriptverbX
: szám / sztring / sztringtömb, önálló igés szkriptek (X értéke 1 és 32 közötti, vagy "verbs" aliasz)verbX Y
: szám / sztring / sztringtömb, egy főnévvel rendelkező szkriptek (Y értéke 1 és 255 közötti, vagy "nouns" aliasz)verbX Y Z
: szám / sztring / sztringtömb, két főnévvel rendelkező szkriptek (Y, Z értéke 1 és 255 közötti, vagy "nouns" aliasz)A szövegek 255 bájtosak lehetnek, és minden szobának saját 32 szövege lehet, melyeket a say
/ sayv
/ sayc
utasításokkal
lehet kiiratni.
Az 1-es számú szoba szkriptjei speciálisak abból a szempontból, hogy minden más szobában is elérhetőek. Emiatt ide érdemes egy
"Vége a játéknak" szobát rakni, aminek a logikája csak egy jmp 0
-ás resetet tartalmaz, így nincs benne további parancsbekérés.
Bármelyik navigációs vagy igés parancs utánni JSON érték lehet egy nem nulla szám, ami egy szobaszám:
"north": 12,
Vagy lehet sztring, ami egy "rooms" aliasz:
"north": "padlás",
De ha egy sztringtömb, akkor az egy utasításokat tartalmazó szkript:
"north": [ "jmp 12" ],
Ezek befolyásolják a játék állapotát, szöveget jelenítenek meg, stb. Az utasítások paraméterei számok, de a megfelelő helyeken "rooms", "vars", stb. aliaszok használhatók.
A rendelkezésre álló utasítások:
end
: szkript végeand
: az utótagja a következő utasítás feltételéhez adódik logikai ÉS kapcsolattalor
: az utótagja a következő utasítás feltételéhez adódik logikai VAGY kapcsolattalbgm X
: háttérzene lejátszása (X értéke 0 és 7 közötti)sfx X
: hangeffekt lejátszása (X értéke 0 és 63 közötti)jmp X
: X szobába lép (X értéke 0 és 254 közötti)jmpv (X)
: mint a jmp
, de a szobát az X változóból veszicall X
: meghívja az 1-es szoba X szkriptjét (X értéke 1 és 64 közötti)callv (X)
: mint a call
, de a szkript számát az X változóból veszigive X
: hozzáadja az X főnevet a leltárhoz (X értéke 1 és 254 közötti)take X
: kiveszi az X főnevet a leltárbólsay X
: az X szöveg megjelenítése (X értéke 1 és 32 közötti)sayv (X) Y
: az X változó értéke + Y szöveg megjelenítésesayc X Y
: vagy az X (hamis), vagy az Y (igaz) szöveg megjelenítése kondíciótól függőenadd (X) Y
: az X változó növelése Y-al (X és Y értéke 1 és 255 közötti)addv (X) (Y)
: az X változó növelése Y változó értékévelsub (X) Y
: az X változó csökkentése Y-al (X és Y értéke 1 és 255 közötti)subv (X) (Y)
: az X változó csökkentése Y változó értékévelset (X) Y
: az X változó értékét Y-ra állítja (Y értéke 0 és 255 közötti)rnd (X) Y
: mint a set
, de egy 0 és Y közötti véletlenszámot rak X-bemov (X) (Y)
: az Y változó értékét X változóba másoljaEzek az utasítások mind elláthatók a következő utótagok egyikével:
if (V) = N
: csak ha a V változó értéke Nif (V) != N
: csak ha a V változó értéke nem Nif (V) <= N
: csak ha a V változó értéke kissebb vagy egyenlő, mint Nif (V) < N
: csak ha a V változó értéke kissebb, mint Nif (V) > N
: csak ha a V változó értéke nagyobb, mint Nhas N
: csak ha az N főnév a leltárban vannot N
: csak ha az N főnév nincs a leltárbanKülönleges eset, ha a (V)
250 vagy nagyobb, ilyenkor az adott navigációs irányt használja: 250 (vagy north
, észak), 251 (vagy
west
, nyugat), 252 (vagy east
, kelet), 253 (vagy south
, dél), 254 (vagy up
, fel), 255 (vagy down
, le). Ha például azt a
feltételt szeretnénk, hogy északra járható-e a szoba, az if north != 0
. Ezek az állapotindexek a leltár bitmaszkját tárolják,
amit a has
illetve not
feltételekkel kell elérni, így nincs ütközés.
A 0-ás szobára ugrás vár egy billentyűleütésre, majd újraindítja a játékot és a 0-ás helyett a megadott induló szobára ugrik (ez
csak kifejezetten jmp
utasításnak adható meg, mert a 0 szám nem használható, mint cél szobaszám).
Alapesetben egy szobaösszeköttetéshez szobaszámot (vagy "rooms" aliaszt) adunk meg, de ez feltétel nélkül átengedi a játékost az egyik szobából a másikba. Például ha van egy "kulcs felvéve" jelző a 7-es állapotban, és a 11-es szobában pedig van egy ajtó az északi irányban a 12-es szoba felé, és azt akarjuk, hogy csak akkor legyen járható, ha a játékos rendelkezik a kulccsal, akkor szkriptelt navigációra van szükség.
"11": {
"text0": [ "Az ajtó zárva." ],
"north": [ "jmp 12 if (7) = 1", "say 1" ]
}
Ilyenkor a north
mezőben szám helyett egy sztringtömben a jmp 12 if (7) = 1
utasítást adjuk meg. Ez csak abban az esetben
ugrik a 12-es szobába, ha a 7-es állapot értéke 1, egyébként marad a 11-esben. Ilyenkor mondhatjuk azt is, hogy "Az ajtó zárva"
a say 1
utasítással (ha korábban a 12-es szobára ugrottunk, akkor ez már nem hajtódik végre). A szobaszám helyett használható
"rooms" aliasz, az állapot index (változó) helyén pedig "vars" aliasz, például jmp padlás if kulcs = 1
. Bonyolultabb összefüggés
is megadható az and
/ or
utasításokkal, amennyiben a befolyásolandó utasítás elé tesszük őket. Például hogy csak éjjel
lehessen átmenni, és csak ha lámpája is van a játékosnak, az [ "and if éjjel = 1", "and has lámpa", "jmp padlás if kulcs = 1" ]
.
Egy másik példa, ami véletlenszerűen ugrik a 100 és 109 közötti szoba valamelyikére:
[ "rnd (1) 10", /* 0 és 9 közötti véletlenszám az 1-es állapotba */
"add (1) 100", /* hozzáadunk 100-at így az most 100 és 109 közötti */
"jmpv (1)" ] /* az állapotban tárolt szobaszámra ugrás */
A kiírás is jöhet változóból, például ha a halál okát a 9-es állapotban tároljuk, ami 0 és 2 közötti, akkor:
"text0": [
"Meghaltál, ennek oka:", /* 1-es szöveg */
"megfulladtál", /* 2-es szöveg */
"éhenhaltál", /* 3-as szöveg */
"bedarált a hegyirém" /* 4-es szöveg */
],
"logic": [ "say 1", "sayv (9) 2" ]
Itt a say
előbb kiírja az 1-es szöveget, majd a sayv
veszi a 9-es állapot értékét, hozzáad 2-őt, és az annyadik szöveget írja
ki a 2-es és 4-es közötti szövegek közül.
Ugyancsak hasznos a feltételes szövegkiírás, ami a kondíciótól függően vagy egy hamis, vagy egy igaz szöveget ír ki. Például:
"text0": [
"Nincs nálad kulcs.", /* 1-es szöveg */
"Kinyitottad a ládát." /* 2-es szöveg */
],
"nyit láda": [ "sayc 1 2 has kulcs", "set (10) 1 has kulcs" ]
Amennyiben a játékosnál nincs kulcs, úgy a sayc
az 1-es, ha van, akkor meg a 2-es szöveget írja ki. Aztán beállítunk egy "láda
nyitva" jelzőt a set
-el, de csak akkor, ha volt kulcs a játékosnál. (Hogy a parancs így megadható legyen, ahhoz kell egy nyit
"verbs" aliasz és egy láda
"nouns" aliasz is. Mégegyszer, az aliaszok csak a JSON-ben használatosak és függetlenek a lefordítható
szavaktól, amit a játékosok a játék közben gépelnek be.)
Minta MEG-4 Kalandjátékok a meg4_advgame repóban találhatók.