VNLEWIKIGeschichten entwickeln. Welten verbinden.English
VNLE Handbuch

Ablaufregeln & Spielaktionen

← Lernweg und Engines

Diese Regeln erklären die Bedeutung des Exports für eigene Skripte und Community-Integrationen. Die JSON enthält Daten, keinen auszuführenden Quellcode. Editorlayout, Auswahlzustand und interne Bildschirmanordnung steuern das Spiel nicht.

Vor dem ersten Schritt

Prüfe format = vnle.story, containerVersion = 1 und die unterstützte execution.contractVersion samt requiredCapabilities. Das Beispiel nutzt 1.1 sowie core.v1 und substory.call-return.v1. Das JSON-Schema prüft Strukturen; für den Ablauf auch Referenzen, Typen und unterstützte Commands prüfen. Unbekannte Knotentypen nie stillschweigend überspringen.

Feldreferenz · JSON Schema

Was jeder Knoten bedeutet

kindVerhalten
dialogueText präsentieren und auf Weiter warten; anschließend continuation.
choiceoptionOrder beachten, option.condition filtern, bei Auswahl effects einmal anwenden und continuation folgen. whenEmpty beachten.
branchcondition auswerten; whenTrue oder whenFalse folgen.
actioneffects der Reihe nach auswerten, danach continuation.
jumpZieleinstieg auflösen, ohne eine neue Rücksprungstelle zu speichern.
callcontinuation merken, dann zum Zieleinstieg wechseln.
returnDie zuletzt gemerkte Fortsetzung wieder aufnehmen. Ohne vorherigen Call ist dies ein Fehler.
commandArgumente auswerten, Spielaktion anfordern, auf Ergebnis warten und den zugehörigen Ausgang fortsetzen.
endGesamtes laufendes Gespräch beenden, auch innerhalb einer Untergeschichte. Return ist die Rückkehr zum Aufrufer.

Bedingungen und typisierte Werte

Ein Operand ist entweder literal mit einem typisierten value oder variable mit variableRef. compare unterstützt eq, ne, lt, lte, gt, gte. all bedeutet alle Teilbedingungen, any mindestens eine, not die Umkehrung. boolesche Werte nicht mit den Strings "true"/"false" verwechseln.

Variableneffekte sind set, add und subtract. add/subtract verwenden Integer; Wertebereich −2147483648 bis 2147483647. Änderungen in ihrer Reihenfolge auswerten, aber bei einem ungültigen Effekt keine halbe Änderung übernehmen. initiale defaultValue-Daten nicht bei jedem Gespräch erneut über den Spielstand schreiben.

Jump · Nach dem Kauf zum Lagerhaus

Jump

Der Hafenschlüssel wurde bereits gekauft: springe direkt zum Einstieg „Warehouse“. target enthält flowRef und entryRef; execution.entries[entryRef].nodeRef liefert den nächsten Knoten. Ein Jump öffnet nicht automatisch eine Engine-Szene oder eine neue Map. Dafür wäre eine passende Spielaktion nötig.

{
  "flowRef": "1f69a7b6-1bdc-4dff-b8ee-9b2819b35168",
  "id": "2e1710dc-c32f-418f-abca-e055d6fd28f3",
  "kind": "jump",
  "target": {
    "entryRef": "a4dd48dc-b0e2-47fc-b102-def52583a8fe",
    "flowRef": "2a0a259c-b76a-4de0-8cee-567713c2d320"
  }
}
Call Substory / Return · Mira erklärt das Lagerhaus

Call Substory / Return

Ja, dieser Ablauf funktioniert über die JSON. Nach der Begrüßung ruft die Geschichte die Erklärung zum verschlossenen Lagerhaus auf. Das Spiel legt die continuation auf einen Stapel und betritt target. Nach Miras Erklärung trifft es auf return, nimmt die oberste Fortsetzung vom Stapel und führt die Prüfung „Already have the key?“ aus. Verschachtelte Aufrufe funktionieren nach demselben Prinzip.

{
  "continuation": {
    "kind": "node",
    "nodeRef": "95e9a55f-f6b1-4696-9c52-6ea3ea2ac7e5"
  },
  "flowRef": "1f69a7b6-1bdc-4dff-b8ee-9b2819b35168",
  "id": "85b3aadf-2b95-4150-bc44-c0c796337874",
  "kind": "call",
  "target": {
    "entryRef": "2bac8555-3cae-4a21-9b8c-b410ab207ebb",
    "flowRef": "ea13b52e-092a-44ff-b087-0ce65d040c9a"
  }
}
{
  "flowRef": "ea13b52e-092a-44ff-b087-0ce65d040c9a",
  "id": "f8b8673a-cb86-40ae-a4f6-d37a5c1563c3",
  "kind": "return"
}

Alle betroffenen Knoten liegen im story.json-Export. Call bedeutet hier nicht, eine weitere JSON-Datei oder ein Skript nachzuladen. maxCallDepth begrenzt die Verschachtelung. Return mit leerem Stapel ist ein Fehler. End beendet hingegen das gesamte Gespräch und leert den Stapel.

Command · Shop öffnen oder einen Schlüssel geben

Command

„Shop öffnen“ ist ein passendes Beispiel: das Spiel öffnet seinen eigenen Shop und lässt das Gespräch warten. Erst nach dem Schließen meldet es einen zuvor vereinbarten Ausgang zurück, beispielsweise gekauft oder abgebrochen. Diese Namen und Argumente müssten im jeweiligen VNLE-Projekt als Spielaktion definiert sein; open_shop ist kein eingebauter VNLE-Befehl.

Der echte Harbour-Export verwendet give_item: der Command verweist auf eine Definition, übergibt die Item-ID und bietet zwei Ausgänge. Das Spiel fügt den Schlüssel seinem Inventar hinzu oder lehnt die Übergabe ab. Der Autor hat für beide Ergebnisse bereits den weiteren Weg definiert.

{
  "arguments": {
    "3cac6185-4404-4a2a-be5f-14afa0f97137": {
      "kind": "literal",
      "value": {
        "entityType": "item",
        "type": "reference",
        "value": "2d71e57e-9b58-4fdb-a33f-42b89bd8bf04"
      }
    }
  },
  "commandRef": "0723beb0-daba-4602-a665-4efc27511bc3",
  "flowRef": "1f69a7b6-1bdc-4dff-b8ee-9b2819b35168",
  "id": "500c28a1-ed85-4c36-9a38-bedacce1c6b7",
  "kind": "command",
  "outcomes": {
    "12bc86a9-b2eb-4eb4-836c-a9efd936bf1b": {
      "continuation": {
        "kind": "node",
        "nodeRef": "382640aa-5b50-4715-9148-b470bc2f7cd6"
      },
      "resultBindings": {}
    },
    "1c527580-69a6-4e99-8503-1b0de3fc8e78": {
      "continuation": {
        "kind": "node",
        "nodeRef": "221d6b0c-99e1-45a8-bc73-768c4ee679eb"
      },
      "resultBindings": {}
    }
  }
}
{
  "id": "0723beb0-daba-4602-a665-4efc27511bc3",
  "key": "give_item",
  "name": "Give item",
  "category": "custom",
  "inputs": [
    {
      "id": "3cac6185-4404-4a2a-be5f-14afa0f97137",
      "name": "Item",
      "valueType": {
        "entityType": "item",
        "kind": "reference"
      }
    }
  ],
  "outcomes": [
    {
      "id": "12bc86a9-b2eb-4eb4-836c-a9efd936bf1b",
      "name": "Received",
      "results": []
    },
    {
      "id": "1c527580-69a6-4e99-8503-1b0de3fc8e78",
      "name": "Declined",
      "results": []
    }
  ]
}
  1. commandRef in execution.commands (Signatur) und content.commandDefinitions (lesbarer key) nachschlagen.
  2. arguments anhand der Eingabe-IDs auswerten; fehlende optionale Argumente verwenden den definierten defaultValue.
  3. Die vom Spiel ausdrücklich unterstützte Aktion einmal anfordern. Währenddessen weder Weiter noch eine zweite Ausführung zulassen.
  4. Ergebnis-ID und typisierte Ergebniswerte prüfen. outcome.resultBindings schreibt Ergebniswerte in Storyvariablen; anschließend outcome.continuation folgen.
  5. Ein technischer Fehler ist nicht automatisch der vom Autor definierte Abbruch. Fehler anzeigen und einen kontrollierten Wiederholungs-/Abbruchweg im Spiel anbieten.

In diesem Projekt führt die abgelehnte Schlüsselübergabe zu einer Erstattung der fünf Goldstücke. Das geschieht durch den exportierten Folgepfad, nicht automatisch durch jeden Command. Inventar, Questjournal und Engine-Maps sind Systeme deines Spiels; ihre JSON-Katalogeinträge allein erzeugen sie nicht.

Platzhalter · „Du hast noch 5 Gold“

Text und Platzhalter

{
  "continuation": {
    "kind": "node",
    "nodeRef": "2e1710dc-c32f-418f-abca-e055d6fd28f3"
  },
  "flowRef": "1f69a7b6-1bdc-4dff-b8ee-9b2819b35168",
  "id": "0d7f959e-8fba-4882-ae98-b66d8416d4d2",
  "kind": "dialogue",
  "speakerRef": "807b2957-7bab-4a28-83a4-1f3d1589bbc2",
  "text": {
    "bindings": {
      "1084cf8e-515e-4b33-92f8-b5c260e88a9e": {
        "kind": "variable",
        "variableRef": "a547610e-661f-4b8d-a25b-21d042f1a2d5"
      }
    },
    "textRef": "fcc775ff-558e-4a41-823d-183aaff03e4b"
  }
}

Textsegmente kind: text direkt zusammensetzen. Bei kind: placeholder über placeholderRef die Definition im Textdatensatz und die zugehörige Bindung in node.text.bindings nachschlagen. Die Bindung liefert einen Literal- oder Variablenwert. Beim Anzeigen festhalten und typgerecht formatieren. Die Typen und Formatoptionen stehen in der Feldreferenz.

PlaceholderDefinition · Message

Fortschritt, Grenzen und Fehler

Speichere aktuelle Position, Storyvariablen, Rücksprungstapel und gegebenenfalls eine ausstehende Spielaktion zusammen mit dem Spielzustand. Sprache ist eine eigene Spieleinstellung. storyBuildId hilft, einen Spielstand der Ablaufversion zuzuordnen; bei einer unvereinbaren Geschichte nicht an einer geratenen Stelle fortsetzen.

maxAutomaticTransitions, maxConditionDepth, maxConditionTerms und maxCallDepth verhindern endlose oder übermäßig tiefe Abläufe. Fehlende Referenzen, keine verfügbaren Antworten mit whenEmpty: fault, unbekannte Commands und ungültige Typen benötigen eine verständliche Fehlermeldung. Ein erneutes Zeichnen der Oberfläche darf niemals Käufe oder Variablenänderungen wiederholen.

An Entwickler oder eine KI weitergeben

Gib den echten Export, Engine-Version, Zielplattform, diese Ablaufregeln und die Engine-Seite weiter. Beschreibe deine UI-Elemente sowie vorhandene Inventar-/Shop-Funktionen. Bitte darum, nur vorhandene JSON-Felder und dokumentierte Engine-APIs zu verwenden und die untenstehenden Fälle tatsächlich zu prüfen.

  1. Zehn Gold: Schlüssel erhalten, fünf Gold übrig; zwei Gold: kein Schlüssel und kein Abzug.
  2. Inventar lehnt ab: Erstattung gemäß Story; keine erfundene Erfolgsmeldung.
  3. Call/Return setzt am vorgesehenen Knoten fort; End innerhalb eines Calls beendet das Gespräch.
  4. Sprachwechsel verändert den Fortschritt nicht; fehlende Übersetzung und absichtlich leerer Text funktionieren.
  5. Ausgelieferte JSON/Bilder/Schrift funktionieren außerhalb des Entwicklungsordners; fehlende Bilder lassen kein altes Porträt stehen.