Textadventures mit LUA

Anmerkung Januar 2021: Leider lässt es repl.it nicht mehr zu, dass nicht angemeldete Benutzer:innen die Codebeispiele ändern. Das ist sehr bedauerlich, ich kann es aber nicht ändern. Ihr müsst also, wenn ihr die Codebeispiele modifizieren oder Übungsaufgaben lösen wollt, einen repl.it Account anlegen. Das ist in der Basisversion kostenlos: https://repl.it/signup

Die Beispiele aus dem letzten Kurstermin

Eine erste Skizze

Eine erste Skizze mit Kommentaren

Ein sehr einfaches Beispiel

Das folgende „Abenteuer“ ist bewusst extrem simpel gehalten, damit es leicht zu verstehen ist:

– Es gibt lediglich drei Orte, und zwar einen roten, einen blauen und einen grünen Raum.
– Jeder Raum bietet zwei Aktionen an, nämlich das Wechseln in die jeweils beiden anderen Räume, und das war’s!

Programm Drei Räume

Übungsaufgaben

Aufgabe 1
Füge dem roten Raum die Aktion „Hallo rufen“ hinzu:
Bei der Ausführung der Aktion soll folgende Nachricht ausgegeben werden:
Du rufst ‚Hallo‘, aber niemand antwortet.


raum_rot = {

  name = "Roter Raum",

  beschreibung = [[
Du befindest Dich in einem roten Raum.]],

  aktionen = [[
a -> In den blauen Raum gehen.
b -> In den grünen Raum gehen.
c -> 'Hallo' rufen]],

  a = function()
    print("Du gehst in den blauen Raum.")
    return raum_blau
  end,

  b = function()
    print("Du gehst in den grünen Raum.")
    return raum_gruen
  end,

  c = function()
    print("Du rufst 'Hallo', aber niemand antwortet.")
    return raum_rot
  end

}

Neu sind die Zeilen 11 und 23 bis 26. Das Komma in Zeile 21 nicht vergessen!
(Jeder Raum ist eine Tabelle, und die Funktion c ist ein Tabelleneintrag – und die werden bekanntlich durch Kommas getrennt!)

Wichtig ist zu verstehen: Weil eine Aktion den Ort ändern kann, liefert die entsprechende Funktion immer einen Ort als Rückgabewert, auch wenn der sich nicht geändert hat.
Das ist hier der Fall: Die Funktion c ändert den Ort nicht, also liefert sie raum_rot zurück.

Lösung als REPL

Aufgabe 2 a
In dem folgenden Beispiel wurde ein vierter, oranger Raum hinzugefügt. Dieser Raum ist mit den anderen dreien nicht verbunden und bietet noch keine Aktionen.

Programm Oranger Raum, unverbunden

Sorge dafür, dass der orange Raum vom grünen Raum aus betreten werden kann! Schau Dir dazu einfach die Übergänge von den anderen Räumen an. Das Prinzip ist immer dasselbe!


raum_gruen = {

  name = "Grüner Raum",

  beschreibung = [[
Du befindest Dich in einem grünen Raum.]],

  aktionen = [[
a -> In den roten Raum gehen.
b -> In den blauen Raum gehen.
c -> In den orangen Raum gehen.]],

  a = function()
    print("Du gehst in den roten Raum.")
    return raum_rot
  end,

  b = function()
    print("Du gehst in den blauen Raum.")
    return raum_blau
  end,

  c = function()
    print("Du gehst in den orangen Raum.")
    return raum_orange
  end

}

Neu sind die Zeile 11 und die Zeilen 23-26.
Verändert haben sich die Zeilen 10 (eckige Klammern und Komma wandern eine Zeile nach hinten) und 21 (Komma hinzu).

Lösung als REPL


Aufgabe 2 b
Wenn Du 2 a gelöst hast, und das Programm testest und den orangen Raum betrittst, was ist das Problem?


Der orange Raum ist eine Sackgasse, Du kommst nicht mehr hinaus.


Aufgabe 2 c
Programmiere eine Verbindung vom orangen Raum in den roten Raum.


raum_orange = {

  name = "Oranger Raum",

  beschreibung = [[
Du befindest Dich in einem orangen Raum.]],

  aktionen = [[
a -> In den roten Raum gehen.]],

  a = function()
    print("Du gehst in den roten Raum")
    return raum_rot
  end

}

Lösung als REPL


Ein fast leeres Adventure mit der Engine 1.2

Folgendes Projekt ist ein guter Ausgangspunkt für ein neues, eigenes Adventure:
Programm Leeres Adventure

Dieses Video zeigt zur Wiederholung, wie ihr – ausgehend von dem leeren Adventure – einen Ort anlegt und ihm eine einfache Aktion hinzufügt:

Und hier seht ihr, wie ihr einen zweiten Ort anlegt und eine Verbindung vom zuerst angelegten Ort schafft. Auch das ist eine Wiederholung:

Aufgabe 3 a
Im Moment ist die Tür zwischen Raum eins und Raum zwei nicht verschlossen. Sichere die Tür mit einem Zahlenschloß! Wenn die Spielerin versucht, die Tür zu öffnen, soll sie um die Eingabe einer Kombination gebeten werden. Anschliessend soll die Eingabe mit der richtigen Kombination verglichen werden. Nur, wenn die Kombination richtig ist, soll der Übergang in den zweiten Raum gelingen!

Hier ist das Repl it mit den beiden Räumen und der Tür, noch ohne Zahlenschloss.

Lösung als REPL

Wie geht es weiter: Ein paar Überlegungen

Der aktuellen Engine 1.1 fehlen noch einige wichtige Fähigkeiten. Einiges, was mir am dringendsten erscheint:

1. Die Beschreibungen der Orte sind unveränderlich. Wenn wir der Truhe aus dem ersten Beispiel den Schlüssel entnehmen, dann steht da hinterher immer noch: „Die Truhe enthält einen Schlüssel…“

2. Das hängt auch damit zusammen, dass die Orte selbst unveränderlich sind.

3. Dabei dürfen wir nicht vergessen, dass ein Ort nicht nur Objekte (wie den Schlüssel) enthalten, sondern auch veränderliche Eigenschaften haben kann: Ein Ort kann ein Zimmer mit einem Lichtschalter sein. Ein Ort kann ein Notizbuch sein, in das wir hineinschreiben können. Ein Ort kann ein Computer sein, der per Passwort entsperrt werden muss…

Lösungsansatz:

ORT.beschreibung sollte kein feststehender String mehr sein, sondern eine Funktion, die (abhängig vom Zustand des Ortes!) einen Beschreibungsstring liefert.

– Wir könnten die Eigenschaften des Ortes „von Hand“ reinbasteln im Sinne von ORT.enthaelt_schluessel = true oder ORT.licht_an = false etc. Das wird aber schnell unübersichtlich. Besser wäre es, wenn jeder Ort eine Tabelle inhalt und eine Tabelle eigenschaften enthält.

– Wir können das einheitlich gestalten und dem Spieler ebenfalls eine Tabelle inhalt und eine Tabelle eigenschaften spendieren. spieler.beutel würden wir dann umbennenen in inhalt. spieler.ist_lebendig würden wir nach spieler.eigenschaften.ist_lebendig verschieben.

Das bietet dann ein paar Vorteile und interessante Möglichkeiten:

– Wir können den Inhalt und die Eigenschaften bei Bedarf einfach aufzählen, zum Beispiel um die Beschreibung zu erzeugen.

– Es könnte eine Funktion geben, die es allgemein möglich macht, Objekte in Orten abzulegen und aufzunehmen.

– Es könnte dann (ähnlich den Rezepten bei Minetest) Aufgaben geben. Beispiel: Das Ziel eines Spiels könnte sein, einen Kuchen zu backen. Die Zutaten sind in verschiedenen Orten verteilt. Der Spieler oder die Spielerin muss sie komplett einsammeln und am Ort kueche ablegen. Dann ist das Spiel gewonnen.