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. |
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: //
.
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.
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.
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.
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.
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: Hier ist die Bedingung nicht verneint. 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.)
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
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.
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.
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.
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.
- 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 nurim_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.
Das nächste Kapitel zeigt, wie man Variablen verwendet und wie man mit ihnen den Ablauf von Aktionen steuern kann.
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 mitEndeAusf
abgeschlossen wird.Die Aktion
Anfang
wird zu Beginn des Spiels durchgeführt.Zu Objekten können die Ausführungsblöcke
VorAusf
undNachAusf
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
undAttrWeg
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