________________________________________________________________________
[<<] [Inhalt] [>>] I. Ein erster Blick auf T.A.G.

2. Grundkonzept eines Adventures

2.1.   Wie ist ein Adventure aufgebaut?
2.2.   Der Text-Adventure-Generator TAG
2.3.   Aufbau der Quelldatei für TAG
2.4.   Der Parser

2.1. Wie ist ein Adventure aufgebaut?

Ein klassisches Text-Adventure besteht aus einer Anzahl von Räumen, die miteinander verbunden sind, aus einigen Objekten, die in diesen Räumen herumliegen, aus Personen, die dort umherwandern und natürlich aus verschiedenen Möglichkeiten, die Objekte und Personen zu manipulieren. Dies sind die sog. Rätsel, von denen man eine ganze Menge lösen muß, um an sein Ziel zu gelangen.

Das Ziel kann dabei alles Mögliche sein. Eine Schatzsuche in unwirtlichen Gegenden oder eine rechtzeitige Flucht vor einer Supernova. Je nachdem, was zu tun ist und wo das Adventure spielt, werden dann auch die Objekte und Personen aussehen. Wenn Ihr eine Idee habt, worum es in Eurem Adventure gehen soll, werden langsam immer mehr Sachen in Eurem Kopf zusammengetragen. Ein Blatt Papier oder zwei sind dabei sehr hilfreich. Diese Aufzeichnungen sind hinterher ziemlich wichtig, um den Überblick zu behalten, und ich rate Euch, sie in einer Mappe zu sammeln oder sie zumindest zusammenzuheften.

Das erste, was bei einem Adventure festgelegt werden muß, sind die Handlung, die Räume, die Objekte und die Rätsel, die gelöst werden müssen. Schnappt Euch also ein Blatt Papier und beginnt, eine Karte zu malen von der Gegend, in der Euer Adventure spielen soll. Am besten ist eine herkömmliche Karte, in der die Orte mit Kästchen dargestellt werden. Diese Karte wird wahrscheinlich nach und nach erweitert oder verändert werden, wenn Euch noch etwas einfällt oder wenn Ihr auf etwas verzichten wollt.

Dann müssen die Objekte auf die Räume verteilt werden. Objekte sind Gegenstände, die aufgehoben werden können, feste Objekte, wie etwa Möbelstücke, Türen oder Bäume, aber auch Personen sind Objekte im Sinne von TAG.

Um die Rätsel lösen zu können, ist es wahrscheinlich erforderlich, daß Ihr neben den Befehlen, die TAG schon mitbringt (z.B. gehen, nehmen, weglegen, untersuchen usw.), Eure eigenen Befehle einführt. Dabei sind Eurer Phantasie keine Grenzen gesetzt, und Ihr könnt verschiedene Synonyme verwenden.

2.2. Der Text-Adventure-Generator TAG

TAG ist ein 'Generator' für Text-Adventures. Er liest einen vom Benutzer erstellten Datensatz, die Quelldatei, und analysiert sie. Wenn keine Fehler gefunden wurden, wird die Datei erstellt. Diese Datei besteht aus drei großen Blöcken. Diese Blöcke sind:

  • Die Datenbank, die alle Informationen über Objekte, Räume, Befehle und Anweisungen enthält.
  • Das Lexikon mit dem Wortschatz, der vom Programm verstanden wird
  • Die Ausgabetexte des Programms. Dieser Block ist i.A. der größte.

Eine weitere Datei, das Logbuch, enthält Informationen zum Generationsvorgang und kann, wenn gewünscht, herausgeschrieben werden.

Die Quelldatei wird in einem beliebigen ASCII-Editor erstellt. Der Standard-Name einer solchen Datei ist job.adv. Anschließend werden die Spieldateien generiert:

        >tag 

Dabei ist der Name der Quelldatei und der zu erstellenden Dateien. (Eine genauere Aufzählung der Optionen, die mit dem Generator verwendet werden können, wird im nächsten Abschnitt gegeben.) Standardmäßig wird für die Spieldatei die Endung .tag benutzt.

Um das so generierte Adventure spielen zu können, benötigt man den Interpreter für Text-Adventures TAM (Text-Adventure-Maschine):

        >tam 

Mit diesem Programm wird dann der Adventure-Datensatz interpretiert und die vom Adventure-Autor gewünschten Handlungen auf den Bildschirm gebracht.

2.3. Aufbau der Quelldatei für TAG

Alle Daten, die der Generator zum Erstellen der Spieldatei und damit zum Ausführen des Adventures benötigt, müssen in der Quelldatei job.adv ein- gegeben werden. Der Aufbau ist so simpel wie möglich gehalten. Die Eingabedatei ist in verschiedene Blöcke unterteilt, die in beliebiger Reihenfolge angegeben werden können. Es gibt verschiedene Arten von Blöcken:

  • Block zur Umgebungsdefinition
    Hier werden allgemeine Parameter, wie Text- und Hintergrundfarbe, Dateisuffixe und -kennungen u.ä. festgelegt. Dieser Block kann ausgelassen werden, dann werden die Standardeinstellungen benutzt.

  • Definitionsblöcke
    In diesen Blöcken werden alle Räume, Objekte, Flaggen, Aktionen und weiteren Spielvariablen definiert. Diese Blöcke beschreiben das eigentliche Adventure.

  • Textblöcke
    Hier werden die Ausgabetexte im Programm definiert. Es können bis zu 255 Blöcke mit jeweils 255 Texten definiert werden.

  • Ende-Block
    Dies ist eigentlich kein richtiger Block, sondern die Anweisung, die den Eingabedatensatz beendet.

Die Befehle in den jeweiligen Blöcken sind ebenfalls so einfach wie möglich. Die Befehle müssen zeilenweise eingegeben werden, eine Zeile für jede Anweisung. TAG unterteilt alle Zeilen in Worte, die mit Leerzeichen und Kommas voneinender getrennt sind. Dabei gibt es verschiedene Arten von 'Wörtern':

  • Schlüsselwörter von TAG
    Dies sind vordefinierte Wörter, die das Programm erkennt. Hierbei wird nicht zwischen Groß- und Kleinschreibung unterschieden. Einige häufig verwendete Konstanten werden durch ein vorangestelltes Prozentzeichen gekennzeichnet.

  • Benutzerdefinierte Schlüsselwörter
    Diese Schlüsselwörter werden vom Benutzer definiert, um Flaggen, Räume, Objekte u.ä. zu beschreiben. Diese Wörter müssen einmalig sein unter den anderen Schlüsselwörtern, benutzerdefiniert oder von TAG. Auch hier wird nicht zwischen Groß- und Kleinschreibung unterschieden.

  • Strings
    Zeichenketten, die von Hochkommas (Apostrophen) eingeschlossen sind, heißen Strings. Bei Strings werden Groß- und Kleinschreibung unterschieden. Sie können eigentlich alle Zeichen außer dem Hochkomma enthalten.

    Im Falle von Texten und Beschreibungen, die während des Spiels ausgegeben werden sollen, können Strings auch über mehrere Zeilen gehen. An Stelle des Zeilenumbruchs wird dann intern ein Leerzeichen eingesetzt. Diese Ausgabestrings können auch kurze Anweisungen in eckigen Klammern enthalten.

    Strings, die nur zur Definition des Vokabulars dienen, bestehen nur aus einem Wort. Sie können nur Buchstaben und Zahlen enthalten.

  • Zahlen
    können in TAG nur ganzzahlig sein. In den meisten Fällen reicht der Bereich von 0 bis 255 aus. Solche Zahlen belegen genau ein Byte und werden in TAG vorrangig verwendet. Für besondere Fälle können Zahlen definiert werden, die Werte bis zwei Milliarden, positiv oder negativ, annehmen können. Diese Zahlen belegen 4 Bytes.

  • Bedingungen
    werden in runde Klammern eingeschlossen, die allerdings nicht ineinander geschachtelt werden können. Diese Klammerausdrücke enthalten wieder mehrere 'Wörter'.

  • Verneinte Bedingungen
    sind Bedingungen, die durch einen vorangestellten Schrägstrich negiert werden.

Alle Zeichen, die in einer Zeile hinter einem Ausrufezeichen oder einem senkrechten Strich (Pipe) stehen, werden als Kommentar betrachtet und vom Programm ignoriert. Dies gilt natürlich nicht für '!' und '|', die sich innerhalb eines Strings befinden.

Kommentarblöcke von mehreren Zeilen können zwischen den Begrenzern /* und */ angegeben werden. Kommentare können also wie folgt aussehen:

        /*  Dies ist ein Kommentarblock,
            der über mehrere Zeilen geht,
            in diesem Fall über drei. */

        /*  Ein Einzeiler. */

        !   Auch ein Einzeiler

Blockkommentare können nicht innerhalb eines Befehls stehen.

Man kann verschiedene Befehlzeilen auf eine Zeile schreiben, indem man die Befehle mit Semikola voneinander trennt. So sind z.B.

        Text 'Hallo, Welt!'
        Absatz

und

        Text 'Hallo, Welt!'; Absatz

gleichwertig. Ob am Ende einer Zeile ein Semikolon steht oder nicht, ist egal. Diese Zeilentrennung funktioniert natürlich nicht innerhalb eines Strings oder eines Klammerausdrucks.

Es gibt noch einige sogenannte Systembefehle, die aus einem Lattenzaun und drei Großbuchstaben bestehen. Dies sind:

#DOS

Schaltet den MS-DOS-Modus ein. Das heißt, die eingelesenen Zeilen werden mit dem MS-DOS-Zeichensatz gelesen, bei dem die Umlaute durch andere Zeichen dargestellt sind. Sollte also Euer Quelltext unter DOS, z.B. mit edit geschrieben worden sein, muß am Dateianfang dieser Befehl stehen, damit die Umlaute und das Es-Zett richtig interpretiert werden.

#WIN

Dito, nur für den Windows-Zeichensatz. Diese Einstellung ist Standard und der Befehl dient nur zum Aufheben von #DOS. (Obwohl TAG unter DOS läuft, sind die Texte in der Spieldatei mit dem Zeichensatz ISO-8859-1 geschrieben, der auch von Windows benutzt wird.)

#DBG

Steht dieser Befehl irgendwo im Quelltext, so wird die Debug-Option aktiviert. Der Befehl sollte also angegeben werden, wenn das Spiel mit dem Debugger TAD geprüft werden soll. (Der Befehl funktioniert zwar, aber da der Debugger nicht fertig ist, ist ein im Moment nutzlos.)

#DAT

Bindet eine externe Datei in den Quelltext ein (Include). Die Syntax ist

#DAT 'datei'

und datei ist eine Datei im ASCII-Format, die weitere Anweisungen im TAG-Format enthält. Ist sie komplett gelesen worden, so wird sie geschlossen und es wird in der Quelldatei an der entsprechenden Stelle nach dem #DAT-Befehl weitergelesen. Es können beliebig viele Dateien nacheinander eingebunden werden, aber eine eingebundene Datei darf keinen #DAT-Befehl enthalten. In der Quelldatei darf der #DAT-Befehl überall zwischen abgeschlossenen Anweisungen stehen. Sinn- vollerweise werden aber immer logische Blöcke in eine externe Datei geschrieben.

#STD

Erlaubt es, die Standardantworten von einer anderen Datei als tag.std zu lesen. Die Syntax ist ähnlich wie bei #DAT

#STD 'datei'

Der Aufbau von datei muß natürlich derselbe wie bei tag.std sein. Im Paket TAG befinden sich vorgefertigte Dateien für Spieler in der ersten, zweiten und dritten Person. Wer möchte, kann die Standardantworten auch im Textblock 'Standard' im Adventure-Datensatz angeben.

#KUM

Schaltet die Fehlerkumulation ein. Das heißt, alle Fehler werden in der LOG-Datei und auf dem Bildschirm ausgegeben, aber übergangen. Zum Schluß wird dann überprüft, ob es Fehler gegeben hat, und dann bricht das Programm erst ab. Das ist ganz nützlich, wenn man längere Passagen neu in die Quelldatei eingefügt hat, da man nicht immer alle Fehler nacheinander abarbeiten muß, sondern sofort einen Überblick über alle Fehler bekommt. (Kann aber auch sehr deprimierend sein. Meist sieht es jedoch schlimmer aus, als es ist, da Fehler Folgefehler erzeugen. So kann z.B. ein weggelassenes Apostroph die ganze Syntax durcheinanderbringen.)

#PIN

Aktiviert den pingeligen Modus. Das bedeutet, daß TAG auch kleine Dinge mit einer Information meldet, etwa, wenn ein Raum keinen Ausgang hat oder ein Objekt keine Beschreibung. Da dies unter Umständen sehr viel - auf den ersten Blick unbrauchbare - Information erzeugt, die die wichtigen Meldun- gen "überschwemmt", ist dieser Modus zu Beginn inaktiv.

#ENG

Schreibt enge Fehlermeldungen, die nur eine Zeile benötigen. Das ist besonders nützlich, wenn die Fehlerkumulation oder der pingelige Modus eingeschaltet sind, da so mehr Meldungen auf einen Bildschirm passen. (Die standardmäßigen Meldungen belegen drei Zeilen.)

#TXT

Schreibt alle Texte auf eine zusätzliche Datei mit dem Namen job.out. Die Textbefehle werden dann herausgeschnitten, das Absatz- und Zeilenformat ist wie im Datensatz. Die Texte werden mit dem momentan aktiven Zeichensatz in der Reihen- folge ihres Auftretens geschrieben. Dies dient dazu, um den Ausgabetext mit einer Rechtschreibprüfung auf Tippfehler zu untersuchen.

Diese Direktiven können auch als Optionen in der Befehlszeile angegeben werden. Die komplette Syntax für das Aufrufen des Generators ist:

        tag {-Optionen} Quelldatei{.adv} {Spieldatei{.tag}}

Mögliche Optionen sind:

-k   Fehlerkumulation
-p   Pingelige Ausgabe
-l   Schreiben einer Log-Datei
-d   Schreiben einer Debug-Datei
-w   Benutzt den Windows-Zeichensatz
-t   Schreibt alle Ausgabetexte auf job.out
-e   Benutzt einzeilige (enge) Fehlermeldungen
-i   Ignoriert die Steueranweisungen im Quelltext

Die Definition der Optionen mit #XXX überschreibt natürlich die Optionen, die beim Aufrufen gesetzt wurden. Jenachdem, ob man Optionen immer wirksam haben oder nur gelegentlich von ihnen Gebrauch machen möchte, sollte man sie in der Quelldatei oder auf der Kommandozeile angeben.

Die Option -i ignoriert nur die Direktiven, die auch auf der Kommandozeile angegeben werden können. #DAT und #STD funktionieren weiterhin.

TAG besitzt ein Fehlersystem mit drei Stufen:

*** FEHLER ***
führen zum sofortigen Abbruch der Adventure-Generierung. Häufig sind es Eingabefehler, fehlende Angaben u.ä, die schnell repariert sind. Ist die Fehlerkumulation eingeschaltet, so werden Fehler nur aufgelistet, aber nicht beachtet.

** WARNUNG **
bedeutet, daß etwas eingegeben wurde, das evtl. Schwierigkeiten machen kann. Zum Beispiel, wenn ein Behälter kein Volumen hat. Das ist wahrscheinlich nicht beabsichtigt, ist aber kein Fehler, da der Behälter immer noch Objekte aufnehmen könnte, die ebenfalls kein Volumen haben. (Sehr abstrakt, gell?) Der Programmierer soll hier nur auf etwas aufmerksam gemacht werden.

* INFORMATION *
ist nützlich, kann in ihrer Fülle den Benutzer aber oft erschlagen. Deshalb wird sie nur angezeigt, wenn der Pingelig-Modus mit #PIN aktiviert wurde. Dennoch ist es nicht schlecht, sich gegen Ende des Projekts, oder wenn man einen logischen Fehler suchen will, sich einmal die Informationen anzeigen zu lassen.

Alle Meldungen erscheinen auf dem Bildschirm mit Angabe der Zeile im Quellcode und ggf. mit dem Namen der eingefügten Datei. Dieselben Meldungen erscheinen auch in der log-Datei, und zwar am Anfang, in der Rubrik 'Logbuch'.

2.4. Der Parser

Der Parser ist der Teil des Programms, der die Befehle aufteilt und untersucht. Zunächst wird der Befehl in einzelne Worte aufgeteilt. Diese Worte werden dann vom Programm untersucht. Der Befehl wird in folgende Elemente aufgeteilt:

aBef Angesprochener Befehl
aObj Objekt, das im Befehl angesprochen wurde.
aObj2 zweites Objekt
aObj3 drittes Objekt (in sehr seltenen Fällen verwendet)
aRitg Richtungsangabe im Befehl

Diese Werte sind das Ergebnis der Analyse des vom Spieler eingegebenen Satzes. Außerdem ermittelt der Parser noch folgende Informationen (die zur Bestimmung des angesprochenen Befehls dienen, aber eventuell von Nutzen sein können):

aVerb benutztes Verb
aPräp eine evtl. zusammen mit einem Objekt angegebene Präposition
aKlammer ist eine Präposition, die bei trennbaren Verben die Vorsilbe angibt (z.B. 'an' in 'mache ... an')

Die Objekte im Satz können durch eine Kette von Eigenschafts- und Hauptworten angegeben werden. Eine solche Kette hat folgendes Aussehen:

{Art} {1. Adj./Adverb} {2. Adj.} Substantiv {weitere Substantive}

Die Angaben in Klammern sind dabei optional. Der Parser versteht also die folgenden Wortketten als Objekte:

        DAS BOOT
        KÜHLES GLAS BIER
        DER FRISCH GEBACKENE LAIB BROT
        DER KLEINE SILBERNE HAUSTÜRSCHLÜSSEL

Die Bedeutung der oben genannten Elemente wird am deutlichsten mit ein paar Satzbeispielen. Die Zeile in Großbuchstaben nach dem Prompt (>) ist die Eingabe des Spielers, die nachfolgenden Zeilen sind das Analyseergebnis des Parsers. Werte, die nicht angegeben werden, sind Null bzw. leer.

        > GEHE NACH NORDEN
                aBef = gehen, aRitg = N (= Norden)
                aVerb = 'gehe'

        > NIMM DIE MÜNZE
                aBef = nehmen, aObj = Münze
                aVerb = 'nimm'

        > NIMM DIE MÜNZE AUS DER TRUHE
                aBef = herausnehmen, aObj = Münze, aObj2 = Truhe
                aVerb = 'nimm', aPräp = 'aus'

        > LEGE MÜNZE HIN
                aBef = hinlegen, aObj = Münze
                aVerb = 'lege', aKlammer = 'hin'

        > LEGE MÜNZE AUF DEN TISCH
                aBef = darauflegen, aObj = Münze, aObj2 = Tisch
                aVerb = 'lege', aPräp = 'auf'

        > ÖFFNE KLEINES SCHLOSS MIT HAARNADEL
                aBef = öffnen_mit, aObj = Truhe, aObj2 = Haarnadel
                aVerb = 'öffne'

        > MACHE TRUHE MIT BRECHEISEN AUF
                aBef = öffnen_mit, aObj = Truhe, aObj2 = Brecheisen
                aVerb = 'mache', aKlammer = 'auf'

        > GIB DEM AFFEN DEN ZUCKER
                aBef = geben, aObj = Zucker, aObj2 = Affe
                aVerb = 'gib'

Bei den Beispielen gibt es einige Dinge, die auffallen:

  • Verschiedene Verben können zum selben Befehl führen, wie bei 'öffne' und 'mache auf'.

  • Andererseits können Eingaben mit demselben Verb verschiedene Befehle bedeuten. Dies kann an einer Verbklammer liegen, wie bei 'lege' und 'lege hin'. Es kann aber auch an den angegebenen Objekten und der verwendeten Präposition liegen, wie bei den beiden Sätzen mit 'nimm'.

  • Je nach Verwendung können Worte wie 'auf', 'an' usw. als Präposition oder als Klammer definiert werden. Präpositionen stehen vor einem Objekt ('auf den Tisch'), Klammern gehören zum Verb ('mache auf').

  • 'mit' ist eine vorgegebene Präposition und wird daher nicht als aPräp definiert. Der Grund ist, daß immer nur ein Objekt mit Präposition je Satz definiert werden kann. 'mit' taucht aber häufig auf und mit dieser Sonderbehandlung kann man auch Sätze eingeben wie 'Grabe mit dem Schäufelchen im Dreck.'

  • 'nach' ist im Beispiel oben ebenfalls keine Präposition im Sinne von aPräp. Es wird als Bestandteil der Richtung interpretiert.

  • Dennoch können 'nach' und 'mit' als Klammern auftauchen, z.B. in Sätzen mit 'nimm mit' oder 'schaue nach'.)

  • Sätze mit drei Objekten sind nicht sehr häufig. aObj3 kann aber in Befehlen wie 'Hole die Münze mit der Zange aus dem Schlitz' vorkommen.

Wird ein Befehl an jemand anderen gerichtet, so wird das angesprochene Objekt in der Variable Akteur gespeichert. Dies ist in Sätzen wie

        > SAGE DEM JUNGEN "FOLGE MIR"
        > PRINZESSIN, "KÜSS DEN FROSCH"
        > COMPUTER, KURS AUF GANYMED

der Fall. Meistens ist Akteur jedoch Null, d.h. der Spieler soll die Anweisung ausführen.

Dieses Kapitel ist nur ein Überblick über die Aufgabe des Parsers. Detailliertere Angaben befinden sich in den Kapiteln über die Befehls- und Objektdefinitionen sowie im Kapitel 15.

Anmerkung: Die eingegebene Anweisung wird vom Programm als Kleinbuchstaben behandelt. Dabei werden automatisch 'ß' in 'ss' und 'ae', 'oe' und 'ue' in die entsprechenden Umlaute umgewandelt. Die Worte, die ins Lexikon von TAG geschrieben werden sollen, werden auch erst in diese Form gebracht.

Martin Oehm, 04.02.2000 Vorheriges KapitelInhaltsverzeichnisNächstes Kapitel