VNLEWIKICréez des histoires. Reliez des mondes.
Français
Manuel VNLE

Règles de progression et actions de jeu

← Parcours d’apprentissage et moteurs

Ces règles expliquent l'exportation pour vos propres scripts et intégrations communautaires. JSON contient des données, pas du code source à exécuter. La mise en page de l'éditeur, la sélection et l'arrangement d'écran interne ne contrôlent pas le jeu.

Avant la première étape

Vérifiez format = vnle.story, containerVersion = 1, ainsi que la compatibilité avec execution.contractVersion et requiredCapabilities. L’exemple utilise 1.1 avec core.v1 et substory.call-return.v1. JSON Schema vérifie la structure ; il faut aussi contrôler les références, les types et les commandes prises en charge. Ne sautez jamais silencieusement un kind inconnu.

Référence des champs · Schéma JSON

Ce que signifie chaque noeud

kindComportement
dialogueAffichez le texte, attendez Continue, puis suivez continuation.
choiceSuivez optionOrder, filtrez selon option.condition, appliquez une seule fois les effects de l’option choisie, puis suivez continuation. Respectez whenEmpty.
branchÉvaluez condition, puis suivez whenTrue ou whenFalse.
actionÉvaluez effects dans l’ordre, puis suivez continuation.
jumpRejoignez le point d’entrée cible sans empiler de nouveau point de retour.
callMémorisez continuation, puis rejoignez le point d’entrée cible.
returnReprenez la dernière continuation mémorisée. Un Return sans Call préalable est une erreur.
commandÉvaluez les arguments, demandez l’action de jeu, attendez sa réponse et suivez l’issue correspondante.
endTerminez toute la conversation en cours, même depuis une sous-histoire. Pour reprendre la conversation appelante, utilisez Return.

Conditions et valeurs typées

Un opérande est soit literal avec une valeur typée, soit variable avec variableRef. compare accepte eq, ne, lt, lte, gt et gte. all exige que toutes les conditions enfants soient vraies ; any, qu’au moins une le soit ; not inverse une condition enfant. Ne confondez pas les booléens avec les chaînes "true"/"false".

Les opérations sur les variables sont set, add et subtract. add/subtract utilisent des entiers de −2147483648 à 2147483647. Évaluez les effets dans l’ordre, sans appliquer une mise à jour partielle si l’un d’eux est invalide. Ne remplacez pas les valeurs sauvegardées par les valeurs initiales defaultValue à chaque conversation.

Saut · Aller à l'entrepôt après avoir acheté

Saut

Si la clé a déjà été achetée, rejoignez directement l’entrée Warehouse. target contient flowRef et entryRef ; execution.entries[entryRef].nodeRef donne le nœud suivant. Un Jump n’ouvre pas automatiquement une scène ou une carte du moteur. Il faut une action de jeu adaptée pour cela.

{
  "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 / Retour · Mira explique l'entrepôt

Appeler une sous-histoire / Revenir

Ce parcours est bien décrit par le JSON. Après la salutation, l’histoire appelle l’explication concernant l’entrepôt verrouillé. Le jeu empile continuation et rejoint target. Après l’explication de Mira, return dépile la dernière continuation et reprend à Already have the key?. Les appels imbriqués suivent la même règle.

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

Tous ces nœuds figurent dans story.json. Call ne signifie pas qu’il faut charger un autre fichier JSON ou script. maxCallDepth limite la profondeur des appels. Return sur une pile vide est une erreur. End, en revanche, termine toute la conversation et vide la pile.

Commande · Ouvrir une boutique ou donner une clé

Commande

Prenons l’action d’ouvrir une boutique : le jeu ouvre sa propre interface et suspend la conversation. Ce n’est qu’à sa fermeture qu’il renvoie l’issue convenue, par exemple purchased ou cancelled. Définissez ces noms et arguments dans une action de jeu du projet VNLE. open_shop n’est pas une commande intégrée à VNLE.

L’export réel du port utilise give_item. La commande référence une définition, fournit l’identifiant de l’objet et prévoit deux issues. Le jeu ajoute la clé à l’inventaire ou refuse le transfert. L’auteur a déjà défini la suite pour les deux cas.

{
  "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. Recherchez commandRef dans execution.commands pour la signature et dans content.commandDefinitions pour la clé lisible.
  2. Évaluez les arguments à partir des identifiants d’entrée. Un argument facultatif absent utilise sa defaultValue déclarée.
  3. Déclenchez une seule fois l’action de jeu explicitement prise en charge. Pendant l’attente, interdisez Continue et tout second déclenchement.
  4. Vérifiez l’identifiant de l’issue et le type des valeurs renvoyées. outcome.resultBindings les affecte aux variables de l’histoire ; suivez ensuite outcome.continuation.
  5. Un problème technique ne correspond pas automatiquement à l’issue d’annulation prévue par l’auteur. Affichez l’erreur et prévoyez une procédure maîtrisée pour réessayer ou annuler.

Dans ce projet, refuser la remise de la clé rembourse cinq pièces d’or. C’est la suite exportée qui le prévoit ; ce comportement n’est pas automatique pour chaque Command. L’inventaire, le journal de quêtes et les cartes appartiennent aux systèmes de votre jeu. Les seules fiches JSON ne les créent pas.

Paramètres de substitution · « Il vous reste 5 pièces d’or »

Texte et paramètres de substitution

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

Concaténez directement les segments kind: text. Pour kind: placeholder, utilisez placeholderRef afin de retrouver la définition dans le texte et l’association dans node.text.bindings. Celle-ci fournit une valeur littérale ou une variable. Capturez la valeur lorsque la réplique s’affiche et formatez-la selon son type. Les types et formats sont décrits dans la référence des champs.

PlaceholderDefinition · Message

Progression, limites et erreurs

Sauvegardez la position, les variables de l’histoire, la pile de retour et toute action en attente avec l’état du jeu. La langue est un réglage distinct. storyBuildId permet de relier une sauvegarde à sa version d’exécution. Ne devinez pas la suite pour une histoire incompatible.

maxAutomaticTransitions, maxConditionDepth, maxConditionTerms et maxCallDepth limitent la progression automatique et les imbrications. Signalez clairement les références absentes, l’absence de réponse avec whenEmpty: fault, les commandes inconnues et les types invalides. Redessiner l’interface ne doit jamais répéter un achat ou une modification de variable.

Confier l’intégration à un développeur ou à une IA

Fournissez l’export réel, la version du moteur, la plateforme cible, ces règles et la page du moteur. Décrivez votre interface et les fonctions existantes d’inventaire ou de boutique. Demandez d’utiliser les véritables champs JSON et les API documentées, puis de tester les cas ci-dessous.

  1. Dix pièces d’or : la clé est reçue et il en reste cinq. Deux pièces : aucune clé reçue et aucune somme déduite.
  2. Si l’inventaire refuse l’objet, le remboursement suit l’histoire. Ne considérez pas le transfert comme réussi.
  3. Call/Return reprend au bon nœud. End à l’intérieur d’un Call termine toute la conversation.
  4. Le changement de langue conserve la progression. Les traductions absentes et les textes volontairement vides sont correctement traités.
  5. Les fichiers JSON, images et polices fournis fonctionnent hors du dossier de développement. Une image manquante ne laisse pas l’ancien portrait affiché.