v
Skip to content

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 ​

json
{
  "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 ​

TipoCamposSe dispara cuando
variable-crossedvariableId, direction (rises-above | drops-below), thresholdLa variable cruza un umbral
state-changevariableId (opcional)Cualquier variable cambia (o una específica)
turn-countatTurn (number), everyNTurns (number)En un número de turno específico, o cada N turnos
session-start—Primer mensaje de una sesión nueva
keywordkeywords[]El mensaje del jugador contiene alguna palabra clave
ai-keywordkeywords[]La respuesta de la IA contiene alguna palabra clave
every-turn—Después de cada turno
actionactionId (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:

json
"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.

json
{
  "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.

json
{
  "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.

json
{
  "type": "remove-directive",
  "directiveId": "romance-mode"
}

notify-player ​

Muestra una notificación toast.

json
{
  "type": "notify-player",
  "style": "warning",
  "message": "You're running low on supplies."
}

Estilos: info, achievement, warning, danger

play-audio ​

Activa una pista de audio.

json
{
  "type": "play-audio",
  "trackId": "bgm-battle",
  "action": "play"
}

toggle-entry ​

Habilita o deshabilita una entrada del lorebook.

json
{
  "type": "toggle-entry",
  "entryId": "secret-lore",
  "enabled": true
}

toggle-rule ​

Habilita o deshabilita otra regla (reacciones en cadena).

json
{
  "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.

json
{
  "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 ​

CampoTipoDescripción
prioritynumberMayor = se dispara primero cuando se activan varias reglas (predeterminado: 0)
cooldownTurnsnumber | nullTurnos mínimos entre disparos
maxFireCountnumber | nullCantidad total de veces que esta regla puede dispararse (null = ilimitado)
enabledbooleanPuede 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:

json
{
  "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 @:

RutaEfecto
@audio.bgmReproducir pista BGM
@audio.sfxReproducir SFX
@audio.ambientReproducir pista ambiente
@audio.stopDetener una pista
@prompt.directive.<id>Inyectar/eliminar directiva
@prompt.entry.<id>Alternar visibilidad de entrada
@prompt.contextMensaje de contexto de un solo uso
@rules.disabled.<id>Alternar regla habilitada/deshabilitada
@ui.notificationMostrar notificación toast
@ai.requestActivar generación de IA
@ai.contextAgregar 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:

  1. message:user — Mensaje del jugador (con contenido para coincidencia de palabras clave)
  2. message:ai — Respuesta de la IA (con contenido para coincidencia de palabras clave)
  3. turn:complete — Turno terminado (con conteo de turno)
  4. state:changed — Uno por cada variable que cambió (con variableId, oldValue, newValue)