Erwartungsgemäß hängt ein Apfel am Baum; aber es ist ein ganz spezieller
Apfel: Wer davon isst, der gewinnt die Erkenntnis. Es ist aber gar
nicht so einfach, ihn zu essen: zuerst muss man ihn haben. Und es
ist verboten, ihn zu nehmen! Wer es aber zweimal unmittelbar hintereinander
versucht, hat Erfolg15:
-
- Object -> Apfel
with name 'Apfel' 'verboten' 'Frucht' 'gross' 'schillernd' 'rund',
short_name "Apfel",
adj "verboten",
dekl 2,
initial "Am Baum hängt ein großer Apfel.",
description "Das also ist die verbotene Frucht:
ein auffallend großer, runder Apfel.
Er schillert in der Sonne, seine
Farbe ist schwer auszumachen.",
before [;
take: if (self has general)
print "Du fasst dir ein Herz und ... ";
else
{
give self general;
"Du lässt die verbotene Frucht
lieber am Baum hängen.";
}
],
after [;
take: "pflückst den Apfel mit zitternden Fingern.";
eat: give Adam Erkenntnis;
"Du isst den Apfel vom Baum der Erkenntnis -
Gedanken strömen auf dich ein wie ein Fluss,
der über seine Ufer tritt.
Du bist einen Augenblick lang benommen.^^
Du hast etwas Verbotenes getan.
Du bist böse. Und du bist nackt."
],
react_before [;
take: if (noun~=self)
give self ~general;
default: give self ~general;
],
has male edible;
- Initial
- ist eine Kurzbeschreibung,
die anstelle des normalen ,,Du siehst hier einen Apfel'' ausgegeben
wird, solange der Spieler den Apfel noch nicht genommen hat (d.h.
solange er das in diesem Fall automatisch vergebene Attribut moved
nicht besitzt).16
- edible
- ist ein Attribut, das
den Apfel essbar macht (man muss ihn aber zuerst haben!)
- general
- ist ein ,,allgemeines''
Attribut, das der Autorin zur Benutzung offen steht - zu Beginn ist
es immer ungesetzt; oft wird es gesetzt, sobald ein mit dem Objekt
verbundenes Rätsel gelöst ist. Hier verwende ich es, um zu markieren,
ob der Spieler bereits einmal versucht hat, den Apfel zu nehmen; der
zweite Versuch wird dann erfolgreich sein.
- self
- ist ein Platzhalter, der
in Code innerhalb einer Objektdefinition das jeweilige Objekt selbst
meint; statt self könnte im obigen Beispiel
überall auch Apfel stehen.
- has
- ist an dieser Stelle ein logischer
Operator, der testet, ob ein Objekt ein bestimmtes Attribut hat oder
nicht.
- if
- und else
ermöglichen es, abhängig von einer Bedingung (self
has general) entweder einen (hier: print
"Du fasst dir ein Herz und ... ";) oder einen anderen {den in geschweiften
Klammern nach else folgenden}
bestimmten Teil des Programms auszuführen. Wie das genau funktioniert,
ist beschrieben in 3.1.3. Es kann nicht schaden, gleich
auch den folgenden Abschnitt über switch
zu lesen, denn die Anweisungen in before
usw. folgen derselben Syntax wie dort beschrieben.
- print
- ist der Befehl, die nachfolgende
Zeichenkette (oder mehrere, mit Komma getrennte) zu drucken und nichts
weiter zu tun. Will man danach eine neue Zeile haben, so kann man
die auszudruckende Zeichenkette mit ^
enden lassen oder den Befehl new_line
anhängen. Dies darf keinesfalls verwechselt werden mit print_ret.
- print_ret
- druckt ebenfalls den oder
die nachfolgenden String(s) aus und läßt eine Zeilenschaltung folgen.
Damit aber nicht genug, es enthält außerdem
noch die abschließende Befehlsfolge return
true.
- return
- bewirkt einen Rücksprung
aus dem [; in eckige Klammern eingeschlossenen];
Programmblock. return kann von einem Rückgabewert
gefolgt sein; die häufigst benötigten Rückgabewerte sind die logischen
Werte true und false.
Für ein return mit diesen Rückgabewerten
gibt es die Kurzschreibweisen rtrue bzw. rfalse.
- "..."
- als selbständiger
Befehl (also nicht nach einer Zuweisung oder nach einem print)
steht tatsächlich für die häufig benötigte Kombination print
"..."; newline; return true;17
- Take
- und
- Eat
- stehen für bestimmte Aktionen;
hier die Aktionen, die ausgelöst werden, wenn der Spieler versucht,
den Apfel zu nehmen oder ihn zu essen. Eine Übersicht über die vordefinierten
Aktionen und die ,,Verben'', d.h. die Eingaben des Spielers,
die die Aktionen auslösen, enthält Kapitel 4.
- before
- ist der Platz für eine
Routine (in eckigen Klammern, aber ohne Namen, deshalb das Semikolon
unmittelbar nach der öffnenden Klammer); die auf Aktionen reagiert,
die der Spieler mit dem Apfel anstellt. Gibt er den Befehl ,,Nimm
den Apfel'', so wird die Routine in der before-property
des Apfels aufgerufen und die auszuführende Aktion auf den Wert Take
gesetzt. Die Routine kann für jede Aktion einen eigenen Zweig enthalten,
in dem festgelegt wird, wie der Apfel auf die Aktion des Spielers
reagiert. Im Beispiel ist nur ein Zweig für Take
enthalten. (Eat wird von der Library abgewiesen,
wenn der Spieler den Apfel nicht hat.)
Das Programm prüft nun das Attribut general;
ist es gesetzt, gibt es mit print "..."
einen einleitenden Text aus und macht nichts weiter. Die Routine gibt
- wenn nicht ausdrücklich etwas anderes angegeben ist - den Wert
false zurück; die Library überprüft, ob
der Apfel genommen werden kann und wird ihn dem Spieler geben, weil
nichts entgegensteht. Ist aber general
nicht gesetzt - und zu Beginn ist es das nicht - dann wird eine
andere Nachricht ausgegeben (mit der Kurzschreibweise "...",
die auch für ein return true; am Ende steht!)
und die Routine gibt true zurück. Das bedeutet
aber für Inform soviel wie ,,Alles fertig - Schluss mit der Aktion'',
der Zug ist zu Ende, der Apfel bleibt wo er war. (Vorher haben wir
allerdings mit dem Befehl give self general;
das Attribut für den nächsten Versuch gesetzt.)
Auch Erkenntnis ist ein Attribut, das gesetzt
wird, wenn der Spieler (repräsentiert durch das Objekt Adam,
wie wir noch sehen werden) den Apfel isst.
- after
- funktioniert nach demselben
Prinzip wie before, wird aber erst aufgerufen, nachdem die Library
geprüft hat, ob die Aktion ausgeführt werden kann und sie auch ausgeführt
hat (z.B. bei Take den Apfel zum child
des Spielers gemacht hat oder bei Eat den
Apfel hat verschwinden lassen). Ein false
als Rückgabewert bedeutet, dass die Library nun auch ihren vordefinierten
Standardtext für die Aktion ausgeben soll; ein true
als Rückgabewert bedeutet wieder ,,Alles fertig - Schluss mit der
Aktion''.
Im Beispiel werden - für ein erfolgreiches Take
oder Eat - Texte mit dem Befehl "..."
ausgegeben, der ein implizites return true;
enthält. Nach diesem Text ist also in beiden Fällen Schluss mit der
jeweiligen Aktion.
- react_before
- funktioniert (ebenso
wie eine weitere property mit dem Namen react_after)
in gleicher Weise; nur wird sie nicht nur bei Befehlen aufgerufen,
in denen der Apfel direktes Objekt ist (,,nimm den Apfel'') sondern
bei allen Befehlen, die im Blickfeld des Apfels18 stattfinden.
Im Beispiel wird sie benutzt, um das Attribut general
wieder zurückzusetzen (man beachte die vorangestellte Tilde!), wenn
der Spieler einen anderen Befehl gibt als ,,nimm den Apfel''. Dies
bewirkt, dass der Apfel nur genommen werden kann, wenn der Spieler
seinen Befehl ,,nimm den Apfel'' zweimal unmittelbar nacheinander
erteilt.