Basic Concepts
Verstehen Sie die Grundlagen interaktiven Storytellings
Wichtige Konzepte
Warum das wichtig ist
🔢 Variables & Query DSL
TellsTree verwendet eine eigene Domain-Specific Language (DSL) für den Zugriff auf Daten in Ihrer Geschichte. Mit dieser Query-Syntax können Sie auf Nodes, Edges, Project-Informationen und Variables zugreifen.
💡 Wichtig: Die DSL ermöglicht dynamische Inhalte, bedingte Verzweigungen und variable Dialoge. Sie ist das Herzstück der interaktiven Funktionen in TellsTree.
📝 Query Syntax
Grundformat:
- entity — Der Entitätstyp:
node,edge,self,project - selector — ID oder
self(optional) - field — Das Datenfeld:
content,variables,label,type, etc. - key — Array-Schlüssel für verschachtelte Daten (optional)
✅ Gültige Queries:
💡 Erläuterungen:
node[21]— Zugriff auf Node mit ID 21self— Aktueller Node oder Edge im Kontextcontent[name]— Feld "name" aus content-Objektvariables[level]— Variable "level"project.title— Projekttitel (ohne Selektor)
🎯 Verfügbare Entities
🔵 node
Zugriff auf Story-Knoten (Charaktere, Dialoge, Szenen, etc.)
content— Content-Daten (Array)variables— Gespeicherte Variablenmedia— Media-URLslabel— Anzeigenametype— Node-Typnode_id/id— Eindeutige ID
🔗 edge
Zugriff auf Verbindungen zwischen Nodes
condition— Bedingungsdaten (Array)type— Edge-Typ (flow/contains/link)edge_id/id— Eindeutige IDfrom_node_id— Start-Nodeto_node_id— Ziel-Node
⭐ self
Referenz auf die aktuelle Entity im Kontext (Node oder Edge)
- Zugriff auf eigene Daten
- Relative Referenzen
- Kontext-abhängige Queries
📁 project
Zugriff auf Projekt-Metadaten
project_id/id— Projekt-IDtitle— Projekttiteldescription— Beschreibungis_public— Öffentlich?
🎨 Template Resolution
Queries können in Templates mit doppelten geschweiften Klammern eingebettet werden.
Syntax:
→ Wird zu: Hello, Alice! (wenn node 15 name="Alice" hat)
🔄 Verschachtelte Queries:
TellsTree unterstützt verschachtelte Query-Resolution. Innerste Ausdrücke in Klammern () werden zuerst aufgelöst.
1. (self.data.speakerId) → 01HQRST...
2. node[id=01HQRST...].data.name → Alice
Beispiele:
→ Your level: 5
→ Hello, John
Anwendungsfälle:
- ✓ Dynamische Dialog-Texte
- ✓ Variable Edge-Labels
- ✓ Bedingte Anzeige-Texte
- ✓ Player-spezifische Inhalte
- ✓ Kontext-abhängige UI
⚖️ Bedingungen (Conditions)
Queries können in Bedingungen verwendet werden, um Edges oder UI-Elemente konditional anzuzeigen.
Struktur:
{
"query": "self.variables[level]",
"operator": ">=",
"value": 5
}
→ Bedingung ist wahr wenn level ≥ 5
Verfügbare Operatoren:
== / equals=== / strict_equals!= / not_equals> / greater_than>= / greater_or_equal< / less_than<= / less_or_equalcontainsinBeispiel-Bedingungen:
🎯 Verwendung in Edges:
Flow-Edges können Bedingungen haben. Nur Edges mit erfüllter Bedingung werden im Gameplay aktiviert. Dies ermöglicht branching narratives basierend auf Spieler-Entscheidungen und Status.
🔒 Sicherheit & Permissions
Automatische Permission-Checks:
- ✓ Alle Queries werden gegen Projekt-Zugriff validiert
- ✓ Nur Nodes/Edges im aktuellen Projekt sind zugreifbar
- ✓ User-Permissions werden automatisch geprüft
- ✓ Öffentliche Projekte sind für alle lesbar
- ✓ Private Projekte nur für Besitzer/Mitglieder
💡 Hinweis: Ungültige Queries (z.B. fehlende Permissions, nicht existierende IDs)
geben null zurück und werden geloggt. Das System ist fail-safe designed.
💎 Best Practices
✅ Do:
- • Verwende
selffür relative Referenzen - • Nutze sprechende Variablen-Namen
- • Teste Bedingungen vor Production
- • Verwende Templates für dynamische Inhalte
- • Halte Queries einfach und lesbar
❌ Don't:
- • Vermeide zu tief verschachtelte Queries
- • Keine Queries auf nicht-existierende IDs
- • Keine zirkulären Referenzen
- • Keine sensiblen Daten in Variables
- • Nicht mehr als 10 Verschachtelungs-Level
📘 Query DSL (Domain-Specific Language)
TellsTree verwendet eine eigene Domain-Specific Language für den Zugriff auf Daten in Ihren Projekten. Die DSL ermöglicht dynamische Inhalte, bedingte Verzweigungen und interaktive Dialoge.
💡 Neu in Version 2.0: Die DSL verwendet jetzt Dot-Notation statt Bracket-Notation für sauberere, lesbarere Ausdrücke.
📝 Syntax-Übersicht
Dot-Notation (Neu):
Bracket-Notation (Alt, veraltet):
✅ Gültige Ausdrücke:
💡 Bedeutung:
self— Aktueller Node oder Edgeproject— Aktuelles Projektnode[id=...]— Spezifischer Node (ULID)$variable— Variable aus Kontext(...)— Gruppierter Ausdruck.field.nested— Verschachtelte Felder
🎯 Referenztypen
🔹 Self-Referenz
Greift auf den aktuellen Node oder Edge zu, der den Ausdruck auswertet.
self.variables.level
self.type
🔹 Project-Referenz
Greift auf das aktuelle Projekt zu.
project.variables.questComplete
project.owner_id
🔹 Entity-Referenz (Node/Edge)
Greift auf einen spezifischen Node oder Edge über seine ULID zu.
edge[id=01HQRST0123456789ABCDEFG10].data.distance
node[id=$targetNodeId].variables.health
$variableName
🔹 Variable-Referenz
Greift auf Variablen aus dem Kontext zu.
$questComplete
$targetNodeId
🔑 Feld-Zugriff
Nach der Referenz können Sie mit Dot-Notation auf verschachtelte Felder zugreifen:
Verschachtelte Pfade:
⚠️ Wichtig: Wenn ein Feld nicht existiert, gibt die DSL im lenient-Modus
null zurück. Im strict-Modus wird eine Exception geworfen.
⚠️ Fehlerbehandlung
Lenient-Modus (Standard):
Fehlende Felder oder Entitäten geben null zurück, keine Fehler werden geworfen.
Strict-Modus:
Fehler werden als Exceptions geworfen. Nützlich für Debugging.
📚 Beispiele
Beispiel 1: Character-Information
Gibt den Namen des Charakters aus dem aktuellen Node zurück.
Beispiel 2: Quest-Fortschritt
Gibt die Anzahl der abgeschlossenen Quests aus den Projekt-Variablen zurück.
Beispiel 3: Referenzierter NPC
Greift auf den Namen eines NPCs zu, dessen ID in der Variable $mentorId gespeichert ist.
Beispiel 4: Verschachtelte Daten
Greift auf die aktuelle Gesundheit aus verschachtelten Variablen zu.
✨ Best Practices
- ✓ Verwenden Sie self für Zugriff auf den aktuellen Node/Edge
- ✓ Verwenden Sie project für globale Projekt-Daten
- ✓ Verwenden Sie Variablen ($varName) für dynamische ID-Referenzen
- ✓ Vermeiden Sie tiefe Verschachtelung (max. 5-7 Ebenen)
- ✗ Verwenden Sie nicht die alte Bracket-Notation (veraltet)
- ✗ Verwenden Sie nicht numerische IDs (nur ULIDs werden unterstützt)
🎯 Conditions System
Das Conditions-System ermöglicht bedingte Logik in TellsTree. Mit Predicates und Conjunctions können Sie komplexe Bedingungen erstellen, die bestimmen, ob ein Edge sichtbar ist oder welche Aktionen verfügbar sind.
💡 Wichtig: Conditions verwenden die DSL-Syntax für den Zugriff auf Daten und unterstützen AND/OR-Verknüpfungen beliebiger Tiefe.
🏗️ Struktur
Eine Condition besteht aus zwei Haupttypen:
🔹 Predicate (Vergleich)
Ein einzelner Vergleich zwischen zwei Werten.
🔹 Conjunction (Verknüpfung)
Verbindet mehrere Conditions mit AND oder OR.
⚙️ Operatoren
== (Gleich)
Strenger Gleichheitsvergleich (keine Typ-Konvertierung).
true zurück, wenn beide Werte identisch sind.
!= (Ungleich)
Strenger Ungleichheitsvergleich.
true zurück, wenn Werte unterschiedlich sind.
in (Enthalten in)
Prüft, ob ein Element in einem Array oder String enthalten ist.
contains (Enthält)
Prüft, ob ein Container ein Element enthält (symmetrisch zu "in").
🔗 Conjunctions (Verknüpfungen)
AND (Alle müssen erfüllt sein)
Gibt true zurück, wenn alle Bedingungen erfüllt sind.
✓ Beide Bedingungen müssen true sein.
OR (Mindestens eine muss erfüllt sein)
Gibt true zurück, wenn mindestens eine Bedingung erfüllt ist.
✓ Mindestens eine Bedingung muss true sein.
Verschachtelte Conjunctions
Conjunctions können beliebig tief verschachtelt werden.
✓ Entspricht: character AND (level >= 10 OR hasKey)
📚 Beispiele
Beispiel 1: Einfache Level-Prüfung
Prüft, ob der Spieler mindestens Level 5 erreicht hat.
Beispiel 2: Klassen-Prüfung
Prüft, ob der Character ein Mage oder Sorcerer ist.
Beispiel 3: Quest-Gating
Prüft mehrere Bedingungen für Quest-Zugang: Level, vorherige Quest und Item.
Beispiel 4: Cross-Node-Referenz
Prüft das Trust-Level eines anderen NPCs (Mentor).
🔀 Edge Conditions
Edges können Conditions haben, die bestimmen, ob sie sichtbar oder klickbar sind.
Edge-Struktur:
💡 Wichtig: Bei Edge-Conditions bezieht sich self auf den
Source-Node, nicht auf den Edge selbst.
✨ Best Practices
- ✓ Verwenden Sie explizite Conjunctions für Klarheit
- ✓ Halten Sie Conditions flach (max. 3-4 Ebenen Tiefe)
- ✓ Verwenden Sie Variablen für dynamische Werte
- ✓ Testen Sie Conditions im strict-Modus während der Entwicklung
- ✗ Vermeiden Sie Typ-Vermischung (Zahlen vs. Strings)
- ✗ Vermeiden Sie zirkuläre Referenzen
- ✗ Verwenden Sie nicht mehr als 10 Bedingungen pro Conjunction
📝 Template System
Das Template-System ermöglicht dynamische Inhalte in TellsTree. Mit der
{{...}}-Syntax können Sie DSL-Ausdrücke in Texte einbetten,
die zur Laufzeit aufgelöst werden.
💡 Wichtig: Templates verwenden dieselbe DSL-Syntax wie Conditions,
aber mit spezieller Template-Markierung {{...}}.
🔤 Template-Syntax
Grundformat:
Alles zwischen {{...}} wird als DSL-Ausdruck behandelt und zur Laufzeit aufgelöst.
✅ Gültige Templates:
💡 Ergebnisse:
🔢 Mehrere Ausdrücke
Sie können beliebig viele Template-Ausdrücke in einem Text verwenden:
Template:
Ergebnis:
🎨 Datentypen
Template-Ausdrücke werden automatisch in Strings konvertiert:
Strings
Zahlen
Booleans
Arrays
Null/Undefined
🔄 Verschachtelte Templates
Templates können andere Templates auflösen (max. 5 Ebenen Tiefe):
Beispiel:
⚠️ Wichtig: Zirkuläre Template-Referenzen werden erkannt und führen zu einem Fehler oder geben das Template unverändert zurück (je nach Modus).
🎯 Anwendungsfälle
1. Dialog-Text
Personalisierte NPC-Dialoge mit Spieler-Namen und Status:
2. Quest-Beschreibungen
Dynamische Quest-Texte mit Zielen und Items:
3. Status-Anzeigen
HUD-Elemente mit aktuellen Werten:
4. Bedingte Texte
Texte, die basierend auf Conditions angezeigt werden:
⚠️ Fehlerbehandlung
Lenient-Modus (Standard):
Fehlgeschlagene Ausdrücke werden durch leere Strings ersetzt:
Strict-Modus:
Fehler werden als Exceptions geworfen (nützlich für Debugging):
📚 Vollständige Beispiele
NPC-Dialog
Quest-Log-Eintrag
✨ Best Practices
- ✓ Verwenden Sie kurze, lesbare Ausdrücke in Templates
- ✓ Speichern Sie komplexe Werte in Variablen
- ✓ Verwenden Sie Fallback-Werte für optionale Felder
- ✓ Testen Sie Templates im strict-Modus während der Entwicklung
- ✗ Vermeiden Sie tiefe Verschachtelung (> 3 Ebenen)
- ✗ Vermeiden Sie komplexe Ausdrücke direkt in Templates
- ✗ Verwenden Sie keine Arrays direkt in Texten (formatieren Sie sie zuerst)
🔗 Edge Types
In TellsTree unterscheiden wir drei grundlegende Edge-Typen, die jeweils unterschiedliche semantische Bedeutungen haben und sich in ihrer Darstellung und Validierung unterscheiden.
💡 Wichtig: Die richtige Wahl des Edge-Typs ist entscheidend für die
Validierung und Darstellung Ihrer interaktiven Geschichten. Nur flow-Edges
können getestet werden und bilden den logischen Ablauf.
📦 1️⃣ contains — Strukturelle Zugehörigkeit
Beschreibt hierarchische Beziehungen und Besitz. Dieser Edge-Typ definiert, dass ein Element Teil eines anderen ist.
Eigenschaften:
- Beschreibt Besitz, Teilmenge, Einbettung
- Keine zeitliche Komponente
- Keine Richtung im Sinne von Ablauf
- Keine Bedingungen möglich
- Nicht test-relevant
Semantische Aliase:
Beispiele:
Chapter
→
Scene
Scene
→
Story-Segment
Dialog
→
Dialog-Entry
Inventory
→
Item
Character
→
Trait
Stage
→
Gameplay-Segment
Alle diese Beziehungen bedeuten: "A gehört zu B"
➡️ UI-Darstellung:
- ✗ Kein Pfeil
- ✓ Sidelane / Grouping / Umrandung
- ✓ Rein organisatorisch
🌊 2️⃣ flow — Gerichtete, bedingte Abfolge
Dies ist der einzige Edge-Typ, der zeitlich, testbar und logisch relevant ist. Flow-Edges definieren den tatsächlichen Ablauf Ihrer Geschichte.
Eigenschaften:
- Immer gerichtet
- Optional: Bedingungen (conditions)
- Optional: Effekte / Events
- Relevant für Validierung
- Kann "offene Enden" erzeugen
Semantische Varianten:
✅ Kritische Regel:
Alle flow-Verbindungen müssen von Start bis Ende gehen. Nur flow-Edges bilden Graphen, die man testen kann.
Beispiel-Ablauf:
Start
→
Scene 1
Scene 1
→
Choice A
Scene 1
→
Choice B
Choice A
→
End
➡️ UI-Darstellung:
- ✓ Gerichteter Pfeil
- ✓ Bedingungen anzeigen
- ✓ Highlighting bei Validierung
- ✓ "Offene Enden" rot markieren
🔗 3️⃣ link — Lose, nicht-sequenzielle Verbindung
Ein Edge-Typ, den viele Systeme nicht sauber trennen. Links sind rein referenziell und haben keine logische oder zeitliche Bedeutung.
Eigenschaften:
- Keine zeitliche Komponente
- Keine Reihenfolge
- Keine Validierungslogik
- Rein semantisch / referenziell
- Optional ein-/ausblendbar
Semantische Varianten:
Beispiele:
Character A
⋯→
Character B
mentions (in dialogue)
Location A
⋯→
Location B
connects_to (map reference)
Scene 5
⋯→
Scene 12
references (callback)
⚠️ Wichtig:
Link-Edges sind niemals testrelevant. Sie dienen nur der Dokumentation und semantischen Verbindung, nicht dem logischen Ablauf.
➡️ UI-Darstellung:
- ✓ Gestrichelte Linie oder Pfeil
- ✓ Label / Beschreibung anzeigen
- ✓ Optional ein-/ausblendbar
- ✗ Niemals in Validierung einbeziehen
📊 Vergleichstabelle
| Eigenschaft | contains | flow | link |
|---|---|---|---|
| Zeitlich | ❌ | ✅ | ❌ |
| Gerichtet | ❌ | ✅ | ➖ (optional) |
| Bedingungen möglich | ❌ | ✅ | ❌ |
| Testrelevant | ❌ | ✅ | ❌ |
| UI-Darstellung | Grouping | Pfeil → | Gestrichelt ⋯→ |
| Validierung | Organisatorisch | Vollständig | Keine |
📦 Nodes
Coming soon...
🕸️ Graph Structure
Coming soon...