VNLEWIKITwórz historie. Łącz światy.
Polski
Podręcznik VNLE

Reguły przebiegu i akcje gry

← Od treści do gry i silniki

Te reguły opisują eksport na potrzeby własnych skryptów i integracji tworzonych przez społeczność. JSON zawiera dane, nie kod do wykonania. Układ edytora, zaznaczenie i rozmieszczenie elementów na ekranie nie sterują grą.

Przed pierwszym krokiem

Sprawdź format = vnle.story, containerVersion = 1, obsługiwaną wersję execution.contractVersion oraz requiredCapabilities. Przykład używa wersji 1.1 z core.v1 i substory.call-return.v1. JSON Schema sprawdza strukturę; wykonanie wymaga też kontroli odwołań, typów i obsługiwanych poleceń. Nigdy nie pomijaj nieznanego typu węzła bez zgłoszenia błędu.

Opis pól · JSON Schema

Co oznacza każdy węzeł

kindDziałanie
dialogueWyświetl tekst i poczekaj na Continue, a następnie wykonaj continuation.
choiceZachowaj optionOrder, odfiltruj opcje według option.condition, zastosuj efekty wybranej opcji dokładnie raz i wykonaj continuation. Uwzględnij whenEmpty.
branchSprawdź condition i przejdź do whenTrue lub whenFalse.
actionWykonaj effects w podanej kolejności, a następnie continuation.
jumpPrzejdź do docelowego punktu wejścia bez zapisywania nowego punktu powrotu.
callZapamiętaj continuation, a następnie przejdź do docelowego punktu wejścia.
returnWznów ostatnio zapisaną kontynuację. Powrót bez wcześniejszego Call jest błędem.
commandOblicz argumenty, wywołaj akcję gry, poczekaj na wynik i przejdź ścieżką odpowiadającą temu wynikowi.
endZakończ całą bieżącą rozmowę, również wewnątrz pobocznej sekwencji. Return wznawia rozmowę wywołującą.

Warunki i typy wartości

Operand to literal z wartością określonego typu albo variable z variableRef. compare obsługuje eq, ne, lt, lte, gt, gte. all wymaga spełnienia wszystkich warunków podrzędnych, any — co najmniej jednego, a not neguje warunek. Nie myl wartości logicznych z tekstami "true"/"false".

Efekty zmiennych to set, add i subtract. add/subtract używają liczb całkowitych od −2147483648 do 2147483647. Wykonuj efekty po kolei, ale nie zapisuj częściowej aktualizacji, jeśli któryś jest nieprawidłowy. Nie nadpisuj zapisanych wartości początkowym defaultValue przy każdej rozmowie.

Jump · Przejście do magazynu po zakupie

Jump

Klucz został już kupiony: przejdź bezpośrednio do punktu wejścia Warehouse. target zawiera flowRef i entryRef; execution.entries[entryRef].nodeRef wskazuje następny węzeł. Jump nie otwiera automatycznie sceny ani mapy silnika. Do tego potrzebna jest odpowiednia akcja gry.

{
  "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 opowiada o magazynie

Call Substory / Return

Tak, ten przebieg jest opisany w JSON. Po powitaniu historia wywołuje wyjaśnienie dotyczące zamkniętego magazynu. Gra odkłada continuation na stos i przechodzi do target. Po wyjaśnieniu Miry dociera do return, zdejmuje ostatnią continuation ze stosu i wykonuje „Already have the key?”. Zagnieżdżone wywołania działają tak samo.

{
  "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"
}

Wszystkie potrzebne węzły znajdują się w eksporcie story.json. Call nie oznacza wczytania innego pliku JSON ani skryptu. maxCallDepth ogranicza zagnieżdżenie. Return przy pustym stosie jest błędem. End kończy natomiast całą rozmowę i czyści stos.

Polecenie · Otwórz sklep lub daj klucz

Polecenie

Dobry przykład to otwarcie sklepu: gra otwiera własny sklep i wstrzymuje rozmowę. Dopiero po zamknięciu sklepu zwraca uzgodniony wynik, np. purchased lub cancelled. Nazwy i argumenty zdefiniuj jako akcję gry w danym projekcie VNLE; open_shop nie jest wbudowanym poleceniem VNLE.

Rzeczywisty eksport Harbour używa give_item: polecenie wskazuje definicję, przekazuje ID przedmiotu i udostępnia dwa wyniki. Gra dodaje klucz do ekwipunku albo odmawia przyjęcia. Autor zdefiniował dalszą ścieżkę dla obu wyników.

{
  "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. Znajdź commandRef w execution.commands (sygnatura) i content.commandDefinitions (czytelny klucz).
  2. Oblicz argumenty według ID parametrów wejściowych; dla brakujących argumentów opcjonalnych użyj zadeklarowanego defaultValue.
  3. Wywołaj jawnie obsługiwaną akcję gry dokładnie raz. Podczas oczekiwania nie pozwalaj na Continue ani ponowne wykonanie.
  4. Sprawdź ID wyniku i typy zwróconych wartości. outcome.resultBindings przypisuje wyniki do zmiennych historii; następnie wykonaj outcome.continuation.
  5. Błąd techniczny nie oznacza automatycznie wyniku anulowania zdefiniowanego przez autora. Pokaż błąd i zapewnij w grze kontrolowaną możliwość ponowienia lub anulowania.

W tym projekcie odmowa przyjęcia klucza prowadzi do zwrotu pięciu sztuk złota. Odpowiada za to wyeksportowana dalsza ścieżka; nie dzieje się tak automatycznie przy każdym Command. Ekwipunek, dziennik zadań i mapy to systemy Twojej gry — same wpisy w katalogach JSON ich nie tworzą.

Podstawiane wartości · „Zostało ci 5 sztuk złota”

Tekst i podstawiane wartości

{
  "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"
  }
}

Łącz bezpośrednio segmenty kind: text. Dla kind: placeholder użyj placeholderRef, aby znaleźć definicję w rekordzie tekstu i powiązanie w node.text.bindings. Powiązanie dostarcza wartość stałą lub wartość zmiennej. Odczytaj ją w chwili wyświetlenia wypowiedzi i sformatuj zgodnie z typem. Typy i opcje formatowania opisano w dokumentacji pól.

PlaceholderDefinition · Wiadomość

Postępy, ograniczenia i błędy

Zapisuj bieżącą pozycję, zmienne historii, stos powrotów i oczekującą akcję gry razem ze stanem gry. Język jest osobnym ustawieniem. storyBuildId pomaga powiązać zapis z wersją wykonania; nie zgaduj dalszej ścieżki dla niezgodnej wersji historii.

maxAutomaticTransitions, maxConditionDepth, maxConditionTerms i maxCallDepth ograniczają automatyczne lub głęboko zagnieżdżone przejścia. Brakujące odwołania, brak dostępnych odpowiedzi przy whenEmpty: fault, nieznane polecenia i nieprawidłowe typy wymagają czytelnych błędów. Ponowne rysowanie interfejsu nie może powtarzać zakupów ani zmian zmiennych.

Przekazanie integracji programiście lub AI

Przekaż rzeczywisty eksport, wersję silnika, platformę docelową, te reguły przebiegu i stronę instrukcji dla silnika. Opisz elementy interfejsu oraz istniejące funkcje ekwipunku i sklepu. Wymagaj użycia faktycznych pól JSON i udokumentowanych API silnika oraz sprawdzenia poniższych przypadków.

  1. 10 sztuk złota: gracz otrzymuje klucz, zostaje 5; 2 sztuki złota: brak klucza i brak potrącenia.
  2. Ekwipunek odmawia przyjęcia: zwrot zgodny z historią, bez pozornego sukcesu.
  3. Call/Return wznawia właściwy węzeł; End wewnątrz Call kończy całą rozmowę.
  4. Zmiana języka zachowuje postęp; brakujące tłumaczenia i celowo pusty tekst są poprawnie obsługiwane.
  5. Dołączone pliki JSON, obrazy i czcionki działają poza folderem projektu; brak obrazu nie pozostawia poprzedniego portretu na ekranie.