Registro de cambios
Últimas actualizaciones y mejoras de Serenity.
1.3.0 — Clasificaciones, guardado de partidas, HUD basado en datos y el nuevo Serenity Hub
Esta versión va de los datos de tus jugadores: ponerlos en pantalla y mantenerlos a salvo. Un sistema de clasificaciones completo, un sistema de guardado con slots y progreso permanente, y un HUD configurable con editor visual y su propio sistema de animación — más soporte de movimiento del gamepad (giroscopio), el Serenity Hub reconstruido como espacio de trabajo con búsqueda, y nuevos asistentes que lo configuran todo sin tocar código.
Añadido
- Clasificaciones (módulo nuevo) — una pila de récords completa, de principio a fin. El asistente de cinco pasos Create Leaderboard (Tools ▸ Serenity ▸ Create ▸ Leaderboard ▸ Create Leaderboard) te guía: elige un preset («High Score», «Best Time»…), elige la puntuación que tu juego ya registra, elige dónde viven los datos — almacenamiento del dispositivo, archivos JSON legibles, una base de datos SQLite embebida, tu propio servicio HTTP o una conexión directa a Postgres/MySQL/MongoDB — y, si quieres, obtén una pantalla de clasificación lista para navegar y conectada a un menú existente. El ranking es determinista con un tratamiento correcto de los empates, los 8 temas incluidos renderizan la tabla con su propio lenguaje visual, y un backend mal configurado nunca rompe el juego: registra una advertencia y recurre al almacenamiento del dispositivo.
- Guardado de partidas y progreso permanente (dos módulos nuevos) — GameSave da a tu juego un número configurable de slots de guardado, cada uno un documento extensible de secciones tipadas (inventario, hitos, finalización — más lo que tu juego registre). Los menús de slots muestran etiqueta, fecha y finalización al instante, sin cargar partidas completas. GameProgress guarda lo que debe sobrevivir al borrado de un slot — contadores de finalización, extras desbloqueados — para que borrar una partida nunca borre lo que el jugador se ha ganado. Los guardados rápidos de Checkpoint viajan dentro del slot activo automáticamente, el guardado en la nube es una elección de backend y no código extra, y dos asistentes (Create Game Save Settings, Create Game Progress Settings) lo configuran todo, backend incluido.
- HUD basado en datos con editor visual — barras de vida, contadores de munición, temporizadores y cualquier dato en vivo, definidos como datos en lugar de scripts cableados a mano. Los elementos se anclan a nueve posiciones de pantalla con dirección de crecimiento independiente, se vinculan a datos de juego en vivo y se dibujan con siete representaciones — texto, número, tiempo (incluido el estilo arcade MM'SS"CC), pila, segmentado, medidor y conjunto de iconos. Configura el jugador 1 y obtén el jugador 2 reflejado automáticamente. HUD Builder guía el binding de datos para que solo puedan configurarse cadenas válidas, y HUD Preview es una superficie de edición real: arrastra para mover, tira de los tiradores para escalar, rota al estilo Photoshop, ajusta a la cuadrícula con Ctrl — cada gesto es un único paso de deshacer, en cualquier resolución y tema. Un validador dedicado detecta los bindings rotos por renombrados antes de que tus jugadores vean un elemento en blanco.
- Los elementos de HUD se anidan y se animan — los elementos pueden agruparse en cajas de layout que ordenan a sus hijos automáticamente (espaciado, alineación, relleno), un número puede dividirse en una parte entera grande y una parte decimal pequeña, y todo se anima con quince presets listos para usar — Punch, Pulse, Heartbeat, Blink, Wiggle, Spin, Shake, Slide in, Fade in, Damage flash, Ghost pulse y más — que cubren escala, rotación, posición, visibilidad y color. Las animaciones se disparan por cambios de valor, señales o al mostrarse, con cooldown por entrada, todo definido en la nueva pestaña Animation del builder y validado como todo lo demás.
- Animation Hub (Tools ▸ Serenity ▸ Browse ▸ Animation ▸ Animation Hub) — una única ventana con búsqueda para toda la animación del proyecto: clips embebidos en modelos, clips sueltos, animator controllers con sus estados y transiciones, y la animación procedural. Crea y edita clips y controllers ahí mismo, previsualiza un clip en vivo sobre el modelo real con controles de reproducción y scrubbing, y simula perfiles procedurales contra valores de estado reales — sin tocar nunca tu escena ni tus assets.
- Soporte de movimiento del gamepad (giroscopio) — DualSense, DualShock 4 y Switch Pro exponen ahora lecturas de giroscopio y acelerómetro, con calibración de deriva incluida. El menú de ajustes de Controles gana las opciones Gyro Aim y Gyro Sensitivity, listas para que tus jugadores las usen, y la nueva ventana Gamepad Motion Monitor muestra los valores de movimiento en vivo por mando conectado para afinarlos.
- Puntuación, subida de nivel — declara las métricas de puntuación en un asset de ajustes en lugar de registrarlas en código (el nuevo asistente Score Settings lo crea), alimenta una métrica con la distancia recorrida gracias al nuevo componente Transform Distance Meter, y otorga cantidades fijas desde cualquier disparador con la nueva AddScoreSignal — todo sin código. Además, Puntuación se instala ahora a través del Pipeline de Inicialización como cualquier otro sistema.
- Las clasificaciones se encuentran con el HUD, sin código — muestra el número 1 de una tabla o el récord personal del jugador local directamente en el HUD mediante servicios vinculables y un componente de caché del mejor registro; envía la puntuación actual desde cualquier disparador — un botón, una reacción a señal — con la única llamada
SubmitNow()del nuevo componente de envío; y renderiza cualquier precisión decimal que tu puntuación necesite. - Ventana Database Drivers (Tools ▸ Serenity ▸ Validate ▸ Database Drivers) — elegir un backend de base de datos real requiere DLLs de driver instaladas a mano; esta ventana lista exactamente qué archivos necesita cada backend, marca los que ya están instalados, enlaza cada uno que falta con su paquete NuGet y versión exactos, y solo ofrece activar el backend cuando el conjunto está completo. Se acabó descubrir las dependencias error a error.
- El Serenity Hub, reconstruido desde cero — la puerta de entrada del paquete es ahora un espacio de trabajo completo: seis vistas (Home, Create, Validate, Browse, Advanced, Learn), una cuadrícula de tarjetas donde cada herramienta muestra su icono y descripción, favoritos y recientes fijados en Home, y búsqueda global con Ctrl+K entre las 89 herramientas. La validación ya no se ejecuta a tus espaldas: los resultados se guardan en caché con su fecha, y los escaneos solo corren cuando tú lo pides.
- AI Prompt Builder (Tools ▸ Serenity ▸ AI ▸ Prompt Builder) — un asistente que te entrevista sobre lo que quieres construir y genera el prompt óptimo para tu agente de IA. Escanea el proyecto para que el prompt amplíe tus assets reales en lugar de crear desde cero, mantiene una biblioteca personal de instrucciones reutilizables y entrega el resultado en el portapapeles, un archivo o directamente en tu agente como slash command. Sus intenciones incluyen ahora una petición libre — describe lo que sea en lenguaje natural y el prompt dirige al agente a los módulos correctos — y una intención dedicada al diseño de HUD.
- Asistente Add Language — añade un idioma a tus tablas de traducción existentes en una sola pasada guiada: cuadrículas filtrables y paginadas con una columna de idioma de referencia para contexto, conexión opcional con tus ajustes de idioma y reversión atómica si algo falla. Nunca inventa claves nuevas.
- Documentación con la marca de tu juego — el sitio de documentación generado toma ahora automáticamente el título, el texto del logo, el eslogan, el pie y el color de acento de tus Player Settings, y la nueva ventana Docs Branding (Tools ▸ Serenity ▸ Docs ▸ Docs Branding) te deja personalizarlo todo con vista previa en vivo.
- Generador de escena de ejemplo (Tools ▸ Serenity ▸ Create ▸ Samples ▸ Generate Sample Scene) — genera la escena de demostración bajo demanda: canvas, HUD de diagnóstico, un host de toasts y un botón conectado para mostrar uno. Seguro de re-ejecutar.
- Nuevos validadores — Addressable Keys detecta rutas de asset guardadas que fallarían silenciosamente al cargar en runtime, con arreglo en un clic; Localization Keys gana una vista previa de idioma en vivo y avisos por idioma para claves que existen pero aún no tienen traducción.
- El Signal Flow Browser ahora lo ve todo — emisores y reacciones de señales colocados en prefabs y escenas, definiciones de acción y señales de opciones de menú o modal aparecen como emisores y reacciones. Una señal disparada solo desde una opción de menú ya no figura erróneamente como «sin usar».
Mejorado
- Todos los selectores de señal tienen búsqueda — los menús planos e interminables para elegir un tipo de señal se sustituyen por un desplegable con búsqueda, en todas partes.
- Todos los asistentes, una misma experiencia — todos los asistentes de creación comparten ahora el mismo motor de pasos, así que la barra de pasos es navegable libremente en ambos sentidos en todos ellos: cualquier paso ya visitado está a un clic.
- Fire Now en el Modal Builder — previsualiza el modal que estás creando con el modo Play en marcha, antes de crear ningún asset.
- Create Player Input puede crear el asset de Input Actions — el asistente ofrece ahora «Create New…» en lugar de exigir un archivo .inputactions existente.
- Los raíles pueden vincularse en runtime —
BindRail(railService, railId)en el seguidor y el conductor de raíl habilita raíles por instancia, por ejemplo NPCs de un pool siguiendo cada uno su propio camino. - Trae tu propio backend de gatillos adaptativos — registra un backend personalizado desde tu propio código (por ejemplo, un SDK de consola con licencia) y sobrevivirá a las actualizaciones del paquete; un backend que falla degrada con elegancia en lugar de romper el feedback.
- Los argumentos del HUD Builder entienden su tipo — los ids de tabla, las claves de puntuación y las selecciones de campos se muestran como desplegables poblados desde los assets de tu propio proyecto en lugar de campos de texto libre, y se refrescan en vivo al añadir tablas o métricas.
- Los sonidos posicionados se oyen por defecto — un one-shot reproducido en una posición del mundo sin ajustes espaciales propios recibe ahora una atenuación razonable en lugar de la de Unity por defecto, que dejaba un aviso disparado a veinte metros prácticamente inaudible.
- Los campos de texto del editor confirman al hacer clic fuera — escribir un valor y pulsar Create o Next ya no descarta la edición que seguía en el campo; escribir de forma sostenida sigue colapsando en un único guardado y un único paso de deshacer.
- Un menú Tools más limpio — las herramientas internas de desarrollo ya no aparecen en tu proyecto.
Corregido
- Los valores de tiempo con horas se formatean ahora como un reloj: 3600 segundos se muestra como
1:00:00. - Todas las operaciones de Addressables corren ahora en el hilo principal de Unity, eliminando errores raros y difíciles de diagnosticar al entrar en modo Play mientras se cargan assets durante el arranque.
- Retag All (Plugin) ya no registra tipos de archivo que la build de Addressables no puede empaquetar, y ahora además limpia las entradas que ya no corresponden — ejecutarlo una vez repara un proyecto ya afectado.
- Iniciar una oleada ya no libera actores del pool creados por otros sistemas a través del mismo servicio.
- Un Signal Emitter puede conectarse ahora directamente al On Click de un botón (nuevos métodos
DispatchSignalusables desde UnityEvents). - El campo de ruta de asset del Inspector ya no rompe una dirección de Addressables válida al editarla.
- Un gamepad cuya conexión falla degrada ahora a silencio en lugar de mostrar errores en mitad de la partida.
- Las actualizaciones del paquete son más resistentes: un marcador de desarrollo obsoleto copiado por accidente en un proyecto de juego se detecta y limpia automáticamente, y la validación del proyecto ya no reporta falsos errores de marca en proyectos limpios.
- La documentación generada aplica ahora el color de acento configurado, y su página de inicio ya no enlaza a una página que no existe en proyectos de juego.
- Salir de la pausa mediante Resume, Back to menu o Restart notifica ahora a los oyentes de pausa exactamente una vez — nada que siga el estado de pausa mediante señales se queda ya atascado en pausa.
- Leer un ajuste de juego BOOL con un valor por defecto configurado ya no lanza una excepción.
- Rendimiento: las asignaciones de memoria por frame en la cadena del HUD y la animación procedural se redujeron en unos dos tercios, y desapareció un tirón causado por trazas de diagnóstico durante las oleadas de spawns con pooling.
Notas de actualización
La mayoría de los proyectos se actualizan con una importación de paquete normal. Si has extendido Serenity, algunos cambios de API pueden necesitar un pequeño retoque:
- Implementaciones propias de
IServiceLocatordeben añadir el miembro no genéricoTryGet(Type, out object)— para un locator basado en diccionario es una delegación de una línea. - Implementaciones propias de
IUiThemeComponentsdeben añadir una propiedadHudElementTemplate; devolvernulles válido y simplemente omite el tematizado del HUD. - Subclases propias del reproductor de secuencias que ramificaban sobre
stage.StageTypedeben compararstage.Kind(un string) en su lugar. Los assets de secuencia existentes migran automáticamente en la primera carga — sin pasos manuales. - Perfiles propios del pipeline de inicialización deben añadir las cuatro nuevas tareas de instalación (
InstallScorey despuésInstallLeaderboard— antes deInstallMenu— másInstallGameSaveeInstallGameProgress), y los instaladores del juego deberían resolverIScoreService,ILeaderboardService,IGameSaveServiceeIGameProgressServicede forma diferida, ya que ahora se registran durante el pipeline. - El módulo ProceduralExpression se llama ahora ProceduralAnimator — actualiza las directivas
using Serenity.ProceduralExpression..., las referencias de asmdef a los nombres de ensamblado antiguos y cualquier receta o string de tipo serializado que nombre el módulo. Las escenas, prefabs y assets siguen resolviendo sin reimportar, porque las identidades de los scripts se conservan. - Las subclases propias de capas procedurales declaran qué canales escriben mediante una única línea con
DrivenChannels, yRegisterTransformTargetrecibe ahora un argumento explícitoallowPositionOverride. - Varios tipos de asset orientados a diseño generan ahora un Guid interno estable en la primera carga — vuelve a guardar esos assets una vez para persistirlo.
- Si la primerísima importación de 1.3.0 muestra «multiple assembly definition files»: elimina el archivo
.asmdefduplicado cuyo GUID del.metano coincide con el del mismo nombre incluido en el paquete, deja que el editor recompile, y la autolimpieza del paquete completa el resto automáticamente. Solo puede ocurrir una vez, en la importación que trae la corrección — las actualizaciones posteriores reconcilian módulos y carpetas renombrados por sí solas.
1.2.2 — Actualizaciones de paquete automáticas y sin residuos: una sola importación, sin archivos sueltos
Mejorado
- Actualiza en una sola importación — subir a la última versión de Serenity es ahora una única importación limpia. El paquete se ordena a sí mismo automáticamente, de modo que los archivos retirados en versiones nuevas no se quedan en tu proyecto ni te estorban.
- Proceso de actualización sin intervención — la actualización se aplica discretamente en segundo plano y deja todo lo que has configurado exactamente como estaba, para que obtengas la última versión de Serenity y vuelvas a crear enseguida.
Nota de actualización
Actualizar desde cualquier versión anterior es una simple importación de paquete: sin borrar carpetas a mano y, en el caso habitual, sin reinicios del editor.
1.2.1 — Service Extension Creator: Extiende Cualquier Cosa (Servicios, Stores, Repositorios, Gateways, Factories, Installers y Tus Propias Clases) + Actualizaciones de Paquete Autolimpiables + Puerta de Preparación de Gameplay Opcional + Limpieza de Deuda Técnica
Novedades
- Service Extension Creator — un nuevo asistente (
Tools ▸ Serenity ▸ Services ▸ Service Extension Creator) que genera código listo para usar y completamente conectado para extender casi cualquier cosa en Serenity: servicios, stores de persistencia, repositorios, gateways, factories — e incluso tus propias clases personalizadas. Se acabó el cableado manual repetitivo para añadir tu propia lógica sobre el framework. - Actualizaciones de paquete sin esfuerzo — actualizar Serenity ahora es una simple importación única. El paquete se limpia solo automáticamente, por lo que los archivos antiguos o renombrados de versiones anteriores ya no quedan sueltos causando conflictos.
- Instalador de skills para agentes de IA — una nueva herramienta para instalar las skills de asistentes de codificación con IA de Serenity directamente en tu proyecto, para Claude Code, Cursor, GitHub Copilot y otras herramientas de IA.
Mejoras
- Pantallas de carga más fluidas — la barra de progreso de carga ahora anima limpiamente hasta el 100% antes de mostrar el juego, en lugar de sentirse abrupta en cargas rápidas.
- La puerta de preparación de gameplay ahora es opcional — los proyectos que no necesitan esperar una configuración adicional de gameplay antes de mostrar un nivel ya no pagan ningún retraso de carga innecesario.
- Pooling de sonido, sacudida de cámara en pantalla dividida, alineación de menús y movimiento sobre rieles recibieron mejoras de pulido y corrección internamente.
Correcciones
- Los sonidos de mostrar/ocultar de menús y modales ahora se reproducen correctamente.
- Salir de un menú hacia atrás ahora reproduce el sonido de "cancelar" correcto en lugar del equivocado.
- Se ajustaron casos límite menores en la sesión de gameplay y en la recarga de armas.
Limpieza
- Se eliminó código legado sin uso y no funcional para mantener el framework liviano.
Nota de actualización
Actualizar desde cualquier versión anterior ahora es una simple importación de paquete — sin necesidad de borrar carpetas manualmente ni reiniciar el editor en el caso habitual.
1.2.0 — Sistema de Game Camera, Theme Builder, Setup Assistant, Serenity Hub, Safe Asset Delete, Preview de Cutscenes en Vivo y Signal Flow Visual
Esta versión va de dos cosas: llevarte de un proyecto vacío a un juego funcionando más rápido que nunca (Serenity Hub, Setup Assistant, Theme Builder) y proteger tu proyecto mientras trabajas (Safe Asset Delete, Validate Everything, previews en vivo). Además incluye un módulo de Game Camera completamente nuevo con pantalla dividida para multijugador local, y todo el núcleo de negocio de Serenity es ahora agnóstico del motor: las reglas de tu juego ya no dependen de tipos de Unity.
Añadido
- Sistema Game Camera (módulo nuevo) — una capa completa de gestión de cámaras detrás de un único servicio,
IGameCameraService. Mantiene un registro de todas las cámaras del juego (autodescubiertas al cargar la escena, incluso las inactivas o sin referenciar), cambia la cámara activa sin romper tus rigs — solo se conmuta el componenteCamera, nunca el GameObject, así que un CinemachineBrain o cualquier script hermano sigue funcionando — y te da pantalla dividida para multijugador local de serie, con layouts de viewport automáticos que se recalculan cuando los jugadores entran y salen. Registra cámaras sin código conUnityGameCameraRegistrar, o excluye una del descubrimiento con el marcadorUnityGameCameraExclude. - Asistente Theme Builder (Tools ▸ Serenity ▸ UI ▸ Theme Builder) — un tema de UI completo y listo para usar, creado desde cero en una sola pasada. Elige tres colores, una fuente, un fondo y un estilo de selección, y genera el asset del tema más 20 prefabs (botones, sliders, dropdowns, toggles, etiquetas, barras de carga, modales, toasts y más) — incluidas animaciones generadas de mostrar/ocultar y de selección con presets None / Subtle / Elegant / Energetic y previews en vivo. Todo queda auto-registrado en Addressables y puede activarse como tu tema inmediatamente. Sin temas de ejemplo, sin clonar nada, sin cableado manual.
- Setup Assistant (Tools ▸ Serenity ▸ Setup Assistant) — de un proyecto vacío a un bucle jugable de arranque → menú principal → gameplay → pausa en cinco pasos guiados. Valida tus elecciones en vivo, muestra una preview real en modo dry-run antes de escribir nada, y cada asset que crea es idempotente: volver a ejecutarlo nunca duplica tu trabajo.
- Serenity Hub (Tools ▸ Serenity ▸ Hub) — la puerta de entrada del paquete: un panel de estado de los paquetes de Unity requeridos, el cableado del instalador y la salud general del proyecto, más un lanzador categorizado de las 50+ herramientas de Serenity. Cada fila enlaza directamente con la herramienta real que lo arregla. Se abre automáticamente en la primera importación.
- Safe Asset Delete — borrar un asset que otros assets todavía referencian ya no deja referencias colgando en silencio. Una ventana de revisión lista cada asset afectado (haz clic para inspeccionarlo), y Delete & Clean elimina el asset y limpia todas las referencias obsoletas por ti, registrando exactamente qué se ha limpiado.
- Signal Flow Browser, rediseñado como diagrama visual — visualiza tu flujo de eventos como un diagrama de nodos que se lee causa → señal → efecto, con tarjetas por colores, chips de filtro (En uso / Sin uso / Dispatcher / Modal / Reacción), conexiones resaltadas al hacer clic y salto directo al asset o al script desde cada nodo. Encontrar las señales que tu proyecto ya no usa es ahora un solo clic.
- Preview de cutscenes en vivo — el Cutscene Outline ahora previsualiza tu cutscene dentro de la ventana del editor: arrastra por la línea de tiempo, pulsa play, y mira los fundidos y las etapas de Timeline renderizados a través de la propia cámara del rig — sin modo Play y sin tocar tu escena abierta.
- Validate Everything (Tools ▸ Serenity ▸ Validate Everything) — un panel que agrega todos los validadores del proyecto, incluidos dos nuevos que cazan assets sin sus etiquetas de Addressables y definiciones de audio ausentes de sus registros — los clásicos huecos de "¿por qué no suena mi sonido?". Los hallazgos con arreglo tienen botones Fix de un clic, con confirmación indicando exactamente qué va a cambiar.
- Checklists post-creación en el Inspector — los assets de clips de audio y pistas de música ahora muestran su estado de etiquetado en Addressables y de registro directamente en el Inspector, cada uno con su arreglo de un clic — así un registro que falta aparece mientras editas, no en runtime.
- Estado del instalador de un vistazo — el inspector del Serenity Installer ahora agrupa sus campos en Required y Optional y muestra el estado en vivo bajo cada uno: verde cuando está asignado, rojo cuando el juego no puede arrancar sin él, amarillo cuando dejarlo vacío desactiva una funcionalidad en silencio.
- Autoría de waves más segura — el campo de actor de una entrada de spawn solo acepta prefabs y avisa cuando está vacío, en lugar de dejarte crear una wave que no genera nada sin decírtelo.
- Núcleo agnóstico del motor — toda la capa de negocio de Serenity compila ahora sin Unity. Las reglas, ajustes y flujos de tu juego se escriben contra contratos de C# puro: más fáciles de testear hoy, portables mañana.
Corregido
- El menú de pausa ya no permanece visible detrás de otros menús al navegar desde la pausa a otra vista (por ejemplo, Opciones).
- Cuatro modales incluidos (End Game Session, Exit Application, Reset Settings, Restart Game) tenían sus referencias de señal rotas en silencio por un renombrado interno anterior; vuelven a resolverse y a ser visibles en el Signal Flow Browser.
- La validación de registro de audio ya no marca falsamente todos los clips y pistas registrados, lo que también restaura los botones Fix (register) de un clic.
- Los dropdowns generados por las herramientas de temas ahora conectan correctamente su valor seleccionado, incluida su traducción en runtime.
- Se tradujeron al inglés varias etiquetas del editor y mensajes de log que quedaban en español.
Actualizar desde 1.1.x
Esta versión incluye cambios de API incompatibles (por eso es la 1.2.0). No hace falta cazarlos a mano: ejecuta Tools ▸ Serenity ▸ Migration ▸ Migrate to 1.2.0 — escanea el código de tu proyecto, muestra una preview antes/después de cada cambio con casillas de verificación, y aplica solo lo que apruebes; lo ambiguo se reporta en lugar de reescribirse, y volver a ejecutarlo siempre es seguro. El paquete incluye una guía de actualización para los pocos casos manuales. Los assets de configuración de personaje existentes necesitan un reetiquetado y re-guardado único — Validate Everything señala cada uno y arregla las etiquetas por ti.
1.1.4 — Sistema de Feedback (Vibración, LED, Gatillos Adaptativos, Screen Shake/Flash, Hit-Stop, Audio), USB y Bluetooth en Linux + Salida Bluetooth de Gamepads en Windows, Detección de Monitores GNOME/KDE en Wayland, Cutscene Wizard, Cutscenes en Bucle, Triggers de Cutscene No-Code y Recetas Tipadas de Cutscenes
Añadido
Salida de gamepads Bluetooth en Linux (DualSense y DualShock 4) — la vibración, el LED y los gatillos adaptativos ahora controlan los mandos por Bluetooth además de por USB. Los writers raw-HID detectan el transporte de cada mando a partir del campo de bus
HID_IDdehidrawy emiten el report que requiere ese bus: por Bluetooth, reports reencapsulados con checksum CRC32 (DualSense report id0x31con una etiqueta de secuencia incremental; DualShock 4 report id0x11); por USB, reports planos0x02/0x05. El checksum lo calcula un helperPlaystationHidChecksum: un CRC-32 reflejado sobre una semilla0xA2más el cuerpo del report, coincidiendo con el driver del kernelhid-playstation. El report0x10del Switch Pro es idéntico en ambos buses.RawHidDeviceexpone una consultaGetBusTypey un enumHidBusTypepara seleccionar el transporte.Salida Bluetooth de PlayStation en Windows (DualSense y DualShock 4) — la vibración y el LED ahora controlan un DualSense o DualShock 4 por Bluetooth en Windows, algo que antes no hacía nada: la salida PlayStation integrada de Unity es inerte por Bluetooth, y la ruta de Windows de Serenity solo enviaba el report USB mediante
ExecuteCommand. Ahora cada writer envía el mismo report Bluetooth que usa Linux (DualSense0x31, DualShock 40x11, ambos con sufijo CRC32) mediante un handle HID raw de Windows (RawHidDevice): USB sigue usandoExecuteCommand, mientras que Bluetooth se enruta por elGamepadHidrawTransportcompartido.RawHidDeviceen Windows recibió tres correcciones necesarias para esto: ahora reconoce la escritura de ruta de dispositivo Bluetooth (vid&0002054c_pid&0ce6) además de la USB (vid_054c&pid_0ce6); resuelve un mando por serial o, cuando el serial no aparece en la ruta, como ocurre por Bluetooth, por la coincidencia VID/PID única y no ambigua; y rellena cada escritura hasta elOutputReportByteLengthdel dispositivo, leído una vez conHidP_GetCaps, porque Windows lo requiere paraWriteFileHID. Además, el DualSense necesita un report únicoRELEASE_LEDSantes del primer report de color, o su lightbar ignora el color y se queda en el estado de encendido inicial. La lightbar del DualShock 4 responde directamente a su byte de flags. Validado en hardware por Bluetooth con ambos mandos. (La entrada Bluetooth en Windows depende del backend HID propio de Unity: funciona cuando Windows termina de instalar la interfaz HID del mando; un emparejamiento a medias muestra el controlador pero no emite input, y se soluciona eliminándolo y emparejándolo de nuevo.)Detección de monitores GNOME y KDE en Wayland —
LinuxSystemMonitorsProviderdetecta la distribución multi-monitor en los principales compositores Wayland probando varios backends por orden de prioridad y usando el primero que devuelve datos:swaymsg(wlroots/Sway),wlr-randr(otros compositores wlroots como Hyprland/river),kscreen-doctor -o(KDE Plasma / KWin) y el método D-Busorg.gnome.Mutter.DisplayConfig.GetCurrentStatemediantegdbus(GNOME). Las sesiones GNOME y KDE Wayland obtienen posición, resolución, tasa de refresco y flag de pantalla principal correctos por monitor. La identidad basada en EDID (fabricante/modelo/serial) se obtiene desde/sys/class/drmpara todos los backends.Sistema de Feedback — un nuevo módulo para game feel, con un único punto de entrada orientado al consumidor:
IFeedbackService(Serenity.Feedback.Application). Una pieza de feedback es una definición —una lista de efectos creada como un único asset— que se reproduce por id:Play("Hit")la dispara en el mando que actuó más recientemente, y el enable e intensity globales viven en un único sitio (SetGlobalEnabled/SetGlobalIntensity, aplicados a cada impulso). El targeting es consciente del multijugador: la misma definición puede dirigirse al mando que actuó, a un jugador unido concreto (PlayForPlayer), a unPlayerInputconcreto (PlayForPlayerInput) o a un dispositivo concreto (PlayForDevice), yStopAllcorta todos los canales y mandos a la vez. El núcleo (definiciones, efectos, matemáticas de intensidad y escalado) es independiente del motor (Serenity.Feedback.Domain/Serenity.Feedback.Application, deliberadamente sin tipos deUnityEngine); la parte de Unity (Serenity.UnityFeedback.Infrastructure) proporciona los canales, la salida de gamepad, la configuración y las herramientas de editor.Ocho efectos de feedback — una definición puede componer cualquiera de estos efectos: Gamepad Vibration (motores duales de baja/alta frecuencia con duración de mantenimiento), Gamepad LED (color de la lightbar del DualSense), Gamepad Adaptive Trigger (DualSense; modo Resistance, Weapon u Off, con recorrido inicial/final y fuerza), Screen Flash (flash de color a pantalla completa con una envolvente alpha-over-time editable, en tiempo sin escalar para sobrevivir a un hit-stop), Gameplay Hit Stop (breve caída de escala temporal en el impacto), Screen Shake (Camera) y Screen Shake (UI) (shake posicional con decaimiento, en espacio de mundo y espacio de pantalla), y Audio (Sound): reproducir un sonido configurado, referenciando un
UnityAudioPlayerClipDefinition, a través del audio player como parte de la misma señal, de modo que una sola definición dispare rumble + flash + sonido a la vez. Los efectos se editan desde el inspector mediante bloques[SerializeReference]FeedbackEffectAuthoring—la capa que contieneColor,[Range]y tooltips— y se convierten a efectos puros; cada efecto lo gestiona su propio canal, y cada impulso háptico/visual se escala por la intensidad global antes de salir. Audio es la excepción: es independiente de los ajustes de enable/intensity de vibración (suena incluso con la vibración del controlador desactivada y su volumen nunca se atenúa), expresado mediante un opt-outBypassesGlobalGatepor efecto en el contrato del efecto, para que el servicio aplique la puerta a cada efecto individualmente en vez de a toda la definición.Salida de gamepad multiplataforma (DualSense / DualShock 4 / Switch Pro) — Serenity controla la vibración, el LED y los gatillos adaptativos gestionando directamente el report HID de salida del controlador. El writer de DualSense lleva vibración, color LED Y ambos gatillos adaptativos en un único report USB, así que una actualización de vibración o color ya no pisa un efecto activo de gatillo (mantiene el estado por dispositivo como única fuente de verdad y reemite el report completo en cada cambio); el writer de DualShock 4 combina vibración y color de lightbar del mismo modo; y un servicio de streaming para Switch Pro controla la vibración HD y el LED del botón Home mediante un handle HID raw (la vibración del mando no queda enganchada, así que se emite en streaming a ~100 Hz en un hilo en segundo plano, con la intensidad mapeada mediante una curva perceptual). El feedback se enruta al dispositivo que realmente disparó la acción mediante un tracker de dispositivo activo, por lo que en multijugador local los efectos de cada jugador aterrizan en su propio mando, y los mandos idénticos se desambiguan por serial.
Soporte de gamepads en Linux — en Linux, el backend de input de Unity no puede enviar reports HID de salida, así que Serenity escribe reports de LED / vibración / gatillos adaptativos directamente al nodo
/dev/hidrawNdel controlador (la misma ruta que usa Switch Pro en todos los sistemas operativos), cubriendo DualSense, DualShock 4 y Switch Pro tanto por USB como por Bluetooth (la selección de report por bus se detalla arriba). Los botones frontales del Switch Pro también se mapean en el backend SDL de Linux, que los expone por etiqueta Nintendo en vez de por posición física, de modo quebuttonSouth= el botón físico inferior como en el resto de plataformas.Trigger de feedback no-code —
PlayFeedbackSignales el puente del event-dispatcher hacia el servicio: despáchalo (por ejemplo desde elSignalEmitterComponentno-code existente, o desde cualquierEventDispatcherAction) con un id de definición y un targeting opcional de jugador/dispositivo, y se reproduce el feedback; así, "cuando ocurra la señal X, vibra / flashea / shakea" no necesita código escrito a mano. Un ScriptableObjectFeedbackDefinition(Serenity ▸ Feedback ▸ Feedback Definition) contiene la lista de efectos configurada, y se incluye un ejemplo funcionalStartGameFeedback(StartGameFeedbackActionreaccionando aStartGameFeedbackActionSignal) bajoEXAMPLES.Feedback de menú — la navegación de menú reproduce feedback sin código: se dispara una definición configurada cuando cambia la opción seleccionada (
MenuTickDefinitionId) y cuando se envía una opción (MenuSubmitDefinitionId), ambas leídas desde el asset de configuración de feedback, por lo que los menús ofrecen respuesta háptica/visual con mando sin cableado por menú (y permanecen en silencio cuando no se configuran valores por defecto).Feedback Builder e inspectores — Tools ▸ Serenity ▸ Feedback ▸ Create Feedback abre una ventana Feedback Builder que crea un
FeedbackDefinition(eliges efectos, configuras sus campos) y genera el asset; el inspector deFeedbackDefinitionrenderiza la lista de efectos mediante una GUI dedicada de lista de efectos (añadir / eliminar / reordenar bloques de efectos), y un assetUnityFeedbackSettings(Serenity ▸ Feedback ▸ Settings) configura los valores globales por defecto, incluidas las definiciones de tick/submit de menú.Trigger de feedback no-code desde el builder + sección de receta tipada
feedbacks— Create Feedback ahora también emite unUnityEventDispatcherSignalDefinition(<Name>Trigger.asset) precableado para despacharPlayFeedbackSignalpara la nueva definición, de modo que un diseñador lo suelta en unSignalEmitterComponenty reproduce el feedback con cero código y sin script generado (independiente de, y en paralelo a, la ruta existente Signal+Action; ambas son ahora toggles opcionales).FeedbackDefinitiontambién pasa a ser una sección de recetafeedbackstipada de primer nivel (importer/exporter/template-generator/discovery), haciendo round-trip de su lista polimórfica de efectos[SerializeReference]mediante el codec compartido, con un flag opcionalgenerateTriggerque crea el mismo trigger no-code al importar. Se incluye un cookbook completo del agregado Feedback (Documentation/Cookbooks/Gameplay/Feedback.md, la plantilla de 12 secciones), y se actualizó el mapa de módulos del README de Cookbooks + índice de SO,ConfiguringSerenitySystems, la raíz de docs y el skill routerserenity-cookbookspara enrutar Feedback.Installer y cableado DI —
UnitySerenityInstaller.InstallFeedback()registra el servicio de feedback (UnityFeedbackInstaller, dependiente de los servicios de game-settings y event-dispatcher) y se ejecuta desde la initialization pipeline de arranque (nueva tareaInstallFeedback). El módulo incluye su propia etiqueta Addressables (module:feedback) para que sus assets se carguen en boot como cualquier otro módulo de Serenity. La salida de gatillos adaptativos es conectable detrás de una interfaz de backend: un backend HID de PC controla el DualSense por USB en escritorio, con un backend PS5-SDK preparado como scaffolding para consola.Cutscene Wizard (Tools ▸ Serenity ▸ Cutscenes ▸ Cutscene Wizard) — un builder IMGUI por pasos para cutscenes (Template → Stages → Rig → Trigger → Create), modelado a partir del Settings Wizard. Inicializa la lista de stages desde un preset (Splash
FadeIn→Wait→FadeOut, Timeline cutsceneFadeIn→PlayTimeline→FadeOut, o Blank), permite editar cada stage (tipo, duración, color de fade, Timeline) con reordenar/añadir/eliminar, opcionalmente crea un rig prefab (unGameObjectconPlayableDirector,playOnAwakedesactivado) o asigna uno existente, y al finalizar registra el nuevoUnityCutsceneDefinitionenUnityCutscenePlayerSettings.Definitionsdel proyecto —encontrando o creando ese asset de settings—, lo que cierra el hueco silencioso de "he creado una cutscene pero nunca carga porque no se añadió a la configuración". La ventana (CreateCutsceneWindow) solo recoge input; unCutsceneCreatorpuro realiza todas las mutaciones de assets con rollback en caso de fallo (igual queModalCreator/GameSettingCreator), yCutscenePresetLibrarycontiene las plantillas.Generación de tareas de boot / init-pipeline — el paso Trigger del wizard también puede crear una
UnityReflectionCallTaskDefinitionPlay{Name}que reproduce la cutscene desde la initialization pipeline (la ruta de boot splash). Replica la tarea incluidaPlayCompanySplashScreen: una llamada de instancia aUnityCutscenePlayerService.PlayAsync,resolveFromServices: true, elIdde la cutscene como único argumento string, con criticidadDegradablepara que un splash fallido nunca detenga el boot. La tarea se crea junto a la definición pero no se inserta automáticamente en un perfil; añádela a unUnityInitializationPipelineProfiledespués deInstallCutscenePlayer.Trigger no-code para reproducir cutscenes — el paso Trigger opcional del wizard genera un
{Name}ActionSignal+ una{Name}Action[AutoRegisterEventAction](mediante el mismoSerenityEventDispatcherActionScriptCreatorque usa el Modal Builder, con un cuerpoExecuteespecífico para cutscenes enCutsceneTriggerScriptCreator). La acción resuelveICutscenePlayerServicedesdeServiceLocatorBridge—el servicio ya está registrado en elServiceLocatorporUnitySerenityInstaller.InstallCutscenePlayer— y lanzaPlayAsync(id)en fire-and-forget (seguro: el servicio limita cada stage y toda la cutscene con timeouts duros de tiempo real). Después, un diseñador despacha la señal generada con elSignalEmitterComponentno-code existente, así que "cuando se dispare la señal X, reproduce la cutscene Y" no necesita código escrito a mano. Antes, las cutscenes no tenían trigger controlado por señal: solo inyección directa deICutscenePlayerService.PlayAsync.Cutscenes en bucle —
ICutscenePlayerServiceganaPlayLoopingAsync(id)/Stop(id)/IsPlaying(id): una cutscene puede ejecutarse ahora como una secuencia persistente y en bucle de fondo (fondos de menú, escenas ambientales) en vez de como una pipeline de stages one-shot.PlayLoopingAsyncinstancia el rig de la definición bajo el servicio de cutscenes (para que sobreviva a cargas de escena), configura elPlayableDirectordel rig en wrap modeLoopy devuelve inmediatamente; es idempotente: reproducir de nuevo una key que ya está en bucle no hace nada, nunca duplica rigs.Stopdestruye el rig, y la reproducción en bucle evita deliberadamente los timeouts por stage y de tiempo real de la pipeline one-shot (un bucle no tiene final que limitar). El paso Trigger del Cutscene Wizard recibió una opción Trigger kind: Play once (la acciónPlayAsyncexistente) o Play looping, que genera una pareja señal/acciónPlay{Name}ActionyStop{Name}Actionpara que una cutscene en bucle pueda iniciarse y detenerse sin código.Creación automática de Timeline en el Cutscene Wizard — un stage
PlayTimelinepuede marcar "Create a new Timeline for this stage" y el wizard crea unTimelineAssetvacío junto a la cutscene y lo asigna, además de insertar la Timeline del primer stage en elPlayableDirectorde un rig recién creado para que el rig se abra listo para authoring en la ventana Timeline (inofensivo en runtime:playOnAwakeestá desactivado y el servicio reasigna por stage). Está protegido detrás de un version defineSERENITY_TIMELINE(com.unity.timelineen el asmdef de editor) para que el assembly compile cuando el paquete Timeline no esté presente.Sección de receta tipada
cutscenes— las cutscenes son ahora una sección tipada de primer nivel de una.serenity-recipe.json(comomenus/modals/audioClips) en vez de viajar por el codec genéricoassets. UnRecipeCutsceneDtocontieneid/output/rigPrefaby unstages[]ordenado (id,stageType—nombre deCutsceneStageType—,duration,fadeColorcomo{r,g,b,a}, ytimelinecomo ruta dePlayableAsset).CutsceneRecipeImporter(descubierto por reflexión, ordenado entremenusymodals) escribe los campos privados de stages mediante unSerializedObjecty resuelve el rig/Timeline por ruta;CutsceneRecipeExporterlos exporta de vuelta. El template generator emite un stub realistaFadeIn→PlayTimeline→FadeOut, el discovery registry expone el vocabularioCutsceneStageType, yexample.serenity-recipe.jsongana una cutscene de ejemplo. Un stagePlayTimelinesin Timeline se importa, pero se reporta como warning.Documentación de cutscenes — el cookbook Cutscenes & Sequences (
Documentation/Cookbooks/Narrative/CutscenesAndSequences.md) se amplió desde un stub de campos hasta la plantilla completa de 12 secciones del agregado (modelo de dominio + límites de timeout duro, las tres rutas de authoring incl. el Wizard, la sección tipada de receta, installer/DI + registro de servicio, contrato de trigger no-code, contratos de ID, ejemplo funcional, verificación y mapa de fuentes). La referencia de schema de recetas, la guía de generación de assets para IA, el README de docs y el catálogo de SO de Cookbooks se actualizaron para listar la nueva seccióncutscenesy el Cutscene Wizard.Consultas de jerarquía con scope de escena —
UnityHierarchyUtilsgana búsqueda multi-root a nivel de escena:GetSceneRoots,FindInSceneWithTag/FindAllInSceneWithTag, yFindInScene<T>/FindAllInScene<T>, cada una con una sobrecarga que recibe unaSceneespecífica y otra sin argumentos que usa por defecto la escena activa. Recorren todos los GameObject raíz de la escena e incluyen objetos inactivos: los escenarios que los helpers existentes de búsqueda desde una única raíz no cubrían.Claude Code skills incluidos en el paquete — Serenity ahora incluye skills Claude Code orientadas a LLM bajo
Assets/Serenity/Documentation/Skills/(para que viajen en el.unitypackage) más un instalador que las activa: Tools ▸ Serenity ▸ AI ▸ Install Claude Skills (SerenityClaudeSkillsInstaller) copia cada carpeta de skill incluida a.claude/skills/del proyecto, que es donde Claude Code realmente descubre skills. UnSKILL.mddejado bajoAssets/no hace nada, porque Claude Code solo escanea<project>/.claude/skillsy~/.claude/skills. El primer skill,serenity-cookbooks, es un router que obliga a un agente IA a leer el Aggregate Cookbook del módulo correspondiente antes de crear o cablear cualquier sistema de Serenity (con reglas estrictas para extraer campos exactos del Project Recipe Template Generator y para reetiquetar Addressables + registrar audio tras la importación). El instalador omite archivos.metade Unity y vive en el assembly existenteSerenity.PackageBootstrapper.Editorjunto al exportador del paquete; la salida regenerable de instalación (.claude/skills/) se ignora en git.
Cambiado
- El catálogo de SO de Cookbooks ahora lista
UnityCutsceneDefinitionbajo la sección tipadacutscenes(antesassets) con el Cutscene Wizard como herramienta de authoring.
Corregido
El emisor de señales no se recuperaba de una búsqueda de servicio demasiado temprana —
SignalEmitterComponentmarcaba sus búsquedas de event-dispatcher y logger como "resueltas" antes de comprobar que hubieran tenido éxito, así que un emisor que se disparaba antes de que boot terminara de registrar los servicios (por ejemplo, un evento de animación de logo durante el splash) cacheaba permanentemente la búsqueda nula fallida; y comoSetActive(false/true)no reinicia campos privados, desactivar y reactivar el objeto tampoco lo recuperaba: el trigger se quedaba silenciosamente muerto (warnings incluidos) durante toda la sesión. Ahora el latch solo se establece tras una resolución correcta, de modo que el siguiente dispatch reintenta y recoge el servicio una vez registrado.El prompt de input primario ignoraba Screen Shake (UI) —
UnityPrimaryInputPromptViewFactorycreaba el contenedor del prompt como unTransformplano, peroUnityUiShakeReceiversolo desplaza elanchoredPositionde hijos directosRectTransformdel canvas raíz, así que el prompt de input nunca se movía durante un feedback de UI screen-shake. Ahora el contenedor es unRectTransformfull-stretch (anclado para rellenar su padre), lo que además lo convierte en un elemento UGUI correcto según la especificación.
Infraestructura
Añadidas las suites de test
Serenity.Feedback(EditMode), que cubren el núcleo independiente del motor: clamping deFeedbackIntensity, escalado de intensidad global conFeedbackScaler, salidaScaledpor efecto y DTOs de feedback-target / definition-data. Extendidas con el contrato de audio gating:AudioEffectreportaBypassesGlobalGateyScaledlo devuelve sin cambios, mientras que los efectos hápticos permanecen bajo gate.Añadido
CutsceneRecipeRoundTripTest(EditMode) a la suiteSerenity.ProjectRecipe.Tests.Editor: importar → comprobar la definición y sus stages, exportar → comprobar el DTO, y un round trip export → re-importar en una nueva raíz. Añadido un nuevo assembly solo de EditorSerenity.UnityCutscenePlayer.Installation.Editorpara el wizard.Añadidos
UnityHierarchyUtilsSceneTests, que cubren las nuevas consultas con scope de escena: enumeración solo de raíces, búsqueda por tag y componente a través de múltiples raíces (hit y miss), objetos inactivos y escenas vacías/inválidas, tanto contra una escena aislada recién creada como contra la escena activa para las sobrecargas sin argumentos.
1.1.3 — Menús en cascada, Toast guiados por tema y sistema de recetas de proyecto efocada en generación con IA
Añadido
Menús en cascada — un sistema de menús multi-columna con navegación drill-down, donde seleccionar una opción abre una subcolumna a su lado. El modelo de navegación y builder agnósticos del motor viven en
Serenity.Menu.Application.Cascade(CascadeMenuModel,CascadeColumn,CascadeMenuPage,CascadeOption,ICascadeMenuContext); el lado Unity (Serenity.Menu.Infrastructure.Cascade) añade el renderer, un proxy de puntero para ratón y tres definiciones ScriptableObject:OptionsCascadeMenu(opciones estáticas creadas con un[SerializeReference] OnSelectSignalpor hoja),DynamicCascadeMenuyTargetCascadeMenu.UnityCascadeViewDefinition(Serenity/Menu/Cascade/Cascade View) convierte una cascada en un target de transición resoluble por el router como cualquier composite view, de modo que una opción de menú puede transicionar hacia ella; se construye bajo el canvas medianteUnityCascadeViewFactory/UnityCascadeViewService(IViewProvider) /UnityCascadeViewInstaller, cableado desdeUnitySerenityInstaller.InstallCascadeViews().DefaultCascadeMenuContextejecuta una cascada estática sin código de juego: la señal opcional de una hoja se despacha al resolverse y después la vista vuelve a quien la abrió.ICascadeMenuContext.Dispatch+OptionsCascadeMenu.OptionDefinition.KeepOpenOnSelectpermiten que una opción terminal dispare su señal sin cerrar la cascada.Renderizado de cascadas con tema — el menú en cascada se renderiza mediante un
CascadeView.prefabcreado por diseñador y específico de cada tema (un nuevo slotCascadeViewTemplateen el tema, creado para los 8 temas a partir del fondo + fuente de título propios de cada uno), en lugar de un panel procedural hardcodeado, de modo que coincide con el tema UI activo.UnityCascadePanelproporciona slots de header + options-root,SetTitle/SetInteractable/SetOptions,ConfigureScrollyAdaptWidth.UnityCascadeViewDefinitionsustituyePanelWidthporMinWidth/MaxWidth+VisibleOptionsCount. La cascada también reproduce losIUiThemeSoundsdel tema al navegar / enviar / cancelar y soporta hover de ratón para enfocar + click para seleccionar.Widgets Serenity UI —
SerenityButton,SerenityGauge,SerenityImage,SerenityLabel,SerenityStatusPanelySerenityUiContext, wrappers runtime sobre los componentes UI tematizados.Sistema Project Recipe — permite crear contenido de Serenity como archivos
.serenity-recipe.jsonlegibles por humanos y convertirlos en ScriptableObjects reales mediante la API del Editor de Unity, sin escribir a mano.asset/.meta/GUIDs. El importer hace create/update idempotente con Validate / Dry-Run / Import, cubriendo secciones tipadas (audioClips/musicTracks/menus/modals) y un codec genéricoSerializedObject. El exporter convierte un proyecto existente de vuelta en una receta. El template generator emite la plantilla base de receta exacta y sin drift para cualquier SO autorable.Notificaciones toast guiadas por tema —
UnityToastComponent, una notificación transitoria y no bloqueante que instancia un mensaje corto, lo mantiene y lo elimina. La visual es el prefab de toast del tema activo, cableado en un nuevo slotToastTemplatedel UI theme, de modo que los toasts heredan las fuentes y aspecto del proyecto. Se puede disparar sin código medianteShow(string),ShowToastSignalyUnityToastSignalReactionComponent.Inspector de Cutscene Player Settings —
UnityCutscenePlayerSettingsEditorpermite que el asset de settings del cutscene-player muestre el inspector estándar de Serenity en lugar del inspector por defecto de Unity, y rellena el Id/Guid vacío del asset.Import → press Play — servicios de proyecto auto-registrables + Addressables extensibles por proyecto.
[AutoRegisterService]permite que los servicios de un juego se auto-registren sin bootstrap MonoBehaviour en la escena.[SerenityAddressable("label")]permite que un tipo ScriptableObject de proyecto entre en el auto-labeler y sea cargado al arrancar sin referencias cableadas a mano en el Inspector.Validación de proyecto headless —
Validate Project (JSON)ejecuta los validadores Health Check, Missing References y Localization Keys, y emite los resultados como JSON para que un agente IA o CI pueda verificar que el proyecto está correctamente cableado. El exit code es1cuando hay errores y0cuando solo hay warnings o no hay problemas.Registro de discoverability —
Project Recipe Registrygenera un volcado machine-readable de señales, action ids, reacciones de código, tipos ScriptableObject autorables, vocabularios enum, secciones de receta y contratos semánticos de ID, para que un agente IA pueda referenciar valores reales en lugar de inventarlos.Importación headless de recetas + reporte machine-readable —
SerenityRecipeEngine.ImportFromCommandLineejecuta Validate / Dry-Run / Import sin GUI de editor y escribe el resultado como JSON medianteSerenityRecipeReport.ToJson(). Esto permite cerrar el ciclo author → validate → import → read-result → retry sin intervención humana.Cableado tipado de señales de menú/modal en recetas — las secciones
menus/modalsahora cablean directamenteEventDispatcherSignals[SerializeReference]:submitSignals[]por opción,onShow,onHide,onCancelyonSubmit.RecipeSignalDtoyRecipeSignalCodecpermiten describir, aplicar, capturar y exportar señales, incluyendo señales con payload.Sección de localización en recetas — la sección
localizationde una.serenity-recipe.jsonahora genera contenido real de Unity Localization: asegura locales, crea o encuentra la String Table Collection y hace upsert de entradas inline key/value. El motor principal de recetas no gana dependencia directa del paquete Unity Localization.Set de documentación Serenity — añadido
Assets/Serenity/Documentation/con referencia de esquema de recetas, guía para agentes IA, documentación por sistema, walkthrough de application-flow, guía MCP, cookbook de cableado y cookbooks por ScriptableObject.Aggregate Cookbooks — añadidos 21 documentos end-to-end orientados a IA, uno por módulo, que documentan sistemas completos como Character, Wave, Stage, GameSession, Score, Combo, GameWeapon, GameRail, GameUi, Ui, ViewBrowser, AssetPrefetcher, ServiceLocator, Timer, Task, Persistence y FilePersistence.
Mapa completo de 38 módulos — el
Cookbooks/README.mdmaestro ahora enlaza cada módulo de Serenity con su documentación autoritativa e incluye un diagrama de composición que muestra cómo GameMode → GameSession → Stage → Wave → Character → Score/Combo/GameUi encajan entre sí.
Cambiado
Reorganización de assets multimedia —
Assets/Mediase ha movido bajoAssets/Serenity/Media. Las referencias enlazan por GUID, por lo que el movimiento es transparente.Revisión completa de la ventana Mixer Topology — el diagrama de routing ahora autoajusta tarjetas multilínea, dibuja iconos por tipo y una leyenda, soporta nodos seleccionables con panel de detalle y resalta conectores.
Corregido
- Doble submit con gamepad en transiciones de menú —
SetActionMapcambiaba el mapa dePlayerInputde forma incondicional, provocando que un Submit mantenido durante una transición se procesara dos veces. Ahora el cambio se omite cuando el mapa solicitado ya es el actual. El renderer de cascada aplica el mismo press-release gate para que el Submit que abrió la cascada no envíe inmediatamente su opción enfocada.
Infraestructura
Añadida la suite
Serenity.ProjectRecipe.Tests.Editorcon 44 tests EditMode, cubriendo importer/exporter de recetas, codec genéricoSerializedObject, template generator, validación de recetas,SerenityRecipeReport.ToJson(),SerenityDiscoveryRegistryy cableado tipado de señales de menú/modal.Añadidos tests PlayMode de placement para
GameModeMusicBinderComponent,UnityToastComponentyUnityAudioPlayerService.Añadida la suite
Serenity.UnityValidation.Tests.Editor, cubriendoSerenityValidationReport.ToJson()y un smoke test deSerenityProjectValidationRunner.RunAll().
1.1.2 — Herramientas de autoría (Modal / Game Settings / Audio), opciones avanzadas para modales, reetiquetado de Addressables, Input Action Invoker y cobertura de tests completa
Añadido
- Herramienta Modal Builder (Tools ▸ Serenity ▸ Modal ▸ Create Modal) — genera un script de Signal + Action reutilizando el generador compartido de scripts de Action, además de un asset
UnityModalSettingsy un assetUnityActionDefinition, todos referenciando la misma señal generada. La cadena del tipo de señal se construye de forma determinista (UnityActionDefinition.Signal=Type.FullName;UnityModalSettings.signalTypeName= nombre completo cualificado por ensamblado), de modo que el selector de señales las hace coincidir exactamente. El inspector de botones de modal se ha extraído a unModalButtonsInspectorGUIcompartido, utilizado tanto por el editor como por la herramienta. - Traducción en runtime del título/texto de los modales —
IsTranslatingTitle/IsTranslatingTextenUiShowModalParametersfluyen hastaUnityModalComponent, que añade u obtiene en runtime unUnityUiTMP_TextLocalizationUpdaterComponentsobre el TMP del título/texto, sin editar el prefab. Anteriormente los títulos/textos de los modales nunca se traducían; solo los botones. - Mostrar modal por id — ahora los modales pueden mostrarse mediante su id configurado, complementando la ruta de visualización basada en parámetros.
- Opciones avanzadas para modales — los modales ahora renderizan el modelo completo
UiOption[]de los menús en lugar del modelo de botón únicamente de tipo submit. Un modal contieneUiOption[] Options,ModalDirection Direction,OptionsGap,ScrollableyVisibleOptionsCount, configurados igual que un menú, con construcción de componentes por tipo de interacción (SUBMIT/SLIDER/TOGGLE/SELECTOR), cambio en runtime del layout group según la dirección y un viewportScrollRectlimitado aVisibleOptionsCount. LosButtonslegacy de los modales se migran de forma perezosa aUiOptions (InteractionType = SUBMIT) preservando todas sus señales.ModalDirection.HORIZONTAL = 0, al contrario queMenuDirection.VERTICAL, para que todos los assets de modales existentes se deserialicen sin cambios. - Submit de opción con múltiples señales —
UiOptionahora contiene unaList<EventDispatcherSignal> OnSubmitSignals, leída medianteUiOption.GetSubmitSignals(), de modo que una sola opción de menú o modal puede despachar varias señales en orden. El antiguoOnSubmitSignalúnico se mantiene por retrocompatibilidad y se migra de forma perezosa. Las nuevas opciones por defecto son unaACTIONvacía, un no-op que simplemente despacha las señales de submit de la opción. - Game Settings Wizard (Tools ▸ Serenity ▸ GameSettings ▸ Settings Wizard) — un asistente IMGUI por pasos que crea assets
UnityGameSettingsDefinition, con biblioteca de presets, autorrelleno en vivo de opciones desdeQualitySettings/Screen.resolutions/Locales/AudioMixer, cableado opcional de servicios y una acción para generar el conjunto completo recomendado. El paso de cableado escribe elIddel ajuste en la clave de configuración del servicio correspondiente (graphics / localization / UI / sound-mixer), para que el ajuste tenga efecto realmente en runtime. - Herramientas de importación de audio por lotes — Tools ▸ Serenity ▸ Audio ▸ Batch Import Sound Effects genera un
UnityAudioPlayerClipDefinitionpor cada archivo seleccionado; Batch Import Music Tracks genera unUnityMusicTrackDefinitionpor archivo con campos compartidos y un foldout avanzado por pista para configurar loops (tail-preserving, región por tiempo/compases, fade). - Audio Channel Manager (Tools ▸ Serenity ▸ Audio ▸ Audio Channel Manager) — una vista de relación mixer ↔ Serenity que analiza inconsistencias, crea canales/grupos y los elimina con un plan dry-run + Undo.
- Ventana Addressables Retag Selected (Tools ▸ Serenity ▸ Addressables ▸ Retag Selected…) — lista los assets reetiquetables bajo cualquier carpeta arrastrada o seleccionada, previsualiza las etiquetas que recibiría cada uno, permite escoger cuáles reetiquetar (Select All / None / Invert) y las aplica. Los archivos no elegibles (extensiones excluidas, documentación/segmentos de manual, assets de localización) se ocultan; se aceptan assets fuera de las raíces del plugin Serenity, y la dirección cae de forma segura a eliminar un
Assets/inicial. - Herramienta Remove GUID Labels (Tools ▸ Serenity ▸ Addressables ▸ Remove GUID Labels) — elimina etiquetas Addressables obsoletas con forma de GUID de todas las entradas y de la tabla de etiquetas de settings, dejando intactas las etiquetas
module:*,type:*yLocale*. - Input Action Invoker —
UnityInputActionInvoker(Add Component ▸ Serenity ▸ Input ▸ Input Action Invoker), un componente drop-in que mapea acciones del Input System a métodos públicos sin parámetros en scripts referenciados, y los llama cuando se dispara el input. Es el equivalente basado en reflexión de Serenity al modo PlayerInput → Invoke Unity Events de Unity. Un inspector personalizado lee los action maps/actions desde unInputActionAssetasignado, o desde el asset de unPlayerInputhermano, y lista en desplegables los métodos invocables de cada target. Cada entrada de acción tiene su propia fase de disparo (Started/Performed/Canceled) y cualquier número de llamadas a métodos. Las acciones se enlazan desde la instancia de acciones por jugador delPlayerInputhermano cuando está presente, manteniendo aislados los callbacks de multijugador local, y caen al asset asignado para uso standalone. - Componente Signal Reaction —
SignalReactionComponent(Add Component ▸ Serenity ▸ Events ▸ Signal Reaction), la contraparte no-code deSignalEmitterComponent: mientras el emitter despacha una señal sin código, este componente reacciona a una. Un inspector personalizado muestra cada reacción como un desplegable buscable de todos los tipos concretosEventDispatcherSignaldel proyecto, además de una respuestaUnityEvent, de modo que un diseñador puede cablear “cuando se despache la señal X, haz Y” íntegramente desde el Inspector. Es la primera forma no-code de reaccionar a una señal; anteriormente solo era posible medianteEventDispatcherAction<TSignal>definido por código. Las suscripciones pasan por elIEventDispatcherServicecompartido, resuelto medianteServiceLocatorBridge; el componente espera a que el servicio esté registrado antes de enlazarse y se desuscribe correctamente al deshabilitarse. ElUnityEventsin parámetros responde a “reacciona cuando ocurra esta señal”; las reacciones que necesitan el payload de la señal siguen perteneciendo a unEventDispatcherAction<TSignal>. - Informe de Missing References (Tools ▸ Serenity ▸ Validate Missing References) — una ventana de editor de un solo clic que escanea cada ScriptableObject
IFoundationSettings(clips, pistas, menús, modales, definiciones, settings…) buscando referencias que fueron asignadas pero que ya no pueden resolverse, como un clip, tabla, prefab o definición eliminado/movido, y lista cada asset y campo problemático con un botón Ping. Solo se reportan referencias perdidas, no campos vacíos. Herramienta orientada a diseñadores para responder “¿qué está roto?”, haciendo visibles los fallos silenciosos por referencias nulas a los que la arquitectura puede ser propensa. - Dashboard Health Check (Tools ▸ Serenity ▸ Validate Health Check) — una ventana única de “¿mi proyecto está cableado correctamente?” para no programadores. Ejecuta nuevas comprobaciones de integridad sobre cada asset
IFoundationSettings:Id/Guidvacíos,Idduplicado dentro de un tipo de definición yGuidduplicado en todo el proyecto, las claves que usan los servicios de Serenity para resolver assets. Cada resultado incluye botón Ping, y agrupa validadores antes dispersos (Validate Installation / UI Theme Prefabs / Branding / Find FoundationSettings / Missing References) detrás de botones de lanzamiento de un clic en lugar de reimplementarlos. - Audición de audio dentro del editor — los inspectores de definiciones AudioClip y Music Track ahora tienen botones Play / Stop de previsualización (
SerenityEditorAudioPreview, un helper de editor compartido que usa elAudioUtilinterno de Unity mediante reflexión, tolerante a diferencias entre versiones y con fallos suaves), de modo que los diseñadores de audio pueden escuchar un clip o pista sin entrar en Play mode. - Validador de claves de localización (Tools ▸ Serenity ▸ Validate Localization Keys) — escanea todos los assets de Serenity en busca de claves de traducción, cualquier campo cuyo toggle
IsTranslating…esté activo — títulos de menús/modales, labels de opciones, texto de modales, valores de game-settings… — y valida cada clave contra las string tables de Unity Localization del proyecto, reportando claves faltantes, que en runtime caen silenciosamente al texto crudo, y campos vacíos marcados como traducibles, cada uno con botón Ping. El escaneo se basa en convención (IsTranslating<Field>→ campo hermano<Field>), por lo que cubre automáticamente cualquier futuro campo traducible. - Game Mode Music Binder —
GameModeMusicBinderComponent(Add Component ▸ Serenity ▸ Game Mode ▸ Game Mode Music Binder), la forma no-code de reproducir música distinta por game mode; anteriormente esto requería unEventDispatcherAction<GameModeChangedSignal>definido por código. Para cadaGameMode, un diseñador asigna un asset Signal Definition, normalmente una señalPlayMusicTrackcreada en el inspector de Signal Definition; al entrar en ese modo, el binder la despacha por la misma rutaDispatch(IEventDispatcherSignalDefinition)que usaSignalEmitterComponent. No construye ningún payload por sí mismo, de modo que funciona con cualquier tipo de señal. Se suscribe aGameModeChangedSignalmedianteServiceLocatorBridge, espera al servicio antes de enlazarse y se desuscribe al deshabilitarse. - Presets de botones de modal — el Modal Builder (Tools ▸ Serenity ▸ UI ▸ Modal Builder) ahora ofrece presets de un clic (OK · OK/Cancel · Yes/No · Confirm/Cancel) que rellenan las opciones del modal con botones SUBMIT, construidos exactamente como
ModalButtonToUiOptionConverter, sin señales todavía para que el diseñador solo tenga que cablear cada botón. Así, los diálogos comunes ya no empiezan desde una lista de botones vacía. - Cutscene Outline (Tools ▸ Serenity ▸ Cutscenes ▸ Cutscene Outline) — una vista outline + validador de solo lectura para assets
UnityCutsceneDefinition: lista las stages en orden con su tipo, duración y referencia clave (asset Timeline / color de fade), muestra el tiempo total de ejecución y marca problemas, especialmente una stagePlayTimelinesin Timeline asignado, que no reproduciría nada en runtime. Lee todo medianteSerializedObject, de modo que ofrece a diseñadores narrativos una vista no-code de “qué ocurre, en qué orden, y si falta algo” sin entrar en Play mode. Es la parte de previsualización estructural del roadmap de Cutscene preview; una previsualización Timeline en vivo y scrubbable queda para una incorporación posterior. - Scrubber de stages de cutscene — la ventana Cutscene Outline ha añadido una línea de tiempo con scrub: una barra proporcional de stages con un playhead arrastrable que resalta la stage activa en cualquier tiempo seleccionado, además de tiempos inicio-fin por stage y resaltado de la stage activa en la lista. Las stages
PlayTimelineusan la duración real de suPlayableAssetasignado para que el layout sea preciso. Esta es la parte a nivel de stage del “cutscene scrub” del roadmap; no reproduce el contenido del Timeline. Una previsualización conPlayableDirectorframe-accurate queda para una incorporación posterior. - Notificaciones Toast —
UnityToastComponent(Add Component ▸ Serenity ▸ UI ▸ Toast), una notificación no bloqueante que muestra un mensaje corto con fade in, lo mantiene y hace fade out. A diferencia de un modal, nunca roba el input. La visual se basa en un prefab asignado por el diseñador con unTMP_Text, por lo que los toasts heredan las fuentes/tema del proyecto; los toasts instanciados se parentan a un contenedor configurable — añade unVerticalLayoutGrouppara apilarlos — y se animan con tiempo no escalado, de modo que funcionan aunque el juego esté pausado. Se pueden disparar de forma totalmente no-code:Show(string)puede cablearse desde cualquierUnityEvent, como elonClickde un Button, una respuesta deSignalReactionComponentcon el mensaje escrito en el inspector, o un animation event. Así, “cuando ocurra la señal X, muestra el toast ‘Saved!’” no necesita ningún script. - Signal Flow Browser (Tools ▸ Serenity ▸ Events ▸ Signal Flow Browser) — una vista de solo lectura del grafo de eventos: para cada
EventDispatcherSignalmuestra quién la despacha (assets Signal Definition creados), qué la escucha (settings de modales) y qué reacciona a ella en código (actions[AutoRegisterEventAction]), todo con Ping y una caja de búsqueda. Los assets creados se descubren de forma genérica medianteSerializedObjecty las reacciones a partir del atributo + la baseEventDispatcherAction<T>, de modo que el cableado no-code de eventos, normalmente invisible, es navegable en un único lugar. - GameMode Overview (Tools ▸ Serenity ▸ GameMode ▸ Transition Overview) — una vista de solo lectura de un
UnityGameModeSettingsDefinition: una tarjeta por cadaGameModeque lista las señales despachadas al entrar y al salir, además de la configuración compartida de action-map/pausa y un recordatorio de que el servicio también despachaGameModeChangedSignal(previous → new)en cada transición. Lee mediante los accessors deIGameModeSettingsDefinition, por lo que siempre lista todos los modos, marcando los que no tienen cableado, y ofrece a los diseñadores una imagen no-code de “qué ocurre cuando se entra/sale de cada modo”. - Init Pipeline Overview (Tools ▸ Serenity ▸ Init ▸ Pipeline Overview) — una vista outline + validador de solo lectura para assets
UnityInitializationPipelineProfile: lista las tareas de arranque en orden de ejecución con su criticidad y peso, muestra la proporción de cada tarea en la barra de progreso y el peso total, y marca problemas, especialmente slots de tareas vacíos, que lanzarían una excepción durante el boot, e Ids vacíos. Lee medianteSerializedObject, de modo que los diseñadores pueden validar mentalmente el flujo de arranque y ver cuántas tareas críticas pueden detener el boot sin entrar en Play mode. Es la parte estructural del simulador de init pipeline del roadmap. - Init Pipeline Simulator (Tools ▸ Serenity ▸ Init ▸ Pipeline Simulator) — un simulador dry-run de arranque para assets
UnityInitializationPipelineProfile: marca las tareas que quieres hacer fallar y ejecuta Run para ver cómo se encadenan las reglas de criticidad. Un fallo crítico detiene el arranque y omite las tareas restantes, mientras que un fallo no crítico se registra y el arranque continúa. Muestra resultados por tarea (ok / failed / skipped) y una barra de progreso simulada que indica hasta dónde llega el boot. Modela el manejo de criticidad deInitializationPipelineService.RunAsyncsin ejecutar las tareas. Es la mitad dinámica del elemento Init Pipeline; la Overview de solo lectura es la mitad estructural. - Diagnostics overlay —
UnityDiagnosticsOverlayComponent(Add Component ▸ Serenity ▸ Debug ▸ Diagnostics Overlay), un HUD en pantalla para Play mode que muestra FPS / frame time, time scale, elGameModeactual y anterior con estado de pausa, y el número de jugadores unidos. Es un panel orientado a diseñadores para responder “¿qué está haciendo el juego ahora mismo?” ante las preguntas habituales de “¿por qué no funciona esto?”. Lee únicamente mediante interfaces de servicio (IGameModeServicevíaServiceLocatorBridge) y degrada a “n/a” cuando un servicio no está activo, se activa mediante una tecla configurable o métodos no-codeToggle()/Show()/Hide()cableables a un UnityEvent o input action, y se oculta en builds no-development salvo que se habilite explícitamente. - Player Join Overlay —
UnityPlayerJoinOverlayComponent(Add Component ▸ Serenity ▸ Debug ▸ Player Join Overlay), un panel en pantalla que lista los jugadores actualmente unidos mediante el Input System — índice de jugador, control scheme y dispositivos de cada slot — para que un diseñador pueda ver cómo ocurren las uniones de multijugador local durante las pruebas en lugar de leer la Console. Es autocontenido, lee únicamentePlayerInput.all, no usa servicios, se activa mediante una tecla configurable (por defecto F4, junto al F3 de Diagnostics Overlay) o métodos no-codeToggle()/Show()/Hide(), y se oculta en builds no-development salvo que se habilite. - Mixer Topology (Tools ▸ Serenity ▸ Audio ▸ Mixer Topology) — un diagrama visual de rutas de solo lectura para un
AudioMixery la configuración de sonido de Serenity: dibuja cada canal de audio de Serenity conectado a su mixer group con conectores en ángulo recto, marca los grupos cuyo volumen está expuesto y cuáles son effect-loop groups, y distribuye las fuentes de cada effect loop alimentando su loop group mediante sends. ReutilizaAudioMixerRelationshipScanner, por lo que se mantiene consistente con el Audio Channel Manager, pero es un viewer puro (“¿cómo se enruta mi audio?”) en lugar de una herramienta de análisis/reparación como el manager. - Autoría de audio posicional / 3D —
AudioPlayerClipahora contienespatialBlend,minDistance,maxDistance,spreadydopplerLevel, aplicados alAudioSourceen el momento de reproducción porUnityAudioPlayerService. Como son parámetros de constructor con sliders[FloatRange], son configurables sin código en el inspector de Signal Definition al construir una señalPlayAudioClip. Combinado con la posición de reproducción existenteAudioWorldPosition, un diseñador puede colocar y moldear un sonido 3D sin código. Cero regresión: los ajustes solo se aplican cuandospatialBlend > 0, de modo que los clips existentes, que por defecto tienen0= 2D, dejan intactos los min-max distance, spread y Doppler propios del AudioSource/prefab y se comportan exactamente como antes. - Componente de input rebinding —
UnityInputRebindComponent(Add Component ▸ Serenity ▸ Input ▸ Input Rebind), rebinding interactivo no-code para un único binding del Input System, el clásico row de settings “pulsa una tecla para reasignar”. Cablea un botón aStartRebind()y otro aResetBinding(); el texto del binding actual se emite mediante unUnityEvent<string>, que puedes cablear al settertextde un TMP/UI text, yonRebindStarted/onRebindStoppedcontrolan un prompt “Press any key…”. EnvuelvePerformInteractiveRebinding, deshabilitando la acción durante el rebind como requiere el Input System, y, cuandopersistestá activado, guarda los binding overrides del asset enPlayerPrefsy los recarga al habilitarse, de modo que los rebinds sobreviven a reinicios. Por defecto reasigna el binding del asset referenciado, pensado para un menú de settings single-player/shared-asset; habilitausePlayerInputpara multijugador local y reasignar la instancia de acción por jugador resuelta desde unPlayerInputpadre, persistiendo por índice de jugador. - Guía Designer Quick Start (
Assets/Documentation/DESIGNER_QUICKSTART.md) — un tour de onboarding no-code: checklist de primer arranque (los cuatro validadores), mapa de cada herramientaTools ▸ Serenityy cada componenteAdd Component ▸ Serenity, y recetas paso a paso (“mostrar un toast cuando ocurra algo”, “música distinta por game mode”, “permitir que los jugadores reasignen una tecla”, “¿por qué no funciona esto?”).
Cambiado
- Orden determinista de menús de editor — cada
[MenuItem("Tools/Serenity/…")]ahora lleva unapriorityexplícita (Setup 0–99, Project/Build 100–199, Authoring 200–299, Validate/Find 300–399, Docs 400+) y cada[CreateAssetMenu]lleva unorderdesde un esquema curado en bloques de 100, de modo que los menús contextuales de Serenity se renderizan igual en todas las máquinas en lugar de depender de un orden arbitrario de compilación. - Normalización de rutas de menú —
Serenity/Ui→Serenity/UI(UiTheme → UI Theme, CompositeView → Composite View) ySerenity/Settings/Unity UI Settings→Serenity/UI/UI Settings. Los assets existentes enlazan por GUID de script, por lo que los renombrados son seguros. - Inspector compartido de opciones — la
ReorderableListde opciones del menú se ha extraído a unUiOptionListInspectorGUIreutilizable, ahora usado tanto porUnityMenuSettingsDefinitionEditorcomo porUnityModalSettingsEditor, con UI idéntica para ValueType / UI Element / Id / Label / Value / Translate-Label + lista de señales por opción. - Renombrado del enum de value-type de opción —
UiComponentValueType.MENU_TRANSITION→TRANSITIONyMENU_ACTION→ACTION, sin cambiar los ordinales, por lo que los assets serializados se preservan. UnityModalController.Navigateahora tiene en cuenta la dirección: los modales HORIZONTAL navegan opciones con izquierda/derecha y editan valores con arriba/abajo; los modales VERTICAL mantienen la navegación previa con arriba/abajo y edición de valores con izquierda/derecha.
Features
- Los diálogos modales ahora pueden crearse con el mismo modelo avanzado, multiopción, scrollable y con layout horizontal o vertical que los menús, y pueden ejecutar una lista de señales por opción, no solo un botón confirmar/cancelar único en cada caso.
- Los flujos comunes de autoría ahora son herramientas de editor de un clic: crear la estructura de un modal (signal + action + settings), crear definiciones de game-settings con presets en vivo y cableado automático de servicios, importar SFX/música por lotes y gestionar canales de audio contra el mixer.
- Las etiquetas Addressables pueden reaplicarse a un subconjunto elegido manualmente de assets bajo cualquier carpeta, y las etiquetas legacy con forma de GUID pueden eliminarse en todo el proyecto.
Corregido
- El Directory Cloner ya no propaga etiquetas Addressables obsoletas con forma de GUID:
UpdateAddressablesEntriesomite etiquetas con apariencia de GUID al copiar las etiquetas de una entrada origen, y la nueva herramienta Remove GUID Labels limpia etiquetas dejadas por el comportamiento antiguo del cloner. - Se han resuelto varios bugs latentes preexistentes detectados al ampliar la cobertura de tests: setters
Id/Guidautorrecursivos deComponentLogger,TimerFormatterService.FormatTimeInSecondsusando un divisor/120en lugar de/3600para horas,AudioWorldPosition.ToStringformateando de forma no invariante yUnityGameSettingsOptionResolver.ResolveSelectablelanzando un NRE con un conjunto de opciones vacío, ahora protegido.
Infraestructura
- Cobertura automatizada de tests completa. Se añadieron tests de comportamiento en todos los módulos puros de Domain + Application, llevando la suite pura de 1.742 → 3.508 tests en verde; después se extendió a la capa testeable de glue Unity, unas 28 assemblies
Unity*, con ~1.130 nuevos tests PlayMode, y a los servicios de I/O de persistencia de archivos del sistema operativo, de 0% a cubiertos, llevando la suite PlayMode completa de 4.131 → 5.334 tests. Se resolvieron los 36 fallos PlayMode preexistentes, corrigiendo bugs reales y actualizando tests obsoletos. La cobertura también alcanzó la capa de herramientas de editor Unity (docfx / generators / importers / validators) en EditMode y los installers Unity, 15 módulos, en PlayMode. - Un harness NUnit standalone net8.0, con un shim de
UnityEngineque implementa aritmética real de Vector/Mathf, ejecuta toda la suite pura Domain + Application en menos de un segundo sin lanzar el editor de Unity ni requerir licencia: el bucle rápido de verificación que impulsó el trabajo de cobertura. - Se añadieron tests PlayMode para
UnityInputActionInvokerusandoInputTestFixturedel Input System (fases Performed / Started / Canceled, rutas standalone-asset y PlayerInput, múltiples métodos por acción, resiliencia ante métodos inválidos y detención de invocaciones al deshabilitar), el primer test basado enInputTestFixturedel repositorio. Se añadió la referenciaUnity.InputSystem.TestFrameworkaTests.asmdef, junto con las demás referencias cross-assembly que requería la nueva cobertura. - Se añadieron tests de lógica pura para las reglas de elegibilidad de reetiquetado Addressables / construcción de address y las invariantes de etiquetas GUID, el builder de opciones avanzadas de modales y la migración Buttons → Options, los writers del Game Settings Wizard y el analizador de relaciones de audio / planner de eliminación de canales.
- Se añadieron tests de
SignalReactionComponentconUnityEventDispatcherServicereal +ServiceLocatorBridge: una señal coincidente invoca la respuesta, un tipo de señal distinto no lo hace y al deshabilitarse se desuscribe.
1.1.1 — Vistas compuestas, menús horizontales, creación de señales desde el Inspector, previsualización de vistas, retorno a la puerta de entrada y controles de punto de inicio musical
Añadido
- Vistas compuestas — un sistema de composición de pantallas basado en flexbox.
UnityCompositeViewDefinition(Serenity/Ui/CompositeView) compone cualquier hijoIViewBase(menús o composiciones anidadas) en una única pantalla con tamaños por hijo al estilo CSS (Fixed px/Flex fr/Percent %/Auto, con mínimos/máximos), dirección Row/Column, alineación, padding y separación, y dos modos de contenido:STACK(todos los hijos visibles) ySWITCHER(un único hijo activo). Está respaldado por un servicio de dominio puroFlexboxSolvery un modelo de layout (LayoutDirection,LayoutSizeUnit,LayoutAlignment,LayoutScrollAxis,LayoutSize,LayoutPadding,LayoutConfig,ContainerContentMode). La dirección se lee en sentido de tabla/cuadrícula:ROW= bandas horizontales apiladas,COLUMN= columnas una al lado de la otra. - Alojamiento de menús dentro de composiciones — un menú puede renderizarse dentro de una región compuesta (
IHostableView). Cada slot compuesto que referencia un menú construye su propia instancia (UnityMenuService.CreateHostedInstance), desacoplando el id de enrutado por instancia del id de definición compartido, de modo que el mismo menú puede aparecer en varias regiones a la vez sin ser robado de su uso independiente. - Router de vistas —
IViewRouter/ViewRouter/IViewProvider(Global.Application). La pantalla inicial se movió fuera de la configuración del servicio de menús haciaIUiSettings.InitialViewId(un selector que acepta un menú o una composición). El router rastrea la vista superior actual, oculta automáticamente la anterior y muestra la vista inicial al arrancar y al volver desde el gameplay. Las transiciones de menú pasan a través de él (RouterMenuTransitionateToView). - Vistas con scroll —
Scrollable+ScrollAxisenUnityViewDefinition, con barras de scroll programáticas (UnityScrollbarBuilder). Los menús hacen scroll con una limitación deVisible Options Count(MenuScrollPolicy) y hacen auto-scroll para mantener visible la opción seleccionada. - Recorrido de foco entre menús — los menús apilados en una composición se pasan el foco de teclado/gamepad entre sí en sus límites (
ICrossMenuHost/IFocusableMenuView), con wrap-around opcional. El control de entrada sigue al hijo activo deSWITCHER(ICompositeViewService.GetActiveInputView). - Asistente Composite View Builder (Tools ▸ Serenity ▸ UI ▸ Composite View Builder) — permite escoger una plantilla paramétrica (N columnas, N filas, una única columna con scroll, navbar+contenido, navbar+columnas/filas, sidebar), nombrar las secciones y generar el árbol de
.assetde composición + menús con la navegación autoconectada (sin cableado manual de rutas::). La dirección de layout por sección y del navbar es seleccionable. - Herramienta View Preview (Tools ▸ Serenity ▸ UI ▸ View Preview) — una renderización en vivo, con tema aplicado, de un menú o composición construida desde las plantillas reales de prefabs del tema a una resolución de dispositivo elegida, además de un modo wireframe estructural. Incluye highlight de opción seleccionada, pruebas de hit por clic, zoom para encajar en la vista, localización en modo edición (etiquetas traducidas reales en lugar de claves sin procesar) y una imagen de fondo opcional.
- Menús horizontales —
MenuDirection(Vertical/Horizontal) en las definiciones de menú distribuye las opciones una al lado de la otra.HorizontalOptionWidthMode(Content/Uniform/Fill/Explicit) conHorizontalOptionWidthcontrola el ancho de columna;OptionsGapyVisible Options Countse aplican horizontalmente, con una barra de scroll horizontal. - Definiciones de despacho de señales creadas desde el Inspector —
UnityEventDispatcherSignalDefinition(Serenity/EventDispatcher/Signal Definition): permite escoger un tipo concreto deEventDispatcherSignal, elegir un constructor y rellenar sus parámetros por completo desde el Inspector;IEventDispatcherService.Dispatch(IEventDispatcherSignalDefinition)la construye y la emite. Soporta primitivos, tipos matemáticos de Unity, enums, referencias aUnityEngine.Object, parámetros de interfaz respaldados por ScriptableObject, parámetros DTO/value-object anidados recursivamente (hasta 6 niveles) y opcionales nullable. - Atributos de autoría para parámetros de señales —
FloatRangeAttribute(rango + slider porcentual + botón de reset),AssetPathReferenceAttribute(dibuja un campo de objeto asset para una ruta string) yFoundationIdReferenceAttribute(selector de id de settings). Aplicados aAudioPlayerClip(volumecomo slider 0–100%,panStereocon reset,filePathcomo campo AudioClip) yAudioPlayerPlayClipInput(serviceId). SignalEmitterComponent— un MonoBehaviour que contiene assets de definición de señal;Dispatch(id)/DispatchFirst()emiten una señal configurada desde callbacks de colisión/trigger, eventos de animación, input o cableado conUnityEvent. Los fallos se registran en log y se absorben para que el flujo de gameplay nunca se rompa.- Modo de rolloff de audio — enum de dominio agnóstico del motor
AudioRolloffMode(Logarithmic/Linear/Custom) másRolloffModeenAudioPlayerClip, controlando la atenuación 3D por distancia (los valores se mapean a Unity en el límite de infraestructura). - Señales OnCancel por vista — una lista de señales
OnCancelenIMenuSettingsDefinition/UnityMenuSettingsDefinition, creada mediante una lista reordenable en el Inspector, que se despacha cuando una entrada de cancelación llega a ese menú. - Retorno a la puerta de entrada primaria —
ReturnToPrimaryInputGateSignal. Creada en elOnCanceldel menú principal, desmonta el contexto de input del menú, desempareja el dispositivo (IPlayerInputService.ReleasePrimaryDevice→IUiInputRouter.Unpair) y rearma la puerta de selección de dispositivo para que un nuevo dispositivo pueda unirse. - Start From Loop Point —
StartFromLoopPointenUnityMusicTrackDefinition/IMusicTrackDefinition/MusicTrack. Cuando está activado, la primera reproducción de una pista empieza en el tiempo de inicio del loop en lugar de00:00:000, saltándose la intro. Se aplica a cualquier pista con región de loop — pistas con preservación de cola (la primera voz y su unión empiezan en el punto de loop) y pistas nativas/one-shot (cut/fade/cross-fade respetan el offset). La sección Loop del inspector de pistas musicales se rehizo: la región de loop permanece editable siempre que cualquiera de los toggles la consuma, y los controles de fade-out de cola quedan limitados al looping con preservación de cola. - Ignore If Already Playing —
IgnoreIfAlreadyPlayingenUnityAudioPlayerSettings/IAudioPlayerSettings. Cuando está activado, una solicitud para reproducir la canción que ya se está reproduciendo se ignora para que siga sonando sin interrupciones en lugar de reiniciarse de forma audible (music player). Por defecto está desactivado para preservar el comportamiento de reinicio permanente.
Cambiado
- La primera pantalla se configura en
UnityUiSettings.InitialViewId(menú o composición) en lugar de en la configuración del servicio de menús;InitMenuIdse retiró de la definición de configuración del servicio de menús. - Las herramientas de autoría de UI se agrupan bajo Tools ▸ Serenity ▸ UI (Composite View Builder, View Preview).
UnityMenuControllerenruta Navigate/Submit/Cancel a través de la vista de input compuesta activa cuando se muestra una, recurriendo al menú actual en caso contrario.
Funcionalidades
- Varios menús existentes y composiciones anidadas pueden componerse en una única pantalla (por ejemplo, una barra de navegación lateral + contenido de settings con scroll + región de detalle) con tamaños flexbox, scroll y recorrido de foco de teclado/gamepad entre regiones — creado visualmente con Composite View Builder y previsualizado en vivo en el editor.
- El mismo menú puede alojarse en varias regiones compuestas simultáneamente, cada una con su propio estado de selección/foco, mientras comparten el mismo game setting subyacente.
- Los menús pueden distribuirse horizontalmente con comportamiento seleccionable de ancho de columna y scroll horizontal.
- Creación y despacho de señales del event dispatcher — incluidas señales con parámetros DTO complejos anidados — completamente desde el Inspector, y activación desde la escena mediante
SignalEmitterComponent. - Una entrada de cancelación que ninguna opción consume ahora despacha las señales
OnCancelde la vista y después navega hacia atrás; las composiciones usan una vuelta atrás en dos niveles (cerrar la región de detalle abierta, o salir de toda la composición). Desde el menú principal, cancelar puede devolver al jugador a la puerta de selección de dispositivo de press-to-start.
Corregido
- La puerta de entrada primaria (prompt de selección de dispositivo) ahora completa la unión al soltar el botón en lugar de al pulsarlo, por lo que la pulsación de unión ya no se filtra al menú mostrado inmediatamente después de unirse (por ejemplo, enviando instantáneamente la opción enfocada). El latch de pulsación se reinicia si el dispositivo latcheado se desconecta mientras se mantiene pulsado, y la puerta se rearma limpiamente cuando se vuelve a mostrar.
- El enrutado de input de UI ahora aplica máscaras de esquema de control para que los bindings de un gamepad emparejado se resuelvan, y empareja teclado + ratón como una unidad cuando no están configurados para dividirse — corrigiendo que el input no llegara a la UI después de unirse con esos dispositivos.
SignalEmitterComponent(y cualquier otro consumidor deServiceLocatorBridgedel lado de Unity) ahora puede resolverIEventDispatcherServiceen runtime, por lo queDispatch(id)/DispatchFirst()emiten en lugar de registrar "no IEventDispatcherService is registered yet."UnitySerenityInstaller.RegisterServiceahora replica cada servicio dentro delIServiceLocatorde runtime (no solo en el contenedor de tiempo de inicialización), con semántica de sobrescritura donde el último gana, coincidiendo con la instalación dual deILogService.- Los clips de audio construidos desde una
IAudioPlayerClipDefinition(por ejemplo, una señalPlayAudioClipSignalcreada desde el Inspector y despachada medianteSignalEmitterComponent) ahora suenan de forma audible. El constructorAudioPlayerClip(IAudioPlayerClipDefinition, AudioPlayerType)anteriormente dejabavolumeypitchcon el valor por defecto de C#0, por lo que el clip se reproducía con volumen 0 / pitch 0 — silencioso, sin error. Ahora inicializa volumen, pitch, loop, pan, reverb mix y rolloff con los mismos valores por defecto que los demás constructores.
Infraestructura
- Añadidos tests para
FlexboxSolver,UiAnchorMapper, Composite View Builder + generador, navegación cruzada de composiciones / rutas de host / tamaños alojados, builders de layout y scrollbar, y la política de scroll de menús. - Añadidos tests para el builder de señales del event dispatcher y el flujo de despacho desde definición, parámetros de señal configurados, atributos de autoría de
AudioPlayerClip, la definiciónOnCancelde menú, la puerta de entrada primaria y el setter de routing-id del view-model. - Actualizadas las definiciones de ensamblado para las nuevas referencias entre capas introducidas por las composiciones, la preview/builder del editor, los menús horizontales y el editor de definiciones de señales.
- Añadidos tests para
MusicTrack.StartFromLoopPoint(por defecto y personalizado), valores por defecto de reproducción audible deAudioPlayerClipcuando se construye desde una definición, y extendido el test double de settings del audio-player con el miembroIgnoreIfAlreadyPlaying.
1.1.0 — Audio posicional y por prioridad, colas de loop musical, bucles de efectos de mixer, menús lazy y compuerta de input por GameMode
Breaking Changes
SpawnPoseya no expone los siete camposfloatplanos (PositionX/Y/Z,RotationX/Y/Z/W). Ahora está respaldado porPosition(System.Numerics.Vector3) yRotation(System.Numerics.Quaternion). La construcción no se ve afectada — el constructor de sietefloatyFromPosition(x, y, z)se mantienen — pero el código que leía los camposfloatindividuales ahora debe leerpose.Position.*/pose.Rotation.*.
Añadido
- Compuerta de input principal como GameMode — un valor
PrimaryInputGateen el enumGameModepermite que el prompt de input principal reutilice la maquinaria existente de señales de transición de entrada/salida por modo. El almacenamiento serializado, la recuperación y las listas reordenables de entrada/salida en el inspector se generan automáticamente para el nuevo modo. - Loops musicales conservando la cola —
StartTime,EndTime,TailPreservingLoop,TailFadeOutDurationyTailFadeOutCurveenIMusicTrackDefinition/MusicTrack/UnityMusicTrackDefinition. Una segunda voz transporta la cola de reverb/ambiente de la pasada anterior a través de la unión del loop, programada con precisión de muestra medianteAudioSettings.dspTime/PlayScheduled, de forma que el loop nunca produzca clicks. Los puntos de loop se definen como códigos de tiempoHH:MM:SS:MMMo en términos de DAW — tempo, compás, barra de inicio/fin — medianteMusicBarTimeCalculator; el fade de la cola sigue una curva Lineal/Exponencial/Logarítmica/S-Curve/Custom. - Reproducción de audio posicional — objeto de valor
AudioWorldPositionyPlaybackPositionopcional enAudioPlayerPlayClipInput; un clip reproducido con posición se reproduce en 3D en ese punto, y sin posición permanece en 2D. Funciona tanto desde una llamada directa al caso de uso como desde una señalPlayAudioClip, sin cambios en la firma del gateway/servicio. - Asignación por prioridad de sonidos — cuando el pool de
AudioSourceestá lleno, un clip puede tomar el control de un sonido en reproducción de menor prioridad en lugar de ser descartado. Esto se gobierna mediantePriority/PriorityPolicy/CanBeReplacedpor clip y unAudioPriorityCandidateSelector(AudioPriorityPolicy: IgnoreIfNoSourceAvailable / ReplaceLowerPriority / ReplaceLowerOrEqualPriority / AlwaysReplace). La semántica de prioridad de Serenity — cuanto más alto, más importante — se mapea a la prioridad invertida deAudioSource.priorityde Unity únicamente en el límite con Unity. - Herramienta de autoría de AudioMixer Effect Loop (
Tools ▸ Serenity ▸ Audio ▸ Create Audio Mixer Effect Loop) — crea un grupo de mixer con una cadenaReceive → effects → Attenuationy un asset reutilizableUnitySoundMixerEffectLoopDefinitionque lo describe. - Ventana de sincronización de Effect Loops (
Tools ▸ Serenity ▸ Audio ▸ Sync Effect Loops) — reconcilia elAudioMixerySoundMixerSettingscon las definiciones de effect-loop del proyecto: crea un Send por cada source hacia el Receive del loop, lo expone como{Source}_{Loop}_Sendy registra la definición. Es idempotente y aditiva. - Selección de grupos source en la herramienta de creación — permite elegir qué grupos hermanos alimentan el loop, con Select All / None.
- Scripts de acciones enable/disable autogenerados — para cada grupo source seleccionado, genera un par de acción/señal Enable + Disable de
EventDispatcher— reutilizando el generador compartido de scripts de acciones — ya preconfigurado para aplicar/limpiar el loop en ese grupo, escrito en una carpeta Events configurable. - Aplicar/limpiar effect-loops en runtime:
ISoundMixerService.ApplyEffectLoop/ClearEffectLoop,SoundMixerApplyEffectLoopSignal/SoundMixerClearEffectLoopSignal, sus casos de uso, DTOs solo de intención y unSoundMixerEffectLoopRouteResolverpuro e independiente del motor. UnitySoundMixerEffectLoopDefinition/UnitySoundMixerEffectLoopSourceScriptableObjects con inspector personalizado, además de un registroEffectLoopsenSoundMixerSettings.AudioMixerYamlReadersolo para editor — lee la estructura de.mixer— yAudioMixerEffectLoopReflectionAdapter— aísla la API internaUnityEditor.Audiodetrás de una única clase.- Modo de instanciación por menú —
MenuInstantiationMode(PreloadOnStartup/LazyOnFirstOpen) enIMenuSettingsDefinitionyUnityMenuSettingsDefinition, editable bajo una sección Advanced en el inspector de configuración del menú. - Pipeline de instanciación lazy de menús:
IMenuInstanceGate,MenuLifecycleResolver,EnsuringMenuTransitionateToView,UnityMenuLazyBuildContext,UnityMenuLazyRegistrationyIUnityMenuViewInstanceFactory/UnityMenuViewInstanceFactory. - Señales de transición de salida por modo —
IGameModeSettingsDefinition.GetExitSignalsForGameMode; el inspector de configuración de GameMode ahora muestra listas reordenables separadas de señales de entrada/salida por modo. - Pausa durante la carga de escena — ajuste
PauseDuringSceneLoadde GameMode — activado por defecto — con un toggle en el editor de settings, que congela el reloj del juego mientras se carga la escena aditiva de gameplay y lo restaura — mediantetry/finally— cuando finaliza la carga, evitando que los objetos recién instanciados simulen por detrás del overlay de carga. - Generación de configuración en la primera ejecución — en una instalación nueva, el idioma detectado del sistema operativo/navegador ahora se persiste en
gameSettings.cfgen el momento de la detección — standalone medianteUnitySystemConfigurationSnapshotStore; WebGL/ResourcesOnly medianteSerenityFallbackLocalizationService— protegido por una comprobación de existencia del archivo para preservar la preferencia guardada de jugadores que ya vuelven.
Cambiado
SpawnPoseahora está respaldado porSystem.NumericsVector3 Position+Quaternion Rotation— sustituyendo los sietefloatplanos —, siguiendo el patrón de objeto de valorRailNodePositionde GameRail; se mantiene como C# puro, sin dependencia del motor.UnityWaveServiceleepose.Position.*/pose.Rotation.*. Ver Breaking Changes.UnityAudioPlayerService.ApplyPlaybackPlacementahora es la única fuente de verdad paraAudioSource.spatialBlend— con posición →1y el emitter se mueve allí; sin posición →0y el emitter se deja en su sitio —;ApplyClipToSourceya no aplica el spatial blend del clip.UnityGameModeServicedespacha las señales del modo salido después deOnExitMode, reflejando el comportamiento existente de las señales de entrada; entrar enPrimaryInputGatedispara sus señales de entrada y salir de él dispara sus señales de salida mediante el mismo dispatch deSetMode.- El pause mixer effect loop ahora se controla mediante señales de entrada/salida de GameMode — Enable al entrar en Pause, Disable al salir de Pause — en lugar de clases de acción dedicadas.
UnityMenuServiceconstruye los menúsLazyOnFirstOpenal mostrarlos por primera vez — cacheados y reutilizados —; los menúsPreloadOnStartupsiguen siendo eager. Los menús iniciales y de pausa configurados como lazy se tratan como preload para evitar tirones en la primera apertura. El comportamiento por defecto no cambia —PreloadOnStartupsigue siendo el valor por defecto.UnitySoundMixerSettingsEditorahora lee los parámetros expuestos en vivo desde el AudioMixer en memoria — se actualiza automáticamente mientras editas, sin necesidad de guardar — y etiqueta la lista de definiciones registradas de forma diferenciada respecto al encabezado de la sección.- Las definiciones de effect-loop usan un único
DefaultWetnormalizado — dry es su complemento,1 - wet—, mostrado como un slider "Dry/Wet"; la herramienta de creación acepta carpetas de destino separadas para Media y Events. - El nivel de salida del loop se trata como un trim estático del mixer — no como un parámetro runtime expuesto —; el Send del source sigue el nivel actual del grupo source.
UnityYamlUtilsse mantuvo como helper YAML genérico — todo el conocimiento específico de AudioMixer YAML se movió al módulo SoundMixer.
Features
- El prompt de selección de dispositivo ahora es un GameMode observable (
PrimaryInputGate) que dispara efectos secundarios mediante señales de entrada/salida sin transicionar los modos de juego por sí mismo — al seleccionar dispositivo emiteOnPrimarySelectedy la composition root despachaEnterMenuSignal, permitiendo que la acciónEnterMenucambie el modo. - La música puede hacer loop entre puntos de inicio/fin definidos mientras una segunda voz transporta la cola de reverb de la pasada anterior a través de la unión, con un fade-out de cola acotado y definido por curva — una duración de
0corta limpiamente en el punto de loop. - Los sonidos pueden reproducirse en una posición del mundo — 3D — y pueden reclamar un slot ocupado del pool a un sonido de menor prioridad en lugar de ser descartados.
- Un effect loop puede ser creado, cableado, registrado y activado/desactivado desde gameplay — por ejemplo, un low-pass/reverb de pausa sobre Music — de extremo a extremo desde el editor, sin escribir a mano routing ni scripts de acciones.
- Los menús pueden optar por creación lazy en la primera apertura, reduciendo el trabajo de arranque, mientras se conserva el arranque eager para los menús que lo necesitan.
- Los modos de juego pueden ejecutar efectos secundarios mediante señales tanto al entrar como al salir de un modo.
Corregido
- Los cambios de valor de menú ahora se aplican a la opción que realmente ha cambiado — no a la actualmente seleccionada — y resuelven la opción seleccionada por su
GetIndex()lógico en lugar de por su posición en la jerarquía, corrigiendo valores de sliders entrelazados donde dos opciones compartían un mismoUiOptionValue— por ejemplo, master/ambient. ISoundMixerServiceahora está registrado en elServiceLocatorruntime, por lo que las acciones deEventDispatcherpueden resolverlo.- Los GUIDs de nivel de mezcla de Send por source se preasignan cuando se crea el Send, por lo que exponer el nivel de Send de cada source ahora funciona correctamente.
- Se eliminaron referencias
[SerializeReference]colgantes a tipos de señales de acción eliminados en assets de ejemplo — un tipo managed desconocido estaba anulando las otras señales válidas al entrar en Play.
Eliminado
- Clases redundantes
EnablePauseMixerEffectLoopAction/DisablePauseMixerEffectLoopActiony el asset de ejemploPauseEffectLoop— reemplazados por señales de salida de GameMode y el generador de scripts de acciones. - Un mapping erróneo de
SoundMixerSettings(Music_SucutruleLoop_Send→Audio_MasterVolume) que referenciaba un parámetro expuesto del mixer inexistente.
Infraestructura
- Añadidos tests para el route resolver de SoundMixer effect-loop, effect loop, installer, casos de uso y cobertura.
- Añadidos tests para el resolver de lifecycle de Menu, el caso de uso ensure-transition y el enum de modo de instanciación de menú.
- Añadidos tests para el music bar/time calculator, fade-curve evaluator y getters de music-track; audio world-position y placement; selección de candidatos por prioridad de audio y prioridad de clips; construcción de
SpawnPose; y las acciones/señales de primary-input-gate de GameMode.
1.0.12 — Soporte WebGL, tema Serenity y localización en runtime
Añadido
- Tema Serenity — un nuevo tema de UI completo con un conjunto completo de componentes (Background, Title, Label, Input, Dropdown, Selector, Slider, Toggle, Submit, Modal, PrimaryInputPrompt, Highlight), incluyendo animator controllers para el bucle de color del highlight y las transiciones de mostrar/ocultar modales.
- Soporte para builds WebGL — el primer target de compilación WebGL para Serenity.
- Herramientas de exportación de recursos para WebGL —
SerenityWebGLResourcesExporter,SerenityWebGLResourcesCleaner,SerenityWebGLResourcesValidator,SerenityWebGLResourcesPathsySerenityWebGLExportManifestpara exportar assets de Serenity al árbolResourcesdel consumidor para builds WebGL. - Fallback de localización en runtime —
SerenityFallbackLocalizationServicecarga JSON por cada par (tabla, locale) desdeResourcesy responde al nuevoILocalizationService.TryTranslate(key, out value), permitiendo traducción y cambio de idioma en vivo en modo ResourcesOnly (WebGL). - Barra de progreso de carga por tema — un slot
LoadingProgressTemplateen los componentes del tema de UI y una variante de prefabLoadingBarpara cada tema (Default, Alternative, Alternative2, Animated, Animated2, Futuristic, Serenity, Writings). - Enum
SerenityAssetLoadingModee interfaces/implementacionesIAssetLoadingModeProvider/UnitySerenityAssetLoadingModeProviderpara seleccionar cómo se cargan los assets (Addressables vs. solo Resources). - Evento
ILocalizationService.GameLanguageChanged, disparado cuando realmente cambia el valor del idioma. - Comando de menú en el editor (
Serenity ▸ UI ▸ Generate LoadingProgress Prefabs) que genera las variantes de prefab de barra de carga por tema y las conecta con las definiciones de tema. - Campo "Loading Progress Prefab" en el inspector de la definición del tema de UI.
- Familia tipográfica Inter (pesos variables y estáticos con assets SDF) e imágenes de soporte (
WhiteBackground,square-roundborder).
Cambiado
- El overlay de carga de gameplay ahora construye su barra de progreso a partir de
LoadingProgressTemplate, recurriendo aSlideableTemplatecuando no hay un prefab dedicado asignado. UnityUiTMP_TextLocalizationUpdaterComponentahora llama aTryTranslateen modo fallback, cachea la clave original de localización entre cambios de idioma y la vuelve a capturar cuando el texto mostrado difiere de la última traducción.UnityLocalizationServicemantieneGameLanguageChangedcomo no-op, delegando el refresco en la propia cadenaOnSelectedLocaleChangedde Unity Localization.- Corregido el comportamiento de
UnityPrimaryInputPromptViewpara builds WebGL. InitializationPipelineService,UnityCutscenePlayerService,ReflectionCallTask,AddressablesAssetLocator,UnityAddressableUtils,UnityAssetUtils,AudioMixerDependencyCacheyUnityMainThreadDispatcheractualizados para soportar carga solo mediante Resources y restricciones de WebGL.- El grupo Addressables de Serenity y la configuración de Addressables se actualizaron para registrar los nuevos assets.
Funcionalidades
- El modo ResourcesOnly ahora realiza traducción real y permite cambiar de idioma en runtime mediante el selector de idioma de la UI de ajustes.
- La exportación de Resources para WebGL utiliza semántica de movimiento durante la exportación y recurre al idioma del navegador como locale inicial.
- El JSON de localización se carga mediante un escaneo recursivo con
Resources.LoadAll<TextAsset>("")y un filtro de forma de string table, sin requerir acoplamiento con el asmdef deUnity.Localization.Editor.
Corregido
- Corregida la desaparición del selector de la barra de carga al salir el ratón, usando un prefab dedicado de progreso de carga en lugar de reutilizar la plantilla interactiva del slider.
- Corregidos los builds ResourcesOnly que anteriormente mostraban las claves de localización en pantalla sin forma de cambiar de idioma en runtime.
- Corregido el selector de idioma —cuyos valores son a su vez claves de localización— que traducía la clave cacheada obsoleta en lugar de la actual.
Infraestructura
- Añadidas herramientas de editor para exportación, limpieza, validación y seguimiento mediante manifest de Resources para WebGL.
- La exportación de localización basada en reflection evita el acoplamiento con el asmdef de
Unity.Localization.Editor. - Añadidos tests para los casos de uso de localización y el instalador de localización.
1.0.8 — Selectores de Editor, Autoetiquetado de Addressables y Validación de TMP Essentials
Añadido
SerenityTmpEssentialsValidator, un validador exclusivo de editor que detecta recursos esenciales de TextMeshPro ausentes e intenta importarlos automáticamente cuando es posible.- Protección en Play Mode ante TMP Essentials ausentes, cancelando la entrada en Play Mode antes de que puedan producirse errores de runtime de Unity/TMP.
- Diálogo manual de recuperación de TMP Essentials con opciones para abrir el importador de TMP, ignorar la advertencia durante la sesión actual o volver a comprobar.
- Postprocesador de importación de Serenity que programa una comprobación de TMP Essentials cada vez que se importan assets de Serenity en una sesión del editor de Unity ya abierta.
SerenityAddressablesAutoLabeler, un postprocesador exclusivo de editor que registra automáticamente los assets ScriptableObject de Serenity recién importados como Addressables.- Asignación automática de labels de Addressables para assets ScriptableObject de Serenity basada en mapeos exactos de tipo y reglas fallback por prefijo de namespace.
- Constantes
ModuleLabelscentralizadas para todas las labels de módulo y labels de tipo de Serenity. - Constantes
ModuleLabels.Typespara labels de Addressables basadas en tipo, como assets de fuente, imagen, audio y personaje. - Labels de módulo adicionales para los sistemas Character, GameMode, SequencePlayer y Wave.
- Combinaciones comunes de labels adicionales para GameSettings + Localization y GameSettings + UI.
- Helper
RenderIdObjectField<TAsset>(...)enFoundationEditorpara renderizar ObjectFields de Unity respaldados por ids serializados en string. EventDispatcherSignalTypePicker, un selector compartido con búsqueda para subtipos concretos deEventDispatcherSignal.EventDispatcherSignalTypeAdvancedDropdown, un selector con búsqueda basado enAdvancedDropdownpara campos string de tipos de señal.- Label de Addressables
module:game-mode. - Registro y etiquetado de Addressables para
GameModeSettings.
Cambiado
SerenityPackageDependencyInstallerahora considera TextMeshPro como satisfecho cuando los tipos runtime de TMP están disponibles, incluso sicom.unity.textmeshprono aparece listado como paquete independiente.- La detección de dependencias de TextMeshPro ahora soporta configuraciones de Unity 6 / UGUI 2.0+ donde TMP viene incluido con
com.unity.ugui. - Las cadenas de labels de Addressables ahora pasan por
Serenity.Shared.Constants.ModuleLabelsen lugar de literales string hardcodeados. InstallationConstants.ModuleLabelsahora actúa como shim de compatibilidad que reexporta los valores canónicos deModuleLabels.InstallationConstants.TypeLabelsahora actúa como shim de compatibilidad que reexportaModuleLabels.Types.UnityAddressablesLabelerahora usa constantes centralizadas deModuleLabelspara labels gestionadas, reglas de ruta y reglas de tipo.UnityAddressablesLabelerahora gestiona labels adicionales de Serenity para los módulos Character, GameMode, SequencePlayer y Wave.UnityAudioPlayerInstaller,UnityMusicPlayerInstaller,UnityGameSettingsInstaller,UnityLocalizationInstaller,UnityMenuInstaller,UnityModalInstaller,UnityPlayerInputInstaller,UnitySoundMixerInstaller,UnitySystemConfigurationInstaller,UnityCharacterInstallery los servicios relacionados con Cutscene/Sequence ahora usan constantes centralizadas de labels de módulo.AudioMixerDependencyCacheahora usa por defectoModuleLabels.AUDIO_MIXERen lugar de una label de Addressables hardcodeada.UnityUiSettingsEditorahora renderizaScaleKeyyFontSizeKeycomo ObjectFields de Unity respaldados por assetsUnityUIGameSettingsDefinition.UnityGameGraphicsSettingsEditorahora renderizaQualityLevelKey,ScreenResolutionKeyeIsFullScreenKeycomo ObjectFields de Unity respaldados por assetsUnityGraphicGameSettingsDefinition.UnityLocalizationSettingsEditorahora renderizaGameLanguageKeyyVoiceLanguageKeycomo ObjectFields de Unity respaldados por assetsUnityLocalizationGameSettingsDefinition.UnityMenuServiceSettingsDefinitionEditorahora renderizaInitMenuIdcomo un ObjectField de Unity respaldado por assetsUnityMenuSettingsDefinition.UnityGameModeSettingsDefinitionEditorahora renderizaPauseMenuIdcomo un ObjectField de Unity respaldado por assetsUnityMenuSettingsDefinition.UnityActionDefinitionEditorahora renderizaSignalmediante un selector de tipo de señal con búsqueda en lugar de un dropdown simple.UnityModalSettingsEditorahora renderizaSignalTypemediante un selector de tipo de señal con búsqueda en lugar de un dropdown simple.UnityModalSettingsEditorahora comparte el descubrimiento de tipos de señal medianteEventDispatcherSignalTypePicker, evitando lógica de reflexión duplicada.UnityMenuSettingsDefinitionEditorahora usa constantes centralizadas de labels de módulo al resolver game settings y menús.UnitySoundMixerSettingsEditorahora usa constantes centralizadas de labels de módulo al resolver game settings de audio.- Los assets de menú de ejemplo de Serenity se han reserializado para incluir valores
ViewIdexplícitos en opciones y valores. - Los assets de menú de ejemplo de Serenity ahora incluyen arrays
OnShowyOnHidevacíos explícitos. - El asset de ejemplo
GameModeSettingsahora incluye entradas de señales de transición para los valores más recientes del enum GameMode.
Funcionalidades
- Los assets ScriptableObject de Serenity recién creados ahora pueden añadirse automáticamente al grupo de Addressables de Serenity con las labels de módulo correctas.
- El autoetiquetado de Addressables ahora soporta mapeos exactos de tipo para assets conocidos de Serenity y fallback por namespace para futuros assets dentro de módulos existentes.
- Los selectores de editor para referencias ScriptableObject respaldadas por ids string ahora soportan drag-and-drop desde la ventana Project.
- Los selectores de editor para referencias ScriptableObject respaldadas por ids string ahora soportan el flujo de búsqueda estándar del Object Picker de Unity.
- Los campos de tipo de señal ahora ofrecen selección con búsqueda conservando los contratos string serializados originales.
UnityActionDefinition.Signalcontinúa almacenandoType.FullName.UnityModalSettings.SignalTypecontinúa almacenandoType.AssemblyQualifiedName.UnityModalSettings.SignalTypeconserva la opción<None>, almacenando un string vacío cuando no hay selección.- La validación de TMP Essentials se ejecuta tanto al iniciar/importar en el editor como de forma síncrona al entrar en Play Mode.
- La autoimportación de TMP Essentials intenta localizar el paquete mediante utilidades de editor de TMP, metadatos del Package Manager o
Library/PackageCache.
Mejorado
- La UX del Inspector ahora se acerca más a los flujos estándar de Unity para referencias respaldadas por assets.
- Se han reducido las selecciones inválidas accidentales provocadas por dropdowns largos sin búsqueda.
- Se ha reducido el código duplicado de dropdowns y reflexión en editores personalizados.
- La gestión de labels de Addressables ahora es más segura y fácil de mantener gracias a una única fuente de verdad.
- El autoetiquetado de Addressables es idempotente y no destructivo: no elimina labels existentes y solo añade labels conocidas de Serenity.
- La detección del paquete TMP es más robusta entre versiones de Unity.
- La detección de TMP Essentials ahora distingue entre que el runtime de TMP esté instalado y que los recursos esenciales de TMP estén realmente presentes en
Assets/. - Los diagnósticos de TMP Essentials ahora registran coincidencias de TMP font assets sin tratarlas como prueba de que Essentials esté instalado.
- El código de instaladores y editor ahora evita dispersar labels de Addressables hardcodeadas por el codebase.
- Las definiciones de assembly se han actualizado donde era necesario para que los módulos puedan referenciar las constantes compartidas de labels.
Corregido
- Corregida la detección falsa de dependencia ausente para TextMeshPro en versiones de Unity donde TMP viene incluido mediante UGUI en lugar de instalarse como
com.unity.textmeshpro. - Corregido el etiquetado ausente
module:game-modeparaGameModeSettings. - Corregidos varios campos de editor que antes requerían selección mediante dropdown aunque representaban ids respaldados por assets.
- Corregido que
UnityActionDefinition.SignalyUnityModalSettings.SignalTypesiguieran siendo dropdowns sin búsqueda tras la refactorización inicial del picker. - Corregida la lógica duplicada de descubrimiento de tipos de señal entre la selección de señales de modal y los menús de señales de botones de modal.
- Corregido el uso de labels de Addressables hardcodeadas en varios instaladores y utilidades de editor.
- Corregida la cobertura de labels gestionadas de Addressables para módulos más recientes de Serenity como Character, GameMode, SequencePlayer y Wave.
Infraestructura
- Añadidas utilidades de editor para el registro automático en Addressables y la asignación de labels.
- Añadidas utilidades de editor para la validación y recuperación de TMP Essentials.
- Añadida infraestructura compartida de editor para la selección de tipos de señal.
- Añadido helper compartido de editor para el puente entre ObjectField e ids string.
- Añadidas referencias de assembly definition a
Serenity.Shared.Constantsdonde ahora se usan constantes centralizadas de labels. - Actualizada la configuración de Addressables para eliminar labels obsoletas e incluir la nueva label
module:game-mode. - Actualizado el grupo de Addressables de Serenity para que
Media/GameMode/GameModeSettingsesté etiquetado conmodule:game-mode. - Actualizados los assets serializados de ejemplo para que coincidan con el modelo actual de datos de menús y game mode.
1.0.5 — Transiciones de Music Player, Señales de GameMode e Integración con Menú
Añadido
- Enum
MusicPlayerTransitionTypecon tres estrategias de transición:CUT,FADEIN_FADEOUTyCROSS_FADE. - Parámetros de transición configurables en
IMusicPlayerService.PlaySong(...)y nuevo métodoPlaySongById(...). - Caso de uso
MusicPlayerPlaySongByIdy DTOMusicPlayerPlaySongByIdInputpara reproducir pistas específicas por identificador con control explícito de loop y transición. - Método gateway
PlaySongByIdenIMusicPlayerGateway. - Contrato
SetGameModeService(IGameModeService)enIMenuServicepara coordinación entre servicios. - Contrato
GetSignalsForGameMode(GameModeEnum)enIGameModeSettingsDefinitionpara configuración de señales por modo. - Valores
InitializationyCutsceneal enumGameMode, estableciendoInitializationcomo modo inicial por defecto. - Secuencias de transición
EventDispatcherSignalpor modo enUnityGameModeSettingsDefinition. - Orquestación
DispatchModeTransitionSignals(...)enUnityGameModeServiceque lanza las señales configuradas después de cada cambio de modo. - Inspector completo basado en ReorderableList para señales de transición por modo en
UnityGameModeSettingsDefinitionEditor. - Registro de
ServiceLocatorparaIMusicPlayerServicedurante la instalación del music player.
Cambiado
UnityGameModeServiceahora se inicializa en modoInitializationen lugar deMenu, posponiendo la primera transición real de modo hasta que el sistema de menús esté listo.UnitySerenityInstaller.ShowMenu()ahora conecta elIGameModeServiceresuelto en el servicio de menú antes de invocarShowInitialMenu(), asegurando que el game mode esté sincronizado al arrancar.UnityMusicPlayerInstallerahora recibeServiceLocatorInstallerpara descubrimiento de servicios en runtime.- Formato de referencia de
Serenity.GameMode.Domain.asmdefestandarizado a GUID. - Nombres de assets listos para producción:
Audio_SoundToTest→Audio_SoundToTrigger,Audio_TrackToTest→Music_TrackList. - Configuración de
AudioTestingMenuactualizada para referenciar los assets de producción renombrados.
Funcionalidades
- La reproducción de música ahora impone una regla de una única pista activa mediante lerping de volumen basado en corrutinas.
- Las solicitudes de reproducción rápidas sustituyen de forma segura transiciones anteriores ("la última solicitud gana"), evitando audio sources huérfanas.
CROSS_FADEvuelve automáticamente aCUTcuando no hay suficientes canales de audio configurados.- Las señales de transición de GameMode se despachan en el orden exacto configurado en el inspector, saltando y registrando de forma segura las entradas nulas.
GameMode.Menuahora se afirma automáticamente cada vez que se ejecutaShowInitialMenu(), manteniendo sincronizados el sistema de menús y el estado de modo.
Mejorado
- El inspector de
UnityGameModeSettingsDefinitionEditorahora renderiza una lista de señales reordenable dedicada por cada valor deGameMode, con dropdowns de selección de subtipo y ordenación drag-and-drop. - Los elementos de la lista de señales muestran el nombre del subtipo concreto de
EventDispatcherSignalpara identificación rápida. - Las assembly definitions
Serenity.Menu.ApplicationySerenity.UnityMenu.Infrastructureahora referencian los contratos de GameMode para coordinación entre capas.
Corregido
- Prevenidas posibles transiciones recursivas de modo apoyándose en el short-circuit de
SetModecuando el modo objetivo coincide con el modo actual. - Actualizadas las firmas del stub del gateway de music player para mantener compatibilidad de interfaz con el nuevo contrato con soporte de transiciones.
Infraestructura
- Nuevas referencias de assembly definition añadidas para conectar capas de MusicPlayer, Menu y GameMode sin dependencias circulares.
- Assembly definition de tests ampliada para incluir
Serenity.UnityMusicPlayer.Installationy cubrir validación a nivel de instalador.
1.0.3 — Señales de Ciclo de Vida de Menú y Mejoras del Inspector
Añadido
- Añadidas colecciones de señales de ciclo de vida
OnShowyOnHideaUnityMenuSettingsDefinition. - Añadido soporte de señales de ciclo de vida de menú a
IMenuSettingsDefinition. - Añadido despacho runtime de señales de ciclo de vida para transiciones de visibilidad de menú.
- Añadido cableado de señales de ciclo de vida en
UnityMenuViewFactory. - Añadido soporte
SetLifecycleSignals(...)aUnityMenuView.
Funcionalidades
- Los menús ahora pueden despachar secuencias personalizadas de
EventDispatcherSignalcuando se muestran u ocultan. - El orden de ejecución de señales de ciclo de vida ahora sigue el orden exacto configurado en el inspector.
- Las colecciones de señales de ciclo de vida ahora soportan reordenación drag-and-drop mediante listas reordenables estándar de Unity.
Mejorado
- Mejorado
UnityMenuSettingsDefinitionEditorcon una sección dedicadaLifecycle Signals. - Las listas de señales de ciclo de vida ahora ofrecen:
- controles de añadir/eliminar,
- ordenación drag-and-drop,
- menús de selección de subtipo,
- estilo de inspector consistente con el resto de editores de Serenity.
- Mejorada la consistencia de UX del inspector reutilizando los mismos patrones de creación de señales ya presentes en otros sistemas de Serenity.
Corregido
- Corregido el renderizado del inspector de señales de ciclo de vida para que las implementaciones de
EventDispatcherSignalpuedan seleccionarse correctamente. - Corregido el flujo de serialización para señales polimórficas de ciclo de vida usando referencias gestionadas de Unity.
- Asegurado que los assets de menú legacy sigan funcionando de forma segura con colecciones de señales de ciclo de vida vacías.
Infraestructura
- Reutilizada la infraestructura existente de
EventDispatcherSignaly el flujo de despacho sin introducir sistemas paralelos de ciclo de vida. - Mantenidos intactos los límites de Clean Architecture exponiendo señales de ciclo de vida mediante abstracciones de solo lectura en la capa de negocio.
1.0.2 — Mejoras de Editor y del Inspector de Localización
Añadido
UnityLocalizationLocaleEditorUtils, un helper de editor basado en reflexión para descubrimiento seguro de locales de Unity Localization sin añadir carga de dependencia de assembly.
Cambiado
- Mejorado
LocalizationSettingsDefinitionEditorpara mejorar la UX de los assetsUnityLocalizationGameSettingsDefinition. - Reforzado el flujo de importación de Serenity y el proceso de recuperación de localization.
- Refactorizado el flujo de señales de botones del editor de modal settings para interacciones de editor más limpias.
Funcionalidades
- Bloqueado el campo
ValueTypeaSELECTABLEcon normalización automática y validación de seguridad para prevenir errores de configuración. - Sustituido el input de texto libre "Key" en la tabla de opciones por un dropdown dinámico poblado desde los locales de Unity Localization.
Mejorado
- Añadido soporte fallback para keys desconocidas y HelpBoxes informativos para guiar a los usuarios cuando los ajustes de Localization faltan o no están configurados.
- Estabilidad de inicialización del paquete tras importar Serenity en un proyecto Unity limpio.
Corregido
- Resolución del color de fondo del loading overlay cuando se usan cámaras de renderizado.
Infraestructura
- Reutilizadas las utilidades UI existentes de
FoundationEditoryUnityGameSettingsDefinitionEditorpara mantener consistencia visual y funcional.
1.0.0 — Lanzamiento Inicial
✨ Funcionalidades
Lógica de juego desacoplada sin dependencias de motor en las capas core. Todo el código de dominio y aplicación compila con noEngineReferences: true, garantizando que las reglas de negocio sean totalmente portables, testeables y libres de acoplamiento con Unity.
Sistema de persistencia extensible y por capas. Una jerarquía de almacenamiento unificada soporta key-value stores respaldados por PlayerPrefs, blob stores basados en archivos con escrituras atómicas y streams append-only, todo detrás de contratos intercambiables que pueden apuntar a archivos locales, servicios cloud o backends personalizados.
Precarga avanzada de assets con presupuestos de memoria. Un motor de prefetch sensible a prioridades, con expulsión LRU, presupuestos de memoria configurables, estrategias de ventana deslizante y bajo demanda, y resolución de labels basada en Addressables, proporciona disponibilidad predecible de assets con presión de recursos controlable.
Game settings tipados y persistidos por repositorio. Un sistema genérico de settings soporta tipos Boolean, Integer, Float y Selectable con notificaciones de cambio de valor, persistencia automática e integración reactiva con módulos de audio, gráficos y localización.
Gestión de personajes basada en estado. Los personajes siguen un ciclo de vida bien definido (Spawning → Active → Dying → Dead) con seguimiento de hit points, snapshots inmutables y puntos de extensión virtuales para especialización específica del juego.
Contador de combo agnóstico al juego. Un modelo puro de conteo con snapshots inmutables que no impone semántica de gameplay: timeout, multiplicador y lógica de puntuación siguen siendo responsabilidad de la capa consumidora.
Persistencia de checkpoints opaca. Slots de guardado con nombre y metadatos extensibles (timestamp, label, stage) almacenan payloads binarios arbitrarios sin interpretar ni validar su contenido, dejando la estrategia de serialización a los consumidores.
Pipeline de inicialización configurable. Un sistema de arranque ordenado por fases y tareas con seguimiento de progreso ponderado, criticidad por tarea (Critical vs. NonCritical) y políticas de ejecución conectables (secuencial o paralela por fase).
Sistema completo de animación procedural. Un motor de procedural expression basado en datos y keys soporta composición de poses por capas (oscilación, drift, ruido, impulso), animación de propiedades de material, animación de escala de transform, acciones discretas one-shot (flinch, recoil, stumble), activación basada en reglas con condiciones de histéresis y ajuste en tiempo real, todo completamente agnóstico al producto.
Sistema de eventos publish/subscribe type-safe. Un event dispatcher centralizado con acciones autoregistradas, clases de señal tipadas y descubrimiento basado en atributos permite comunicación desacoplada entre módulos.
Reproducción de audio multicategoría. Un sistema de audio enrutado por gateway soporta canales SFX, Music, Voice, Ambient, Environment y UI con pooling por categoría y configuración de clips guiada por settings.
Music player dedicado con soporte de crossfade. La gestión de música de fondo ofrece operaciones play, stop, fade-in, fade-out y crossfade de forma independiente del sistema de audio de formato corto.
Abstracción de audio mixer. Gestión de volumen y mute por grupos (Master, Music, SFX, Voice, UI) con persistencia automática mediante integración con game settings.
Gestión de ciclo de vida de stages. Un agregado stage de nivel superior rastrea estados de inicio, completado y fallo con notificaciones basadas en señales consumidas por módulos downstream como waves, timers y scoring.
Progresión secuencial de waves. Estructura stage wave-by-wave con detección automática de clear y señales encadenadas para wave start, wave cleared y all-waves-cleared.
Scoring dinámico multimétrica. Un modelo de puntuación sin límite direccionado por keys con nombre soporta registro runtime de métricas y operaciones aritméticas completas (add, subtract, multiply, divide, set, reset) con persistencia respaldada por repositorio.
Gestión del modo de aplicación. Un servicio de game mode coordina transiciones entre estados Menu, Game y Pause con estrategias de pausa conectables, cambio de action-map de input y coordinación basada en señales.
Seguimiento del ciclo de vida de sesión. Gestión de estado por sesión con fuentes de tiempo agnósticas al motor, acumulación de ticks frame-by-frame y snapshots inmutables de sesión.
Sistema de gestión de timers. Timers con nombre en modos countdown, elapsed y repeating proporcionan progreso normalizado, control pause/resume y notificaciones de ciclo de vida basadas en señales.
Navegación de menús con soporte de stack. Un sistema de menús basado en navigation stack soporta operaciones show, hide, push, pop y peek con configuración por menú y señales de ciclo de vida.
Sistema de diálogos modales. Diálogos modales configurables con factorías de botones, gestión de resultados basada en callbacks y señales preconstruidas para confirmaciones comunes (salir de la aplicación, reiniciar juego, resetear settings).
Fundación UI agnóstica a plataforma. Una jerarquía de vistas, sistema de theme/style y modelo de componentes permiten construcción UI componible sin dependencias de motor en la capa de dominio.
Gestión de estado de game UI. Modelos abstractos de estado para HUD y results-screen con delegación de renderizado mediante presenter-port permiten testear la lógica UI aislada de la infraestructura de renderizado.
Localización con integración de settings. Gestión de idioma de juego y voz con cambio automático de idioma impulsado por cambios persistentes en game settings.
Gestión de ajustes gráficos. Gestión reactiva de quality level, screen resolution y fullscreen mode impulsada por eventos de cambio de valor de game settings.
Detección de configuración del sistema. Consultas de capacidades de hardware (memoria, GPU, pantalla) con generación de perfil de calidad recomendado para configuración automática.
Modelo genérico de spawning y pooling. Creación y destrucción de entidades rastreadas por handle, con consultas de estado de pool, desacopladas de la mecánica de instanciación mediante un factory port.
Identidad de entidades de gameplay. Identidad de entidad basada en GUID con clasificación semántica (Player, Character, Hazard) proporciona un vocabulario de referencia compartido entre sistemas de gameplay.
Modelo de movimiento basado en rail. Rail paths con nombre y seguimiento de progreso normalizado permiten movimiento on-rails dirigido externamente sin acoplamiento a interpolación o easing.
Gestión de estado de armas. Mecánicas de trigger, cambio de fire-mode y seguimiento de magazine/ammo con snapshots de solo lectura, independientes de la representación visual o de sistemas de proyectiles.
Motor de orquestación de secuencias. Un sistema genérico de ejecución ordenada proporciona iteración de stages basada en completado, consumida por agregados verticales como el cutscene player.
Reproducción de cinemáticas. Ejecución temporizada de stages con tipos fade, timeline, wait y dialog construida sobre la base de orquestación de secuencias.
Logging estructurado con verbosidad por categoría. Un sistema de logging configurable con niveles de severidad, overrides por categoría, perfiles de enrutado de logs y component loggers consumidos por todos los módulos.
Navegación de view browser. Navegación forward/back entre pantallas con consultas de estado de navegación para flujos de browsing impulsados por UI.
Service locator mínimo. Un contrato de resolución de servicios respaldado por diccionario para casos estrechos donde la inyección por constructor no es práctica, por ejemplo acciones de evento instanciadas por reflexión.
Sistema de tareas componible. Contratos de unidades de trabajo asíncronas con niveles de criticidad, invocación de métodos basada en reflexión, resolución de argumentos sensible a servicios y soporte de despacho al main thread.
Persistencia basada en archivos con escrituras atómicas. Un file-system blob store con seguridad write-then-rename, resolución de rutas específica de plataforma y soporte de streams append-only.
🧱 Arquitectura
Aplicación estricta de Clean Architecture. Cada agregado sigue una estructura estricta Domain ← Application ← Installation con flechas de dependencia solo hacia dentro. Las capas Domain tienen cero o mínimas dependencias externas; las capas Application dependen únicamente de contratos de dominio y servicios fundacionales transversales; las capas Installation cablean implementaciones específicas de plataforma.
Aislamiento del motor mediante assembly definitions. Los assemblies core de negocio declaran noEngineReferences: true, garantizando enforcement en tiempo de compilación de que ninguna API de Unity se filtra en la lógica de dominio o aplicación.
Principios SOLID en todo el sistema. Agregados de responsabilidad única, contratos de servicio segregados por interfaz, extensión open/closed mediante instaladores abstractos y factory ports, e inversión de dependencias mediante interfaces agnósticas a plataforma.
Vocabulario Domain-Driven Design. Las entidades llevan estado mutable con transiciones protegidas, los value objects proporcionan identidad y snapshots inmutables, y los agregados definen bounded contexts con puntos de integración explícitos.
Diseño de API guiado por casos de uso. Las operaciones de cara al consumidor están encapsuladas en clases de caso de uso tipadas con DTOs de entrada dedicados, agrupadas en contenedores inyectables para grafos de dependencias limpios.
Patrón de snapshot inmutable. Todos los agregados con estado exponen snapshots de solo lectura para consultas, asegurando que los consumidores no puedan mutar accidentalmente el estado interno.
Patrón de instalador abstracto. Cada agregado define un instalador abstracto que declara el contrato de wiring; las capas concretas de plataforma (Unity, tests o targets personalizados) proporcionan implementaciones sin modificar el código de negocio.
Comunicación intermódulo basada en señales. Las señales de evento tipadas fluyen por un dispatcher centralizado, manteniendo los agregados desacoplados y permitiendo coordinación reactiva.
📦 Módulos
Global — Contratos fundacionales, eventos de ciclo de vida (exit/restart), jerarquía de interfaces de casos de uso, modelo de componentes para composición UI y la base abstracta de instalador consumida por todos los demás agregados.
EventDispatcher — Sistema de eventos publish/subscribe type-safe con acciones autoregistradas, clases de señal tipadas y descubrimiento basado en atributos.
Logging — Logging configurable con niveles de severidad, overrides de verbosidad por categoría, perfiles de enrutado de logs, component loggers y soporte de salida a archivo/consola.
ServiceLocator — Resolución mínima de servicios tipados con implementación por defecto respaldada por diccionario.
Task — Contratos de unidades de trabajo asíncronas con criticidad, invocación de métodos basada en reflexión y resolución extensible de argumentos.
InitializationPipeline — Sistema de arranque ordenado por fases y tareas con seguimiento de progreso ponderado, gestión de fallos basada en criticidad y políticas de ejecución conectables.
Persistence — Jerarquía de almacenamiento por capas: key-value stores, blob stores basados en streams y append-only stores, todo detrás de contratos de plataforma intercambiables.
FilePersistence — File-system blob store con seguridad de escritura atómica write-then-rename y resolución de rutas específica de plataforma.
PlayerPrefsPersistence — Key-value store ligero respaldado por Unity PlayerPrefs con codificación Base64.
GameSettings — Sistema de settings tipados (Boolean, Integer, Float, Selectable) con persistencia por repositorio y notificaciones de cambio de valor.
Checkpoint — Persistencia opaca de checkpoint binario con slots con nombre (Slot1–3, Auto, Quick) y metadatos extensibles.
Score — Modelo de scoring dinámico multimétrica con métricas ilimitadas por key, operaciones aritméticas completas y persistencia por repositorio.
Combo — Contador de combo agnóstico al juego con snapshots inmutables y puntos de extensión virtuales para multiplicador, timeout o comportamiento de decay.
Character — Ciclo de vida de personaje basado en estado (Spawning → Active → Dying → Dead) con gestión de hit points, enums de estado heredables y snapshots inmutables.
GameplayEntity — Identidad de entidad basada en GUID con clasificación semántica y referencias ligeras entre sistemas.
GameSpawner — Spawning de entidades y gestión de estado de pool rastreados por handle con un factory port para la estrategia de instanciación.
Stage — Ciclo de vida de stage de nivel superior (NotStarted → InProgress → Completed/Failed) con resolución de spawn points y contratos de autoría de rail paths.
Wave — Progresión secuencial de waves con detección automática de clear y señales de ciclo de vida encadenadas.
Timer — Gestión de timers con nombre en modos countdown, elapsed y repeating, progreso normalizado y señales de ciclo de vida.
GameMode — Máquina de estados de modo de aplicación (Menu, Game, Pause) con estrategias de pausa conectables y transiciones basadas en señales.
GameSession — Seguimiento de ciclo de vida por sesión con fuentes de tiempo agnósticas al motor y acumulación de tiempo transcurrido basada en ticks.
AudioPlayer — Reproducción de audio multicategoría con enrutado gateway, channel pooling y operaciones guiadas por casos de uso.
MusicPlayer — Gestión de música de fondo con operaciones play, stop, fade y crossfade.
SoundMixer — Gestión de volumen y mute por grupos con integración reactiva de game settings.
GameGraphics — Gestión reactiva de quality level, resolution y fullscreen impulsada por cambios en game settings.
SystemConfiguration — Detección de capacidades de hardware con generación de perfil de calidad recomendado.
PlayerInput — Abstracción de input agnóstica a plataforma con cambio de action-map y contratos de binding de input actions.
Ui — Jerarquía de vistas, sistema de theme/style y modelo de componentes para construcción UI componible e independiente del motor.
Menu — Sistema de menús basado en navigation stack con configuración por menú y señales de ciclo de vida.
Modal — Diálogos modales configurables con factorías de botones, resultados basados en callbacks y señales de confirmación preconstruidas.
GameUi — Gestión abstracta de estado de HUD y results-screen con delegación mediante presenter-port.
ViewBrowser — Navegación forward/back entre pantallas con consultas de estado.
Localization — Gestión de idioma de juego y voz con cambio automático de idioma impulsado por settings.
SequencePlayer — Motor genérico de orquestación de ejecución ordenada para iteración de stages basada en completado.
CutscenePlayer — Reproducción cinemática con stages temporizados (fade, timeline, wait, dialog) construida sobre la base de orquestación de secuencias.
GameRail — Registro de rail paths con nombre y seguimiento de progreso normalizado para movimiento on-rails.
GameWeapon — Mecánicas de trigger, cambio de fire-mode y seguimiento de magazine/ammo con snapshots de solo lectura.
ProceduralExpression — Sistema de animación procedural basado en datos con composición de poses por capas, animación de material/transform, activación basada en reglas, acciones discretas y soporte de ajuste en tiempo real.
Shared — Constantes transversales (nombres de servicio, labels de módulo, identificadores de contexto) y clases utilitarias (parseo, reflexión, generación de GUID).
🛠️ Tooling
Generador de documentación API basado en DocFX. Un builder de documentación integrado accesible desde Tools → Serenity → Docs compila todos los assemblies con documentación XML de Roslyn y genera un sitio API estático navegable mediante DocFX, con instalación automática, generación de configuración y soporte de plantilla con branding.
Herramienta de setup de Procedural Expression. Un wizard de setup de un clic (Tools → Serenity → Procedural Expression → Setup Minimal Idle) autodetecta huesos de esqueletos, genera todos los assets de configuración necesarios y conecta un perfil de animación procedural a cualquier prefab, soportando personajes riggeados, objetos simples, props y elementos UI.
Inspector de diagnósticos de Asset Prefetcher. Un inspector personalizado de Editor para el servicio de prefetch proporciona refresco de caché, limpieza, exportación al portapapeles, visualización de diagnósticos, polling de auto-refresco y visualización de categorías de assets con código de color.
Inspector de System Configuration. Un inspector personalizado para system configuration settings proporciona una interfaz completa para timing de recopilación de datos, scope y ajuste de heurísticas.
Inspectores de Menu y Modal. Inspectores personalizados de Editor para menu views y componentes modal proporcionan visualización de configuración de solo lectura, gestión de binding de señales e interfaces de configuración de botones.
Configuración basada en ScriptableObject. Prefetch policy profiles, procedural expression profiles, state keys, layers, actions, rules, audio settings, definiciones de game settings y localization tables se authoran como assets ScriptableObject, permitiendo configuración por no programadores y presets versionados.
Patrón de instalador abstracto para wiring de plataforma. Cada agregado define un instalador abstracto con dependencias explícitas; los instaladores concretos específicos de Unity gestionan creación de MonoBehaviours, integración con Addressables y registro en service locator.
Panel de debug de Procedural Expression. Una GUI overlay en runtime (activada con F12) muestra valores live de state-key con sliders con código de color, pistas de rango y controles de reset para ajuste en tiempo real en Play Mode.
Property drawers personalizados de Procedural Expression. Drawers de referencia de Bone ID con selección dropdown sensible al perfil, editores de reglas con configuración inline de condiciones y editores de perfil con validación y visualización de propiedades derivadas.
🎯 Propósito
Serenity existe para eliminar el boilerplate recurrente que acompaña a cada proyecto Unity: wiring de persistencia, gestión de settings, enrutado de audio, secuenciación de inicialización, transiciones de modo y fontanería de eventos. En lugar de proporcionar sistemas de gameplay opinados, ofrece la columna vertebral arquitectónica — contratos limpios, límites por capas y módulos componibles — sobre la que se construye el código específico de cada juego.
Al imponer aislamiento estricto del motor en las capas core, Serenity garantiza que la lógica de negocio siga siendo testeable fuera de Unity, portable entre plataformas y resistente a cambios en la API del motor. El patrón de instalador abstracto significa que cambiar un backend de persistencia o un sistema de input requiere implementar una única interfaz, no refactorizar un árbol de dependencias.
Cada módulo sigue las mismas convenciones estructurales: entidades de dominio con transiciones de estado protegidas, snapshots inmutables para consultas seguras, clases de casos de uso con entradas tipadas y puntos de integración basados en señales. Esta consistencia reduce el tiempo de onboarding y hace que los patrones entre módulos sean reconocibles de inmediato.
Serenity no es una plantilla de juego. No proporciona personajes, ni niveles, ni condiciones de victoria. Proporciona la base que hace que esos sistemas sean más limpios, más rápidos de construir y más fáciles de mantener durante toda la vida de un proyecto.
✨ Funcionalidades
Lógica de juego desacoplada sin dependencias del motor en las capas core. Todo el código de dominio y aplicación compila bajo
noEngineReferences: true, garantizando que las reglas de negocio sean completamente portables, testeables y libres de acoplamiento con Unity.Sistema de persistencia extensible y por capas. Una jerarquía unificada de almacenamiento da soporte a key-value stores (respaldados por PlayerPrefs), blob stores basados en archivos con escrituras atómicas y streams append-only, todo ello detrás de contratos intercambiables capaces de apuntar a archivos locales, servicios cloud o backends personalizados.
Precarga avanzada de assets con presupuestos de memoria. Un motor de prefetch consciente de prioridades, con expulsión LRU, presupuestos de memoria configurables, estrategias sliding-window y on-demand, y resolución de labels basada en Addressables proporciona disponibilidad predecible de assets con una presión de recursos controlable.
Game settings tipados y persistidos en repositorio. Un sistema genérico de configuración soporta tipos Boolean, Integer, Float y Selectable, con notificaciones de cambio de valor, persistencia automática e integración reactiva con los módulos de audio, gráficos y localización.
Gestión de personajes basada en estados. Los personajes siguen un ciclo de vida bien definido (
Spawning → Active → Dying → Dead) con seguimiento de puntos de vida, snapshots inmutables y puntos de extensión virtuales para especializaciones específicas del juego.Sistema de combos agnóstico del juego. Un modelo puro de conteo con snapshots inmutables que no impone semánticas de gameplay: el timeout, los multiplicadores y la lógica de puntuación quedan bajo responsabilidad de la capa consumidora.
Persistencia opaca de checkpoints. Slots de guardado con nombre y metadatos extensibles (
timestamp, etiqueta, etapa) almacenan payloads binarios arbitrarios sin interpretar ni validar su contenido, dejando la estrategia de serialización en manos del consumidor.Pipeline de inicialización configurable. Sistema de arranque basado en fases y tareas con seguimiento ponderado del progreso, criticidad por tarea (
CriticalvsNonCritical) y políticas de ejecución configurables (secuencial o paralela por fase).Sistema completo de animación procedural. Un motor procedural basado en datos y claves soporta composición de poses en capas (oscilación, drift, ruido, impulso), animación de propiedades de materiales, animación de escala de transforms, acciones discretas de un solo disparo (
flinch,recoil,stumble), activación basada en reglas con condiciones de histéresis y ajuste en tiempo real, todo completamente agnóstico al producto.Sistema de eventos publish/subscribe tipado. Un event dispatcher centralizado con acciones auto-registrables, clases de señales tipadas y descubrimiento basado en atributos permite una comunicación desacoplada entre módulos.
Reproducción de audio multi-categoría. Un sistema de audio con routing mediante gateways soporta canales SFX, Music, Voice, Ambient, Environment y UI, con pooling específico por categoría y configuración de clips basada en settings.
Reproductor de música dedicado con soporte crossfade. La gestión de música de fondo ofrece operaciones de play, stop, fade-in, fade-out y crossfade independientes del sistema de audio de corta duración.
Abstracción de audio mixer. Gestión de volumen y mute por grupos (
Master,Music,SFX,Voice,UI) con persistencia automática mediante integración con game settings.Gestión del ciclo de vida de stages. Un aggregate principal de stages realiza seguimiento de estados de inicio, completado y fallo mediante notificaciones basadas en señales consumidas por módulos descendentes como waves, timers y scoring.
Progresión secuencial de waves. Estructura wave-by-wave con detección automática de limpieza y señales en cascada para eventos de inicio de wave, wave completada y todas las waves completadas.
Sistema de puntuación multi-métrica dinámica. Un modelo de scoring ilimitado basado en claves soporta registro dinámico de métricas y operaciones aritméticas completas (
add,subtract,multiply,divide,set,reset) con persistencia respaldada por repositorio.Gestión de modos de aplicación. Un servicio de game modes coordina transiciones entre estados Menu, Game y Pause mediante estrategias de pausa configurables, cambio de action maps de input y coordinación basada en señales.
Seguimiento del ciclo de vida de sesiones. Gestión de estado por sesión con fuentes de tiempo agnósticas al motor, acumulación de ticks frame a frame y snapshots de sesión inmutables.
Sistema de temporizadores. Temporizadores con nombre compatibles con modos countdown, elapsed y repeating, proporcionando progreso normalizado, control de pausa/reanudación y notificaciones de ciclo de vida basadas en señales.
Navegación de menús con soporte stack. Un sistema de menús basado en stack de navegación soporta operaciones
show,hide,push,popypeek, con configuración específica por menú y señales de ciclo de vida.Sistema de diálogos modales. Diálogos modales configurables con factories de botones, manejo de resultados basado en callbacks y señales preconstruidas para confirmaciones comunes (salir de la aplicación, reiniciar juego, resetear settings).
Fundación UI agnóstica de plataforma. Una jerarquía de vistas, sistema de themes/styles y modelo de componentes permiten construir interfaces composables sin dependencias del motor en la capa de dominio.
Gestión del estado de la UI del juego. Modelos abstractos de HUD y pantallas de resultados con delegación de renderizado mediante presenter-port permiten testear lógica UI de forma aislada de la infraestructura de renderizado.
Localización integrada con game settings. Gestión del idioma del juego y de voces con cambio automático impulsado por cambios persistentes en los game settings.
Gestión de configuración gráfica. Gestión reactiva de niveles de calidad, resolución de pantalla y modo fullscreen impulsada por eventos de cambio de valor de game settings.
Detección de configuración del sistema. Consultas de capacidades hardware (memoria, GPU, display) con generación automática de perfiles de calidad recomendados.
Modelo genérico de spawning y pooling. Creación y destrucción de entidades con seguimiento mediante handles y consultas del estado del pool, desacopladas de la mecánica de instanciación mediante un factory port.
Identidad de entidades gameplay. Identidad basada en GUID con clasificación semántica (
Player,Character,Hazard) que proporciona un vocabulario compartido de referencias entre sistemas gameplay.Modelo de movimiento sobre raíles. Rails con nombre y seguimiento de progreso normalizado permiten movimiento on-rails impulsado externamente sin acoplamiento a lógica de interpolación o easing.
Gestión de estado de armas. Mecánicas de trigger, cambio de fire mode y seguimiento de cargadores y munición mediante snapshots de solo lectura, independientes de la representación visual o de los sistemas de proyectiles.
Motor de orquestación de secuencias. Un sistema genérico de ejecución ordenada proporciona iteración de stages basada en completado, consumida por aggregates verticales como el reproductor de cutscenes.
Reproducción de cutscenes cinematográficas. Ejecución temporal de stages con tipos fade, timeline, wait y dialog construidos sobre la base del motor de orquestación de secuencias.
Logging estructurado con verbosidad basada en categorías. Sistema configurable de logging con niveles de severidad, overrides por categoría, perfiles de routing y component loggers consumidos por todos los módulos.
Navegación View Browser. Navegación forward/back entre pantallas con consultas de estado orientadas a flujos UI.
Service Locator minimalista. Contrato de resolución de servicios basado en diccionario para casos concretos donde la inyección por constructor resulta impráctica (por ejemplo, acciones de eventos instanciadas mediante reflexión).
Sistema de tareas componible. Contratos de trabajo asíncrono con niveles de criticidad, invocación de métodos basada en reflexión, resolución de argumentos consciente de servicios y soporte de dispatching al hilo principal.
Persistencia basada en archivos con escrituras atómicas. Blob store basado en sistema de archivos con seguridad write-then-rename, resolución de rutas específica por plataforma y soporte para streams append-only.
🧱 Arquitectura
Aplicación estricta de Clean Architecture. Cada aggregate sigue una estructura estricta
Domain ← Application ← Installationcon dependencias únicamente hacia dentro. Las capas de dominio tienen cero o mínimas dependencias externas; las capas de aplicación dependen únicamente de contratos de dominio y servicios foundation transversales; las capas de instalación conectan implementaciones específicas de plataforma.Aislamiento del motor mediante assembly definitions. Los assemblies core de negocio declaran
noEngineReferences: true, garantizando a nivel de compilación que ninguna API de Unity se filtre hacia la lógica de dominio o aplicación.Principios SOLID de extremo a extremo. Aggregates de responsabilidad única, contratos de servicio segregados por interfaz, extensión open/closed mediante installers abstractos y factory ports, e inversión de dependencias mediante interfaces agnósticas de plataforma.
Vocabulario Domain-Driven Design. Las entidades contienen estado mutable con transiciones protegidas, los value objects proporcionan identidad y snapshots inmutables, y los aggregates definen bounded contexts con puntos de integración explícitos.
Diseño de API orientado a casos de uso. Las operaciones orientadas al consumidor se encapsulan en clases de casos de uso tipadas con DTOs de entrada dedicados, agrupadas en contenedores inyectables para mantener grafos de dependencias limpios.
Patrón de snapshots inmutables. Todos los aggregates con estado exponen snapshots de solo lectura para consultas, garantizando que los consumidores no puedan mutar accidentalmente el estado interno.
Patrón de installer abstracto. Cada aggregate define un installer abstracto que declara el contrato de wiring; las capas concretas de plataforma (Unity, tests o targets personalizados) proporcionan implementaciones sin modificar código de negocio.
Comunicación inter-módulo basada en señales. Las señales de eventos tipadas fluyen a través de un dispatcher centralizado, manteniendo desacoplados los aggregates mientras permiten coordinación reactiva.
📦 Módulos
Global — Contratos foundation, eventos de ciclo de vida (
exit/restart), jerarquía de interfaces de casos de uso, modelo de componentes para composición UI y base de installers abstractos consumida por todos los demás aggregates.EventDispatcher — Sistema de eventos publish/subscribe tipado con acciones auto-registrables, clases de señales tipadas y descubrimiento basado en atributos.
Logging — Sistema configurable de logging con niveles de severidad, overrides de verbosidad por categoría, perfiles de routing, component loggers y soporte de salida a archivo/consola.
ServiceLocator — Resolución mínima de servicios tipados con implementación por defecto basada en diccionario.
Task — Contratos de trabajo asíncrono con criticidad, invocación de métodos mediante reflexión y resolución extensible de argumentos.
InitializationPipeline — Sistema de arranque basado en fases y tareas con seguimiento ponderado del progreso, gestión de fallos basada en criticidad y políticas de ejecución configurables.
Persistence — Jerarquía de almacenamiento por capas: key-value stores, blob stores basados en streams y append-only stores, todo ello detrás de contratos de plataforma intercambiables.
FilePersistence — Blob store basado en sistema de archivos con seguridad write-then-rename y resolución de rutas específica por plataforma.
PlayerPrefsPersistence — Key-value store ligero respaldado por Unity PlayerPrefs con codificación Base64.
GameSettings — Sistema de settings tipados (
Boolean,Integer,Float,Selectable) con persistencia en repositorio y notificaciones de cambio de valor.Checkpoint — Persistencia opaca de checkpoints binarios con slots nombrados (
Slot1–3,Auto,Quick) y metadatos extensibles.Score — Modelo dinámico de scoring multi-métrica con métricas ilimitadas basadas en claves, operaciones aritméticas completas y persistencia en repositorio.
Combo — Sistema de combos agnóstico del juego con snapshots inmutables y puntos de extensión virtuales para multiplicadores, timeout o comportamiento de degradación.
Character — Ciclo de vida de personajes basado en estados (
Spawning → Active → Dying → Dead) con gestión de hit points, enums de estado heredables y snapshots inmutables.GameplayEntity — Identidad de entidades basada en GUID con clasificación semántica y referencias ligeras entre sistemas.
GameSpawner — Spawning de entidades con seguimiento mediante handles y gestión del estado del pool mediante un factory port para la estrategia de instanciación.
Stage — Ciclo de vida principal de stages (
NotStarted → InProgress → Completed/Failed) con resolución de spawn points y contratos de autoría de rail paths.Wave — Progresión secuencial de waves con detección automática de limpieza y señales de ciclo de vida en cascada.
Timer — Gestión de temporizadores con nombre compatibles con modos countdown, elapsed y repeating, con progreso normalizado y señales de ciclo de vida.
GameMode — Máquina de estados de modos de aplicación (
Menu,Game,Pause) con estrategias de pausa configurables y transiciones impulsadas por señales.GameSession — Seguimiento del ciclo de vida por sesión con fuentes de tiempo agnósticas al motor y acumulación de tiempo basada en ticks.
AudioPlayer — Reproducción de audio multi-categoría con routing mediante gateways, pooling de canales y operaciones orientadas a casos de uso.
MusicPlayer — Gestión de música de fondo con operaciones de play, stop, fade y crossfade.
SoundMixer — Gestión de volumen y mute por grupos con integración reactiva con game settings.
GameGraphics — Gestión reactiva de calidad, resolución y fullscreen impulsada por cambios en game settings.
SystemConfiguration — Detección de capacidades hardware con generación de perfiles de calidad recomendados.
PlayerInput — Abstracción de input agnóstica de plataforma con cambio de action maps y contratos de binding de acciones.
Ui — Jerarquía de vistas, sistema de themes/styles y modelo de componentes para construcción de UI composable e independiente del motor.
Menu — Sistema de menús basado en stack de navegación con configuración específica por menú y señales de ciclo de vida.
Modal — Diálogos modales configurables con factories de botones, resultados basados en callbacks y señales de confirmación preconstruidas.
GameUi — Gestión abstracta de HUD y pantallas de resultados mediante delegación presenter-port.
ViewBrowser — Navegación forward/back entre pantallas con consultas de estado.
Localization — Gestión del idioma del juego y de voces con cambio automático impulsado por settings.
SequencePlayer — Motor genérico de orquestación de ejecución ordenada para iteración de stages basada en completado.
CutscenePlayer — Reproducción cinematográfica con stages temporizados (
fade,timeline,wait,dialog) construidos sobre la base del motor de secuencias.GameRail — Registro de rail paths con nombre y seguimiento de progreso normalizado para movimiento on-rails.
GameWeapon — Mecánicas de trigger, cambio de fire mode y seguimiento de cargadores y munición mediante snapshots de solo lectura.
ProceduralExpression — Sistema de animación procedural basado en datos con composición de poses en capas, animación de materiales/transforms, activación basada en reglas, acciones discretas y soporte de ajuste en tiempo real.
Shared — Constantes transversales (
service names,module labels,context identifiers) y clases utilitarias (parsing,reflection, generación de GUIDs).
🛠️ Herramientas
Generador de documentación API basado en DocFX. Un generador de documentación integrado, accesible desde
Tools → Serenity → Docs, compila todos los assemblies utilizando documentación XML de Roslyn y genera un sitio estático navegable de la API mediante DocFX, con instalación automática, generación de configuración y soporte para templates personalizados con branding.Herramienta de configuración de Procedural Expression. Un asistente de configuración en un solo clic (
Tools → Serenity → Procedural Expression → Setup Minimal Idle) detecta automáticamente los huesos del esqueleto, genera todos los assets de configuración necesarios y conecta un perfil de animación procedural a cualquier prefab, dando soporte a personajes riggeados, objetos simples, props y elementos UI.Inspector de diagnóstico del Asset Prefetcher. Un inspector personalizado de Editor para el servicio de prefetch proporciona refresco de caché, limpieza, exportación al portapapeles, visualización de diagnósticos, polling con auto-refresh y visualización por colores de categorías de assets.
Inspector de configuración del sistema. Un inspector personalizado para settings de configuración del sistema proporciona una interfaz completa para controlar tiempos de recopilación de datos, alcance y ajuste de heurísticas.
Inspectores de Menu y Modal. Inspectores personalizados de Editor para vistas de menú y componentes modales proporcionan visualización de configuración en modo solo lectura, gestión de bindings de señales e interfaces de configuración de botones.
Configuración basada en ScriptableObjects. Los perfiles de políticas de prefetch, perfiles de procedural expression, state keys, layers, acciones, reglas, configuraciones de audio, definiciones de game settings y tablas de localización se crean como assets ScriptableObject, permitiendo configuración por parte de usuarios no programadores y presets versionables.
Patrón de installer abstracto para wiring de plataforma. Cada aggregate define un installer abstracto con dependencias explícitas; los installers concretos específicos de Unity gestionan la creación de MonoBehaviours, la integración con Addressables y el registro en el service locator.
Panel de depuración de Procedural Expression. Un overlay GUI en runtime (activable mediante F12) muestra valores live de state keys utilizando sliders codificados por color, indicadores de rango y controles de reset para realizar ajustes en tiempo real durante el Play Mode.
Custom property drawers de Procedural Expression. Drawers personalizados para referencias de Bone IDs con selección mediante dropdown consciente del perfil, editores de reglas con configuración inline de condiciones y editores de perfiles con validación y visualización de propiedades derivadas.
🎯 Propósito
Serenity existe para eliminar el boilerplate recurrente que acompaña a cualquier proyecto de Unity: wiring de persistencia, gestión de settings, routing de audio, secuenciación de inicialización, transiciones de modos y plumbing de eventos. En lugar de proporcionar sistemas gameplay cerrados u opinados, Serenity ofrece la columna vertebral arquitectónica — contratos limpios, límites por capas y módulos componibles — sobre la que se construye el código específico de cada juego.
Al imponer un aislamiento estricto del motor en las capas core, Serenity garantiza que la lógica de negocio siga siendo testeable fuera de Unity, portable entre plataformas y resistente a cambios en la API del motor. El patrón de installer abstracto permite sustituir un backend de persistencia o un sistema de input implementando una única interfaz, sin necesidad de refactorizar un árbol entero de dependencias.
Cada módulo sigue las mismas convenciones estructurales: entidades de dominio con transiciones de estado protegidas, snapshots inmutables para consultas seguras, clases de casos de uso con entradas tipadas y puntos de integración basados en señales. Esta consistencia reduce el tiempo de onboarding y hace que los patrones entre módulos sean reconocibles de inmediato.
Serenity no es una plantilla de juego. No proporciona personajes, niveles ni condiciones de victoria. Proporciona la base que hace que esos sistemas sean más limpios, más rápidos de construir y más fáciles de mantener a lo largo de toda la vida útil de un proyecto.
English
Español
Català