Reglas y Reacciones
Las reglas se disparan automáticamente entre turnos basadas en eventos. Manejan mecánicas precisas sin intervención de la IA.
Esquema de Regla
{
"id": "low-health-warning",
"name": "Low Health Warning",
"description": "Warn the player when health is critical",
"trigger": {
"type": "variable-crossed",
"variableId": "health",
"direction": "drops-below",
"threshold": 20
},
"conditions": [],
"conditionLogic": "all",
"actions": [
{
"type": "notify-player",
"style": "warning",
"message": "Tu visión se nubla. Apenas puedes mantenerte en pie."
},
{
"type": "inject-directive",
"directiveId": "critical-health",
"content": "El jugador está al borde de la muerte. Describe su deterioro físico — tambaleo, visión borrosa, manos temblorosas.",
"position": "after_char",
"persistent": true
}
],
"priority": 50,
"enabled": true,
"cooldownTurns": null,
"maxFireCount": null
}Tipos de Disparador
| Tipo | Campos | Se dispara cuando |
|---|---|---|
variable-crossed | variableId, direction (rises-above | drops-below), threshold | La variable cruza un umbral |
state-change | variableId (opcional) | Cualquier variable cambia (o una específica) |
turn-count | atTurn (number), everyNTurns (number) | En un número de turno específico, o cada N turnos |
session-start | — | Primer mensaje de una sesión nueva |
keyword | keywords[] | El mensaje del jugador contiene alguna palabra clave |
ai-keyword | keywords[] | La respuesta de la IA contiene alguna palabra clave |
every-turn | — | Después de cada turno |
action | actionId (string) | Se ejecuta una acción específica (p. ej., desde un botón de UI personalizada) |
manual | — | Solo se dispara cuando lo activa otra regla |
Condiciones
Verificaciones de estado opcionales que deben pasar para que la regla se dispare:
"conditions": [
{
"variableId": "story-phase",
"operator": "eq",
"value": "act2"
},
{
"variableId": "health",
"operator": "gt",
"value": 0
}
]Operadores: eq, neq, gt, lt, gte, lte, contains
conditionLogic: "all" (AND) o "any" (OR)
Tipos de Acción
modify-variable
Cambia el valor de una variable.
{
"type": "modify-variable",
"variableId": "hunger",
"operation": "subtract",
"value": 5
}Operaciones: set, add, subtract, multiply, toggle, append, merge, push, delete
inject-directive
Agrega instrucciones al prompt de la IA para turnos futuros.
{
"type": "inject-directive",
"directiveId": "romance-mode",
"content": "The character has developed feelings. Write romantic tension naturally.",
"position": "after_char",
"persistent": true
}Posiciones: top, before_char, after_char, auto, depth, bottom
persistent: true mantiene la directiva activa hasta que se elimine explícitamente. persistent: false (predeterminado) = de un solo uso, eliminada después de un turno.
duration: número opcional. Cuando se establece, la directiva se elimina automáticamente después de N turnos.
remove-directive
Elimina una directiva previamente inyectada.
{
"type": "remove-directive",
"directiveId": "romance-mode"
}notify-player
Muestra una notificación toast.
{
"type": "notify-player",
"style": "warning",
"message": "You're running low on supplies."
}Estilos: info, achievement, warning, danger
play-audio
Activa una pista de audio.
{
"type": "play-audio",
"trackId": "bgm-battle",
"action": "play"
}toggle-entry
Habilita o deshabilita una entrada del lorebook.
{
"type": "toggle-entry",
"entryId": "secret-lore",
"enabled": true
}toggle-rule
Habilita o deshabilita otra regla (reacciones en cadena).
{
"type": "toggle-rule",
"ruleId": "phase-2-triggers",
"enabled": true
}send-context
Envía un mensaje de contexto de un solo uso a la IA en el siguiente turno.
{
"type": "send-context",
"message": "El jugador acaba de activar un evento oculto. Reacciona en consecuencia.",
"role": "system"
}role: "system" (predeterminado) o "user" — determina cómo se inyecta el contexto en la conversación.
Opciones de Regla
| Campo | Tipo | Descripción |
|---|---|---|
priority | number | Mayor = se dispara primero cuando se activan varias reglas (predeterminado: 0) |
cooldownTurns | number | null | Turnos mínimos entre disparos |
maxFireCount | number | null | Cantidad total de veces que esta regla puede dispararse (null = ilimitado) |
enabled | boolean | Puede ser alternada por otras reglas |
Reacciones (Sistema de Patrón de Eventos)
Las reacciones son un sistema de reglas más nuevo y flexible basado en patrones de eventos genéricos:
{
"id": "zone-enter-forest",
"name": "Enter Forest",
"when": {
"eventType": "spatial:zone-enter",
"zone": "forest"
},
"conditions": [],
"conditionLogic": "all",
"then": [
{
"type": "set",
"path": "weather",
"value": "foggy"
},
{
"type": "set",
"path": "@audio.ambient",
"value": "forest-ambient",
"operation": "set"
},
{
"type": "emit",
"event": { "type": "spatial:ambience-changed" }
}
]
}Rutas de Efecto del Sistema
Las reacciones pueden apuntar a características del sistema mediante rutas @:
| Ruta | Efecto |
|---|---|
@audio.bgm | Reproducir pista BGM |
@audio.sfx | Reproducir SFX |
@audio.ambient | Reproducir pista ambiente |
@audio.stop | Detener una pista |
@prompt.directive.<id> | Inyectar/eliminar directiva |
@prompt.entry.<id> | Alternar visibilidad de entrada |
@prompt.context | Mensaje de contexto de un solo uso |
@rules.disabled.<id> | Alternar regla habilitada/deshabilitada |
@ui.notification | Mostrar notificación toast |
@ai.request | Activar generación de IA |
@ai.context | Agregar contexto para el siguiente mensaje de IA |
Eventos generados en cada turno
Después de que la IA responde, estos eventos se emiten y se verifican contra todas las reglas/reacciones:
message:user— Mensaje del jugador (con contenido para coincidencia de palabras clave)message:ai— Respuesta de la IA (con contenido para coincidencia de palabras clave)turn:complete— Turno terminado (con conteo de turno)state:changed— Uno por cada variable que cambió (con variableId, oldValue, newValue)
