Reglas del flujo y acciones de juego
← Guía de aprendizaje y motores
Estas reglas explican la exportación para tus propios scripts y las integraciones de la comunidad. El JSON contiene datos, no código fuente que deba ejecutarse. La disposición del editor, la selección y la organización interna de la pantalla no controlan el juego.
Antes del primer paso
Comprueba format = vnle.story, containerVersion = 1, que execution.contractVersion sea compatible y las requiredCapabilities. El ejemplo utiliza 1.1 con core.v1 y substory.call-return.v1. JSON Schema comprueba la estructura; la ejecución también requiere verificar referencias, tipos y comandos admitidos. Nunca omitas silenciosamente un tipo de nodo desconocido.
Referencia de campos · JSON Schema
Lo que cada nodo significa
| kind | Comportamiento |
|---|---|
dialogue | Muestra el texto y espera a Continue; después sigue continuation. |
choice | Sigue optionOrder, filtra según option.condition, aplica una sola vez los effects de la opción elegida y sigue continuation. Respeta whenEmpty. |
branch | Evalúa condition; sigue whenTrue o whenFalse. |
action | Evalúa effects en orden y después sigue continuation. |
jump | Resuelve la entrada de destino sin añadir un nuevo punto de retorno. |
call | Guarda continuation y entra en la entrada de destino. |
return | Reanuda la continuación guardada más recientemente. Ejecutar Return sin un Call previo es un error. |
command | Evalúa los argumentos, solicita una acción al juego, espera su resultado y sigue la salida correspondiente. |
end | Termina toda la conversación actual, también dentro de una subhistoria. Return, en cambio, reanuda la conversación que hizo la llamada. |
Condiciones y valores tipados
Un operando es literal con un valor tipado, o variable con variableRef. compare admite eq, ne, lt, lte, gt y gte. all exige que se cumplan todas las condiciones hijas; any, al menos una; not invierte una condición hija. No confundas los booleanos con las cadenas "true"/"false".
Los efectos sobre variables son set, add y subtract. add/subtract usan enteros entre −2147483648 y 2147483647. Evalúa los efectos en orden, pero no apliques una actualización parcial si alguno es inválido. No sobrescribas los valores guardados con los datos iniciales de defaultValue cada vez que empieza una conversación.
Saltar · Ir al almacén después de comprar
Salto
Si ya se compró la llave del puerto, salta directamente a la entrada de Warehouse. target contiene flowRef y entryRef; execution.entries[entryRef].nodeRef proporciona el siguiente nodo. Un Jump no abre automáticamente una escena o un mapa del motor. Eso requiere una acción de juego adecuada.
{
"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 explica el almacén
Llamar subhistoria / Volver
Sí, este recorrido está descrito en el JSON. Tras el saludo, la historia llama a la explicación sobre el almacén cerrado. El juego guarda continuation en una pila y entra en target. Después de la explicación de Mira, alcanza return, extrae la continuación más reciente y ejecuta «Already have the key?». Las llamadas anidadas siguen la misma regla.
{
"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"
}Todos los nodos implicados están en la exportación story.json. Call no significa cargar otro JSON ni otro script. maxCallDepth limita la profundidad de anidamiento. Return con una pila vacía es un error. End, en cambio, termina toda la conversación y vacía la pila.
Comando · Abrir una tienda o dar una llave
Comando
«Open shop» es un buen ejemplo: el juego abre su propia tienda y pausa la conversación. Solo al cerrar la tienda comunica un resultado acordado, como purchased o cancelled. Define esos nombres y argumentos como una acción de juego en ese proyecto de VNLE; open_shop no es un comando incorporado en VNLE.
La exportación real del puerto utiliza give_item: el comando referencia una definición, proporciona el identificador del objeto y ofrece dos resultados. El juego añade la llave al inventario o rechaza la entrega. La persona que escribió la historia ya ha definido la continuación de ambos resultados.
{
"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": []
}
]
}- Busca commandRef en execution.commands (firma) y content.commandDefinitions (clave legible).
- Evalúa los argumentos usando los identificadores de entrada; los argumentos opcionales ausentes utilizan su defaultValue declarado.
- Solicita una sola vez la acción de juego que se admite explícitamente. Mientras esperas, no permitas Continue ni una segunda ejecución.
- Valida el identificador del resultado y sus valores tipados. outcome.resultBindings asigna esos valores a las variables de la historia; después sigue outcome.continuation.
- Un fallo técnico no equivale automáticamente al resultado de cancelación definido por el autor. Muestra el error y ofrece en el juego una forma controlada de reintentar o cancelar.
En este proyecto, rechazar la entrega de la llave provoca el reembolso de cinco monedas de oro. Lo hace la continuación exportada; no es automático para cada Command. El inventario, el registro de misiones y los mapas del motor son sistemas de tu juego: los registros del catálogo JSON no los crean por sí solos.
Marcadores de posición · «Te quedan 5 monedas de oro»
Texto y marcadores de posición
{
"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"
}
}Concatena directamente los segmentos kind: text. Para kind: placeholder, usa placeholderRef para encontrar su definición en el registro de texto y su asociación en node.text.bindings. Esta proporciona un valor literal o de variable. Captúralo al mostrar la frase y dale formato según su tipo. Los tipos y opciones de formato figuran en la referencia de campos.
Progresos, límites y errores
Guarda la posición, las variables de la historia, la pila de retornos y cualquier acción pendiente junto con el estado del juego. El idioma es un ajuste independiente. storyBuildId permite asociar la partida guardada con su versión de ejecución; no inventes una continuación para una historia incompatible.
maxAutomaticTransitions, maxConditionDepth, maxConditionTerms y maxCallDepth limitan los recorridos automáticos o muy anidados. Las referencias ausentes, la falta de respuestas con whenEmpty: fault, los comandos desconocidos y los tipos inválidos necesitan errores claros. Volver a dibujar la interfaz nunca debe repetir compras ni cambios de variables.
Entrega a un desarrollador o a una IA
Proporciona la exportación real, la versión del motor, la plataforma de destino, estas reglas y la página del motor. Describe los elementos de tu interfaz y las funciones de inventario o tienda existentes. Pide que se usen los campos JSON reales y las API documentadas del motor, y que se prueben los casos siguientes.
- Con diez monedas de oro: se recibe la llave y quedan cinco. Con dos: no se recibe la llave ni se descuenta oro.
- Si el inventario rechaza el objeto, se reembolsa según lo previsto en la historia; no se da la entrega por realizada.
- Call/Return reanuda en el nodo previsto; End dentro de un Call termina la conversación.
- El cambio de idioma conserva el progreso; funcionan las traducciones ausentes y los textos vacíos intencionadamente.
- Los archivos JSON, las imágenes y las fuentes incluidos funcionan fuera de la carpeta de desarrollo. Si falta una imagen, no queda visible el retrato anterior.