[ T. A. G. ] [ Tutorium ]

 

Kapitel 5

Anweisungen

 

5.1    Ein ordentlicher Anfang

Bis jetzt wird unser Spieler ohne Kommentar ins Geschehen geworfen: Er bekommt die erste Raumbeschreibung um die Ohren geknallt, und los gehts. Das ist nicht die feine englische Art, deswegen wollen wir ihm einen ordentlichen Einstieg ins Spiel geben.

Dazu definieren wir eine Aktion. Eine Aktion ist eine Anzahl von Anweisungen, die nacheinander ausgeführt werden. Bis jetzt heben wir unsere Spielwelt nur mit den standardmäßig in T.A.G. vorhandenen Definionen erschaffen. Das wird sich in diesem Kapitel ändern, wenn wir unsere eigenen Regeln schreiben!

Aber zurück zum Anfang des Adventures. Es gibt eine Aktion Anfang, die zu Beginn des Spiels aufgerufen wird. (Sie wird auch aufgerufen, wenn der Spieler einen Neustart mit »Neu« wünscht.) Diese Aktion definieren wir:

    Aktion  Anfang
    Ausf
      Text  '[f]D E R   T E S T[n]
            [x]Ein interaktives Versuchsgelände,
            (C) 2000 Cecilia McIntyre

            Du bist hier offensichtlich in eine
            ziemlich eigenartige Welt geraten. Am
            besten, du schaust dich einmal um und
            erkundest, was es mit dieser Gegend auf
            sich hat.'

      Sei maxInv 5   ! Ich kann 5 Teile tragen ...
      Sei maxVol 80  ! ... bis zu einem Volumen von 80

      geheZu vor_dem_Haus
    EndeAusf

In dieser Aktion tauchen viele neue Elemente auf. Zunächst sehen wir, dass die Aktion mit Ausf beginnt und mit EndeAusf endet. Alles dazwischen ist bis jetzt Neuland.

Die erste Anweisung lautet Text, gefolgt von einem über mehrere Zeilen gehenden Text in einfachen Anführungszeichen. Diese Texte kennen wir ja schon, und die Anweisung Text heißt einfach nur »gib diesen Text formatiert auf dem Bildschirm aus.« - wer hätte das gedacht?

Innerhalb des Textes tauchen wieder die kryptischen Zeichen innerhalb der eckigen Klammern auf, die wir von der Liste der Gegenstände in einem anderen Objekt bereits kennen. Dies sind sogenennte Textbefehle. Hier wird folgendes verwendet:

    [f]     Fettdruck ein
    [n]     Normaldruck ein, d.h. Fettdruck aus
    [x]     Unformatierter Zeilennumbruch, d.h. eine neue Zeile.

Ein weiterer Textbefehl ist, auch wenn man das nicht gleich auf den ersten Blick sieht, die Leerzeile, die, wie wir wissen, einen Absatz bedeutet. Wenn nichts anderes definiert ist, hat der Absatz in T.A.M. eine Leerzeile ohne nachfolgende Einrückung. Eine andere Möglichkeit, einen Absatz zu schreiben, wäre [#] im Fließtext.

   Da die Texte zwischen Apostrophen stehen, muss ein Apostroph umschrieben werden. dazu kann man das Prozentzeichen % benutzen oder eine der Notationen [,] oder ["]. Um ein Prozentzeichen zu schreiben, benutzt man [%]. Um eckige Klammern zu schreiben, müssen diese doppelt angegeben werden: [[ oder ]].

Die Textbefehle werden intern als Sequenz von Zeichen, die mit einem Schrägstrich beginnen, abgelegt. Daher muss auch der Schrägstrich immer doppelt stehen: //.

Die nächsten Anweisungen heißen sei. Hier wird der Variablen maxInv der Wert 5 und der Variablen maxVol der Wert 80 zugewiesen. In vielen Programmiersprachen sehen solche Anweisungen so (oder so ähnlich) aus: maxInv = 5, aber T.A.G. geht hier einen eher rudimentären Weg.

Alles, was hinter dem Ausrufezeichen steht wird von T.A.G. übrigens nicht beachtet. Man nennt das einen Kommentar, und es kann nützlich sein, ab und zu einmal ein paar zusätzliche Bemerkungen einzufügen, damit man später in seinem eigenen Adventure noch durchblickt.

Die letzte Anweisung lautet geheZu und bewirkt, dass der Spieler zu einem bestimmten Raum bewegt wird. Danach wird die Raumbeschreibung ausgegeben.

Das hätten wir nicht unbedingt machen müssen, denn wenn der Spieler am Anfang noch nirgendwo ist, wird er automatisch in den zuerst definierten Raum gestellt und es wird ebenfalls die Raumbeschreibung ausgegeben. Aber es ist »sauberer« so, und außerdem kann man die Zeile später schnell abändern, wenn der Spieler lieber doch im Wald beginnen soll.

 

5.2    Ins Geschehen eingreifen

Bis jetzt haben wir nur die bereits in T.A.G. vorhandenen Definitionen verwendet und konnten damit eine Spielwelt mit bestimmten Regeln schaffen. Ein eigenes Adventure benötigt aber zu diesen allgemein gültigen Regeln noch weitere, die der Autor selbst definieren kann. Das wollen wir jetzt machen.

Zum Beispiel könnte der Spieler auf die Idee kommen, die Taschenlampe zu öffnen, um an die Batterien zu kommen. Die Antwort darauf wäre »Du kannst doch keine Taschenlampe öffnen.«, was nicht besonders toll ist. Wir wollen dem Spieler stattdessen etwas anderes sagen, dazu erweitern wir die Definition der Taschenlampe:

    Obj     Lampe
    ...
    VorAusf
        (öffnen)
            Text 'Wozu? Die Batterien tun es noch,
                und es gibt nichts, wozu man sie
                sonst gebrauchen könnte.'
            Stop
    EndeAusf

Die zusätzliche Definition ist wieder ein Ausführungsblock, er wird wie eine Aktion mit EndeAusf abgeschlossen, beginnt aber mit VorAusf. Eine VorAusf kann zu einem Objekt definiert werden, VorAusf bedeutet dabei (etwas holprig): »Führe diesen Block aus, bevor du den eigentlichen Befehl abarbeitest.«

Das erste Element im Block ist ein Befehlsname, der in runden Klammern steht. Solche Angaben in runden Klammern bedeuten: Wenn der vom Spieler eingegebene Befehl öffnen ist, dann führe alles aus, was jetzt kommt, bis du einen anderen Befehl in runden Klammern oder EndeAusf erreichst.

Dann folgen zwei Anweisungen. Die Text-Anweisung kennen wir schon, sie gibt den folgenden Text aus. Die nächste Anweisung Stop bewirkt, dass der ganze Befehl öffnen sofort abgebrochen wird. Sagt der Spieler also »öffne Lampe«, dann wird der Text mit den Batterien ausgegeben, und das war's. Die normale Prozedur zum Öffnen von Gegenständen wird nicht mehr aufgerufen, da vorher mit dem Stop-Befehl eingegriffen wurde. Würde das Stop vor dem Text stehen, so würde nicht einmal der Text angezeigt.

Bei »öffne Rucksack« oder einem anderen Objekt passiert natürlich nichts, denn da die VorAusf bei der Lampe definiert wurde, gilt sie auch nur für die Lampe.

   Da diese Kombination von Text und Stop häufig vorkommt, kann man sie abkürzen zu Stop 'Wozu? ...'. Man kann also den Ausgabetext direkt hinter der Anweisung Stop angeben.

Anstatt die Durchführung eines Befehls vorher abzufangen, kann man ihn auch nachträglich ergänzen. Die Definition hierfür heißt NachAusf:

    Obj     Zettel
    ...
    NachAusf
      (nehmen)
          Wenn /(Zettel bewegt)
              Text 'Der Zettel fühlt sich feucht an,
                  als Du ihn aus dem taubenetzten Gras
                  fischst.'
    EndeAusf

Hier ist der Befehl »nimm Zettel« bereits erfolgreich ausgeführt worden, es wurde gecheckt, dass der Spieler den Zettel nicht schon hat, weitere Gegenstände aufnehmen kann, usw. Der Zettel befindet sich bereits beim Spieler. Nun wird nachträglich ein anderer Text ausgegeben. Dabei sollte man beachten, dass der erste Text in der NachAusf den Standard-Text bei erfolgreichem Ausführen ersetzt, alle weiteren Texte werden wie gehabt nacheinander ausgegeben.

Die Ausgabe des Textes ist hier allerdings an eine Bedingung geknüpft. Eine Bedingung in T.A.G. ist ein Ausdruck in runden Klammern. Die Bedingung heißt hier (Zettel bewegt). Bewegt ist ein Attribut, das gesetzt wird, sobald der Spieler den Gegenstand aufhebt. Dieses Attribut wird auch benutzt, um festzustellen, ob die Erst-Beschreibung ausgegeben wird oder nicht.

Der Bedingung geht ein Schrägstrich voran. Schrägstriche bedeuten in T.A.G. Verneinungen. Die Bedingung ist also erfüllt, wenn der Zettel noch nicht bewegt wurde. Das Wort Wenn vor der Bedingung heißt: »Wenn diese Bedingung erfüllt ist, dann führe den nächsten Befehl aus, ansonsten überspringe ihn.« Der Text wird also nur ausgegeben, wenn der Zettel zum ersten Mal aufgehoben wird. Danach besitzt er das Attribut bewegt, und die Text-Anweisung wird übersprungen.

Räume können übrigens auch eine Vor- und NachAusf haben. Sie wird immer dann aufgerufen, wenn sich der Spieler in diesem Raum befindet:

    Raum    Im_Haus
    ...
    NachAusf
        (gehen)
            Wenn /(aRaum besucht)
            Text '[#]Hier ist es irgendwie unheimlich.
                Du bist wahrscheinlich seit Jahren
                der Erste, der dieses Haus betritt.'
    EndeAusf

Damit wird dem Spieler beim ersten Betreten des Hauses gesagt, dass es unheimlich hier ist. aRaum ist eine Variable, die den momentanen Aufenthaltsort beschreibt. Da dies in diesem Fall immer Im_Haus ist, könnte man auch schreiben /(im_Haus besucht).

 

5.3    Bedingungen und Steuerstrukturen

Bedingungen spielen gerade bei Adventures eine wichtige Rolle: Der Geheimgang ist nur sichtbar, wenn Hebel A gezogen ist, Knopf B zweimal gedrückt wurde und der Spieler den Gegenstand C bei sich hat. So oder so ähnlich sehen viele Rätsel aus.

Die Bedingungen sind relativ selbsterklärend. Die wichtigsten sind:

([Objekt/Raum] [Attribut])
ist wahr, wenn das Objekt oder der Raum ein Attribut besitzt.

([Objekt] in [Ort])
ist wahr, wenn ein Objekt an einem bestimmten Ort ist. Der Ort ist dabei, wie mit der Ort-Zeile in der Objektdefinition angegeben. Wenn Ort ein Raum ist, wird in vorangestellt.

([Objekt] [Zustand])
ist wahr, wenn ein Objekt den Zustand hat.

(Proz [Zahl])
ist in Zahl Prozent aller Fälle wahr. Hier wird zufällig eine Zahl zwischen 0 und 100 bestimmt, wenn diese kleiner ist als Zahl, so ist die Bedingung wahr. (Proz 50) ist eine fifty-fifty-Chance.

(Licht_In [Raum])
ist wahr, wenn man im Raum sehen kann. Dies ist genauer, als /(Raum dunkel), da Lichtquellen mit berücksichtigt werden.

All diese Bedingungen können mit einem Schrägstrich verneint werden.

Diese Bedingungen werden in sogenannten Steuerstrukturen benutzt. Eine haben wir schon kennengelernt:

    Wenn ([Bedingung]) [Anweisung]

    Wenn ([Bedingung])
        
[Anweisung]

Diese beiden Formen sind gleich und meinen: Wenn die Bedingung wahr ist, führe die Anweisung aus. Hier kann nur eine Anweisung stehen. Oft möchte man mehrere Anweisungen von einer Bedingung abhängig machen. Dann benutzt man

    Wenn ([Bedingung]) dann
        
[beliebig viele Anweisungen]
    Ende

Dies funktioniert genau wie die einfache Wenn-Bedingung, alles zwischen dann und Ende wird nur ausgeführt, wenn die Bedingung wahr ist.

Zu diesem Konstrukt gibt es eine Erweiterung. Manchmal möchte man eine Fallunterscheidung machen: Wenn das gilt, mache das, wenn nicht, etwas anderes. Dazu kann man die Wenn-dann-Bedingung mit sonst erweitern:

    Wenn ([Bedingung]) dann
        
[Anweisungen für erfüllte Bedingung]
    sonst

        [Anweisungen für nicht erfüllte Bedingung]
    Ende

Eine Sache, die in Adventures sehr häufig vorkommt, sind Bedingungen, die zum sofortigen Abbruch des Befehls führen, wenn sie nicht erfüllt sind. Zum Beispiel checkt anziehen, ob das Objekt ein Kleidungsstück ist, nehmen, ob man es mitmehmen kann, liegen, ob es eine Liege ist usw. Ist dies nicht der Fall, bekommt der Spieler einen Satz auf den Bildschirm, und er darf einen neuen Befehl eingeben. Dies würde im Moment so aussehen:

    Wenn /([Bedingung]) dann
        Text '
[Text]'
        Stop
    Ende

oder kürzer

    Wenn /([Bedingung]) Stop '[Text]'

Eine Alternative hierzu ist:

    Bed ([Bedingung]) '[Text]'

Man muss nur aufpassen, dass hier die Bedingung nicht verneint ist. Die Bed-Bedingung ist die Bedingung zum Weitermachen, die Wenn-Bedingung die zum Abbrechen. Welche Schreibweise man benutzt, ist aber letztendlich egal.

Aufgabe 11 *
Erzeuge einen Pilz, der im Wald steht. Wenn man ihn zum ersten Mal aufhebt, soll ein Text ausgegeben werden, der sagt, wie er mit einem leisen »Plopp« aus der Erde gezogen wird. Wenn man ihn isst, soll man in 20 Prozent aller Fälle vergiftet werden. (Die Anweisung, um den Spieler sterben zu lassen, heißt gestorben. Konsequenterweise wird damit auch der momentane Befehl abgebrochen.)

Mann kann mehrere Bedingungen verknüpfen. Dazu gibt es die Operatoren und und oder:

([Bedingung a]) und ([Bedingung b])
ist wahr, wenn beide Bedingungen erfüllt sind.

([Bedingung a]) oder ([Bedingung b])
ist wahr, wenn mindestens eine Bedingung erfüllt ist.

   Man kann in T.A.G. keine Bedingungen ineinander schachteln. Man kann auch immer nur einen Ausdruck verneinen. Folgende Bedingungen muss man also umschreiben:

    /(a und b) --> /a oder /b

    /(a oder b) --> /a und /b

 

5.4    Objekte manipulieren

Bis jetzt haben wir nie Sachen wirklich verändert, sondern immer nur dem Spieler gesagt, dass etwas nicht geht. Nun wollen wir anfangen, die Objekte wirklich zu manipulieren.

Wir definieren nun einen Lichtschalter im Keller:

    Obj     Lichtschalter
    Name    'Lichtschalter an der Wand' m
    vor     'licht'
    subst   'schalter' m
    Ort     Keller
    Attr    immob
    Besch   'Das Symbol einer Glühbirne ziert den
            Schalter.'
    Erst    'An einer Wand ist auf etwa ein Meter
            Höhe ein Schalter.'
    VorAusf
        (drücken)
             Wenn (Keller dunkel) dann
                 Text 'Der Raum wird von einem
                     eigenartigen, kalten Licht
                     durchflutet, das von den Wänden
                     herzukommen scheint.'
                 AttrWeg Keller dunkel
             sonst
                 Text 'Der Keller ist jetzt wieder so
                     stockfinster wie zuvor.'
               AttrHin Keller dunkel
             Ende
    EndeAusf

Die Anweisungen AttrHin und AttrWeg geben dem Raum ein Attribut oder nehmen es ihm weg. Diese Anweisungen funktionieren auch bei Objekten:

    ObjAttr gelesen

    Obj     Zettel
    ...
    VorAusf
        (lesen)
            Bed /(Zettel gelesen)
                'Das hast Du doch schon gelesen.'
    EndeAusf

    NachAusf
        (lesen)
            AttrHin Zettel gelesen
    EndeAusf

Mit ObjAttr kann man eigene Attribute für Objekte definieren. Es gibt auch ein RaumAttr für zusätzliche Raumattribute. Mit dieser neuen Definition wird verhindert, dass der Spieler den Zettel zweimal liest. Zugegeben, kein realitätsnahes Beispiel, aber es zeigt, wie es geht: Beim ersten Mal ist der Zettel noch nicht gelesen. Der Text wird wie üblich angezeigt. Im Nachhinein bekommt der Zettel aber das Attribut gelesen. Beim nächsten Mal bricht dann die VorAusf den Befehl ab.

Aufgabe 12
Ändere den Pilz so ab, dass er nicht beim ersten Probieren tödlich ist, sondern erst beim zweiten Mal. Dann aber bestimmt. (Dazu sollte sichergestellt sein, dass der Spieler beim ersten Mal nur knabbert, damit der Pilz nicht verschwindet.)

Ein anderes Beispiel: Unser Rucksack soll zuerst geschlossen werden, bevor er aufgesetzt wird:

    Obj     Rucksack
    ...
    VorAusf
        (anziehen)
            Wenn (Rucksack offen) dann
                Text '(Du schließt den Rucksack erst,
                     bevor du ihn aufsetzt.)[#]'
                ObjZust Rucksack geschlossen
            Ende
    EndeAusf

Hier wird dem Spieler mitgeteilt, dass er den Rucksack implizit zumacht, bevor er den Rucksack aufsetzt. Es ist eine Konvention, dies dem Spieler in runden Klammern mitzuteilen.

Die Anweisung ObjZust weist dem genannten Objekt dann einen neuen Zustand zu. Es gibt übrigens den Zustand normal, der bedeutet: kein besonderer Zustand.

Aufgabe 13 *
Ändere den Pilz, so dass er beim ersten Mal nur genommen werden kann, wenn der Spieler das Taschenmesser bei sich hat und dieses offen ist. Natürlich muss eine Meldung kommen, dass der Pilz abgeschnitten wurde.

Aufgabe 14 *
Definiere einen Blechkasten, der nicht auf herkömmliche Weise geöffnet und geschlossen werden kann. Stattdessen besitzt dieser Kasten einen Knopf, der ihn öffnet und schließt.

Wir haben nun den Zustand und die Attribute der Objekte verändert, eine Sache fehlt noch: der Ort. Hierzu heißt die Anweisung ObjNach [Objekt] [Ort]:

    Obj     Lichtschalter
    ...
    VorAusf
        (drücken)
            Wenn (Keller dunkel) dann
                Text  'Der Raum wird von einem
                    eigenartigen, kalten Licht
                    durchflutet, das von den Wänden
                    herzukommen scheint.'
                AttrWeg Keller dunkel
                Wenn (Ring in nirgendwo) dann
                    Text '[#]Durch das gleichmäßige Licht
                        entdeckst du in einer Ecke des
                        Kellers einen Ring, den du vorher
                        mit deiner Funzel nie entdeckt
                        hättest.'
                    ObjNach Ring Keller
                Ende
            sonst
                Text 'Der Keller ist jetzt wieder so
                    stockfinster wie zuvor.'
                AttrHin Keller dunkel
            Ende
            Stop
    EndeAusf

    Obj     Ring
    Name    'Ring' m
    subst   'ring' m
    Erst    'In einer Ecke des Kellers liegt ein Ring.'
    Attr    Kleidung

Hier wird ein Ring in den Keller gelegt, den der Spieler entdeckt, wenn er den Lichtschalter drückt. Die Angabe des Ortes erfolgt wie in der Ort-Zeile der Objekt-Definition.

Nirgendwo ist ein Ort, den der Spieler nie betreten kann. Dort werden Gegenstände aufbewahrt, die zu Beginn des Spiels noch nicht verfügbar sind. Ein Gegenstand ist automatisch im nirgendwo, wenn die Ort-Zeile weggelassen wird.

   Es gibt einen zweiten Raum, den der Spieler nicht betreten kann. Er heißt Nirwana und dort kommen alle Gegenstände hin, die aus dem Spiel verschwinden.

Aufgabe 15 *
Definiere einen Wäscheschacht im Haus, so dass alles, was dort hineingelegt wird, automatisch in den Keller rutscht. Dazu muss die Pseudoaktion empfangen abgefangen werden. (Tip: Der Schacht muss nur im_Haus definiert sein.)

Aufgabe 16
Definiere einen Weidenkorb im Keller, den der Spieler nicht mitnehmen kann, und in den die Wäsche (oder was auch immer) aus dem Wäscheschacht rutscht.

Eine weitere Art, Objekte zu verändern, ist einfach ihren Ort zu vertauschen. Das ist besonders wirkungsvoll, wenn eines der Objekte im Nirgendwo ist. Ohne dass es der Spieler mitbekommt, bezieht er sich auf ein anderes Objekt. Die Anweisung hierfür lautet: Tausche [Objekt1] [Objekt2].

Aufgabe 17
Definiere eine Ming-Vase, die zu einem Scherbenhaufen wird, wenn der Spieler sie wirft oder zerstört.

Zusammenfassung:
Aktionen bestehen aus einer Anzahl von Anweisungen, die nacheinander abgearbeitet werden. Die Definition dieser Anweisungen erfolgt in einem Ausführungsblock, der mit Ausf beginnt und mit EndeAusf abgeschlossen wird.

Die Aktion Anfang wird zu Beginn des Spiels durchgeführt.

Zu Objekten können die Ausführungsblöcke VorAusf und NachAusf definiert werden, um in den Ablauf einer Befehlsausführung einzugreifen.

Bedingungen sind Ausdrücke in runden Klammern, die bestimmte Sachverhalte in der Spielwelt überprüfen. Sie werden oft in Steuerstrukturen wie wenn/dann benutzt.

Mit den Anweisungen ObjNach, ObjZust, AttrHin und AttrWeg können Objekte außerhalb der in T.A.G. bereits vorhandenen Regeln manipuliert werden.

Verweise
Handbuch, Kapitel 5: Programmieren der Ausführungsblöcke
Handbuch, Kapitel 6: Die verschiedenen Aktionen im Spiel


Nächstes Kapitel
Voriges Kapitel
nach oben
Inhalt


________
Startseite --> Textadventures --> T.A.G. --> Tutorium --> Kapitel 5
Übersicht
Martin Oehm

[ www.martin-oehm.de - Startseite ]
[ Textadventures ]
[ T. A. G. ]

Inhalt

Einleitung
Spielwelt
Objekte I
Objekte II
Anweisungen
Variablen
Befehle
Klassen
Personen
Diverses

Lösungen