Editor de Reacciones#
El Editor de Reacciones es donde defines qué pasa cuando el jugador interactúa con el mundo: mirar una puerta, usar una llave en una cerradura, dar un objeto a un personaje, caminar sobre un disparador. Para cada interacción construyes una reacción: una cadena de tokens de efecto (decir una línea, poner un flag, otorgar un objeto, abrir un cuarto…) ejecutados en orden.
Llegas a él desde el Hub (con el dev server corriendo). Abre sobre el proyecto activo; elige un Room (y, en el modo correspondiente, un Item o Character) en la barra de herramientas. Cambiar de cuarto, hotspot, objeto, personaje o modo con ediciones sin guardar te pregunta primero: Seguir editando te deja donde estabas con la edición intacta, y Descartar y continuar la tira y sigue. Un clic despistado nunca descarta en silencio una cadena que estabas armando. En los modos que trabajan sobre un cuarto, bajo la barra hay una franja de miniaturas de salas para saltar de una a otra sin volver al desplegable. Viene en tres tamaños y se puede plegar, y tu elección queda recordada; los modos de objeto y personaje la ocultan, porque ninguno está acotado a un cuarto.
El editor también recuerda dónde estabas: al volver, reabre en el modo en que andabas y sobre el mismo cuarto, objeto o personaje. Cada modo guarda su propio puntero, así que pasar a ITEM y regresar a HOTSPOT te deja en el cuarto que tenías, no en un selector vacío. Si lo que editabas ya no existe, el selector simplemente aparece vacío en vez de dar error. Como todo lo demás aquí, se lleva por proyecto.
Los cinco modos#
Una fila de pestañas de modo decide a qué le adjuntas reacciones:
- Hotspot: la cuadrícula central. Eliges un cuarto y obtienes una matriz verbo × hotspot: cada hotspot cruzado con cada verbo (mirar, usar, tomar, abrir…). Cada celda guarda la reacción de ese verbo sobre ese hotspot. El canvas del cuarto al lado muestra los hotspots (rueda para zoom, arrastra para pan).
- Item: reacciones ligadas a un objeto del inventario: usar el objeto sobre el mundo, combinarlo con otro objeto, etc.
- Character: reacciones y líneas por personaje, incluyendo los mensajes bilingües que un personaje puede decir. Hablar con tiene su propia fila con tres modos: Línea (el personaje contesta con una frase), Diálogo (abre una conversación; elige una o créala con Nuevo diálogo…) y Cadena (cualquier cadena de efectos). Es la misma fila que muestra el Character Editor, así que editarla en un lado edita la misma reacción. Si no se puede leer la lista de diálogos del proyecto, la barra de estado te lo dice al abrir un personaje: un diálogo asignado aparece como «no existe», pero se conserva al guardar.
- Room: entry reactions a nivel de cuarto que disparan al llegar el jugador: en la primera visita, en cada visita, o en un conteo de visita específico.
- Region: reacciones de walkover que disparan cuando un personaje camina sobre una región del suelo (simples, o condicionadas por una regla de puzzle; ver abajo).
Cómo funciona una celda de reacción#
Cada celda muestra si tiene ninguno, uno o varios efectos. Haz clic para abrir el
editor de cadenas de efecto compartido (el mismo selector de tokens que usan las herramientas
de cinemática y puzzle) y construye la secuencia paso a paso; los argumentos se autocablean
desde el proyecto (cuartos, hotspots, objetos, personajes). Una reacción es solo una lista
ordenada de tokens, así que "mirar el cuadro" puede ser un único SAY, mientras que "usar la
llave en la puerta" podría ser SAY → SETFLAG → PLAYSOUND → WARPTOROOM.
Como las reacciones son cadenas de tokens de efecto, todo lo de la página de
Tokens de efecto aplica aquí: tiers, formatos de
argumento, interpolación {flag}, y la regla de que los tokens nuevos deben registrarse en el
manifiesto.
Condicionar con una regla de puzzle: editar o crear en el sitio#
Una reacción simple siempre dispara igual; a veces la quieres condicionada: "solo si la caja fuerte ya está abierta", "solo después del Acto 2". Esa condición es una regla del Editor de Puzzles, pero nunca tienes que salir del Editor de Reacciones para cablearla. Cada fila de verbo lleva un botón de regla de puzzle, en uno de dos estados:
- Una fila que ya tiene regla muestra la insignia ámbar ⚡ regla de puzzle. Haz clic para abrir la regla que la condiciona en un modal, ahí mismo: la condición y los efectos que se disparan cuando se cumple. Añade o elimina reglas, edita la condición, y Guardar reglas escribe directo al archivo de puzzle. Todo lo que quede fuera de la regla de este verbo (vigías, otras claves) sigue en el Editor de Puzzles completo.
- Una fila sin regla todavía muestra un botón punteado +⚡ crear regla de puzzle. Al
pulsarlo se abre el mismo modal con la clave de la regla ya sembrada (
<hotspot>.<verbo>, de solo lectura; la clave es la dirección por la que el motor la busca) y una regla vacía lista para llenar. Guárdala y la insignia cambia al ⚡ sólido en el sitio, sin recargar. Una regla vacía que nunca llenes se descarta al guardar, así un clic despistado no puede matar en silencio la reacción simple que está debajo.
El modal también trae un campo Nota del autor para la regla que estás mirando: por qué
existe esta regla, que la regla misma no puede decir. Se guarda en el .rules.js como un
comentario // justo arriba de esa entrada, anclado a la clave y no a una posición, así que
sobrevive al guardado y viaja con la regla cuando se reordenan. (Es el mismo campo que el Editor
de Puzzles muestra en cada card de reacción y de vigía; allá la clave es
editable y renombrarla se lleva la nota, mientras que aquí la clave es la dirección de la entidad y
es de solo lectura.)
Guardar reglas reescribe el archivo de puzzle entero de la sala, no solo la regla que
editaste. Todo lo que está en el modelo sobrevive al viaje de ida y vuelta, notas incluidas, y el
bloque de comentarios de la cabecera, arriba de todo, se preserva. Lo único que no se puede
cargar es un comentario escrito adentro de un bloque que se re-emite desde el objeto vivo
(cutscenes:); esos el editor frena y te los lista antes de escribir. Cancelar deja el archivo
byte por byte como estaba.
Esto no es solo para hotspots. Las filas de verbo de Character llevan la misma insignia:
sus reglas viven en el bucket 🌐 Global (_global.rules.js), así una reacción de NPC
condicionada se resuelve aunque el jugador se haya ido a otro cuarto. Las filas compuestas de
interacción de objetos llevan una insignia por par verbo_item, y las filas de walkover de
Region se pueden hacer condicionales de la misma forma.
Un compuesto cuya conducta vive enteramente en una regla (lo creaste con ⚡ y nunca llenaste una reacción plana) igual tiene su fila aquí, sembrada desde el archivo de reglas y no desde la entidad. Sin eso quedaría invisible justo en la superficie que lo creó, mientras funciona perfecto en el juego.
Una insignia responde por su propia clave y por ninguna otra. La fila del use a secas
habla de <hotspot>.use; <hotspot>.use_moneda es de la sección de interacciones con objetos
de más abajo, que trae su propia insignia para ese par. Así que un hotspot cuya única regla es
un compuesto muestra el verbo a secas en estado crear (ese verbo de verdad no tiene regla
propia) y al tocarlo arranca una regla bajo la clave pelada, no abre la del compuesto. Lo mismo
vale para un personaje: <charId>.give y <charId>.give_moneda son filas separadas con reglas
separadas.
Borrar una fila con regla borra la regla. En un personaje, la ✕ de una fila de verbo y objeto
que tiene regla te pregunta primero, porque esa regla es la que hace funcionar la interacción en
el juego. Si confirmas, sale de _global.rules.js junto con su comentario; el resto de las reglas
del archivo queda como estaba. Una fila sin regla simplemente se quita. Mientras una fila tenga
regla, su verbo y su objeto quedan bloqueados: para cambiar cualquiera de los dos, bórrala con ✕
y agrega otra.
Mensajes de sistema#
El botón ⚙ Mensajes de sistema edita los mensajes genéricos del motor: los fallbacks y
líneas de estado que no están atados a un hotspot concreto. Vienen en familias: fallbacks de
interacción (el "no pasa nada" de un verbo desconocido, dos cosas que no se combinan, y las dos
líneas de una puerta con cerradura, «Está cerrado con llave.» y «Ya no está cerrado con
llave.»), fallbacks de personaje (alguien sin nada que decir, alguien que rechaza un objeto),
interacción con objetos (las líneas por defecto de recoger y de usar), entorno (luz on/off),
avisos del HUD (el "mantén tecla para saltar" sobre una cinemática; su {key} se rellena con
la tecla que el jugador tenga vinculada de verdad, así que reescribe la frase, no la clave;
además, las etiquetas cortas junto a los botones del mando y el aviso que pausa el juego cuando
se desconecta el mando), y
guardar/cargar, que además carga los fallos honestos con los que un jugador se topa de vez en
cuando: una partida que no entró, una partida que volvió dañada o escrita por una versión más
nueva del juego, una puerta que no abrió. Vienen del catálogo
core/systemMessages.js del motor y tus ediciones se guardan directo al catálogo de la tabla
de strings del proyecto (strings.json) bajo un lid determinista (sysmsg.<id>), el mismo
lid que el Editor de Traducción siempre lista, así puedes reescribir
la voz entera del motor aquí o traducirla allá, sin tocar código.
Un selector de alcance arriba del modal decide de quién es la voz que editas. (Genérico: todos los personajes) es el default compartido: todos los mensajes, una sola voz para todo el juego. + Agregar voz de personaje lista cada personaje definido, y elegir uno acota el modal a los overrides de ese personaje, pero solo para los mensajes con voz, los que el jugador lee como narración (los fallbacks, la línea de recogida, la línea de interactuar). Las confirmaciones mecánicas (guardar/cargar, luz on/off) se quedan genéricas, compartidas por todos, y no aparecen en el alcance de un personaje. Los overrides son dispersos: deja una fila en blanco y ese personaje simplemente hereda la línea genérica. En runtime se prueba primero el override del personaje activo, luego el mensaje genérico, luego el default del motor, así un personaje huraño puede gruñir "No puedo." mientras el resto recibe el fallback cortés.
Cada tier busca el idioma exacto. Si escribiste un override solo en el idioma por defecto de tu proyecto y el jugador juega en otro, el motor no te devuelve el override en el idioma equivocado: baja al tier siguiente y usa la traducción que el propio motor trae para ese idioma. O sea que un override sin traducir se nota solo en el idioma en que lo escribiste. Tradúcelo en el Editor de Traducción para que llegue a los demás.
Chequeos al guardar#
Guardar bloquea si a un token le falta un argumento obligatorio. Antes de escribir nada,
el editor revisa cada effect token que autoraste (las cadenas por verbo, las filas
compuestas <verbo>_<objeto>, y los eventos onEnter del modo Room) contra el manifiesto de
efectos, el mismo juez que usa el Editor de Puzzles. Si encuentra uno, no escribe nada: un
status de una línea dice exactamente dónde mirar y qué falta, p. ej. "No se guardó: en
«give», al token SETFLAG le falta un argumento obligatorio (Flag)." El modal ⚡ regla de
puzzle lleva la misma reja en su propio guardado: se reabre sobre la entrada que estabas
editando en vez de cerrarse y perder tu trabajo, así que un guardado bloqueado no te cuesta
nada de lo que ya habías escrito.
Validar también avisa (nunca bloquea) cuando el propio orden de una cadena arriesga
quedarse congelada. Abrir un modal del motor que pausa el mundo (la bolsa de inventario,
Opciones, Guardar/Cargar, la confirmación de salir, el menú de pausa) y después esperar una caminata
bloqueante en la misma cadena la deja varada: un WAIT/WAITFOR sigue contando con el
modal abierto, pero nadie camina, así que a los 10 segundos la cadena se aborta y los tokens
que siguen a la caminata no corren. Un CLOSEGUI de ese modal antes de la caminata quita el
aviso. El chequeo también marca una
cadena que se topa con una escena/cinemática/etapa de arcade (sin problema una vez que termina,
un problema si nunca termina sola) o un token que reconstruye el mundo y descarta en silencio
lo que quedaba en cola después. Es el mismo lint que comparten el Editor de Puzzles y el
modal de reacciones propio del Editor de Salas: los tres lugares que autoran estas cadenas.
Dónde se guardan las reacciones#
Save escribe cada tipo de reacción a su hogar natural:
- Reacciones de Hotspot / Room / Region viven dentro del módulo del cuarto
(
hotspot.reactions[verb]y afines), y se guardan con el cuarto. - Reacciones de Item se guardan en el
items.jsondel proyecto. - Reacciones/mensajes de Character se guardan en
characters.json. - Los mensajes de sistema se guardan en el catálogo
strings.jsondel proyecto (un lid determinista por mensaje; un mensaje dejado en el default del motor no escribe nada).
Los IDs de verbo son fijos y en inglés. La cuadrícula se construye desde la lista de verbos del motor (
core/verbs.js); las reacciones se indexan por ID de verbo (look,use,give…), que se mantienen en inglés aunque la UI del editor esté localizada. Renombrar un ID de verbo dejaría huérfano cadahotspot.reactions[verb]; solo las etiquetas se localizan.Las reacciones son contenido: commitéalas. Viven en disco en los archivos de cuarto / objetos / personajes, sin undo al recargar. Tras una pasada sustancial de autoría, commitea para que Git sea tu red de seguridad.