Directivas y Macros de IA
La IA escribe una historia. Insertadas en esa historia hay pequeñas instrucciones — [health: -15], [gold: +50] — que el motor elimina antes de que el jugador vea nada. El jugador lee una narrativa limpia mientras el estado del juego cambia silenciosamente detrás de escena.
Este es el sistema de directivas: el puente entre la narrativa y las mecánicas. Y las macros son su compañera: marcadores como {{char}} y {{user}} que hacen que tus entradas se adapten automáticamente al contexto.
Si aún no has leído Variables: Lo que la IA rastrea, empieza por ahí. Las directivas solo tienen sentido una vez que entiendes lo que están cambiando.
Por qué existen las directivas
En un RPG de mesa, el director de juego dice "el goblin te corta el brazo, recibes 15 de daño" y el jugador borra un número en su hoja. En Yumina, la IA es el director de juego y el motor es la hoja de personaje.
La IA podría simplemente escribir "el jugador ahora tiene 85 de salud", pero entonces necesitarías que el motor analizara lenguaje natural, descifrara qué variable cambió y calculara el nuevo valor. Eso es frágil y poco fiable.
En su lugar, la IA escribe un corchete estructurado al final de su narrativa:
La garra del goblin te rasguña el antebrazo, trazando una línea ardiente de dolor.
[health: -15]El motor ve [health: -15], resta 15, recorta a los límites min/max y elimina la directiva del texto. El jugador solo ve la historia. El panel de estado se actualiza silenciosamente.
Esta separación es lo que hace que el sistema sea fiable. La IA maneja la ficción. El motor maneja las matemáticas.
Sintaxis de directivas
Toda directiva sigue el mismo patrón:
[variable-id: operation value]Tres partes dentro de los corchetes: qué Variable, qué hacer y con qué valor.
Las nueve operaciones
| Operación | Sintaxis | Ejemplo | Qué ocurre |
|---|---|---|---|
| Set | [var: set value] o [var: value] | [location: set "forest"] | Reemplaza el valor de la Variable por completo |
| Add | [var: add N] o [var: +N] | [gold: +50] | Suma N a una Variable numérica |
| Subtract | [var: subtract N] o [var: -N] | [health: -15] | Resta N a una Variable numérica |
| Multiply | [var: multiply N] o [var: *N] | [damage: *2] | Multiplica una Variable numérica por N |
| Toggle | [var: toggle] | [has-key: toggle] | Invierte un booleano (true pasa a false, false pasa a true) |
| Append | [var: append "text"] | [log: append ", found key"] | Añade texto al final de una Variable string |
| Merge | [var: merge {...}] | [stats: merge {"level": 2}] | Fusiona superficialmente un objeto en una Variable JSON |
| Push | [var: push {...}] | [inventory: push {"name": "Sword"}] | Añade un elemento al final de un array JSON |
| Delete | [var: delete "key"] o [var: delete N] | [config: delete "old-field"], [inventory: delete 0] | Elimina una clave de un objeto JSON (string entre comillas) o un elemento por índice de un array JSON (número). El valor después de delete es obligatorio: [var: delete] sin nada se degrada silenciosamente a un set implícito. |
Reglas de sintaxis de valores
- Números: dígitos sin formato —
10,3.5,-7 - Strings: entre comillas dobles —
"forest","magic sword" - Booleanos: palabras clave sin formato —
true,false - JSON: objeto o array en línea —
{"level": 2},[1, 2, 3]
La trampa de la abreviatura
Esta es la fuente de confusión más común para nuevos creadores:
[health: -10] → resta 10 (abreviatura de subtract)
[health: +10] → suma 10 (abreviatura de add)
[health: *2] → multiplica por 2 (abreviatura de multiply)
[health: 10] → ESTABLECE health a 10 (set implícito, NO suma)El símbolo inicial (-, +, *) determina la operación. Sin símbolo significa set. Así que [health: 50] no suma 50: reemplaza el valor actual por 50.
Para establecer explícitamente un valor negativo (raro, pero posible), escribe [health: set -10].
Nombrado: ID o nombre visible
Las directivas pueden referenciar una Variable por su ID (player-hp) o su nombre visible (Player HP). El motor mantiene un mapa de nombre a ID y resuelve ambos. Los ID son más fiables, especialmente cuando los nombres visibles contienen espacios.
Rutas anidadas para Variables JSON
Cuando tienes una Variable JSON con estructura anidada, la IA puede apuntar a campos específicos usando notación de punto:
[relationships.aria.trust: +10]
[game-state.factions.ember-court.affinity: set 75]
[inventory.0.durability: -1]El motor navega la ruta automáticamente. Si los objetos intermedios no existen, los crea. Esto significa que la IA puede actualizar un campo en lo profundo de un objeto complejo sin tocar nada más.
Directivas de audio
El audio usa una sintaxis de corchetes similar — [audio: track-id action] — con acciones como play, stop, crossfade, volume y encadenamiento de pistas. Para la referencia completa de directivas de audio con ejemplos, consulta Diseño de audio.
El formato JSON Patch
Para operaciones complejas, especialmente eliminar elementos de arrays, el motor admite un formato JSON Patch envuelto en XML. Este es también el formato usado por mundos migrados desde SillyTavern.
<UpdateVariable target="inventory">
<JSONPatch>
[
{"op": "remove", "path": "/0"},
{"op": "replace", "path": "/1/durability", "value": 5}
]
</JSONPatch>
</UpdateVariable>Se admiten cuatro operaciones de patch:
| Operación | Qué hace | Ejemplo |
|---|---|---|
replace | Establece un valor en una ruta | {"op": "replace", "path": "/health", "value": 80} |
delta | Suma o resta (positivo suma, negativo resta) | {"op": "delta", "path": "/gold", "value": -50} |
insert | Añade un nuevo par clave-valor | {"op": "insert", "path": "/inventory/torch", "value": 1} |
remove | Elimina una clave o elemento de array | {"op": "remove", "path": "/0"} |
Las rutas usan barras inclinadas (/health, /inventory/0) que el motor convierte internamente a rutas con puntos.
Cuándo usar JSON Patch vs directivas con corchetes
La mayoría del tiempo, las directivas con corchetes son más simples y la IA las produce más fiablemente. JSON Patch es útil para dos casos específicos:
Eliminar elementos de array por índice:
[inventory: delete 0]funciona, pero{"op": "remove", "path": "/0"}de JSON Patch es el formato que algunos modelos de IA producen de manera más consistente al lidiar con arrays.Operaciones por lotes sobre una sola Variable: cuando necesitas actualizar varios campos en una Variable JSON a la vez, un único bloque JSON Patch es más limpio que cinco directivas con corchetes separadas.
Si estás escribiendo reglas de comportamiento para la IA, dile qué formato usar. La mayoría de los mundos se limitan exclusivamente a las directivas con corchetes. Solo introduce JSON Patch si necesitas específicamente eliminar elementos de array y la sintaxis con corchetes no funciona de manera fiable.
Cómo procesa el motor la salida de la IA
Cuando la IA devuelve una respuesta, el motor la pasa por una tubería de análisis antes de que el jugador vea nada. Entender esta tubería te ayuda a depurar situaciones donde las directivas no se están detectando.
Paso 1: Eliminar etiquetas de pensamiento. Algunos modelos (como Gemini) emiten razonamiento interno en etiquetas <thinking>...</thinking>. El motor las elimina primero.
Paso 2: Extraer bloques JSON Patch. El motor busca bloques XML <UpdateVariable> y los convierte en operaciones de efecto internas.
Paso 3: Extraer directivas de audio. Cualquier cosa que coincida con [audio: ...] se extrae y se encola para el sistema de audio.
Paso 4: Extraer directivas JSON. Las directivas con corchetes que contienen valores JSON (merge, push, set con objetos/arrays) se extraen. Estas se analizan primero porque sus cargas útiles JSON podrían contener caracteres que confunden a la regex más simple.
Paso 5: Extraer directivas estándar. Todo lo que coincide con [var: op value]: las operaciones de add, subtract, set, toggle y demás operaciones simples.
Paso 6: Limpiar el texto. Todas las directivas extraídas se eliminan. Las líneas en blanco extra se colapsan. El resultado es texto narrativo limpio más una lista de efectos.
El jugador ve el texto limpio. El motor aplica los efectos para actualizar el estado del juego. Luego se evalúan las reglas (comprobando si ahora se cumplen condiciones) y el ciclo se completa.
Por qué importa el orden de análisis
Las directivas JSON se extraen antes que las directivas estándar porque una directiva como [stats: merge {"health": 50, "mana": 30}] contiene dos puntos y números que la regex estándar malinterpretaría. Al manejar los patrones JSON primero, el motor evita falsas coincidencias.
Si una directiva no se reconoce, la causa más común es JSON mal formado: una llave sin pareja o una comilla faltante. El motor omite silenciosamente las directivas que no puede analizar en lugar de fallar.
Referencia completa → Especificación del mundo: Variables
Macros: texto dinámico en tus entradas
Las macros son marcadores que escribes en las entradas y que el motor reemplaza con valores reales antes de enviar a la IA. Se ven así: {{char}}, {{user}}, {{turnCount}}.
La idea central: escribe tus entradas una vez, y se adaptan a cualquier contexto. Cambia el nombre del personaje y cada {{char}} se actualiza automáticamente. El jugador elige una persona y {{user}} la sigue.
Macros esenciales
| Macro | Se expande a | Salida de ejemplo |
|---|---|---|
{{char}} | Nombre del personaje actual | Luna |
{{user}} | Nombre del jugador (o nombre de la persona activa) | Kai |
{{turnCount}} | Número de turno actual | 42 |
Estas tres cubren la mayoría de los casos de uso. Usarás {{char}} y {{user}} en casi todas las entradas.
Macros de aleatoriedad
| Macro | Comportamiento | Ejemplo |
|---|---|---|
{{random::a::b::c}} | Elige una al azar cada vez | {{random::sunny::cloudy::rainy}} podría dar "cloudy" |
{{pick::a::b::c}} | Selección estable: mismo resultado dentro de un turno | {{pick::red::blue::green}} siempre da el mismo color en el mismo turno |
{{roll::NdS+M}} | Tirada de dados: N dados, S caras, más modificador M | {{roll::2d6+3}} podría dar 11 |
La diferencia entre random y pick: random vuelve a tirar cada vez que la macro se expande, así que la misma entrada expandida dos veces podría dar resultados diferentes. pick usa un hash estable basado en la posición de la macro en la entrada y el número de turno actual: da el mismo resultado cada vez dentro de un turno, pero puede cambiar al siguiente turno.
Usa random para variedad (clima, descripciones de multitudes). Usa pick cuando importa la consistencia dentro de un turno (el atuendo de un personaje debe ser el mismo si se referencia dos veces). Usa roll cuando quieres mecánicas basadas en dados a las que la IA pueda reaccionar.
Macros de tiempo y fecha
| Macro | Se expande a | Salida de ejemplo |
|---|---|---|
{{time}} | Hora actual (HH:MM) | 14:30 |
{{date}} | Fecha actual (formato local) | 13/5/2026 |
{{weekday}} | Día de la semana | martes |
{{isodate}} | Formato de fecha ISO | 2026-05-13 |
{{isotime}} | Formato de hora ISO | 14:30:00 |
{{idle}} | Tiempo desde el último mensaje del jugador | 5 minutos |
Estos son tiempo del mundo real, no tiempo dentro del juego. Útil para mundos que mezclan tiempo real y ficticio, o para mecánicas de detección de inactividad ("si el jugador no ha respondido en 10 minutos, el personaje envía un mensaje preocupado").
Macros de contexto
| Macro | Se expande a |
|---|---|
{{lastMessage}} | Texto completo del último mensaje |
{{lastUserMessage}} | Último mensaje del jugador |
{{lastCharMessage}} | Último mensaje del personaje |
{{model}} | Nombre del modelo de IA en uso |
Macros de persona del jugador
Los jugadores crean personas desde la página de Perfil → carrusel de personas: identidades con nombre, apariencia, personalidad e historia de fondo. Cuando una persona está activa, estas macros la usan:
| Macro | Se expande a |
|---|---|
{{persona_name}} | Nombre de la persona activa |
{{persona_appearance}} | Descripción física |
{{persona_personality}} | Rasgos de carácter |
{{persona_backstory}} | Historia y origen |
{{persona}} | Los cuatro campos combinados |
Consejo: coloca {{persona}} en una entrada de System Presets llamada "Acerca del jugador" y la IA siempre sabrá a quién está interpretando el jugador. Cuando cambian de persona, la IA se pone al día automáticamente.
{{user}} primero comprueba si hay una persona activa: si existe una, usa el nombre de la persona. Si no, recurre al campo playerName del mundo. Las entradas antiguas que usan {{user}} funcionan sin problemas con el sistema de personas.
Macros de utilidad
| Macro | Qué hace |
|---|---|
{{// comment text}} | Comentario. Se expande a nada: te permite dejar notas en las entradas sin enviar nada a la IA |
{{trim}} | Elimina espacios en blanco circundantes. Para control preciso de formato cuando las macros dejan huecos extraños |
Recurso de Variable
Si un nombre de macro no coincide con ninguna macro incorporada, el motor comprueba si coincide con un ID de Variable. Si tienes una Variable llamada mood con un valor actual de "suspicious", entonces {{mood}} se expande a "suspicious".
Si no coincide ni con una macro incorporada ni con una Variable, el motor deja {{xxx}} tal cual. Sin errores, sin fallos.
Patrones que funcionan
Combate con daño proporcional
Define health (número, 0-100) con reglas de comportamiento que especifiquen rangos de daño por tipo de arma. La IA escribe narrativa y luego añade la directiva:
La daga del bandido te alcanza en las costillas: un corte
superficial, pero quema. Retrocedes tambaleándote, manteniendo la guardia alta.
[health: -8]
Balanceas tu espadón en un arco amplio. El bandido intenta
esquivarlo pero recibe la hoja en el hombro. Grita.
[enemy-hp: -22]El jugador ve una escena de combate. Los números se encargan de la contabilidad.
Progresión de relación con entradas condicionales
Empareja una Variable numérica (aria-trust, 0-100) con entradas con compuerta basada en umbrales. La IA actualiza la confianza mediante directivas y el sistema de entradas ajusta automáticamente lo que la IA sabe sobre el comportamiento del personaje en cada etapa:
- Entrada "Aria — Cautelosa" (condición:
aria-trust < 30): formal, mantiene la distancia - Entrada "Aria — Calentándose" (condición:
aria-trust >= 30 AND < 60): comparte opiniones, sonrisa ocasional - Entrada "Aria — Cercana" (condición:
aria-trust >= 60): vulnerable, protectora, bromas privadas
La IA usa directivas para mover el número: [aria-trust: +5] después de una interacción amable. El sistema de entradas decide qué versión de Aria ve la IA. Ninguno de los dos sistemas conoce al otro: se comunican a través de la Variable.
Descripciones de escena dinámicas con macros
Una entrada que se adapta al contexto:
{{char}} alza la vista cuando {{user}} entra en la habitación. La hora actual
es {{time}}, y el clima afuera está {{random::clear::overcast::drizzling}}.
El humor de {{char}} parece {{mood}} hoy.Si el personaje es Luna, el jugador es Kai, son las 2pm y la Variable mood es "tense", la IA recibe:
Luna alza la vista cuando Kai entra en la habitación. La hora actual es 14:00,
y el clima afuera está overcast.
El humor de Luna parece tense hoy.Chequeos de habilidad basados en dados
Pon esto en una entrada de instrucción del narrador:
Cuando {{user}} intente algo arriesgado, usa el resultado del tirado
para determinar el éxito. Tirada: {{roll::1d20}}. 15+ = éxito,
10-14 = éxito parcial, menos de 10 = fracaso.La IA recibe un número real y puede narrar en consecuencia. Esto desplaza el juicio de "a discreción de la IA" a los dados: más justo y más parecido a un juego.
Errores comunes
Directivas en el lugar equivocado. La IA debería escribir las directivas al final de su respuesta narrativa, no en medio de una oración. Si las directivas aparecen en línea, el análisis sigue funcionando, pero es más difícil de depurar. En tus reglas de comportamiento, puedes instruir a la IA: "Coloca todas las directivas al final de tu respuesta."
Esperar que la IA haga matemáticas. La IA escribe [health: -15]. El motor hace la resta. No escribas reglas de comportamiento como "calcula el nuevo valor de salud": la IA solo necesita emitir la directiva correcta y el motor maneja la aritmética, incluido el ajuste min/max.
Errores de sintaxis JSON en directivas. Una llave sin pareja o una comilla faltante hace que el motor omita silenciosamente la directiva. Si una directiva merge o push no se está aplicando, comprueba que la carga útil JSON sea válida. El motor no falla: simplemente continúa.
Confundir {{random}} con {{pick}}. Si el color de ojos de un personaje cambia cada vez que se expande la entrada, usaste random cuando querías pick. Usa pick para atributos estables, random para variedad intencional.
Sobreingeniería con JSON Patch. A menos que necesites específicamente eliminar elementos de arrays, quédate con las directivas con corchetes. Son más simples, la IA las produce de manera más consistente y son más fáciles de depurar.
Olvidar que {{user}} sigue a las personas. Si un jugador cambia de persona, {{user}} cambia al nombre de la nueva persona. Esto suele ser lo que quieres, pero ten cuidado si estás usando {{user}} de una forma que no debería cambiar a mitad de sesión.
Consulta también
- Diseñando el estado del juego — eligiendo tipos de Variable y escribiendo reglas de comportamiento
- Cómo escribir buenas entradas — usando
{{macros}}dentro de entradas y diseño de entradas condicionales - Diseño de audio — la referencia completa de directivas de audio
Sintaxis de directivas y especificaciones de operaciones → Especificación del mundo: Variables
