Direkt zum Hauptinhalt

Quest-Editor

Der Builder unter /dashboard/storyquests/<id>/builder ist das Werkzeug, in dem du deine Quest zusammenbaust. Eine separate Route /dashboard/storyquests/<id>/flowchart zeigt die reine Graph-Ansicht ohne die restlichen Panels — praktisch, wenn du nur die Struktur überblicken willst, ohne im Detail-Editor zu landen.

Layout

Der Builder hat drei Bereiche:

  • Links: Übersichts-Liste aller Nodes, Items und Variablen. Such-Feld oben. Klick öffnet das jeweilige Element rechts.
  • Mitte: Flowchart mit Nodes als Boxen und Choices als Pfeile. Zoom mit Mausrad, Pan mit Mittelklick.
  • Rechts: Detail-Panel für das gerade ausgewählte Element.

Oben die Aktions-Buttons: 📊 Flowchart (springt zur reinen Graph-Route), ▶ Playtest, 📤 Export JSON, 🤖 KI-Tools, « Veröffentlichen » und « Speichern » (Auto-Save ist aktiv, der Button erzwingt einen Snapshot).

Nodes bearbeiten

Ein Node hat folgende Felder:

  • Titel: Interner Name, nicht für Zuschauer sichtbar.
  • Erzähltext: Markdown-fähig, wird im Overlay/Chat angezeigt. Unterstützt Slash-Vorlagen beim Tippen: /haendler bzw. /shop für eine fertige Händler-Node-Struktur, /secret für einen Geheimpfad mit ⭐-Marker im Flowchart.
  • Node-Typ: normal, combat oder ending. Nur diese drei — es gibt keinen vierten „Quiz"- oder „Dialog"-Typ auf Node-Ebene (Dialoge/NPCs laufen über das darunterliegende Event-System, siehe unten).
  • Bei Typ combat: enemy_name, enemy_hp, enemy_attack, enemy_defense — definiert den Gegner für die eingebaute W16-Kampflogik.
  • Hintergrund/Sound: Asset-Picker aus der Media Library (/dashboard/media). Optional.

Choices bearbeiten

Eine Choice hat:

  • Label/Text: Was im Overlay/Chat als Option auftaucht.
  • Alias (optional): Zusätzliche Chat-Kommandos.
  • Ziel-Node (target_node_id): Wohin die Choice normalerweise führt.
  • Würfelprobe (roll_required): Wenn aktiviert, ersetzt roll_target + roll_modifier + getrennte success_node_id/failure_node_id das einfache Ziel. Geprüft wird W16-Wurf + roll_modifier >= roll_target. Ohne beide Ziel-Nodes (Erfolg und Misserfolg) lässt sich die Probe nicht speichern — der Builder verlangt explizit beide Pfade.
  • Effekte (effect_json): eine Liste aus add_item, remove_item, set_variable, inc_variable, dec_variable, add_hp, damage_hp. Der Builder bildet das als Formular ab — du musst kein JSON von Hand schreiben, aber es hilft zu wissen, dass genau diese sieben Effekt-Typen existieren und alles andere ignoriert wird (vorwärtskompatibel, kein Fehler).
  • Conditions (condition_json): Wann die Choice angezeigt wird.

Die Effekte laufen erst nach Voting-/Klick-Ende, nicht beim Anzeigen — wichtig fürs Verständnis bei Variablen, die eine Choice selbst mit anzeigt (z.B. „nur sichtbar wenn mut >= 3" prüft den Wert vor dem Klick, nicht danach).

Variables

Unter « Variables » legst du benannte Variablen an: Integer (mut, gold), Boolean (hat_schluessel), String (held_name). Jede Variable hat einen Startwert, mit dem jede neue Session beginnt — vergiss diesen Default nicht, sonst ist der State beim ersten Zugriff null.

Items

Unter « Items » definierst du Inventar-Gegenstände mit Name, Beschreibung und optional Icon. Effekte auf Choices: Item geben (add_item) / Item entfernen (remove_item), jeweils mit Menge. Conditions: has_item mit Mindestmenge.

Conditions — der tatsächliche Satz an Typen

Anders als ein freier „AND/OR mit Klammern"-Baukasten arbeitet die Engine mit genau diesen Condition-Typen (der Builder klickt sie für dich zusammen, aber es hilft zu wissen, was darunterliegt):

  • has_item — Inventar enthält Item X in Mindestmenge Y.
  • variable_equals — Variable == Wert.
  • variable_gte / variable_lte — Variable ≥ / ≤ Wert.
  • hp_gte — Charakter-HP ≥ Wert (nur relevant, wenn die Quest Kampf-Nodes nutzt).
  • all — UND-Verknüpfung einer Liste von Sub-Conditions.
  • any — ODER-Verknüpfung einer Liste von Sub-Conditions.

Ein Beispiel für „Mut mindestens 3 UND Schlüssel im Inventar" ist technisch:

{"type":"all","conditions":[
  {"type":"variable_gte","var_key":"mut","value":3},
  {"type":"has_item","item_key":"schluessel","qty":1}
]}

Du klickst das im Builder zusammen, ohne JSON einzugeben. Bei komplexen, verschachtelten all/any-Kombinationen lohnt sich vorher ein Playtest-Durchlauf, um das Verhalten zu bestätigen.

Erweiterte Story-Events (jenseits von Choices)

Für Storys, die mehr wollen als Node→Choice→Node, kennt die Engine zusätzlich datengetriebene Events, die z.B. beim Betreten eines Node ausgelöst werden können: loot (vergibt mehrere Items auf einmal), trap (Wahrnehmungsprobe, bei Fehlschlag automatisch Schaden), teleport (springt direkt zu einem Node, ohne Choice), random (gewichtete Zufallsverzweigung zwischen mehreren Ziel-Nodes), sowie dialogue und npc für Sprech-/NPC-Begegnungen (setzt intern Tracking-Variablen wie __npc_<key>_attitude und _met). Diese Events sind mächtiger als das reine Node/Choice-Modell, aber im Builder-UI (Stand Beta) noch nicht überall als eigenes Formular abgebildet — für sehr spezielle Verzweigungen (z.B. gewichtete Zufallspfade) ist der Weg über die API mit direktem JSON aktuell der zuverlässigste.

Validierung

Vor « Veröffentlichen » läuft eine Validierung. Sie warnt bei:

  • Choices ohne Ziel-Node (bzw. Würfelproben ohne beide Erfolgs-/Misserfolgs-Ziele).
  • Nodes ohne eingehende Verbindung (außer Start-Node) — also unerreichbar.
  • Endlos-Schleifen ohne ending-Node.
  • Referenzen auf gelöschte Variablen/Items.
  • Conditions, die immer false sind (z.B. widersprüchliche all-Kombination).

Warnungen blocken nicht zwingend, Fehler schon. Lies die Liste durch, bevor du veröffentlichst.

KI-Tools im Builder

Über 🤖 KI-Tools öffnest du ein Modal mit vier Funktionen: Szene generieren (aus 1-2 Sätzen einen neuen Node-Vorschlag), Choices vorschlagen (2-4 Folge-Choices für den aktuell gewählten Node), Gegner generieren (Stats + Beschreibung aus einem Prompt, für combat-Nodes), und Body umschreiben (Ton-Variante des aktuellen Erzähltexts, überschreibt erst nach „Übernehmen").

Wichtig für Erwartungsmanagement: Das Modal ist im UI noch mit „(Stub-Modus, Real-Provider folgt)" beschriftet — das Label ist aber veraltet. Im Backend prüft AiHooks, ob ein OPENAI_API_KEY gesetzt ist: Wenn ja, geht die Anfrage tatsächlich an einen echten OpenAiProvider (Modell gpt-4o-mini per Default), der die storyquest_node/branch/enemy/tone-Anfrage-Arten explizit kennt. Nur wenn dieser Call fehlschlägt oder ein ungültiges Ergebnis liefert, fällt AiHooks auf eine deterministische Heuristik zurück (Antwort enthält dann mode: stub statt mode: real). Erwarte also bei gesetztem Key kontextsensitive Vorschläge, nicht nur generische Standardwerte — nur ohne Key oder bei Ausfall greift die Heuristik. Jeder KI-Call wird über AiAuditLogger protokolliert, unabhängig vom Stub-/Real-Status.

Vorlagen (Templates)

Auf /dashboard/storyquests gibt es « Aus Vorlage erstellen » mit sechs eingebauten Beispiel-Storys: Der Erste Schritt (Mini-Tutorial mit einer Würfelprobe), Im verzauberten Wald, Das vergessene Verlies, Die Höhle des Schattenwolfs (mit Kampf-Node und Loot), Die verlassene Klinik (Horror-Genre) und Generationsschiff Aurora (Sci-Fi, inkl. KI-Drohnen-Kampf). Jede Vorlage erzeugt eine vollständige, eigenständige Kopie in deinem Account — guter Ausgangspunkt, um Kampf-Nodes oder Würfelproben am funktionierenden Beispiel zu studieren, statt sie blind zu bauen.

Import/Export

« Export » lädt deine Quest als JSON herunter — vollständiges Backup inkl. Nodes/Choices/Items/Variablen/Grundstats. Über POST /v1/storyquests/import spielst du eine exportierte Quest (oder eine der o.g. Vorlagen im gleichen Format) in einen anderen Account ein — gut für Showcase-Sharing oder Backup. Der Import-Endpunkt ist derselbe generische Importer, den auch die Vorlagen-Erstellung intern nutzt, d.h. Export→Import ist ein garantierter Round-Trip.

Die API-Routen für die Bearbeitung sind unter /v1/storyquests/<id>/nodes, /choices, /items, /variables. Für Bulk-Operationen (z.B. 50 Nodes auf einmal anlegen) lohnt sich ein Skript gegen die API statt manuelles Klicken — insbesondere für datengetriebene Events wie random mit vielen gewichteten Branches, die im UI noch keine eigene Oberfläche haben.

Analytics

Es gibt keine Dashboard-Route /dashboard/storyquests/<id>/analytics und auch keine Heatmap/Stimm-Verteilung/Drop-off-UI im Beta-Stand — das ist im aktuellen Code nicht vorhanden. Serverseitig existiert nur GET /v1/storyquests/<id>/stats mit Finish-/Abbruch-/Wipe-Rate über alle Sessions, aber ohne eigene Anzeige im Dashboard.