Registre de canvis

Últimes actualitzacions i millores de Serenity.

Tornar a l'inici

1.3.0 — Classificacions, desament de partides, HUD basat en dades i el nou Serenity Hub

Aquesta versió va de les dades dels teus jugadors: posar-les en pantalla i mantenir-les fora de perill. Un sistema de classificacions complet, un sistema de desament amb slots i progrés permanent, i un HUD configurable amb editor visual i el seu propi sistema d'animació — més suport de moviment del gamepad (giroscopi), el Serenity Hub reconstruït com a espai de treball amb cerca, i nous assistents que ho configuren tot sense tocar codi.

Afegit

  • Classificacions (mòdul nou) — una pila de rècords completa, de principi a fi. L'assistent de cinc passos Create Leaderboard (Tools ▸ Serenity ▸ Create ▸ Leaderboard ▸ Create Leaderboard) et guia: tria un preset («High Score», «Best Time»…), tria la puntuació que el teu joc ja registra, tria on viuen les dades — emmagatzematge del dispositiu, fitxers JSON llegibles, una base de dades SQLite incrustada, el teu propi servei HTTP o una connexió directa a Postgres/MySQL/MongoDB — i, si vols, obtén una pantalla de classificació llesta per navegar i connectada a un menú existent. El rànquing és determinista amb un tractament correcte dels empats, els 8 temes inclosos renderitzen la taula amb el seu propi llenguatge visual, i un backend mal configurat no trenca mai el joc: registra un avís i recorre a l'emmagatzematge del dispositiu.
  • Desament de partides i progrés permanent (dos mòduls nous)GameSave dona al teu joc un nombre configurable de slots de desament, cadascun un document extensible de seccions tipades (inventari, fites, finalització — més el que el teu joc registri). Els menús de slots mostren etiqueta, data i finalització a l'instant, sense carregar partides completes. GameProgress desa el que ha de sobreviure a l'esborrat d'un slot — comptadors de finalització, extres desbloquejats — perquè esborrar una partida no esborri mai el que el jugador s'ha guanyat. Els desaments ràpids de Checkpoint viatgen dins del slot actiu automàticament, el desament al núvol és una elecció de backend i no codi extra, i dos assistents (Create Game Save Settings, Create Game Progress Settings) ho configuren tot, backend inclòs.
  • HUD basat en dades amb editor visual — barres de vida, comptadors de munició, temporitzadors i qualsevol dada en viu, definits com a dades en lloc de scripts cablejats a mà. Els elements s'ancoren a nou posicions de pantalla amb direcció de creixement independent, es vinculen a dades de joc en viu i es dibuixen amb set representacions — text, número, temps (inclòs l'estil arcade MM'SS"CC), pila, segmentat, indicador i conjunt d'icones. Configura el jugador 1 i obtén el jugador 2 reflectit automàticament. HUD Builder guia el binding de dades perquè només es puguin configurar cadenes vàlides, i HUD Preview és una superfície d'edició real: arrossega per moure, estira els tiradors per escalar, gira a l'estil Photoshop, ajusta a la graella amb Ctrl — cada gest és un únic pas de desfer, a qualsevol resolució i tema. Un validador dedicat detecta els bindings trencats per canvis de nom abans que els teus jugadors vegin un element en blanc.
  • Els elements de HUD es nien i s'animen — els elements es poden agrupar en caixes de layout que ordenen els seus fills automàticament (espaiat, alineació, farciment), un número es pot dividir en una part entera gran i una part decimal petita, i tot s'anima amb quinze presets llestos per usar — Punch, Pulse, Heartbeat, Blink, Wiggle, Spin, Shake, Slide in, Fade in, Damage flash, Ghost pulse i més — que cobreixen escala, rotació, posició, visibilitat i color. Les animacions es disparen per canvis de valor, senyals o en mostrar-se, amb cooldown per entrada, tot definit a la nova pestanya Animation del builder i validat com tota la resta.
  • Animation Hub (Tools ▸ Serenity ▸ Browse ▸ Animation ▸ Animation Hub) — una única finestra amb cerca per a tota l'animació del projecte: clips incrustats en models, clips solts, animator controllers amb els seus estats i transicions, i l'animació procedural. Crea i edita clips i controllers allà mateix, previsualitza un clip en viu sobre el model real amb controls de reproducció i scrubbing, i simula perfils procedurals contra valors d'estat reals — sense tocar mai la teva escena ni els teus assets.
  • Suport de moviment del gamepad (giroscopi) — DualSense, DualShock 4 i Switch Pro exposen ara lectures de giroscopi i acceleròmetre, amb calibratge de deriva inclòs. El menú d'ajustos de Controls guanya les opcions Gyro Aim i Gyro Sensitivity, llestes perquè els teus jugadors les facin servir, i la nova finestra Gamepad Motion Monitor mostra els valors de moviment en viu per comandament connectat per afinar-los.
  • Puntuació, pujada de nivell — declara les mètriques de puntuació en un asset d'ajustos en lloc de registrar-les en codi (el nou assistent Score Settings el crea), alimenta una mètrica amb la distància recorreguda gràcies al nou component Transform Distance Meter, i atorga quantitats fixes des de qualsevol disparador amb la nova AddScoreSignal — tot sense codi. A més, Puntuació s'instal·la ara a través del Pipeline d'Inicialització com qualsevol altre sistema.
  • Les classificacions es troben amb el HUD, sense codi — mostra el número 1 d'una taula o el rècord personal del jugador local directament al HUD mitjançant serveis vinculables i un component de memòria cau del millor registre; envia la puntuació actual des de qualsevol disparador — un botó, una reacció a senyal — amb l'única crida SubmitNow() del nou component d'enviament; i renderitza qualsevol precisió decimal que la teva puntuació necessiti.
  • Finestra Database Drivers (Tools ▸ Serenity ▸ Validate ▸ Database Drivers) — triar un backend de base de dades real requereix DLLs de driver instal·lades a mà; aquesta finestra llista exactament quins fitxers necessita cada backend, marca els que ja estan instal·lats, enllaça cadascun que falta amb el seu paquet NuGet i versió exactes, i només ofereix activar el backend quan el conjunt és complet. S'ha acabat descobrir les dependències error a error.
  • El Serenity Hub, reconstruït des de zero — la porta d'entrada del paquet és ara un espai de treball complet: sis vistes (Home, Create, Validate, Browse, Advanced, Learn), una graella de targetes on cada eina mostra la seva icona i descripció, preferits i recents fixats a Home, i cerca global amb Ctrl+K entre les 89 eines. La validació ja no s'executa d'amagat: els resultats es desen en memòria cau amb la seva data, i els escaneigs només corren quan ho demanes.
  • AI Prompt Builder (Tools ▸ Serenity ▸ AI ▸ Prompt Builder) — un assistent que t'entrevista sobre el que vols construir i genera el prompt òptim per al teu agent d'IA. Escaneja el projecte perquè el prompt ampliï els teus assets reals en lloc de crear des de zero, manté una biblioteca personal d'instruccions reutilitzables i lliura el resultat al porta-retalls, un fitxer o directament al teu agent com a slash command. Les seves intencions inclouen ara una petició lliure — descriu el que sigui en llenguatge natural i el prompt dirigeix l'agent als mòduls correctes — i una intenció dedicada al disseny de HUD.
  • Assistent Add Language — afegeix un idioma a les teves taules de traducció existents en una sola passada guiada: graelles filtrables i paginades amb una columna d'idioma de referència per a context, connexió opcional amb els teus ajustos d'idioma i reversió atòmica si alguna cosa falla. No inventa mai claus noves.
  • Documentació amb la marca del teu joc — el lloc de documentació generat pren ara automàticament el títol, el text del logo, l'eslògan, el peu i el color d'accent dels teus Player Settings, i la nova finestra Docs Branding (Tools ▸ Serenity ▸ Docs ▸ Docs Branding) et deixa personalitzar-ho tot amb vista prèvia en viu.
  • Generador d'escena d'exemple (Tools ▸ Serenity ▸ Create ▸ Samples ▸ Generate Sample Scene) — genera l'escena de demostració sota demanda: canvas, HUD de diagnòstic, un host de toasts i un botó connectat per mostrar-ne un. Segur de tornar a executar.
  • Nous validadorsAddressable Keys detecta rutes d'asset desades que fallarien silenciosament en carregar en runtime, amb arranjament en un clic; Localization Keys guanya una vista prèvia d'idioma en viu i avisos per idioma per a claus que existeixen però encara no tenen traducció.
  • El Signal Flow Browser ara ho veu tot — emissors i reaccions de senyals col·locats en prefabs i escenes, definicions d'acció i senyals d'opcions de menú o modal apareixen com a emissors i reaccions. Un senyal disparat només des d'una opció de menú ja no figura erròniament com a «sense usar».

Millorat

  • Tots els selectors de senyal tenen cerca — els menús plans i interminables per triar un tipus de senyal se substitueixen per un desplegable amb cerca, a tot arreu.
  • Tots els assistents, una mateixa experiència — tots els assistents de creació comparteixen ara el mateix motor de passos, així que la barra de passos és navegable lliurement en tots dos sentits en tots ells: qualsevol pas ja visitat és a un clic.
  • Fire Now al Modal Builder — previsualitza el modal que estàs creant amb el mode Play en marxa, abans de crear cap asset.
  • Create Player Input pot crear l'asset d'Input Actions — l'assistent ofereix ara «Create New…» en lloc d'exigir un fitxer .inputactions existent.
  • Els raïls es poden vincular en runtimeBindRail(railService, railId) al seguidor i al conductor de raïl habilita raïls per instància, per exemple NPCs d'un pool seguint cadascun el seu propi camí.
  • Porta el teu propi backend de gallets adaptatius — registra un backend personalitzat des del teu propi codi (per exemple, un SDK de consola amb llicència) i sobreviurà a les actualitzacions del paquet; un backend que falla degrada amb elegància en lloc de trencar el feedback.
  • Els arguments del HUD Builder entenen el seu tipus — els ids de taula, les claus de puntuació i les seleccions de camps es mostren com a desplegables poblats des dels assets del teu propi projecte en lloc de camps de text lliure, i es refresquen en viu en afegir taules o mètriques.
  • Els sons posicionats se senten per defecte — un one-shot reproduït en una posició del món sense ajustos espacials propis rep ara una atenuació raonable en lloc de la d'Unity per defecte, que deixava un avís disparat a vint metres pràcticament inaudible.
  • Els camps de text de l'editor confirmen en fer clic fora — escriure un valor i prémer Create o Next ja no descarta l'edició que encara era al camp; escriure de manera sostinguda continua col·lapsant en un únic desament i un únic pas de desfer.
  • Un menú Tools més net — les eines internes de desenvolupament ja no apareixen al teu projecte.

Corregit

  • Els valors de temps amb hores es formaten ara com un rellotge: 3600 segons es mostra com a 1:00:00.
  • Totes les operacions d'Addressables corren ara al fil principal d'Unity, eliminant errors estranys i difícils de diagnosticar en entrar en mode Play mentre es carreguen assets durant l'arrencada.
  • Retag All (Plugin) ja no registra tipus de fitxer que la build d'Addressables no pot empaquetar, i ara a més neteja les entrades que ja no corresponen — executar-lo una vegada repara un projecte ja afectat.
  • Iniciar una onada ja no allibera actors del pool creats per altres sistemes a través del mateix servei.
  • Un Signal Emitter es pot connectar ara directament a l'On Click d'un botó (nous mètodes DispatchSignal usables des d'UnityEvents).
  • El camp de ruta d'asset de l'Inspector ja no trenca una adreça d'Addressables vàlida en editar-la.
  • Un gamepad amb una connexió que falla degrada ara a silenci en lloc de mostrar errors enmig de la partida.
  • Les actualitzacions del paquet són més resistents: un marcador de desenvolupament obsolet copiat per accident en un projecte de joc es detecta i es neteja automàticament, i la validació del projecte ja no reporta falsos errors de marca en projectes nets.
  • La documentació generada aplica ara el color d'accent configurat, i la seva pàgina d'inici ja no enllaça a una pàgina que no existeix en projectes de joc.
  • Sortir de la pausa mitjançant Resume, Back to menu o Restart notifica ara els oients de pausa exactament una vegada — res que segueixi l'estat de pausa mitjançant senyals no es queda ja encallat en pausa.
  • Llegir un ajust de joc BOOL amb un valor per defecte configurat ja no llança una excepció.
  • Rendiment: les assignacions de memòria per frame a la cadena del HUD i l'animació procedural es van reduir en uns dos terços, i va desaparèixer una estrebada causada per traces de diagnòstic durant les onades de spawns amb pooling.

Notes d'actualització

La majoria dels projectes s'actualitzen amb una importació de paquet normal. Si has estès Serenity, alguns canvis d'API poden necessitar un petit retoc:

  • Implementacions pròpies d'IServiceLocator han d'afegir el membre no genèric TryGet(Type, out object) — per a un locator basat en diccionari és una delegació d'una línia.
  • Implementacions pròpies d'IUiThemeComponents han d'afegir una propietat HudElementTemplate; retornar null és vàlid i simplement omet el tematitzat del HUD.
  • Subclasses pròpies del reproductor de seqüències que ramificaven sobre stage.StageType han de comparar stage.Kind (un string) en el seu lloc. Els assets de seqüència existents migren automàticament a la primera càrrega — sense passos manuals.
  • Perfils propis del pipeline d'inicialització han d'afegir les quatre noves tasques d'instal·lació (InstallScore i després InstallLeaderboard — abans d'InstallMenu — més InstallGameSave i InstallGameProgress), i els instal·ladors del joc haurien de resoldre IScoreService, ILeaderboardService, IGameSaveService i IGameProgressService de manera diferida, ja que ara es registren durant el pipeline.
  • El mòdul ProceduralExpression es diu ara ProceduralAnimator — actualitza les directives using Serenity.ProceduralExpression..., les referències d'asmdef als noms d'assemblat antics i qualsevol recepta o string de tipus serialitzat que anomeni el mòdul. Les escenes, prefabs i assets continuen resolent sense reimportar, perquè les identitats dels scripts es conserven.
  • Les subclasses pròpies de capes procedurals declaren quins canals escriuen mitjançant una única línia amb DrivenChannels, i RegisterTransformTarget rep ara un argument explícit allowPositionOverride.
  • Diversos tipus d'asset orientats a disseny generen ara un Guid intern estable a la primera càrrega — torna a desar aquests assets una vegada per persistir-lo.
  • Si la primeríssima importació de la 1.3.0 mostra «multiple assembly definition files»: elimina el fitxer .asmdef duplicat el GUID del .meta del qual no coincideix amb el del mateix nom inclòs al paquet, deixa que l'editor recompili, i l'autoneteja del paquet completa la resta automàticament. Només pot passar una vegada, a la importació que porta la correcció — les actualitzacions posteriors reconcilien mòduls i carpetes reanomenats per si soles.

1.2.2 — Actualitzacions de paquet automàtiques i sense residus: una sola importació, sense fitxers solts

Millorat

  • Actualitza en una sola importació — pujar a l'última versió de Serenity és ara una única importació neta. El paquet s'ordena a si mateix automàticament, de manera que els fitxers retirats en versions noves no es queden al teu projecte ni et molesten.
  • Procés d'actualització sense intervenció — l'actualització s'aplica discretament en segon pla i deixa tot el que has configurat exactament com estava, perquè obtinguis l'última versió de Serenity i tornis a crear de seguida.

Nota d'actualització

Actualitzar des de qualsevol versió anterior és una simple importació de paquet: sense esborrar carpetes a mà i, en el cas habitual, sense reinicis de l'editor.

1.2.1 — Service Extension Creator: Estén Qualsevol Cosa (Serveis, Stores, Repositoris, Gateways, Factories, Installers i les Teves Pròpies Classes) + Actualitzacions de Paquet Autonetejables + Porta de Preparació de Gameplay Opcional + Neteja de Deute Tècnic

Novetats

  • Service Extension Creator — un nou assistent (Tools ▸ Serenity ▸ Services ▸ Service Extension Creator) que genera codi llest per fer servir i completament connectat per estendre gairebé qualsevol cosa a Serenity: serveis, stores de persistència, repositoris, gateways, factories — i fins i tot les teves pròpies classes personalitzades. S'ha acabat el cablejat manual repetitiu per afegir la teva pròpia lògica sobre el framework.
  • Actualitzacions de paquet sense esforç — actualitzar Serenity ara és una simple importació única. El paquet es neteja sol automàticament, de manera que els fitxers antics o reanomenats de versions anteriors ja no queden solts causant conflictes.
  • Instal·lador de skills per a agents d'IA — una nova eina per instal·lar les skills dels assistents de codificació amb IA de Serenity directament al teu projecte, per a Claude Code, Cursor, GitHub Copilot i altres eines d'IA.

Millores

  • Pantalles de càrrega més fluides — la barra de progrés de càrrega ara anima de manera neta fins al 100% abans de mostrar el joc, en lloc de sentir-se abrupta en càrregues ràpides.
  • La porta de preparació de gameplay ara és opcional — els projectes que no necessiten esperar una configuració addicional de gameplay abans de mostrar un nivell ja no paguen cap retard de càrrega innecessari.
  • Pooling de so, sacsejada de càmera en pantalla dividida, alineació de menús i moviment sobre rails van rebre millores de polit i correcció internament.

Correccions

  • Els sons de mostrar/amagar de menús i modals ara es reprodueixen correctament.
  • Sortir enrere d'un menú ara reprodueix el so de "cancel·lar" correcte en lloc de l'equivocat.
  • Es van ajustar casos límit menors a la sessió de gameplay i a la recàrrega d'armes.

Neteja

  • Es va eliminar codi llegat sense ús i no funcional per mantenir el framework lleuger.

Nota d'actualització

Actualitzar des de qualsevol versió anterior ara és una simple importació de paquet — sense necessitat d'esborrar carpetes manualment ni reiniciar l'editor en el cas habitual.

1.2.0 — Sistema de Game Camera, Theme Builder, Setup Assistant, Serenity Hub, Safe Asset Delete, Preview de Cutscenes en Viu i Signal Flow Visual

Aquesta versió va de dues coses: portar-te d'un projecte buit a un joc funcionant més ràpid que mai (Serenity Hub, Setup Assistant, Theme Builder) i protegir el teu projecte mentre treballes (Safe Asset Delete, Validate Everything, previews en viu). A més inclou un mòdul de Game Camera completament nou amb pantalla dividida per a multijugador local, i tot el nucli de negoci de Serenity és ara agnòstic del motor: les regles del teu joc ja no depenen de tipus d'Unity.

Afegit

  • Sistema Game Camera (mòdul nou) — una capa completa de gestió de càmeres darrere d'un únic servei, IGameCameraService. Manté un registre de totes les càmeres del joc (autodescobertes en carregar l'escena, fins i tot les inactives o sense referenciar), canvia la càmera activa sense trencar els teus rigs — només es commuta el component Camera, mai el GameObject, així que un CinemachineBrain o qualsevol script germà continua funcionant — i et dona pantalla dividida per a multijugador local de sèrie, amb layouts de viewport automàtics que es recalculen quan els jugadors entren i surten. Registra càmeres sense codi amb UnityGameCameraRegistrar, o exclou-ne una del descobriment amb el marcador UnityGameCameraExclude.
  • Assistent Theme Builder (Tools ▸ Serenity ▸ UI ▸ Theme Builder) — un tema d'UI complet i llest per fer servir, creat des de zero en una sola passada. Tria tres colors, una font, un fons i un estil de selecció, i genera l'asset del tema més 20 prefabs (botons, sliders, dropdowns, toggles, etiquetes, barres de càrrega, modals, toasts i més) — incloses animacions generades de mostrar/amagar i de selecció amb presets None / Subtle / Elegant / Energetic i previews en viu. Tot queda auto-registrat a Addressables i es pot activar com el teu tema immediatament. Sense temes d'exemple, sense clonar res, sense cablejat manual.
  • Setup Assistant (Tools ▸ Serenity ▸ Setup Assistant) — d'un projecte buit a un bucle jugable d'arrencada → menú principal → gameplay → pausa en cinc passos guiats. Valida les teves eleccions en viu, mostra una preview real en mode dry-run abans d'escriure res, i cada asset que crea és idempotent: tornar-lo a executar mai no duplica la teva feina.
  • Serenity Hub (Tools ▸ Serenity ▸ Hub) — la porta d'entrada del paquet: un tauler d'estat dels paquets d'Unity requerits, el cablejat de l'instal·lador i la salut general del projecte, més un llançador categoritzat de les 50+ eines de Serenity. Cada fila enllaça directament amb l'eina real que ho arregla. S'obre automàticament en la primera importació.
  • Safe Asset Delete — esborrar un asset que altres assets encara referencien ja no deixa referències penjades en silenci. Una finestra de revisió llista cada asset afectat (fes-hi clic per inspeccionar-lo), i Delete & Clean elimina l'asset i neteja totes les referències obsoletes per tu, registrant exactament què s'ha netejat.
  • Signal Flow Browser, redissenyat com a diagrama visual — visualitza el teu flux d'esdeveniments com un diagrama de nodes que es llegeix causa → senyal → efecte, amb targetes per colors, xips de filtre (En ús / Sense ús / Dispatcher / Modal / Reacció), connexions ressaltades en fer clic i salt directe a l'asset o a l'script des de cada node. Trobar els senyals que el teu projecte ja no fa servir és ara un sol clic.
  • Preview de cutscenes en viu — el Cutscene Outline ara previsualitza la teva cutscene dins de la finestra de l'editor: arrossega per la línia de temps, prem play, i mira els fosos i les etapes de Timeline renderitzats a través de la pròpia càmera del rig — sense mode Play i sense tocar la teva escena oberta.
  • Validate Everything (Tools ▸ Serenity ▸ Validate Everything) — un tauler que agrega tots els validadors del projecte, inclosos dos de nous que cacen assets sense les seves etiquetes d'Addressables i definicions d'àudio absents dels seus registres — els clàssics forats de "per què no sona el meu so?". Les troballes amb arranjament tenen botons Fix d'un clic, amb confirmació indicant exactament què canviarà.
  • Checklists post-creació a l'Inspector — els assets de clips d'àudio i pistes de música ara mostren el seu estat d'etiquetatge a Addressables i de registre directament a l'Inspector, cadascun amb el seu arranjament d'un clic — així un registre que falta apareix mentre edites, no en runtime.
  • Estat de l'instal·lador d'un cop d'ull — l'inspector del Serenity Installer ara agrupa els seus camps en Required i Optional i mostra l'estat en viu sota cadascun: verd quan està assignat, vermell quan el joc no pot arrencar sense ell, groc quan deixar-lo buit desactiva una funcionalitat en silenci.
  • Autoria de waves més segura — el camp d'actor d'una entrada de spawn només accepta prefabs i avisa quan és buit, en lloc de deixar-te crear una wave que no genera res sense dir-t'ho.
  • Nucli agnòstic del motor — tota la capa de negoci de Serenity compila ara sense Unity. Les regles, ajustos i fluxos del teu joc s'escriuen contra contractes de C# pur: més fàcils de testejar avui, portables demà.

Corregit

  • El menú de pausa ja no roman visible darrere d'altres menús en navegar des de la pausa a una altra vista (per exemple, Opcions).
  • Quatre modals inclosos (End Game Session, Exit Application, Reset Settings, Restart Game) tenien les seves referències de senyal trencades en silenci per un reanomenament intern anterior; tornen a resoldre's i a ser visibles al Signal Flow Browser.
  • La validació de registre d'àudio ja no marca falsament tots els clips i pistes registrats, cosa que també restaura els botons Fix (register) d'un clic.
  • Els dropdowns generats per les eines de temes ara connecten correctament el seu valor seleccionat, inclosa la seva traducció en runtime.
  • Es van traduir a l'anglès diverses etiquetes de l'editor i missatges de log que quedaven en espanyol.

Actualitzar des de 1.1.x

Aquesta versió inclou canvis d'API incompatibles (per això és la 1.2.0). No cal caçar-los a mà: executa Tools ▸ Serenity ▸ Migration ▸ Migrate to 1.2.0 — escaneja el codi del teu projecte, mostra una preview abans/després de cada canvi amb caselles de verificació, i aplica només el que aprovis; allò ambigu es reporta en lloc de reescriure's, i tornar-lo a executar sempre és segur. El paquet inclou una guia d'actualització per als pocs casos manuals. Els assets de configuració de personatge existents necessiten un reetiquetatge i re-desat únic — Validate Everything assenyala cadascun i arregla les etiquetes per tu.

1.1.4 — Sistema de Feedback (Vibració, LED, Gallets Adaptatius, Screen Shake/Flash, Hit-Stop, Àudio), USB i Bluetooth a Linux + Sortida Bluetooth de Gamepads a Windows, Detecció de Monitors GNOME/KDE a Wayland, Cutscene Wizard, Cutscenes en Bucle, Triggers de Cutscene No-Code i Receptes Tipades de Cutscenes

Afegit

  • Sortida de gamepads Bluetooth a Linux (DualSense i DualShock 4) — la vibració, el LED i els gallets adaptatius ara controlen els comandaments per Bluetooth a més de per USB. Els writers raw-HID detecten el transport de cada comandament a partir del camp de bus HID_ID de hidraw i emeten el report que requereix aquest bus: per Bluetooth, reports reemmarcats amb checksum CRC32 (DualSense report id 0x31 amb una etiqueta de seqüència incremental; DualShock 4 report id 0x11); per USB, reports plans 0x02/0x05. El checksum el calcula un helper PlaystationHidChecksum: un CRC-32 reflectit sobre una llavor 0xA2 més el cos del report, coincidint amb el driver del kernel hid-playstation. El report 0x10 del Switch Pro és idèntic en tots dos busos. RawHidDevice exposa una consulta GetBusType i un enum HidBusType per seleccionar el transport.

  • Sortida Bluetooth de PlayStation a Windows (DualSense i DualShock 4) — la vibració i el LED ara controlen un DualSense o DualShock 4 per Bluetooth a Windows, cosa que abans no feia res: la sortida PlayStation integrada de Unity és inert per Bluetooth, i la ruta de Windows de Serenity només enviava el report USB mitjançant ExecuteCommand. Ara cada writer envia el mateix report Bluetooth que fa servir Linux (DualSense 0x31, DualShock 4 0x11, tots dos amb sufix CRC32) mitjançant un handle HID raw de Windows (RawHidDevice): USB continua fent servir ExecuteCommand, mentre que Bluetooth s’encamina pel GamepadHidrawTransport compartit. RawHidDevice a Windows va rebre tres correccions necessàries per a això: ara reconeix l’escriptura de ruta de dispositiu Bluetooth (vid&0002054c_pid&0ce6) a més de la USB (vid_054c&pid_0ce6); resol un comandament per serial o, quan el serial no apareix a la ruta, com passa per Bluetooth, per la coincidència VID/PID única i no ambigua; i omple cada escriptura fins al OutputReportByteLength del dispositiu, llegit una vegada amb HidP_GetCaps, perquè Windows ho requereix per a WriteFile HID. A més, el DualSense necessita un report únic RELEASE_LEDS abans del primer report de color, o la seva lightbar ignora el color i es queda en l’estat inicial d’encesa. La lightbar del DualShock 4 respon directament al seu byte de flags. Validat en hardware per Bluetooth amb tots dos comandaments. (L’entrada Bluetooth a Windows depèn del backend HID propi de Unity: funciona quan Windows acaba d’instal·lar la interfície HID del comandament; un aparellament a mitges mostra el controlador però no emet input, i se soluciona eliminant-lo i aparellant-lo de nou.)

  • Detecció de monitors GNOME i KDE a WaylandLinuxSystemMonitorsProvider detecta la distribució multi-monitor als principals compositors Wayland provant diversos backends per ordre de prioritat i fent servir el primer que retorna dades: swaymsg (wlroots/Sway), wlr-randr (altres compositors wlroots com Hyprland/river), kscreen-doctor -o (KDE Plasma / KWin) i el mètode D-Bus org.gnome.Mutter.DisplayConfig.GetCurrentState mitjançant gdbus (GNOME). Les sessions GNOME i KDE Wayland obtenen posició, resolució, taxa de refresc i flag de pantalla principal correctes per monitor. La identitat basada en EDID (fabricant/model/serial) s’obté des de /sys/class/drm per a tots els backends.

  • Sistema de Feedback — un nou mòdul per al game feel, amb un únic punt d’entrada orientat al consumidor: IFeedbackService (Serenity.Feedback.Application). Una peça de feedback és una definició —una llista d’efectes creada com un únic asset— que es reprodueix per id: Play("Hit") la dispara al comandament que ha actuat més recentment, i l’enable i la intensity globals viuen en un únic lloc (SetGlobalEnabled / SetGlobalIntensity, aplicats a cada impuls). El targeting és conscient del multijugador: la mateixa definició pot dirigir-se al comandament que ha actuat, a un jugador unit concret (PlayForPlayer), a un PlayerInput concret (PlayForPlayerInput) o a un dispositiu concret (PlayForDevice), i StopAll talla tots els canals i comandaments alhora. El nucli (definicions, efectes, matemàtiques d’intensitat i escalat) és independent del motor (Serenity.Feedback.Domain / Serenity.Feedback.Application, deliberadament sense tipus de UnityEngine); la part de Unity (Serenity.UnityFeedback.Infrastructure) proporciona els canals, la sortida de gamepad, la configuració i les eines d’editor.

  • Vuit efectes de feedback — una definició pot compondre qualsevol d’aquests efectes: Gamepad Vibration (motors duals de baixa/alta freqüència amb durada de manteniment), Gamepad LED (color de la lightbar del DualSense), Gamepad Adaptive Trigger (DualSense; mode Resistance, Weapon o Off, amb recorregut inicial/final i força), Screen Flash (flash de color a pantalla completa amb una envolvent alpha-over-time editable, en temps sense escalar per sobreviure a un hit-stop), Gameplay Hit Stop (breu caiguda de l’escala temporal en l’impacte), Screen Shake (Camera) i Screen Shake (UI) (shake posicional amb decaïment, en espai de món i espai de pantalla), i Audio (Sound): reproduir un so configurat, referenciant un UnityAudioPlayerClipDefinition, a través de l’audio player com a part del mateix cue, de manera que una sola definició dispari rumble + flash + so alhora. Els efectes s’editen des de l’inspector mitjançant blocs [SerializeReference] FeedbackEffectAuthoring —la capa que conté Color, [Range] i tooltips— i es converteixen a efectes purs; cada efecte el gestiona el seu propi canal, i cada impuls hàptic/visual s’escala per la intensitat global abans de sortir. L’àudio és l’excepció: és independent dels ajustos d’enable/intensity de vibració (sona fins i tot amb la vibració del controlador desactivada i el seu volum mai s’atenua), expressat mitjançant un opt-out BypassesGlobalGate per efecte en el contracte de l’efecte, perquè el servei apliqui la porta a cada efecte individualment en lloc de fer-ho a tota la definició.

  • Sortida de gamepad multiplataforma (DualSense / DualShock 4 / Switch Pro) — Serenity controla la vibració, el LED i els gallets adaptatius gestionant directament el report HID de sortida del controlador. El writer de DualSense porta vibració, color LED I tots dos gallets adaptatius en un únic report USB, de manera que una actualització de vibració o color ja no trepitja un efecte actiu de gallet (manté l’estat per dispositiu com a única font de veritat i reemet el report complet en cada canvi); el writer de DualShock 4 combina vibració i color de lightbar de la mateixa manera; i un servei de streaming per a Switch Pro controla la vibració HD i el LED del botó Home mitjançant un handle HID raw (la vibració del comandament no queda enganxada, així que s’emet en streaming a ~100 Hz en un fil en segon pla, amb la intensitat mapada mitjançant una corba perceptual). El feedback s’encamina al dispositiu que realment ha disparat l’acció mitjançant un tracker de dispositiu actiu, de manera que en multijugador local els efectes de cada jugador arriben al seu propi comandament, i els comandaments idèntics es desambigüen per serial.

  • Suport de gamepads a Linux — a Linux, el backend d’input de Unity no pot enviar reports HID de sortida, així que Serenity escriu reports de LED / vibració / gallets adaptatius directament al node /dev/hidrawN del controlador (la mateixa ruta que fa servir Switch Pro en tots els sistemes operatius), cobrint DualSense, DualShock 4 i Switch Pro tant per USB com per Bluetooth (la selecció de report per bus es detalla més amunt). Els botons frontals del Switch Pro també es mapen al backend SDL de Linux, que els exposa per etiqueta Nintendo en lloc de per posició física, de manera que buttonSouth = el botó físic inferior com a la resta de plataformes.

  • Trigger de feedback no-codePlayFeedbackSignal és el pont de l’event-dispatcher cap al servei: despatxa’l (per exemple des del SignalEmitterComponent no-code existent, o des de qualsevol EventDispatcherAction) amb un id de definició i un targeting opcional de jugador/dispositiu, i es reprodueix el feedback; així, “quan passi la senyal X, vibra / flasheja / shakeja” no necessita codi escrit a mà. Un ScriptableObject FeedbackDefinition (Serenity ▸ Feedback ▸ Feedback Definition) conté la llista d’efectes configurada, i s’inclou un exemple funcional StartGameFeedback (StartGameFeedbackAction reaccionant a StartGameFeedbackActionSignal) sota EXAMPLES.

  • Feedback de menú — la navegació de menú reprodueix feedback sense codi: es dispara una definició configurada quan canvia l’opció seleccionada (MenuTickDefinitionId) i quan s’envia una opció (MenuSubmitDefinitionId), totes dues llegides des de l’asset de configuració de feedback, de manera que els menús ofereixen resposta hàptica/visual amb comandament sense cablejat per menú (i romanen en silenci quan no es configuren valors per defecte).

  • Feedback Builder i inspectorsTools ▸ Serenity ▸ Feedback ▸ Create Feedback obre una finestra Feedback Builder que crea un FeedbackDefinition (tries efectes, configures els seus camps) i genera l’asset; l’inspector de FeedbackDefinition renderitza la llista d’efectes mitjançant una GUI dedicada de llista d’efectes (afegir / eliminar / reordenar blocs d’efectes), i un asset UnityFeedbackSettings (Serenity ▸ Feedback ▸ Settings) configura els valors globals per defecte, incloses les definicions de tick/submit de menú.

  • Trigger de feedback no-code des del builder + secció de recepta tipada feedbacksCreate Feedback ara també emet un UnityEventDispatcherSignalDefinition (<Name>Trigger.asset) precablejat per despatxar PlayFeedbackSignal per a la nova definició, de manera que un dissenyador el deixa anar en un SignalEmitterComponent i reprodueix el feedback amb zero codi i sense script generat (independent de, i en paral·lel a, la ruta existent Signal+Action; totes dues són ara toggles opcionals). FeedbackDefinition també passa a ser una secció de recepta feedbacks tipada de primer nivell (importer/exporter/template-generator/discovery), fent round-trip de la seva llista polimòrfica d’efectes [SerializeReference] mitjançant el codec compartit, amb un flag opcional generateTrigger que crea el mateix trigger no-code en importar. S’inclou un cookbook complet de l’agregat Feedback (Documentation/Cookbooks/Gameplay/Feedback.md, la plantilla de 12 seccions), i s’ha actualitzat el mapa de mòduls del README de Cookbooks + índex de SO, ConfiguringSerenitySystems, l’arrel de docs i el skill router serenity-cookbooks per encaminar Feedback.

  • Installer i cablejat DIUnitySerenityInstaller.InstallFeedback() registra el servei de feedback (UnityFeedbackInstaller, dependent dels serveis de game-settings i event-dispatcher) i s’executa des de la initialization pipeline d’arrencada (nova tasca InstallFeedback). El mòdul inclou la seva pròpia etiqueta Addressables (module:feedback) perquè els seus assets es carreguin en boot com qualsevol altre mòdul de Serenity. La sortida de gallets adaptatius és connectable darrere d’una interfície de backend: un backend HID de PC controla el DualSense per USB a escriptori, amb un backend PS5-SDK preparat com a scaffolding per a consola.

  • Cutscene Wizard (Tools ▸ Serenity ▸ Cutscenes ▸ Cutscene Wizard) — un builder IMGUI per passos per a cutscenes (Template → Stages → Rig → Trigger → Create), modelat a partir del Settings Wizard. Inicialitza la llista de stages des d’un preset (Splash FadeIn→Wait→FadeOut, Timeline cutscene FadeIn→PlayTimeline→FadeOut, o Blank), permet editar cada stage (tipus, durada, color de fade, Timeline) amb reordenar/afegir/eliminar, opcionalment crea un rig prefab (un GameObject amb PlayableDirector, playOnAwake desactivat) o n’assigna un d’existent, i en finalitzar registra el nou UnityCutsceneDefinition a UnityCutscenePlayerSettings.Definitions del projecte —trobant o creant aquest asset de settings—, cosa que tanca el buit silenciós de “he creat una cutscene però mai carrega perquè no s’ha afegit a la configuració”. La finestra (CreateCutsceneWindow) només recull input; un CutsceneCreator pur fa totes les mutacions d’assets amb rollback en cas de fallada (igual que ModalCreator / GameSettingCreator), i CutscenePresetLibrary conté les plantilles.

  • Generació de tasques de boot / init-pipeline — el pas Trigger del wizard també pot crear una UnityReflectionCallTaskDefinition Play{Name} que reprodueix la cutscene des de la initialization pipeline (la ruta de boot splash). Replica la tasca inclosa PlayCompanySplashScreen: una crida d’instància a UnityCutscenePlayerService.PlayAsync, resolveFromServices: true, l’Id de la cutscene com a únic argument string, amb criticitat Degradable perquè un splash fallit no aturi mai el boot. La tasca es crea al costat de la definició però no s’insereix automàticament en un perfil; afegeix-la a un UnityInitializationPipelineProfile després de InstallCutscenePlayer.

  • Trigger no-code per reproduir cutscenes — el pas Trigger opcional del wizard genera un {Name}ActionSignal + una {Name}Action [AutoRegisterEventAction] (mitjançant el mateix SerenityEventDispatcherActionScriptCreator que fa servir el Modal Builder, amb un cos Execute específic per a cutscenes a CutsceneTriggerScriptCreator). L’acció resol ICutscenePlayerService des de ServiceLocatorBridge —el servei ja està registrat al ServiceLocator per UnitySerenityInstaller.InstallCutscenePlayer— i llança PlayAsync(id) en fire-and-forget (segur: el servei limita cada stage i tota la cutscene amb timeouts durs de temps real). Després, un dissenyador despatxa la senyal generada amb el SignalEmitterComponent no-code existent, així que “quan es dispari la senyal X, reprodueix la cutscene Y” no necessita codi escrit a mà. Abans, les cutscenes no tenien trigger controlat per senyal: només injecció directa de ICutscenePlayerService.PlayAsync.

  • Cutscenes en bucleICutscenePlayerService guanya PlayLoopingAsync(id) / Stop(id) / IsPlaying(id): una cutscene pot executar-se ara com una seqüència persistent i en bucle de fons (fons de menú, escenes ambientals) en lloc d’una pipeline de stages one-shot. PlayLoopingAsync instancia el rig de la definició sota el servei de cutscenes (perquè sobrevisqui a càrregues d’escena), configura el PlayableDirector del rig en wrap mode Loop i retorna immediatament; és idempotent: reproduir de nou una key que ja està en bucle no fa res, mai duplica rigs. Stop destrueix el rig, i la reproducció en bucle evita deliberadament els timeouts per stage i de temps real de la pipeline one-shot (un bucle no té final per limitar). El pas Trigger del Cutscene Wizard ha rebut una opció Trigger kind: Play once (l’acció PlayAsync existent) o Play looping, que genera una parella senyal/acció Play{Name}Action i Stop{Name}Action perquè una cutscene en bucle pugui iniciar-se i aturar-se sense codi.

  • Creació automàtica de Timeline al Cutscene Wizard — un stage PlayTimeline pot marcar "Create a new Timeline for this stage" i el wizard crea un TimelineAsset buit al costat de la cutscene i l’assigna, a més d’inserir la Timeline del primer stage al PlayableDirector d’un rig acabat de crear perquè el rig s’obri llest per a authoring a la finestra Timeline (inofensiu en runtime: playOnAwake està desactivat i el servei reassigna per stage). Està protegit darrere d’un version define SERENITY_TIMELINE (com.unity.timeline a l’asmdef d’editor) perquè l’assembly compili quan el paquet Timeline no és present.

  • Secció de recepta tipada cutscenes — les cutscenes són ara una secció tipada de primer nivell d’una .serenity-recipe.json (com menus/modals/audioClips) en lloc de viatjar pel codec genèric assets. Un RecipeCutsceneDto conté id/output/rigPrefab i un stages[] ordenat (id, stageType —nom de CutsceneStageType—, duration, fadeColor com {r,g,b,a}, i timeline com a ruta de PlayableAsset). CutsceneRecipeImporter (descobert per reflexió, ordenat entre menus i modals) escriu els camps privats de stages mitjançant un SerializedObject i resol el rig/Timeline per ruta; CutsceneRecipeExporter els exporta de tornada. El template generator emet un stub realista FadeIn→PlayTimeline→FadeOut, el discovery registry exposa el vocabulari CutsceneStageType, i example.serenity-recipe.json guanya una cutscene d’exemple. Un stage PlayTimeline sense Timeline s’importa, però es reporta com a warning.

  • Documentació de cutscenes — el cookbook Cutscenes & Sequences (Documentation/Cookbooks/Narrative/CutscenesAndSequences.md) s’ha ampliat des d’un stub de camps fins a la plantilla completa de 12 seccions de l’agregat (model de domini + límits de timeout dur, les tres rutes d’authoring incl. el Wizard, la secció tipada de recepta, installer/DI + registre de servei, contracte de trigger no-code, contractes d’ID, exemple funcional, verificació i mapa de fonts). La referència de schema de receptes, la guia de generació d’assets per a IA, el README de docs i el catàleg de SO de Cookbooks s’han actualitzat per llistar la nova secció cutscenes i el Cutscene Wizard.

  • Consultes de jerarquia amb scope d’escenaUnityHierarchyUtils guanya cerca multi-root a nivell d’escena: GetSceneRoots, FindInSceneWithTag / FindAllInSceneWithTag, i FindInScene<T> / FindAllInScene<T>, cadascuna amb una sobrecàrrega que rep una Scene específica i una altra sense arguments que fa servir per defecte l’escena activa. Recorren tots els GameObject arrel de l’escena i inclouen objectes inactius: els escenaris que els helpers existents de cerca des d’una única arrel no cobrien.

  • Claude Code skills inclosos al paquet — Serenity ara inclou skills Claude Code orientades a LLM sota Assets/Serenity/Documentation/Skills/ (perquè viatgin dins del .unitypackage) més un instal·lador que les activa: Tools ▸ Serenity ▸ AI ▸ Install Claude Skills (SerenityClaudeSkillsInstaller) copia cada carpeta de skill inclosa a .claude/skills/ del projecte, que és on Claude Code realment descobreix skills. Un SKILL.md deixat sota Assets/ no fa res, perquè Claude Code només escaneja <project>/.claude/skills i ~/.claude/skills. El primer skill, serenity-cookbooks, és un router que obliga un agent IA a llegir l’Aggregate Cookbook del mòdul corresponent abans de crear o cablejar qualsevol sistema de Serenity (amb regles estrictes per extreure camps exactes del Project Recipe Template Generator i per reetiquetar Addressables + registrar àudio després de la importació). L’instal·lador omet fitxers .meta de Unity i viu a l’assembly existent Serenity.PackageBootstrapper.Editor al costat de l’exportador del paquet; la sortida regenerable d’instal·lació (.claude/skills/) s’ignora a git.

Canviat

  • El catàleg de SO de Cookbooks ara llista UnityCutsceneDefinition sota la secció tipada cutscenes (abans assets) amb el Cutscene Wizard com a eina d’authoring.

Corregit

  • L’emissor de senyals no es recuperava d’una cerca de servei massa primerencaSignalEmitterComponent marcava les seves cerques d’event-dispatcher i logger com a “resoltes” abans de comprovar que haguessin tingut èxit, així que un emissor que es disparava abans que boot acabés de registrar els serveis (per exemple, un esdeveniment d’animació de logo durant el splash) cachejava permanentment la cerca nul·la fallida; i com que SetActive(false/true) no reinicia camps privats, desactivar i reactivar l’objecte tampoc el recuperava: el trigger quedava silenciosament mort (warnings inclosos) durant tota la sessió. Ara el latch només s’estableix després d’una resolució correcta, de manera que el següent dispatch reintenta i recull el servei un cop registrat.

  • El prompt d’input primari ignorava Screen Shake (UI)UnityPrimaryInputPromptViewFactory creava el contenidor del prompt com un Transform pla, però UnityUiShakeReceiver només desplaça l’anchoredPosition de fills directes RectTransform del canvas arrel, així que el prompt d’input mai es movia durant un feedback de UI screen-shake. Ara el contenidor és un RectTransform full-stretch (ancorat per omplir el seu pare), cosa que a més el converteix en un element UGUI correcte segons l’especificació.

Infraestructura

  • Afegides les suites de test Serenity.Feedback (EditMode), que cobreixen el nucli independent del motor: clamping de FeedbackIntensity, escalat d’intensitat global amb FeedbackScaler, sortida Scaled per efecte i DTOs de feedback-target / definition-data. Esteses amb el contracte d’audio gating: AudioEffect reporta BypassesGlobalGate i Scaled el retorna sense canvis, mentre que els efectes hàptics romanen sota gate.

  • Afegit CutsceneRecipeRoundTripTest (EditMode) a la suite Serenity.ProjectRecipe.Tests.Editor: importar → comprovar la definició i els seus stages, exportar → comprovar el DTO, i un round trip export → reimportar en una nova arrel. Afegit un nou assembly només d’Editor Serenity.UnityCutscenePlayer.Installation.Editor per al wizard.

  • Afegits UnityHierarchyUtilsSceneTests, que cobreixen les noves consultes amb scope d’escena: enumeració només d’arrels, cerca per tag i component a través de múltiples arrels (hit i miss), objectes inactius i escenes buides/invàlides, tant contra una escena aïllada acabada de crear com contra l’escena activa per a les sobrecàrregues sense arguments.

1.1.3 — Menús en cascada, Toasts guiats pel tema i sistema de receptes de projecte focalitzat en generació amb IA

Afegit

  • Menús en cascada — un sistema de menús multi-columna amb navegació drill-down, on seleccionar una opció obre una subcolumna al seu costat. El model de navegació i builder agnòstics del motor viuen a Serenity.Menu.Application.Cascade (CascadeMenuModel, CascadeColumn, CascadeMenuPage, CascadeOption, ICascadeMenuContext); el costat Unity (Serenity.Menu.Infrastructure.Cascade) afegeix el renderer, un proxy de punter per a ratolí i tres definicions ScriptableObject: OptionsCascadeMenu (opcions estàtiques creades amb un [SerializeReference] OnSelectSignal per fulla), DynamicCascadeMenu i TargetCascadeMenu. UnityCascadeViewDefinition (Serenity/Menu/Cascade/Cascade View) converteix una cascada en un target de transició resoluble pel router com qualsevol composite view, de manera que una opció de menú pot transicionar-hi; es construeix sota el canvas mitjançant UnityCascadeViewFactory / UnityCascadeViewService (IViewProvider) / UnityCascadeViewInstaller, cablejat des de UnitySerenityInstaller.InstallCascadeViews(). DefaultCascadeMenuContext executa una cascada estàtica sense codi de joc: el senyal opcional d’una fulla es despatxa en resoldre’s i després la vista torna a qui l’ha oberta. ICascadeMenuContext.Dispatch + OptionsCascadeMenu.OptionDefinition.KeepOpenOnSelect permeten que una opció terminal dispari el seu senyal sense tancar la cascada.

  • Renderitzat de cascades amb tema — el menú en cascada es renderitza mitjançant un CascadeView.prefab creat pel dissenyador i específic de cada tema (un nou slot CascadeViewTemplate al tema, creat per als 8 temes a partir del fons + font de títol propis de cadascun), en lloc d’un panell procedural hardcodejat, de manera que coincideix amb el tema UI actiu. UnityCascadePanel proporciona slots de header + options-root, SetTitle/SetInteractable/SetOptions, ConfigureScroll i AdaptWidth. UnityCascadeViewDefinition substitueix PanelWidth per MinWidth/MaxWidth + VisibleOptionsCount. La cascada també reprodueix els IUiThemeSounds del tema en navegar / enviar / cancel·lar i suporta hover de ratolí per enfocar + click per seleccionar.

  • Widgets Serenity UISerenityButton, SerenityGauge, SerenityImage, SerenityLabel, SerenityStatusPanel i SerenityUiContext, wrappers runtime sobre els components UI tematitzats.

  • Sistema Project Recipe — permet crear contingut de Serenity com a fitxers .serenity-recipe.json llegibles per humans i convertir-los en ScriptableObjects reals mitjançant l’API de l’Editor de Unity, sense escriure a mà .asset/.meta/GUIDs. L’importer fa create/update idempotent amb Validate / Dry-Run / Import, cobrint seccions tipades (audioClips / musicTracks / menus / modals) i un codec genèric SerializedObject. L’exporter converteix un projecte existent de nou en una recepta. El template generator emet la plantilla base de recepta exacta i sense drift per a qualsevol SO autorable.

  • Notificacions toast guiades pel temaUnityToastComponent, una notificació transitòria i no bloquejant que instancia un missatge curt, el manté i l’elimina. La visual és el prefab de toast del tema actiu, cablejat en un nou slot ToastTemplate de l’UI theme, de manera que els toasts hereten les fonts i l’aspecte del projecte. Es pot disparar sense codi mitjançant Show(string), ShowToastSignal i UnityToastSignalReactionComponent.

  • Inspector de Cutscene Player SettingsUnityCutscenePlayerSettingsEditor permet que l’asset de settings del cutscene-player mostri l’inspector estàndard de Serenity en lloc de l’inspector per defecte de Unity, i omple l’Id/Guid buit de l’asset.

  • Import → press Play — serveis de projecte auto-registrables + Addressables extensibles per projecte. [AutoRegisterService] permet que els serveis d’un joc s’auto-registrin sense bootstrap MonoBehaviour a l’escena. [SerenityAddressable("label")] permet que un tipus ScriptableObject de projecte entri a l’auto-labeler i es carregui en arrencar sense referències cablejades a mà a l’Inspector.

  • Validació de projecte headlessValidate Project (JSON) executa els validadors Health Check, Missing References i Localization Keys, i emet els resultats com a JSON perquè un agent IA o CI pugui verificar que el projecte està correctament cablejat. L’exit code és 1 quan hi ha errors i 0 quan només hi ha warnings o no hi ha problemes.

  • Registre de discoverabilityProject Recipe Registry genera un bolcat machine-readable de senyals, action ids, reaccions de codi, tipus ScriptableObject autorables, vocabularis enum, seccions de recepta i contractes semàntics d’ID, perquè un agent IA pugui referenciar valors reals en lloc d’inventar-los.

  • Importació headless de receptes + informe machine-readableSerenityRecipeEngine.ImportFromCommandLine executa Validate / Dry-Run / Import sense GUI d’editor i escriu el resultat com a JSON mitjançant SerenityRecipeReport.ToJson(). Això permet tancar el cicle author → validate → import → read-result → retry sense intervenció humana.

  • Cablejat tipat de senyals de menú/modal en receptes — les seccions menus/modals ara cablegen directament EventDispatcherSignals [SerializeReference]: submitSignals[] per opció, onShow, onHide, onCancel i onSubmit. RecipeSignalDto i RecipeSignalCodec permeten descriure, aplicar, capturar i exportar senyals, incloent-hi senyals amb payload.

  • Secció de localització en receptes — la secció localization d’una .serenity-recipe.json ara genera contingut real de Unity Localization: assegura locales, crea o troba la String Table Collection i fa upsert d’entrades inline key/value. El motor principal de receptes no guanya dependència directa del paquet Unity Localization.

  • Set de documentació Serenity — afegit Assets/Serenity/Documentation/ amb referència d’esquema de receptes, guia per a agents IA, documentació per sistema, walkthrough d’application-flow, guia MCP, cookbook de cablejat i cookbooks per ScriptableObject.

  • Aggregate Cookbooks — afegits 21 documents end-to-end orientats a IA, un per mòdul, que documenten sistemes complets com Character, Wave, Stage, GameSession, Score, Combo, GameWeapon, GameRail, GameUi, Ui, ViewBrowser, AssetPrefetcher, ServiceLocator, Timer, Task, Persistence i FilePersistence.

  • Mapa complet de 38 mòduls — el Cookbooks/README.md mestre ara enllaça cada mòdul de Serenity amb la seva documentació autoritativa i inclou un diagrama de composició que mostra com GameMode → GameSession → Stage → Wave → Character → Score/Combo/GameUi encaixen entre si.

Canviat

  • Reorganització d’assets multimèdiaAssets/Media s’ha mogut sota Assets/Serenity/Media. Les referències enllacen per GUID, de manera que el moviment és transparent.

  • Revisió completa de la finestra Mixer Topology — el diagrama de routing ara autoajusta targetes multilínia, dibuixa icones per tipus i una llegenda, suporta nodes seleccionables amb panell de detall i ressalta connectors.

Corregit

  • Doble submit amb gamepad en transicions de menúSetActionMap canviava el mapa de PlayerInput de manera incondicional, provocant que un Submit mantingut durant una transició es processés dues vegades. Ara el canvi s’omet quan el mapa sol·licitat ja és l’actual. El renderer de cascada aplica el mateix press-release gate perquè el Submit que ha obert la cascada no enviï immediatament la seva opció enfocada.

Infraestructura

  • Afegida la suite Serenity.ProjectRecipe.Tests.Editor amb 44 tests EditMode, cobrint importer/exporter de receptes, codec genèric SerializedObject, template generator, validació de receptes, SerenityRecipeReport.ToJson(), SerenityDiscoveryRegistry i cablejat tipat de senyals de menú/modal.

  • Afegits tests PlayMode de placement per a GameModeMusicBinderComponent, UnityToastComponent i UnityAudioPlayerService.

  • Afegida la suite Serenity.UnityValidation.Tests.Editor, cobrint SerenityValidationReport.ToJson() i un smoke test de SerenityProjectValidationRunner.RunAll().

1.1.2 — Eines d’autoria (Modal / Game Settings / Àudio), opcions avançades per a modals, reetiquetatge d’Addressables, Input Action Invoker i cobertura de tests completa

Afegit

  • Eina Modal Builder (Tools ▸ Serenity ▸ Modal ▸ Create Modal) — genera un script de Signal + Action reutilitzant el generador compartit de scripts d’Action, a més d’un asset UnityModalSettings i un asset UnityActionDefinition, tots referenciant el mateix senyal generat. La cadena del tipus de senyal es construeix de manera determinista (UnityActionDefinition.Signal = Type.FullName; UnityModalSettings.signalTypeName = nom complet qualificat per assemblat), de manera que el selector de senyals els fa coincidir exactament. L’inspector de botons de modal s’ha extret a un ModalButtonsInspectorGUI compartit, utilitzat tant per l’editor com per l’eina.
  • Traducció en runtime del títol/text dels modalsIsTranslatingTitle / IsTranslatingText a UiShowModalParameters flueixen fins a UnityModalComponent, que afegeix o obté en runtime un UnityUiTMP_TextLocalizationUpdaterComponent sobre el TMP del títol/text, sense editar el prefab. Anteriorment els títols/textos dels modals mai es traduïen; només els botons.
  • Mostrar modal per id — ara els modals es poden mostrar mitjançant el seu id configurat, complementant la ruta de visualització basada en paràmetres.
  • Opcions avançades per a modals — els modals ara renderitzen el model complet UiOption[] dels menús en lloc del model de botó únicament de tipus submit. Un modal conté UiOption[] Options, ModalDirection Direction, OptionsGap, Scrollable i VisibleOptionsCount, configurats igual que un menú, amb construcció de components per tipus d’interacció (SUBMIT / SLIDER / TOGGLE / SELECTOR), canvi en runtime del layout group segons la direcció i un viewport ScrollRect limitat a VisibleOptionsCount. Els Buttons legacy dels modals es migren de manera mandrosa a UiOptions (InteractionType = SUBMIT) preservant tots els seus senyals. ModalDirection.HORIZONTAL = 0, al contrari que MenuDirection.VERTICAL, perquè tots els assets de modals existents es deserialitzin sense canvis.
  • Submit d’opció amb múltiples senyalsUiOption ara conté una List<EventDispatcherSignal> OnSubmitSignals, llegida mitjançant UiOption.GetSubmitSignals(), de manera que una sola opció de menú o modal pot despatxar diversos senyals en ordre. L’antic OnSubmitSignal únic es manté per retrocompatibilitat i es migra de manera mandrosa. Les noves opcions per defecte són una ACTION buida, un no-op que simplement despatxa els senyals de submit de l’opció.
  • Game Settings Wizard (Tools ▸ Serenity ▸ GameSettings ▸ Settings Wizard) — un assistent IMGUI per passos que crea assets UnityGameSettingsDefinition, amb biblioteca de presets, autocompletat en viu d’opcions des de QualitySettings / Screen.resolutions / Locales / AudioMixer, cablejat opcional de serveis i una acció per generar el conjunt complet recomanat. El pas de cablejat escriu l’Id de l’ajust a la clau de configuració del servei corresponent (graphics / localization / UI / sound-mixer), perquè l’ajust tingui efecte realment en runtime.
  • Eines d’importació d’àudio per lotsTools ▸ Serenity ▸ Audio ▸ Batch Import Sound Effects genera un UnityAudioPlayerClipDefinition per cada fitxer seleccionat; Batch Import Music Tracks genera un UnityMusicTrackDefinition per fitxer amb camps compartits i un foldout avançat per pista per configurar loops (tail-preserving, regió per temps/compassos, fade).
  • Audio Channel Manager (Tools ▸ Serenity ▸ Audio ▸ Audio Channel Manager) — una vista de relació mixer ↔ Serenity que analitza inconsistències, crea canals/grups i els elimina amb un pla dry-run + Undo.
  • Finestra Addressables Retag Selected (Tools ▸ Serenity ▸ Addressables ▸ Retag Selected…) — llista els assets reetiquetables sota qualsevol carpeta arrossegada o seleccionada, previsualitza les etiquetes que rebria cadascun, permet escollir quins reetiquetar (Select All / None / Invert) i les aplica. Els fitxers no elegibles (extensions excloses, documentació/segments de manual, assets de localització) s’oculten; s’accepten assets fora de les arrels del plugin Serenity, i l’adreça cau de manera segura a eliminar un Assets/ inicial.
  • Eina Remove GUID Labels (Tools ▸ Serenity ▸ Addressables ▸ Remove GUID Labels) — elimina etiquetes Addressables obsoletes amb forma de GUID de totes les entrades i de la taula d’etiquetes de settings, deixant intactes les etiquetes module:*, type:* i Locale*.
  • Input Action InvokerUnityInputActionInvoker (Add Component ▸ Serenity ▸ Input ▸ Input Action Invoker), un component drop-in que mapeja accions de l’Input System a mètodes públics sense paràmetres en scripts referenciats, i els crida quan es dispara l’input. És l’equivalent basat en reflexió de Serenity al mode PlayerInput → Invoke Unity Events de Unity. Un inspector personalitzat llegeix els action maps/actions des d’un InputActionAsset assignat, o des de l’asset d’un PlayerInput germà, i llista en desplegables els mètodes invocables de cada target. Cada entrada d’acció té la seva pròpia fase de dispar (Started / Performed / Canceled) i qualsevol nombre de crides a mètodes. Les accions s’enllacen des de la instància d’accions per jugador del PlayerInput germà quan és present, mantenint aïllats els callbacks de multijugador local, i cauen a l’asset assignat per a ús standalone.
  • Component Signal ReactionSignalReactionComponent (Add Component ▸ Serenity ▸ Events ▸ Signal Reaction), la contrapart no-code de SignalEmitterComponent: mentre que l’emitter despatxa un senyal sense codi, aquest component reacciona a un. Un inspector personalitzat mostra cada reacció com un desplegable cercable de tots els tipus concrets EventDispatcherSignal del projecte, a més d’una resposta UnityEvent, de manera que un dissenyador pot cablejar “quan es despatxi el senyal X, fes Y” íntegrament des de l’Inspector. És la primera manera no-code de reaccionar a un senyal; anteriorment només era possible mitjançant EventDispatcherAction<TSignal> definit per codi. Les subscripcions passen per l’IEventDispatcherService compartit, resolt mitjançant ServiceLocatorBridge; el component espera que el servei estigui registrat abans d’enllaçar-se i es desubscriu correctament en deshabilitar-se. El UnityEvent sense paràmetres respon a “reacciona quan passi aquest senyal”; les reaccions que necessiten el payload del senyal continuen pertanyent a un EventDispatcherAction<TSignal>.
  • Informe de Missing References (Tools ▸ Serenity ▸ Validate Missing References) — una finestra d’editor d’un sol clic que escaneja cada ScriptableObject IFoundationSettings (clips, pistes, menús, modals, definicions, settings…) buscant referències que van ser assignades però que ja no es poden resoldre, com ara un clip, taula, prefab o definició eliminat/mogut, i llista cada asset i camp problemàtic amb un botó Ping. Només es reporten referències perdudes, no camps buits. Eina orientada a dissenyadors per respondre “què està trencat?”, fent visibles els errors silenciosos per referències nul·les als quals l’arquitectura pot ser propensa; segon element entregat del
  • Dashboard Health Check (Tools ▸ Serenity ▸ Validate Health Check) — una finestra única de “el meu projecte està cablejat correctament?” per a no programadors. Executa noves comprovacions d’integritat sobre cada asset IFoundationSettings: Id/Guid buits, Id duplicat dins d’un tipus de definició i Guid duplicat a tot el projecte, les claus que fan servir els serveis de Serenity per resoldre assets. Cada resultat inclou botó Ping, i agrupa validadors abans dispersos (Validate Installation / UI Theme Prefabs / Branding / Find FoundationSettings / Missing References) darrere de botons de llançament d’un sol clic en lloc de reimplementar-los.
  • Audició d’àudio dins de l’editor — els inspectors de definicions AudioClip i Music Track ara tenen botons Play / Stop de previsualització (SerenityEditorAudioPreview, un helper d’editor compartit que utilitza l’AudioUtil intern de Unity mitjançant reflexió, tolerant a diferències entre versions i amb fallades suaus), de manera que els dissenyadors d’àudio poden escoltar un clip o pista sense entrar en Play mode.
  • Validador de claus de localització (Tools ▸ Serenity ▸ Validate Localization Keys) — escaneja tots els assets de Serenity buscant claus de traducció, qualsevol camp amb el toggle IsTranslating… activat — títols de menús/modals, labels d’opcions, text de modals, valors de game-settings… — i valida cada clau contra les string tables de Unity Localization del projecte, reportant claus que falten, que en runtime cauen silenciosament al text cru, i camps buits marcats com a traduïbles, cadascun amb botó Ping. L’escaneig es basa en convenció (IsTranslating<Field> → camp germà <Field>), de manera que cobreix automàticament qualsevol futur camp traduïble.
  • Game Mode Music BinderGameModeMusicBinderComponent (Add Component ▸ Serenity ▸ Game Mode ▸ Game Mode Music Binder), la manera no-code de reproduir música diferent per game mode; anteriorment això requeria un EventDispatcherAction<GameModeChangedSignal> definit per codi. Per a cada GameMode, un dissenyador assigna un asset Signal Definition, normalment un senyal PlayMusicTrack creat a l’inspector de Signal Definition; en entrar en aquest mode, el binder el despatxa per la mateixa ruta Dispatch(IEventDispatcherSignalDefinition) que fa servir SignalEmitterComponent. No construeix cap payload per si mateix, de manera que funciona amb qualsevol tipus de senyal. Se subscriu a GameModeChangedSignal mitjançant ServiceLocatorBridge, espera el servei abans d’enllaçar-se i es desubscriu en deshabilitar-se.
  • Presets de botons de modal — el Modal Builder (Tools ▸ Serenity ▸ UI ▸ Modal Builder) ara ofereix presets d’un clic (OK · OK/Cancel · Yes/No · Confirm/Cancel) que emplenen les opcions del modal amb botons SUBMIT, construïts exactament com ModalButtonToUiOptionConverter, sense senyals encara perquè el dissenyador només hagi de cablejar cada botó. Així, els diàlegs comuns ja no comencen des d’una llista de botons buida.
  • Cutscene Outline (Tools ▸ Serenity ▸ Cutscenes ▸ Cutscene Outline) — una vista outline + validador de només lectura per a assets UnityCutsceneDefinition: llista les stages en ordre amb el seu tipus, durada i referència clau (asset Timeline / color de fade), mostra el temps total d’execució i marca problemes, especialment una stage PlayTimeline sense Timeline assignat, que no reproduiria res en runtime. Llegeix tot mitjançant SerializedObject, de manera que ofereix a dissenyadors narratius una vista no-code de “què passa, en quin ordre, i si falta alguna cosa” sense entrar en Play mode. És la part de previsualització estructural del roadmap de Cutscene preview; una previsualització Timeline en viu i scrubbable queda per a una incorporació posterior.
  • Scrubber de stages de cutscene — la finestra Cutscene Outline ha afegit una línia de temps amb scrub: una barra proporcional de stages amb un playhead arrossegable que ressalta la stage activa en qualsevol temps seleccionat, a més de temps inici-fi per stage i ressaltat de la stage activa a la llista. Les stages PlayTimeline fan servir la durada real del seu PlayableAsset assignat perquè el layout sigui precís. Aquesta és la part a nivell de stage del “cutscene scrub” del roadmap; no reprodueix el contingut del Timeline. Una previsualització amb PlayableDirector frame-accurate queda per a una incorporació posterior.
  • Notificacions ToastUnityToastComponent (Add Component ▸ Serenity ▸ UI ▸ Toast), una notificació no bloquejant que mostra un missatge curt amb fade in, el manté i fa fade out. A diferència d’un modal, mai roba l’input. La visual es basa en un prefab assignat pel dissenyador amb un TMP_Text, de manera que els toasts hereten les fonts/tema del projecte; els toasts instanciats es parenten a un contenidor configurable — afegeix un VerticalLayoutGroup per apilar-los — i s’animen amb temps no escalat, de manera que funcionen encara que el joc estigui pausat. Es poden disparar de manera totalment no-code: Show(string) es pot cablejar des de qualsevol UnityEvent, com l’onClick d’un Button, una resposta de SignalReactionComponent amb el missatge escrit a l’inspector, o un animation event. Així, “quan passi el senyal X, mostra el toast ‘Saved!’” no necessita cap script.
  • Signal Flow Browser (Tools ▸ Serenity ▸ Events ▸ Signal Flow Browser) — una vista de només lectura del graf d’esdeveniments: per a cada EventDispatcherSignal mostra qui el despatxa (assets Signal Definition creats), què l’escolta (settings de modals) i què hi reacciona en codi (actions [AutoRegisterEventAction]), tot amb Ping i una caixa de cerca. Els assets creats es descobreixen de manera genèrica mitjançant SerializedObject i les reaccions a partir de l’atribut + la base EventDispatcherAction<T>, de manera que el cablejat no-code d’esdeveniments, normalment invisible, és navegable en un únic lloc.
  • GameMode Overview (Tools ▸ Serenity ▸ GameMode ▸ Transition Overview) — una vista de només lectura d’un UnityGameModeSettingsDefinition: una targeta per cada GameMode que llista els senyals despatxats en entrar i en sortir, a més de la configuració compartida d’action-map/pausa i un recordatori que el servei també despatxa GameModeChangedSignal(previous → new) en cada transició. Llegeix mitjançant els accessors d’IGameModeSettingsDefinition, per la qual cosa sempre llista tots els modes, marcant els que no tenen cablejat, i ofereix als dissenyadors una imatge no-code de “què passa quan s’entra/surt de cada mode”.
  • Init Pipeline Overview (Tools ▸ Serenity ▸ Init ▸ Pipeline Overview) — una vista outline + validador de només lectura per a assets UnityInitializationPipelineProfile: llista les tasques d’arrencada en ordre d’execució amb la seva criticitat i pes, mostra la proporció de cada tasca a la barra de progrés i el pes total, i marca problemes, especialment slots de tasques buits, que llançarien una excepció durant el boot, i Ids buits. Llegeix mitjançant SerializedObject, de manera que els dissenyadors poden validar mentalment el flux d’arrencada i veure quantes tasques crítiques poden aturar el boot sense entrar en Play mode. És la part estructural del simulador d’init pipeline del roadmap.
  • Init Pipeline Simulator (Tools ▸ Serenity ▸ Init ▸ Pipeline Simulator) — un simulador dry-run d’arrencada per a assets UnityInitializationPipelineProfile: marca les tasques que vols fer fallar i executa Run per veure com s’encadenen les regles de criticitat. Una fallada crítica atura l’arrencada i omet les tasques restants, mentre que una fallada no crítica es registra i l’arrencada continua. Mostra resultats per tasca (ok / failed / skipped) i una barra de progrés simulada que indica fins on arriba el boot. Modela el maneig de criticitat d’InitializationPipelineService.RunAsync sense executar les tasques. És la meitat dinàmica de l’element Init Pipeline; l’Overview de només lectura és la meitat estructural.
  • Diagnostics overlayUnityDiagnosticsOverlayComponent (Add Component ▸ Serenity ▸ Debug ▸ Diagnostics Overlay), un HUD en pantalla per a Play mode que mostra FPS / frame time, time scale, el GameMode actual i anterior amb estat de pausa, i el nombre de jugadors units. És un panell orientat a dissenyadors per respondre “què està fent el joc ara mateix?” davant les preguntes habituals de “per què no funciona això?”. Llegeix únicament mitjançant interfícies de servei (IGameModeService via ServiceLocatorBridge) i degrada a “n/a” quan un servei no està actiu, s’activa mitjançant una tecla configurable o mètodes no-code Toggle() / Show() / Hide() cablejables a un UnityEvent o input action, i s’oculta en builds no-development tret que s’habiliti explícitament.
  • Player Join OverlayUnityPlayerJoinOverlayComponent (Add Component ▸ Serenity ▸ Debug ▸ Player Join Overlay), un panell en pantalla que llista els jugadors actualment units mitjançant l’Input System — índex de jugador, control scheme i dispositius de cada slot — perquè un dissenyador pugui veure com ocorren les unions de multijugador local durant les proves en lloc de llegir la Console. És autocontingut, llegeix únicament PlayerInput.all, no fa servir serveis, s’activa mitjançant una tecla configurable (per defecte F4, juntament amb el F3 de Diagnostics Overlay) o mètodes no-code Toggle() / Show() / Hide(), i s’oculta en builds no-development tret que s’habiliti.
  • Mixer Topology (Tools ▸ Serenity ▸ Audio ▸ Mixer Topology) — un diagrama visual de rutes de només lectura per a un AudioMixer i la configuració de so de Serenity: dibuixa cada canal d’àudio de Serenity connectat al seu mixer group amb connectors en angle recte, marca els grups amb volum exposat i quins són effect-loop groups, i distribueix les fonts de cada effect loop alimentant el seu loop group mitjançant sends. Reutilitza AudioMixerRelationshipScanner, per la qual cosa es manté consistent amb l’Audio Channel Manager, però és un viewer pur (“com s’enruta el meu àudio?”) en lloc d’una eina d’anàlisi/reparació com el manager.
  • Autoria d’àudio posicional / 3DAudioPlayerClip ara conté spatialBlend, minDistance, maxDistance, spread i dopplerLevel, aplicats a l’AudioSource en el moment de reproducció per UnityAudioPlayerService. Com que són paràmetres de constructor amb sliders [FloatRange], són configurables sense codi a l’inspector de Signal Definition en construir un senyal PlayAudioClip. Combinat amb la posició de reproducció existent AudioWorldPosition, un dissenyador pot col·locar i modelar un so 3D sense codi. Zero regressió: els ajustos només s’apliquen quan spatialBlend > 0, de manera que els clips existents, que per defecte tenen 0 = 2D, deixen intactes els min-max distance, spread i Doppler propis de l’AudioSource/prefab i es comporten exactament com abans.
  • Component d’input rebindingUnityInputRebindComponent (Add Component ▸ Serenity ▸ Input ▸ Input Rebind), rebinding interactiu no-code per a un únic binding de l’Input System, el clàssic row de settings “prem una tecla per reasssignar”. Cableja un botó a StartRebind() i un altre a ResetBinding(); el text del binding actual s’emet mitjançant un UnityEvent<string>, que pots cablejar al setter text d’un TMP/UI text, i onRebindStarted / onRebindStopped controlen un prompt “Press any key…”. Embolica PerformInteractiveRebinding, deshabilitant l’acció durant el rebind com requereix l’Input System, i, quan persist està activat, desa els binding overrides de l’asset a PlayerPrefs i els recarrega en habilitar-se, de manera que els rebinds sobreviuen als reinicis. Per defecte reasssigna el binding de l’asset referenciat, pensat per a un menú de settings single-player/shared-asset; habilita usePlayerInput per a multijugador local i reasssignar la instància d’acció per jugador resolta des d’un PlayerInput pare, persistint per índex de jugador.
  • Guia Designer Quick Start (Assets/Documentation/DESIGNER_QUICKSTART.md) — un tour d’onboarding no-code: checklist de primer arrencada (els quatre validadors), mapa de cada eina Tools ▸ Serenity i cada component Add Component ▸ Serenity, i receptes pas a pas (“mostrar un toast quan passi alguna cosa”, “música diferent per game mode”, “permetre que els jugadors reasssignin una tecla”, “per què no funciona això?”).

Canviat

  • Ordre determinista dels menús d’editor — cada [MenuItem("Tools/Serenity/…")] ara porta una priority explícita (Setup 0–99, Project/Build 100–199, Authoring 200–299, Validate/Find 300–399, Docs 400+) i cada [CreateAssetMenu] porta un order des d’un esquema curat en blocs de 100, de manera que els menús contextuals de Serenity es renderitzen igual a totes les màquines en lloc de dependre d’un ordre arbitrari de compilació.
  • Normalització de rutes de menúSerenity/UiSerenity/UI (UiTheme → UI Theme, CompositeView → Composite View) i Serenity/Settings/Unity UI SettingsSerenity/UI/UI Settings. Els assets existents enllacen per GUID de script, de manera que els canvis de nom són segurs.
  • Inspector compartit d’opcions — la ReorderableList d’opcions del menú s’ha extret a un UiOptionListInspectorGUI reutilitzable, ara utilitzat tant per UnityMenuSettingsDefinitionEditor com per UnityModalSettingsEditor, amb UI idèntica per a ValueType / UI Element / Id / Label / Value / Translate-Label + llista de senyals per opció.
  • Canvi de nom de l’enum de value-type d’opcióUiComponentValueType.MENU_TRANSITIONTRANSITION i MENU_ACTIONACTION, sense canviar els ordinals, de manera que els assets serialitzats es preserven.
  • UnityModalController.Navigate ara té en compte la direcció: els modals HORIZONTAL naveguen opcions amb esquerra/dreta i editen valors amb amunt/avall; els modals VERTICAL mantenen la navegació prèvia amb amunt/avall i edició de valors amb esquerra/dreta.

Features

  • Els diàlegs modals ara es poden crear amb el mateix model avançat, multiopció, scrollable i amb layout horitzontal o vertical que els menús, i poden executar una llista de senyals per opció, no només un botó confirmar/cancel·lar únic en cada cas.
  • Els fluxos comuns d’autoria ara són eines d’editor d’un clic: crear l’estructura d’un modal (signal + action + settings), crear definicions de game-settings amb presets en viu i cablejat automàtic de serveis, importar SFX/música per lots i gestionar canals d’àudio contra el mixer.
  • Les etiquetes Addressables es poden reaplicar a un subconjunt escollit manualment d’assets sota qualsevol carpeta, i les etiquetes legacy amb forma de GUID es poden eliminar a tot el projecte.

Corregit

  • El Directory Cloner ja no propaga etiquetes Addressables obsoletes amb forma de GUID: UpdateAddressablesEntries omet etiquetes amb aparença de GUID en copiar les etiquetes d’una entrada origen, i la nova eina Remove GUID Labels neteja etiquetes deixades pel comportament antic del cloner.
  • S’han resolt diversos bugs latents preexistents detectats en ampliar la cobertura de tests: setters Id/Guid autorecursius de ComponentLogger, TimerFormatterService.FormatTimeInSeconds utilitzant un divisor /120 en lloc de /3600 per a hores, AudioWorldPosition.ToString formatant de manera no invariant i UnityGameSettingsOptionResolver.ResolveSelectable llançant un NRE amb un conjunt d’opcions buit, ara protegit.

Infraestructura

  • Cobertura automatitzada de tests completa. Es van afegir tests de comportament a tots els mòduls purs de Domain + Application, portant la suite pura de 1.742 → 3.508 tests en verd; després es va estendre a la capa testeable de glue Unity, unes 28 assemblies Unity*, amb ~1.130 nous tests PlayMode, i als serveis d’I/O de persistència de fitxers del sistema operatiu, de 0% a coberts, portant la suite PlayMode completa de 4.131 → 5.334 tests. Es van resoldre les 36 fallades PlayMode preexistents, corregint bugs reals i actualitzant tests obsolets. La cobertura també va arribar a la capa d’eines d’editor Unity (docfx / generators / importers / validators) en EditMode i als installers Unity, 15 mòduls, en PlayMode.
  • Un harness NUnit standalone net8.0, amb un shim de UnityEngine que implementa aritmètica real de Vector/Mathf, executa tota la suite pura Domain + Application en menys d’un segon sense llançar l’editor de Unity ni requerir llicència: el bucle ràpid de verificació que va impulsar el treball de cobertura.
  • Es van afegir tests PlayMode per a UnityInputActionInvoker utilitzant InputTestFixture de l’Input System (fases Performed / Started / Canceled, rutes standalone-asset i PlayerInput, múltiples mètodes per acció, resiliència davant mètodes invàlids i aturada d’invocacions en deshabilitar), el primer test basat en InputTestFixture del repositori. Es va afegir la referència Unity.InputSystem.TestFramework a Tests.asmdef, juntament amb la resta de referències cross-assembly que requeria la nova cobertura.
  • Es van afegir tests de lògica pura per a les regles d’elegibilitat de reetiquetatge Addressables / construcció d’address i les invariants d’etiquetes GUID, el builder d’opcions avançades de modals i la migració Buttons → Options, els writers del Game Settings Wizard i l’analitzador de relacions d’àudio / planner d’eliminació de canals.
  • Es van afegir tests de SignalReactionComponent amb UnityEventDispatcherService real + ServiceLocatorBridge: un senyal coincident invoca la resposta, un tipus de senyal diferent no ho fa i en deshabilitar-se es desubscriu.

1.1.1 — Vistes compostes, menús horitzontals, creació de senyals des de l'Inspector, previsualització de vistes, retorn a la porta d'entrada i controls de punt d'inici musical

Afegit

  • Vistes compostes — un sistema de composició de pantalles basat en flexbox. UnityCompositeViewDefinition (Serenity/Ui/CompositeView) compon qualsevol fill IViewBase (menús o composicions imbricades) en una única pantalla amb mides per fill a l'estil CSS (Fixed px / Flex fr / Percent % / Auto, amb mínims/màxims), direcció Row/Column, alineació, padding i separació, i dos modes de contingut: STACK (tots els fills visibles) i SWITCHER (un únic fill actiu). Està recolzat per un servei de domini pur FlexboxSolver i un model de layout (LayoutDirection, LayoutSizeUnit, LayoutAlignment, LayoutScrollAxis, LayoutSize, LayoutPadding, LayoutConfig, ContainerContentMode). La direcció es llegeix en sentit de taula/graella: ROW = bandes horitzontals apilades, COLUMN = columnes una al costat de l'altra.
  • Allotjament de menús dins de composicions — un menú pot renderitzar-se dins d'una regió composta (IHostableView). Cada slot compost que referencia un menú construeix la seva pròpia instància (UnityMenuService.CreateHostedInstance), desacoblant l'id d'encaminament per instància de l'id de definició compartit, de manera que el mateix menú pot aparèixer en diverses regions alhora sense ser robat del seu ús independent.
  • Router de vistesIViewRouter / ViewRouter / IViewProvider (Global.Application). La pantalla inicial s'ha mogut fora de la configuració del servei de menús cap a IUiSettings.InitialViewId (un selector que accepta un menú o una composició). El router rastreja la vista superior actual, oculta automàticament l'anterior i mostra la vista inicial en arrencar i en tornar des del gameplay. Les transicions de menú passen a través d'ell (RouterMenuTransitionateToView).
  • Vistes amb scrollScrollable + ScrollAxis a UnityViewDefinition, amb barres de scroll programàtiques (UnityScrollbarBuilder). Els menús fan scroll amb una limitació de Visible Options Count (MenuScrollPolicy) i fan auto-scroll per mantenir visible l'opció seleccionada.
  • Recorregut de focus entre menús — els menús apilats en una composició es passen el focus de teclat/gamepad entre si als seus límits (ICrossMenuHost / IFocusableMenuView), amb wrap-around opcional. El control d'entrada segueix el fill actiu de SWITCHER (ICompositeViewService.GetActiveInputView).
  • Assistent Composite View Builder (Tools ▸ Serenity ▸ UI ▸ Composite View Builder) — permet escollir una plantilla paramètrica (N columnes, N files, una única columna amb scroll, navbar+contingut, navbar+columnes/files, sidebar), posar nom a les seccions i generar l'arbre de .asset de composició + menús amb la navegació autoconnectada (sense cablejat manual de rutes ::). La direcció de layout per secció i del navbar és seleccionable.
  • Eina View Preview (Tools ▸ Serenity ▸ UI ▸ View Preview) — una renderització en viu, amb tema aplicat, d'un menú o composició construïda des de les plantilles reals de prefabs del tema a una resolució de dispositiu escollida, a més d'un mode wireframe estructural. Inclou highlight d'opció seleccionada, proves de hit per clic, zoom per encaixar a la vista, localització en mode edició (etiquetes traduïdes reals en lloc de claus sense processar) i una imatge de fons opcional.
  • Menús horitzontalsMenuDirection (Vertical / Horizontal) a les definicions de menú distribueix les opcions una al costat de l'altra. HorizontalOptionWidthMode (Content / Uniform / Fill / Explicit) amb HorizontalOptionWidth controla l'amplada de columna; OptionsGap i Visible Options Count s'apliquen horitzontalment, amb una barra de scroll horitzontal.
  • Definicions de despatx de senyals creades des de l'InspectorUnityEventDispatcherSignalDefinition (Serenity/EventDispatcher/Signal Definition): permet escollir un tipus concret d'EventDispatcherSignal, triar un constructor i omplir-ne els paràmetres completament des de l'Inspector; IEventDispatcherService.Dispatch(IEventDispatcherSignalDefinition) la construeix i l'emet. Suporta primitius, tipus matemàtics de Unity, enums, referències a UnityEngine.Object, paràmetres d'interfície recolzats per ScriptableObject, paràmetres DTO/value-object imbricats recursivament (fins a 6 nivells) i opcionals nullable.
  • Atributs d'autoria per a paràmetres de senyalsFloatRangeAttribute (rang + slider percentual + botó de reset), AssetPathReferenceAttribute (dibuixa un camp d'objecte asset per a una ruta string) i FoundationIdReferenceAttribute (selector d'id de settings). Aplicats a AudioPlayerClip (volume com a slider 0–100%, panStereo amb reset, filePath com a camp AudioClip) i AudioPlayerPlayClipInput (serviceId).
  • SignalEmitterComponent — un MonoBehaviour que conté assets de definició de senyal; Dispatch(id) / DispatchFirst() emeten una senyal configurada des de callbacks de col·lisió/trigger, esdeveniments d'animació, input o cablejat amb UnityEvent. Els errors es registren al log i s'absorbeixen perquè el flux de gameplay no es trenqui mai.
  • Mode de rolloff d'àudio — enum de domini agnòstic del motor AudioRolloffMode (Logarithmic / Linear / Custom) més RolloffMode a AudioPlayerClip, controlant l'atenuació 3D per distància (els valors es mapegen a Unity al límit d'infraestructura).
  • Senyals OnCancel per vista — una llista de senyals OnCancel a IMenuSettingsDefinition / UnityMenuSettingsDefinition, creada mitjançant una llista reordenable a l'Inspector, que es despatxa quan una entrada de cancel·lació arriba a aquell menú.
  • Retorn a la porta d'entrada primàriaReturnToPrimaryInputGateSignal. Creada a l'OnCancel del menú principal, desmunta el context d'input del menú, desemparella el dispositiu (IPlayerInputService.ReleasePrimaryDeviceIUiInputRouter.Unpair) i rearma la porta de selecció de dispositiu perquè un nou dispositiu pugui unir-se.
  • Start From Loop PointStartFromLoopPoint a UnityMusicTrackDefinition / IMusicTrackDefinition / MusicTrack. Quan està activat, la primera reproducció d'una pista comença al temps d'inici del loop en lloc de 00:00:000, saltant-se la intro. S'aplica a qualsevol pista amb regió de loop — pistes amb preservació de cua (la primera veu i la seva unió comencen al punt de loop) i pistes natives/one-shot (cut/fade/cross-fade respecten l'offset). La secció Loop de l'inspector de pistes musicals s'ha refet: la regió de loop roman editable sempre que qualsevol dels toggles la consumeixi, i els controls de fade-out de cua queden limitats al looping amb preservació de cua.
  • Ignore If Already PlayingIgnoreIfAlreadyPlaying a UnityAudioPlayerSettings / IAudioPlayerSettings. Quan està activat, una sol·licitud per reproduir la cançó que ja s'està reproduint s'ignora perquè continuï sonant sense interrupcions en lloc de reiniciar-se de manera audible (music player). Per defecte està desactivat per preservar el comportament de reinici permanent.

Canviat

  • La primera pantalla es configura a UnityUiSettings.InitialViewId (menú o composició) en lloc de la configuració del servei de menús; InitMenuId s'ha retirat de la definició de configuració del servei de menús.
  • Les eines d'autoria d'UI s'agrupen sota Tools ▸ Serenity ▸ UI (Composite View Builder, View Preview).
  • UnityMenuController encamina Navigate/Submit/Cancel a través de la vista d'input composta activa quan se'n mostra una, recorrent al menú actual en cas contrari.

Funcionalitats

  • Diversos menús existents i composicions imbricades poden compondre's en una única pantalla (per exemple, una barra de navegació lateral + contingut de settings amb scroll + regió de detall) amb mides flexbox, scroll i recorregut de focus de teclat/gamepad entre regions — creat visualment amb Composite View Builder i previsualitzat en viu a l'editor.
  • El mateix menú pot allotjar-se en diverses regions compostes simultàniament, cadascuna amb el seu propi estat de selecció/focus, mentre comparteixen el mateix game setting subjacent.
  • Els menús poden distribuir-se horitzontalment amb comportament seleccionable d'amplada de columna i scroll horitzontal.
  • Creació i despatx de senyals de l'event dispatcher — incloses senyals amb paràmetres DTO complexos imbricats — completament des de l'Inspector, i activació des de l'escena mitjançant SignalEmitterComponent.
  • Una entrada de cancel·lació que cap opció consumeix ara despatxa les senyals OnCancel de la vista i després navega enrere; les composicions usen una tornada enrere en dos nivells (tancar la regió de detall oberta, o sortir de tota la composició). Des del menú principal, cancel·lar pot retornar el jugador a la porta de selecció de dispositiu de press-to-start.

Corregit

  • La porta d'entrada primària (prompt de selecció de dispositiu) ara completa la unió en deixar anar el botó en lloc de fer-ho en prémer-lo, de manera que la pulsació d'unió ja no es filtra al menú mostrat immediatament després d'unir-se (per exemple, enviant instantàniament l'opció enfocada). El latch de pulsació es reinicia si el dispositiu latchejat es desconnecta mentre es manté premut, i la porta es rearma netament quan es torna a mostrar.
  • L'encaminament d'input d'UI ara aplica màscares d'esquema de control perquè els bindings d'un gamepad emparellat es resolguin, i emparella teclat + ratolí com una unitat quan no estan configurats per dividir-se — corregint que l'input no arribés a la UI després d'unir-se amb aquests dispositius.
  • SignalEmitterComponent (i qualsevol altre consumidor de ServiceLocatorBridge del costat de Unity) ara pot resoldre IEventDispatcherService en runtime, de manera que Dispatch(id) / DispatchFirst() emeten en lloc de registrar "no IEventDispatcherService is registered yet." UnitySerenityInstaller.RegisterService ara replica cada servei dins de l'IServiceLocator de runtime (no només al contenidor de temps d'inicialització), amb semàntica de sobreescriptura on l'últim guanya, coincidint amb la instal·lació dual d'ILogService.
  • Els clips d'àudio construïts des d'una IAudioPlayerClipDefinition (per exemple, una senyal PlayAudioClipSignal creada des de l'Inspector i despatxada mitjançant SignalEmitterComponent) ara sonen de manera audible. El constructor AudioPlayerClip(IAudioPlayerClipDefinition, AudioPlayerType) anteriorment deixava volume i pitch amb el valor per defecte de C# 0, per la qual cosa el clip es reproduïa amb volum 0 / pitch 0 — silenciós, sense error. Ara inicialitza volum, pitch, loop, pan, reverb mix i rolloff amb els mateixos valors per defecte que els altres constructors.

Infraestructura

  • Afegits tests per a FlexboxSolver, UiAnchorMapper, Composite View Builder + generador, navegació creuada de composicions / rutes de host / mides allotjades, builders de layout i scrollbar, i la política de scroll de menús.
  • Afegits tests per al builder de senyals de l'event dispatcher i el flux de despatx des de definició, paràmetres de senyal configurats, atributs d'autoria d'AudioPlayerClip, la definició OnCancel de menú, la porta d'entrada primària i el setter de routing-id del view-model.
  • Actualitzades les definicions d'assemblat per a les noves referències entre capes introduïdes per les composicions, la preview/builder de l'editor, els menús horitzontals i l'editor de definicions de senyals.
  • Afegits tests per a MusicTrack.StartFromLoopPoint (per defecte i personalitzat), valors per defecte de reproducció audible d'AudioPlayerClip quan es construeix des d'una definició, i estès el test double de settings de l'audio-player amb el membre IgnoreIfAlreadyPlaying.

1.1.0 — Àudio posicional i per prioritat, cues de loop musical, bucles d’efectes de mixer, menús lazy i comporta d’input per GameMode

Breaking Changes

  • SpawnPose ja no exposa els set camps float plans (PositionX/Y/Z, RotationX/Y/Z/W). Ara està recolzat per Position (System.Numerics.Vector3) i Rotation (System.Numerics.Quaternion). La construcció no es veu afectada — el constructor de set float i FromPosition(x, y, z) es mantenen — però el codi que llegia els camps float individuals ara ha de llegir pose.Position.* / pose.Rotation.*.

Afegit

  • Comporta d’input principal com a GameMode — un valor PrimaryInputGate a l’enum GameMode permet que el prompt d’input principal reutilitzi la maquinària existent de senyals de transició d’entrada/sortida per mode. L’emmagatzematge serialitzat, la recuperació i les llistes reordenables d’entrada/sortida a l’inspector es generen automàticament per al nou mode.
  • Loops musicals conservant la cuaStartTime, EndTime, TailPreservingLoop, TailFadeOutDuration i TailFadeOutCurve a IMusicTrackDefinition / MusicTrack / UnityMusicTrackDefinition. Una segona veu transporta la cua de reverb/ambient de la passada anterior a través de la unió del loop, programada amb precisió de mostra mitjançant AudioSettings.dspTime / PlayScheduled, de manera que el loop no produeixi mai clicks. Els punts de loop es defineixen com a codis de temps HH:MM:SS:MMM o en termes de DAW — tempo, compàs, barra d’inici/final — mitjançant MusicBarTimeCalculator; el fade de la cua segueix una corba Lineal/Exponencial/Logarítmica/S-Curve/Custom.
  • Reproducció d’àudio posicional — objecte de valor AudioWorldPosition i PlaybackPosition opcional a AudioPlayerPlayClipInput; un clip reproduït amb posició es reprodueix en 3D en aquell punt, i sense posició es manté en 2D. Funciona tant des d’una crida directa al cas d’ús com des d’un senyal PlayAudioClip, sense canvis a la signatura del gateway/servei.
  • Assignació per prioritat de sons — quan el pool d’AudioSource és ple, un clip pot prendre el control d’un so en reproducció de menor prioritat en lloc de ser descartat. Això es governa mitjançant Priority / PriorityPolicy / CanBeReplaced per clip i un AudioPriorityCandidateSelector (AudioPriorityPolicy: IgnoreIfNoSourceAvailable / ReplaceLowerPriority / ReplaceLowerOrEqualPriority / AlwaysReplace). La semàntica de prioritat de Serenity — com més alt, més important — es mapeja a la prioritat invertida d’AudioSource.priority de Unity només al límit amb Unity.
  • Eina d’autoria d’AudioMixer Effect Loop (Tools ▸ Serenity ▸ Audio ▸ Create Audio Mixer Effect Loop) — crea un grup de mixer amb una cadena Receive → effects → Attenuation i un asset reutilitzable UnitySoundMixerEffectLoopDefinition que el descriu.
  • Finestra de sincronització d’Effect Loops (Tools ▸ Serenity ▸ Audio ▸ Sync Effect Loops) — reconcilia l’AudioMixer i SoundMixerSettings amb les definicions d’effect-loop del projecte: crea un Send per cada source cap al Receive del loop, l’exposa com {Source}_{Loop}_Send i registra la definició. És idempotent i additiva.
  • Selecció de grups source a l’eina de creació — permet triar quins grups germans alimenten el loop, amb Select All / None.
  • Scripts d’accions enable/disable autogenerats — per a cada grup source seleccionat, genera una parella d’acció/senyal Enable + Disable d’EventDispatcher — reutilitzant el generador compartit de scripts d’accions — ja preconfigurada per aplicar/netejar el loop en aquell grup, escrita en una carpeta Events configurable.
  • Aplicar/netejar effect-loops en runtime: ISoundMixerService.ApplyEffectLoop / ClearEffectLoop, SoundMixerApplyEffectLoopSignal / SoundMixerClearEffectLoopSignal, els seus casos d’ús, DTOs només d’intenció i un SoundMixerEffectLoopRouteResolver pur i independent del motor.
  • UnitySoundMixerEffectLoopDefinition / UnitySoundMixerEffectLoopSource com a ScriptableObjects amb inspector personalitzat, a més d’un registre EffectLoops a SoundMixerSettings.
  • AudioMixerYamlReader només per a editor — llegeix l’estructura de .mixer — i AudioMixerEffectLoopReflectionAdapter — aïlla l’API interna UnityEditor.Audio darrere d’una única classe.
  • Mode d’instanciació per menúMenuInstantiationMode (PreloadOnStartup / LazyOnFirstOpen) a IMenuSettingsDefinition i UnityMenuSettingsDefinition, editable sota una secció Advanced a l’inspector de configuració del menú.
  • Pipeline d’instanciació lazy de menús: IMenuInstanceGate, MenuLifecycleResolver, EnsuringMenuTransitionateToView, UnityMenuLazyBuildContext, UnityMenuLazyRegistration i IUnityMenuViewInstanceFactory / UnityMenuViewInstanceFactory.
  • Senyals de transició de sortida per modeIGameModeSettingsDefinition.GetExitSignalsForGameMode; l’inspector de configuració de GameMode ara mostra llistes reordenables separades de senyals d’entrada/sortida per mode.
  • Pausa durant la càrrega d’escena — ajust PauseDuringSceneLoad de GameMode — activat per defecte — amb un toggle a l’editor de settings, que congela el rellotge del joc mentre es carrega l’escena additiva de gameplay i el restaura — mitjançant try/finally — quan finalitza la càrrega, evitant que els objectes acabats d’instanciar simulin darrere de l’overlay de càrrega.
  • Generació de configuració en la primera execució — en una instal·lació nova, l’idioma detectat del sistema operatiu/navegador ara es persisteix a gameSettings.cfg en el moment de la detecció — standalone mitjançant UnitySystemConfigurationSnapshotStore; WebGL/ResourcesOnly mitjançant SerenityFallbackLocalizationService — protegit per una comprovació d’existència del fitxer per preservar la preferència guardada dels jugadors que tornen.

Canviat

  • SpawnPose ara està recolzat per System.Numerics Vector3 Position + Quaternion Rotation — substituint els set float plans —, seguint el patró d’objecte de valor RailNodePosition de GameRail; es manté com a C# pur, sense dependència del motor. UnityWaveService llegeix pose.Position.* / pose.Rotation.*. Vegeu Breaking Changes.
  • UnityAudioPlayerService.ApplyPlaybackPlacement ara és l’única font de veritat per a AudioSource.spatialBlend — amb posició → 1 i l’emitter es mou allà; sense posició → 0 i l’emitter es deixa al seu lloc —; ApplyClipToSource ja no aplica l’spatial blend del clip.
  • UnityGameModeService despatxa els senyals del mode sortit després d’OnExitMode, reflectint el comportament existent dels senyals d’entrada; entrar a PrimaryInputGate dispara els seus senyals d’entrada i sortir-ne dispara els seus senyals de sortida mitjançant el mateix dispatch de SetMode.
  • El pause mixer effect loop ara es controla mitjançant senyals d’entrada/sortida de GameMode — Enable en entrar a Pause, Disable en sortir de Pause — en lloc de classes d’acció dedicades.
  • UnityMenuService construeix els menús LazyOnFirstOpen quan es mostren per primera vegada — cachejats i reutilitzats —; els menús PreloadOnStartup continuen sent eager. Els menús inicials i de pausa configurats com a lazy es tracten com a preload per evitar estrebades en la primera obertura. El comportament per defecte no canvia — PreloadOnStartup continua sent el valor per defecte.
  • UnitySoundMixerSettingsEditor ara llegeix els paràmetres exposats en viu des de l’AudioMixer en memòria — s’actualitza automàticament mentre edites, sense necessitat de desar — i etiqueta la llista de definicions registrades de manera diferenciada respecte a l’encapçalament de la secció.
  • Les definicions d’effect-loop fan servir un únic DefaultWet normalitzat — dry és el seu complement, 1 - wet —, mostrat com un slider "Dry/Wet"; l’eina de creació accepta carpetes de destí separades per a Media i Events.
  • El nivell de sortida del loop es tracta com un trim estàtic del mixer — no com un paràmetre runtime exposat —; el Send del source segueix el nivell actual del grup source.
  • UnityYamlUtils es va mantenir com a helper YAML genèric — tot el coneixement específic d’AudioMixer YAML es va moure al mòdul SoundMixer.

Features

  • El prompt de selecció de dispositiu ara és un GameMode observable (PrimaryInputGate) que dispara efectes secundaris mitjançant senyals d’entrada/sortida sense transicionar els modes de joc per si mateix — en seleccionar dispositiu emet OnPrimarySelected i la composition root despatxa EnterMenuSignal, permetent que l’acció EnterMenu canviï el mode.
  • La música pot fer loop entre punts d’inici/final definits mentre una segona veu transporta la cua de reverb de la passada anterior a través de la unió, amb un fade-out de cua acotat i definit per corba — una durada de 0 talla netament al punt de loop.
  • Els sons poden reproduir-se en una posició del món — 3D — i poden reclamar un slot ocupat del pool a un so de menor prioritat en lloc de ser descartats.
  • Un effect loop pot ser creat, cablejat, registrat i activat/desactivat des de gameplay — per exemple, un low-pass/reverb de pausa sobre Music — d’extrem a extrem des de l’editor, sense escriure a mà routing ni scripts d’accions.
  • Els menús poden optar per creació lazy en la primera obertura, reduint el treball d’arrencada, mentre es conserva l’arrencada eager per als menús que ho necessiten.
  • Els modes de joc poden executar efectes secundaris mitjançant senyals tant en entrar com en sortir d’un mode.

Corregit

  • Els canvis de valor de menú ara s’apliquen a l’opció que realment ha canviat — no a l’actualment seleccionada — i resolen l’opció seleccionada pel seu GetIndex() lògic en lloc de per la seva posició a la jerarquia, corregint valors de sliders entrellaçats on dues opcions compartien un mateix UiOptionValue — per exemple, master/ambient.
  • ISoundMixerService ara està registrat al ServiceLocator runtime, de manera que les accions d’EventDispatcher el poden resoldre.
  • Els GUIDs de nivell de mescla de Send per source es preassignen quan es crea el Send, de manera que exposar el nivell de Send de cada source ara funciona correctament.
  • S’han eliminat referències [SerializeReference] penjants a tipus de senyals d’acció eliminats en assets d’exemple — un tipus managed desconegut estava anul·lant els altres senyals vàlids en entrar a Play.

Eliminat

  • Classes redundants EnablePauseMixerEffectLoopAction / DisablePauseMixerEffectLoopAction i l’asset d’exemple PauseEffectLoop — substituïts per senyals de sortida de GameMode i el generador de scripts d’accions.
  • Un mapping erroni de SoundMixerSettings (Music_SucutruleLoop_SendAudio_MasterVolume) que referenciava un paràmetre exposat del mixer inexistent.

Infraestructura

  • Afegits tests per al route resolver de SoundMixer effect-loop, effect loop, installer, casos d’ús i cobertura.
  • Afegits tests per al resolver de lifecycle de Menu, el cas d’ús ensure-transition i l’enum de mode d’instanciació de menú.
  • Afegits tests per al music bar/time calculator, fade-curve evaluator i getters de music-track; audio world-position i placement; selecció de candidats per prioritat d’àudio i prioritat de clips; construcció de SpawnPose; i les accions/senyals de primary-input-gate de GameMode.

1.0.12 — Suport WebGL, tema Serenity i localització en runtime

Afegit

  • Tema Serenity — un nou tema d'UI complet amb un conjunt complet de components (Background, Title, Label, Input, Dropdown, Selector, Slider, Toggle, Submit, Modal, PrimaryInputPrompt, Highlight), incloent-hi animator controllers per al bucle de color del highlight i les transicions de mostrar/amagar modals.
  • Suport per a builds WebGL — el primer target de compilació WebGL per a Serenity.
  • Eines d'exportació de recursos per a WebGLSerenityWebGLResourcesExporter, SerenityWebGLResourcesCleaner, SerenityWebGLResourcesValidator, SerenityWebGLResourcesPaths i SerenityWebGLExportManifest per exportar assets de Serenity a l'arbre Resources del consumidor per a builds WebGL.
  • Fallback de localització en runtimeSerenityFallbackLocalizationService carrega JSON per cada parell (taula, locale) des de Resources i respon al nou ILocalizationService.TryTranslate(key, out value), permetent la traducció i el canvi d'idioma en viu en mode ResourcesOnly (WebGL).
  • Barra de progrés de càrrega per tema — un slot LoadingProgressTemplate als components del tema d'UI i una variant de prefab LoadingBar per a cada tema (Default, Alternative, Alternative2, Animated, Animated2, Futuristic, Serenity, Writings).
  • Enum SerenityAssetLoadingMode i interfícies/implementacions IAssetLoadingModeProvider / UnitySerenityAssetLoadingModeProvider per seleccionar com es carreguen els assets (Addressables vs. només Resources).
  • Esdeveniment ILocalizationService.GameLanguageChanged, disparat quan realment canvia el valor de l'idioma.
  • Comanda de menú a l'editor (Serenity ▸ UI ▸ Generate LoadingProgress Prefabs) que genera les variants de prefab de barra de càrrega per tema i les connecta amb les definicions de tema.
  • Camp "Loading Progress Prefab" a l'inspector de la definició del tema d'UI.
  • Família tipogràfica Inter (pesos variables i estàtics amb assets SDF) i imatges de suport (WhiteBackground, square-roundborder).

Canviat

  • L'overlay de càrrega de gameplay ara construeix la seva barra de progrés a partir de LoadingProgressTemplate, recorrent a SlideableTemplate quan no hi ha cap prefab dedicat assignat.
  • UnityUiTMP_TextLocalizationUpdaterComponent ara crida TryTranslate en mode fallback, desa a la memòria cau la clau original de localització entre canvis d'idioma i la torna a capturar quan el text mostrat difereix de l'última traducció.
  • UnityLocalizationService manté GameLanguageChanged com a no-op, delegant el refresc a la pròpia cadena OnSelectedLocaleChanged de Unity Localization.
  • Corregit el comportament de UnityPrimaryInputPromptView per a builds WebGL.
  • InitializationPipelineService, UnityCutscenePlayerService, ReflectionCallTask, AddressablesAssetLocator, UnityAddressableUtils, UnityAssetUtils, AudioMixerDependencyCache i UnityMainThreadDispatcher actualitzats per suportar càrrega només mitjançant Resources i restriccions de WebGL.
  • El grup Addressables de Serenity i la configuració d'Addressables s'han actualitzat per registrar els nous assets.

Funcionalitats

  • El mode ResourcesOnly ara fa traducció real i permet canviar d'idioma en runtime mitjançant el selector d'idioma de la UI d'ajustos.
  • L'exportació de Resources per a WebGL utilitza semàntica de moviment durant l'exportació i recorre a l'idioma del navegador com a locale inicial.
  • El JSON de localització es carrega mitjançant un escaneig recursiu amb Resources.LoadAll<TextAsset>("") i un filtre de forma de string table, sense requerir acoblament amb l'asmdef de Unity.Localization.Editor.

Corregit

  • Corregida la desaparició del selector de la barra de càrrega en sortir el ratolí, fent servir un prefab dedicat de progrés de càrrega en lloc de reutilitzar la plantilla interactiva del slider.
  • Corregits els builds ResourcesOnly que anteriorment mostraven les claus de localització en pantalla sense manera de canviar d'idioma en runtime.
  • Corregit el selector d'idioma —els valors del qual són alhora claus de localització— que traduïa la clau desada a la memòria cau obsoleta en lloc de l'actual.

Infraestructura

  • Afegides eines d'editor per a exportació, neteja, validació i seguiment mitjançant manifest de Resources per a WebGL.
  • L'exportació de localització basada en reflection evita l'acoblament amb l'asmdef de Unity.Localization.Editor.
  • Afegits tests per als casos d'ús de localització i l'instal·lador de localització.

1.0.8 — Selectors d’Editor, Autoetiquetatge d’Addressables i Validació de TMP Essentials

Afegit

  • SerenityTmpEssentialsValidator, un validador només d’editor que detecta recursos essencials de TextMeshPro absents i intenta importar-los automàticament quan és possible.
  • Protecció en Play Mode davant TMP Essentials absents, cancel·lant l’entrada en Play Mode abans que es puguin produir errors de runtime de Unity/TMP.
  • Diàleg manual de recuperació de TMP Essentials amb opcions per obrir l’importador de TMP, ignorar l’avís durant la sessió actual o tornar a comprovar.
  • Postprocessador d’importació de Serenity que programa una comprovació de TMP Essentials cada vegada que s’importen assets de Serenity en una sessió de l’editor de Unity ja oberta.
  • SerenityAddressablesAutoLabeler, un postprocessador només d’editor que registra automàticament els assets ScriptableObject de Serenity acabats d’importar com a Addressables.
  • Assignació automàtica de labels d’Addressables per a assets ScriptableObject de Serenity basada en mapatges exactes de tipus i regles de fallback per prefix de namespace.
  • Constants ModuleLabels centralitzades per a totes les labels de mòdul i labels de tipus de Serenity.
  • Constants ModuleLabels.Types per a labels d’Addressables basades en tipus, com ara assets de font, imatge, àudio i personatge.
  • Labels de mòdul addicionals per als sistemes Character, GameMode, SequencePlayer i Wave.
  • Combinacions comunes de labels addicionals per a GameSettings + Localization i GameSettings + UI.
  • Helper RenderIdObjectField<TAsset>(...) a FoundationEditor per renderitzar ObjectFields de Unity recolzats per ids serialitzats en string.
  • EventDispatcherSignalTypePicker, un selector compartit amb cerca per a subtipus concrets d’EventDispatcherSignal.
  • EventDispatcherSignalTypeAdvancedDropdown, un selector amb cerca basat en AdvancedDropdown per a camps string de tipus de senyal.
  • Label d’Addressables module:game-mode.
  • Registre i etiquetatge d’Addressables per a GameModeSettings.

Canviat

  • SerenityPackageDependencyInstaller ara considera TextMeshPro satisfet quan els tipus runtime de TMP estan disponibles, encara que com.unity.textmeshpro no consti com a paquet independent.
  • La detecció de dependències de TextMeshPro ara suporta configuracions de Unity 6 / UGUI 2.0+ on TMP ve inclòs amb com.unity.ugui.
  • Les cadenes de labels d’Addressables ara passen per Serenity.Shared.Constants.ModuleLabels en lloc de literals string hardcodejats.
  • InstallationConstants.ModuleLabels ara actua com a shim de compatibilitat que reexporta els valors canònics de ModuleLabels.
  • InstallationConstants.TypeLabels ara actua com a shim de compatibilitat que reexporta ModuleLabels.Types.
  • UnityAddressablesLabeler ara usa constants centralitzades de ModuleLabels per a labels gestionades, regles de ruta i regles de tipus.
  • UnityAddressablesLabeler ara gestiona labels addicionals de Serenity per als mòduls Character, GameMode, SequencePlayer i Wave.
  • UnityAudioPlayerInstaller, UnityMusicPlayerInstaller, UnityGameSettingsInstaller, UnityLocalizationInstaller, UnityMenuInstaller, UnityModalInstaller, UnityPlayerInputInstaller, UnitySoundMixerInstaller, UnitySystemConfigurationInstaller, UnityCharacterInstaller i els serveis relacionats amb Cutscene/Sequence ara usen constants centralitzades de labels de mòdul.
  • AudioMixerDependencyCache ara usa per defecte ModuleLabels.AUDIO_MIXER en lloc d’una label d’Addressables hardcodejada.
  • UnityUiSettingsEditor ara renderitza ScaleKey i FontSizeKey com a ObjectFields de Unity recolzats per assets UnityUIGameSettingsDefinition.
  • UnityGameGraphicsSettingsEditor ara renderitza QualityLevelKey, ScreenResolutionKey i IsFullScreenKey com a ObjectFields de Unity recolzats per assets UnityGraphicGameSettingsDefinition.
  • UnityLocalizationSettingsEditor ara renderitza GameLanguageKey i VoiceLanguageKey com a ObjectFields de Unity recolzats per assets UnityLocalizationGameSettingsDefinition.
  • UnityMenuServiceSettingsDefinitionEditor ara renderitza InitMenuId com un ObjectField de Unity recolzat per assets UnityMenuSettingsDefinition.
  • UnityGameModeSettingsDefinitionEditor ara renderitza PauseMenuId com un ObjectField de Unity recolzat per assets UnityMenuSettingsDefinition.
  • UnityActionDefinitionEditor ara renderitza Signal mitjançant un selector de tipus de senyal amb cerca en lloc d’un dropdown simple.
  • UnityModalSettingsEditor ara renderitza SignalType mitjançant un selector de tipus de senyal amb cerca en lloc d’un dropdown simple.
  • UnityModalSettingsEditor ara comparteix el descobriment de tipus de senyal mitjançant EventDispatcherSignalTypePicker, evitant lògica de reflexió duplicada.
  • UnityMenuSettingsDefinitionEditor ara usa constants centralitzades de labels de mòdul en resoldre game settings i menús.
  • UnitySoundMixerSettingsEditor ara usa constants centralitzades de labels de mòdul en resoldre game settings d’àudio.
  • Els assets de menú d’exemple de Serenity s’han reserialitzat per incloure valors ViewId explícits en opcions i valors.
  • Els assets de menú d’exemple de Serenity ara inclouen arrays OnShow i OnHide explícitament buits.
  • L’asset d’exemple GameModeSettings ara inclou entrades de senyals de transició per als valors més nous de l’enum GameMode.

Funcionalitats

  • Els assets ScriptableObject de Serenity creats recentment ara es poden afegir automàticament al grup Addressables de Serenity amb les labels de mòdul correctes.
  • L’autoetiquetatge d’Addressables ara suporta mapatges exactes de tipus per a assets coneguts de Serenity i fallback de namespace per a assets futurs dins de mòduls existents.
  • Els selectors d’editor per a referències ScriptableObject recolzades per ids en string ara suporten drag-and-drop des de la finestra Project.
  • Els selectors d’editor per a referències ScriptableObject recolzades per ids en string ara suporten el flux estàndard de cerca de l’Object Picker de Unity.
  • Els camps de tipus de senyal ara ofereixen selecció amb cerca tot preservant els contractes string serialitzats originals.
  • UnityActionDefinition.Signal continua emmagatzemant Type.FullName.
  • UnityModalSettings.SignalType continua emmagatzemant Type.AssemblyQualifiedName.
  • UnityModalSettings.SignalType conserva l’opció <None>, emmagatzemant un string buit quan no hi ha selecció.
  • La validació de TMP Essentials s’executa tant en l’arrencada/importació de l’editor com de manera síncrona en entrar a Play Mode.
  • L’autoimportació de TMP Essentials intenta localitzar el paquet mitjançant utilitats d’editor de TMP, metadades del Package Manager o Library/PackageCache.

Millorat

  • L’UX de l’Inspector ara s’acosta més als fluxos estàndard de Unity per a referències recolzades per assets.
  • S’han reduït les seleccions invàlides accidentals causades per dropdowns llargs sense cerca.
  • S’ha reduït el codi duplicat de dropdown i reflexió entre editors personalitzats.
  • La gestió de labels d’Addressables ara és més segura i més fàcil de mantenir gràcies a una única font de veritat.
  • L’autoetiquetatge d’Addressables és idempotent i no destructiu: no elimina labels existents i només afegeix labels conegudes de Serenity.
  • La detecció del paquet TMP és més robusta entre versions de Unity.
  • La detecció de TMP Essentials ara distingeix entre tenir instal·lat el runtime de TMP i tenir presents els TMP Essential Resources reals dins d’Assets/.
  • Els diagnòstics de TMP Essentials ara registren coincidències d’assets de font TMP sense tractar-les com a prova que Essentials està instal·lat.
  • El codi d’instal·ladors i editors ara evita escampar labels d’Addressables hardcodejades per tot el codi base.
  • Les definicions d’assembly s’han actualitzat quan calia perquè els mòduls puguin referenciar les constants compartides de labels.

Corregit

  • Corregida una detecció falsa de dependència absent per a TextMeshPro en versions de Unity on TMP ve inclòs a través d’UGUI en lloc d’instal·lar-se com com.unity.textmeshpro.
  • Corregit l’etiquetatge absent module:game-mode per a GameModeSettings.
  • Corregits diversos camps d’editor que abans requerien selecció per dropdown tot i representar ids recolzats per assets.
  • Corregit que UnityActionDefinition.Signal i UnityModalSettings.SignalType continuessin com a dropdowns sense cerca després del primer refactor del selector.
  • Corregida la lògica duplicada de descobriment de tipus de senyal entre la selecció de senyal de modal i els menús de senyal dels botons de modal.
  • Corregit l’ús de labels d’Addressables hardcodejades en diversos instal·ladors i utilitats d’editor.
  • Corregida la cobertura de labels gestionades d’Addressables per a mòduls més nous de Serenity com Character, GameMode, SequencePlayer i Wave.

Infraestructura

  • Afegides utilitats d’editor per al registre automàtic d’Addressables i l’assignació de labels.
  • Afegides utilitats d’editor per a la validació i recuperació de TMP Essentials.
  • Afegida infraestructura compartida de selectors d’editor per a la selecció de tipus de senyal.
  • Afegit helper d’editor compartit per fer de pont entre ObjectField i string-id.
  • Afegides referències de definició d’assembly a Serenity.Shared.Constants allà on ara s’usen constants centralitzades de labels.
  • Actualitzada la configuració d’Addressables per eliminar labels obsoletes i incloure la nova label module:game-mode.
  • Actualitzat el grup Addressables de Serenity perquè Media/GameMode/GameModeSettings estigui etiquetat amb module:game-mode.
  • Actualitzats els assets serialitzats d’exemple perquè coincideixin amb el model de dades actual de menú i game mode.

1.0.5 — Transicions de Music Player, Senyals de GameMode i Integració amb Menu

Afegit

  • Enum MusicPlayerTransitionType amb tres estratègies de transició: CUT, FADEIN_FADEOUT i CROSS_FADE.
  • Paràmetres de transició configurables a IMusicPlayerService.PlaySong(...) i nou mètode PlaySongById(...).
  • Cas d’ús MusicPlayerPlaySongById i DTO MusicPlayerPlaySongByIdInput per reproduir pistes concretes per identificador amb control explícit de loop i transició.
  • Mètode de gateway PlaySongById a IMusicPlayerGateway.
  • Contracte SetGameModeService(IGameModeService) a IMenuService per a coordinació entre serveis.
  • Contracte GetSignalsForGameMode(GameModeEnum) a IGameModeSettingsDefinition per a configuració de senyals per mode.
  • Valors Initialization i Cutscene a l’enum GameMode, establint Initialization com el mode inicial per defecte.
  • Seqüències de transició EventDispatcherSignal per mode a UnityGameModeSettingsDefinition.
  • Orquestració DispatchModeTransitionSignals(...) a UnityGameModeService, que dispara els senyals configurats després de cada canvi de mode.
  • Inspector complet basat en ReorderableList per als senyals de transició per mode a UnityGameModeSettingsDefinitionEditor.
  • Registre de ServiceLocator per a IMusicPlayerService durant la instal·lació del music player.

Canviat

  • UnityGameModeService ara s’inicialitza en mode Initialization en lloc de Menu, ajornant la primera transició real de mode fins que el sistema de menús estigui preparat.
  • UnitySerenityInstaller.ShowMenu() ara connecta el IGameModeService resolt amb el servei de menú abans d’invocar ShowInitialMenu(), assegurant que el game mode queda sincronitzat en arrencar.
  • UnityMusicPlayerInstaller ara rep ServiceLocatorInstaller per al descobriment de serveis en runtime.
  • Format de referència de Serenity.GameMode.Domain.asmdef estandarditzat a GUID.
  • Nomenclatura d’assets preparada per a producció: Audio_SoundToTestAudio_SoundToTrigger, Audio_TrackToTestMusic_TrackList.
  • Configuració d’AudioTestingMenu actualitzada per referenciar els assets de producció reanomenats.

Funcionalitats

  • La reproducció de música ara imposa una regla d’una sola pista activa mitjançant lerping de volum basat en coroutines.
  • Les peticions de reproducció ràpides i consecutives substitueixen de manera segura les transicions anteriors (“l’última petició guanya”), evitant AudioSources orfes.
  • CROSS_FADE fa fallback automàticament a CUT quan no hi ha prou canals d’àudio configurats.
  • Els senyals de transició de GameMode es despatxen en l’ordre exacte configurat a l’inspector, amb entrades null saltades i registrades de manera segura.
  • GameMode.Menu ara s’assegura automàticament cada vegada que s’executa ShowInitialMenu(), mantenint sincronitzats el sistema de menús i l’estat de mode.

Millorat

  • L’inspector UnityGameModeSettingsDefinitionEditor ara renderitza una llista dedicada i reordenable de senyals per cada valor de GameMode, amb dropdowns de selecció de subtipus i ordenació per drag-and-drop.
  • Els elements de la llista de senyals mostren el nom del subtipus concret d’EventDispatcherSignal per identificar-los d’un cop d’ull.
  • Les definicions d’assembly Serenity.Menu.Application i Serenity.UnityMenu.Infrastructure ara referencien contractes de GameMode per a coordinació entre capes.

Corregit

  • Evitades possibles transicions recursives de mode confiant en el short-circuit de SetMode quan el mode objectiu coincideix amb el mode actual.
  • Actualitzades les signatures del stub de gateway del music player per mantenir la compatibilitat d’interfície amb el nou contracte amb transicions.

Infraestructura

  • Afegides noves referències de definició d’assembly per connectar les capes MusicPlayer, Menu i GameMode sense dependències circulars.
  • Definició d’assembly de tests ampliada per incloure Serenity.UnityMusicPlayer.Installation per a cobertura de validació a nivell d’instal·lador.

1.0.3 — Senyals de Cicle de Vida de Menú i Millores d’Inspector

Afegit

  • Afegides col·leccions de senyals de cicle de vida OnShow i OnHide a UnityMenuSettingsDefinition.
  • Afegit suport de senyals de cicle de vida de menú a IMenuSettingsDefinition.
  • Afegit despatx runtime de senyals de cicle de vida per a transicions de visibilitat de menú.
  • Afegit cablejat de senyals de cicle de vida a UnityMenuViewFactory.
  • Afegit suport SetLifecycleSignals(...) a UnityMenuView.

Funcionalitats

  • Els menús ara poden despatxar seqüències personalitzades d’EventDispatcherSignal quan es mostren o s’amaguen.
  • L’ordre d’execució dels senyals de cicle de vida ara segueix l’ordre exacte configurat a l’inspector.
  • Les col·leccions de senyals de cicle de vida ara suporten reordenació per drag-and-drop mitjançant llistes reordenables estàndard de Unity.

Millorat

  • Millorat UnityMenuSettingsDefinitionEditor amb una secció dedicada Lifecycle Signals.
  • Les llistes de senyals de cicle de vida ara ofereixen:
    • controls d’afegir/eliminar,
    • ordenació per drag-and-drop,
    • menús de selecció de subtipus,
    • estil d’inspector coherent amb la resta d’editors de Serenity.
  • Millorada la coherència d’UX de l’inspector reutilitzant els mateixos patrons de creació de senyals ja presents en altres sistemes de Serenity.

Corregit

  • Corregit el renderitzat de l’inspector de senyals de cicle de vida perquè les implementacions d’EventDispatcherSignal es puguin seleccionar correctament.
  • Corregit el flux de serialització per a senyals de cicle de vida polimòrfics amb referències gestionades de Unity.
  • Assegurat que els assets de menú legacy continuïn funcionant de manera segura amb col·leccions de senyals de cicle de vida buides.

Infraestructura

  • Reutilitzada la infraestructura existent d’EventDispatcherSignal i el flux de despatx sense introduir sistemes paral·lels de cicle de vida.
  • Mantinguts intactes els límits de Clean Architecture exposant els senyals de cicle de vida mitjançant abstraccions de capa business només de lectura.

1.0.2 — Millores d’Editor i Inspector de Localization

Afegit

  • UnityLocalizationLocaleEditorUtils, un helper d’editor basat en reflexió per al descobriment segur de locales de Unity Localization sense sobrecàrrega de dependència d’assembly.

Canviat

  • Millorat LocalizationSettingsDefinitionEditor per optimitzar l’UX dels assets UnityLocalizationGameSettingsDefinition.
  • Endurit el flux d’importació de Serenity i el procés de recuperació de localization.
  • Refactoritzat el flux de senyals de botons de l’editor de configuració de modals per obtenir interaccions d’editor més netes.

Funcionalitats

  • Bloquejat el camp ValueType a SELECTABLE amb normalització automàtica i validació de seguretat per evitar errors de configuració.
  • Substituïda l’entrada de text lliure “Key” a la taula Options per un dropdown dinàmic poblat des dels locales de Unity Localization.

Millorat

  • Afegit suport de fallback per a keys desconegudes i HelpBoxes informatius per guiar els usuaris quan la configuració de Localization falta o no està configurada.
  • Estabilitat d’inicialització del paquet després d’importar Serenity en un projecte Unity nou.

Corregit

  • Resolució del color de fons de l’overlay de càrrega quan s’usen càmeres de renderitzat.

Infraestructura

  • Reutilitzades utilitats UI existents de FoundationEditor i UnityGameSettingsDefinitionEditor per mantenir coherència visual i funcional.

1.0.0 — Llançament Inicial

✨ Funcionalitats

  • Lògica de joc desacoblada amb zero dependències del motor a les capes core. Tot el codi de domini i aplicació compila amb noEngineReferences: true, garantint que les regles de negoci siguin plenament portables, testejables i lliures d’acoblament amb Unity.

  • Sistema de persistència extensible i en capes. Una jerarquia d’emmagatzematge unificada suporta key-value stores (recolzats per PlayerPrefs), blob stores basats en fitxers amb escriptures atòmiques i streams només d’afegit — tot darrere de contractes intercanviables que poden apuntar a fitxers locals, serveis cloud o backends personalitzats.

  • Precarrega avançada d’assets amb pressupostos de memòria. Un motor de prefetch conscient de prioritats amb eviction LRU, pressupostos de memòria configurables, estratègies de finestra lliscant i sota demanda, i resolució de labels basada en Addressables proporciona disponibilitat previsible d’assets amb pressió de recursos controlable.

  • Game settings tipats i persistits per repositori. Un sistema genèric de settings suporta tipus d’opció Boolean, Integer, Float i Selectable amb notificacions de canvi de valor, persistència automàtica i integració reactiva amb mòduls d’àudio, gràfics i localization.

  • Gestió de personatges basada en estat. Els personatges segueixen un cicle de vida ben definit (Spawning → Active → Dying → Dead) amb seguiment de punts de vida, snapshots immutables i punts d’extensió virtuals per a especialització específica del joc.

  • Comptador de combos agnòstic del joc. Un model pur de comptatge amb snapshots immutables que no imposa semàntica de gameplay — timeout, multiplicador i lògica de puntuació continuen sent responsabilitat de la capa consumidora.

  • Persistència de checkpoints opaca. Slots de guardat amb nom i metadades extensibles (timestamp, label, stage) emmagatzemen payloads binaris arbitraris sense interpretar-ne ni validar-ne el contingut, deixant l’estratègia de serialització als consumidors.

  • Pipeline d’inicialització configurable. Un sistema d’arrencada ordenat per fases i tasques amb seguiment de progrés ponderat, criticitat per tasca (Critical vs. NonCritical) i polítiques d’execució pluggables (seqüencial o paral·lela per fase).

  • Sistema complet d’animació procedural. Un motor d’expressions procedurals basat en dades i claus suporta composició de poses per capes (oscil·lació, drift, soroll, impuls), animació de propietats de material, animació d’escala de transform, accions discretes one-shot (flinch, recoil, stumble), activació basada en regles amb condicions d’histèresi i ajust en temps real — tot plenament agnòstic del producte.

  • Sistema d’esdeveniments publish/subscribe type-safe. Un event dispatcher centralitzat amb accions autoregistrades, classes de senyal tipades i descobriment basat en atributs permet comunicació desacoblada entre mòduls.

  • Reproducció d’àudio multicategoria. Un sistema d’àudio enrutat per gateway suporta canals SFX, Music, Voice, Ambient, Environment i UI amb pooling per categoria i configuració de clips guiada per settings.

  • Music player dedicat amb suport de crossfade. La gestió de música de fons ofereix operacions de play, stop, fade-in, fade-out i crossfade de manera independent del sistema d’àudio de curta durada.

  • Abstracció d’audio mixer. Gestió de volum i mute per grups (Master, Music, SFX, Voice, UI) amb persistència automàtica mitjançant integració amb game settings.

  • Gestió del cicle de vida d’stage. Un agregat stage de nivell superior rastreja estats d’inici, finalització i fallada amb notificacions basades en senyals consumides per mòduls descendents com waves, timers i scoring.

  • Progressió seqüencial de waves. Estructura d’stage wave-by-wave amb detecció automàtica de clear i senyals en cascada per a wave start, wave cleared i all-waves-cleared.

  • Puntuació dinàmica multimètrica. Un model de scoring sense límit adreçat per keys amb nom suporta registre runtime de mètriques i operacions aritmètiques completes (add, subtract, multiply, divide, set, reset) amb persistència recolzada per repositori.

  • Gestió de mode d’aplicació. Un servei de game-mode coordina transicions entre estats Menu, Game i Pause amb estratègies de pausa pluggables, canvi d’action-map d’input i coordinació guiada per senyals.

  • Seguiment de cicle de vida de sessió. Gestió d’estat per sessió amb fonts de temps agnòstiques del motor, acumulació de tick frame-by-frame i snapshots de sessió immutables.

  • Sistema de gestió de timers. Timers amb nom amb modes countdown, elapsed i repeating ofereixen progrés normalitzat, control pause/resume i notificacions de cicle de vida basades en senyals.

  • Navegació de menú amb suport de stack. Un sistema de menú basat en navigation-stack suporta show, hide, push, pop i peek amb configuració per menú i senyals de cicle de vida.

  • Sistema de diàlegs modals. Diàlegs modals configurables amb factories de botons, gestió de resultat basada en callbacks i senyals preconstruïts per a confirmacions comunes (sortir de l’aplicació, reiniciar el joc, restablir settings).

  • Foundation UI agnòstica de plataforma. Una jerarquia de vistes, sistema de theme/style i model de components permeten construcció UI composable sense dependències del motor a la capa de domini.

  • Gestió d’estat de Game UI. Models d’estat abstractes de HUD i results-screen amb delegació de renderitzat mitjançant presenter-port permeten testejar la lògica UI aïllada de la infraestructura de renderitzat.

  • Localization amb integració de settings. Gestió de llengua de joc i veu amb canvi automàtic d’idioma impulsat per canvis persistents de game settings.

  • Gestió de settings gràfics. Gestió reactiva de nivell de qualitat, resolució de pantalla i mode fullscreen guiada per esdeveniments de canvi de valor de game settings.

  • Detecció de configuració del sistema. Consultes de capacitat de hardware (memòria, GPU, display) amb generació de perfil de qualitat recomanat per a configuració automàtica.

  • Model genèric de spawning i pooling. Creació i destrucció d’entitats rastrejades per handles amb consultes d’estat de pool, desacoblat de la mecànica d’instanciació mitjançant un factory port.

  • Identitat d’entitats de gameplay. Identitat d’entitat basada en GUID amb classificació semàntica (Player, Character, Hazard) proporciona un vocabulari de referència compartit entre sistemes de gameplay.

  • Model de moviment basat en rails. Rail paths amb nom i seguiment de progrés normalitzat permeten moviment on-rails impulsat externament sense acoblament amb interpolació o easing.

  • Gestió d’estat d’armes. Mecàniques de trigger, canvi de fire-mode i seguiment de magazine/ammo amb snapshots només de lectura — independent de la representació visual o dels sistemes de projectils.

  • Motor d’orquestració de seqüències. Un sistema genèric d’execució ordenada proporciona iteració d’stages basada en completament consumida per agregats verticals com el cutscene player.

  • Reproducció de cutscenes cinemàtiques. Execució temporitzada d’stages amb tipus fade, timeline, wait i dialog construïda damunt la foundation d’orquestració de seqüències.

  • Logging estructurat amb verbositat per categoria. Un sistema de logging configurable amb nivells de severitat, overrides per categoria, perfils d’encaminament de logs i component loggers consumits per cada mòdul.

  • Navegació de view browser. Navegació forward/back de pantalles amb consultes d’estat de navegació per a fluxos de browsing impulsats per UI.

  • Service locator mínim. Un contracte de resolució de serveis recolzat per diccionari per a casos estrets on la injecció per constructor és impracticable, com accions d’esdeveniment instanciades per reflexió.

  • Sistema de tasques composable. Contractes d’unitats de treball async amb nivells de criticitat, invocació de mètodes basada en reflexió, resolució d’arguments conscient de serveis i suport de despatx al main-thread.

  • Persistència basada en fitxers amb escriptures atòmiques. Un blob store de sistema de fitxers amb seguretat write-then-rename, resolució de paths específica de plataforma i suport de streams només d’afegit.

🧱 Arquitectura

  • Aplicació estricta de Clean Architecture. Cada agregat segueix una capa estricta Domain ← Application ← Installation amb fletxes de dependència només cap endins. Les capes de domini tenen zero o mínimes dependències externes; les capes d’aplicació depenen només de contractes de domini i serveis foundation transversals; les capes d’instal·lació connecten implementacions específiques de plataforma.

  • Aïllament del motor mitjançant assembly definitions. Els assemblies core business declaren noEngineReferences: true, garantint en temps de compilació que cap API de Unity es filtri a la lògica de domini o aplicació.

  • Principis SOLID a tot arreu. Agregats d’una sola responsabilitat, contractes de servei segregats per interfície, extensió open/closed mitjançant instal·ladors abstractes i factory ports, i inversió de dependències mitjançant interfícies agnòstiques de plataforma.

  • Vocabulari de Domain-Driven Design. Les entitats porten estat mutable amb transicions protegides, els value objects ofereixen identitat i snapshots immutables, i els agregats defineixen bounded contexts amb punts d’integració explícits.

  • Disseny d’API guiat per casos d’ús. Les operacions orientades al consumidor s’encapsulen en classes de cas d’ús tipades amb DTOs d’entrada dedicats, agrupades en contenidors injectables per a grafs de dependència nets.

  • Patró de snapshot immutable. Tots els agregats amb estat exposen snapshots només de lectura per a consultes, assegurant que els consumidors no puguin mutar accidentalment l’estat intern.

  • Patró d’instal·lador abstracte. Cada agregat defineix un instal·lador abstracte que declara el contracte de cablejat; les capes concretes de plataforma (Unity, tests o targets personalitzats) proporcionen implementacions sense modificar el codi business.

  • Comunicació entre mòduls basada en senyals. Senyals d’esdeveniment tipats flueixen a través d’un dispatcher centralitzat, mantenint els agregats desacoblats mentre permeten coordinació reactiva.

📦 Mòduls

  • Global — Contractes foundation, esdeveniments de cicle de vida (exit/restart), jerarquia d’interfícies de casos d’ús, model de components per a composició UI i base d’instal·lador abstracte consumida per tots els altres agregats.

  • EventDispatcher — Sistema publish/subscribe type-safe amb accions autoregistrades, classes de senyal tipades i descobriment basat en atributs.

  • Logging — Logging configurable amb nivells de severitat, overrides de verbositat per categoria, perfils d’encaminament de logs, component loggers i suport de sortida a fitxer/consola.

  • ServiceLocator — Resolució de serveis tipada mínima amb una implementació per defecte basada en diccionari.

  • Task — Contractes d’unitats de treball async amb criticitat, invocació de mètodes basada en reflexió i resolució d’arguments extensible.

  • InitializationPipeline — Sistema d’arrencada ordenat per fases i tasques amb seguiment de progrés ponderat, gestió de fallades basada en criticitat i polítiques d’execució pluggables.

  • Persistence — Jerarquia d’emmagatzematge en capes: key-value stores, blob stores basats en streams i stores només d’afegit — tot darrere de contractes de plataforma intercanviables.

  • FilePersistence — Blob store de sistema de fitxers amb seguretat d’escriptura atòmica write-then-rename i resolució de paths específica de plataforma.

  • PlayerPrefsPersistence — Key-value store lleuger recolzat per Unity PlayerPrefs amb codificació Base64.

  • GameSettings — Sistema de settings tipats (Boolean, Integer, Float, Selectable) amb persistència de repositori i notificacions de canvi de valor.

  • Checkpoint — Persistència opaca de checkpoints binaris amb slots amb nom (Slot1–3, Auto, Quick) i metadades extensibles.

  • Score — Model de scoring multimètric dinàmic amb mètriques il·limitades basades en keys, operacions aritmètiques completes i persistència de repositori.

  • Combo — Comptador de combos agnòstic del joc amb snapshots immutables i punts d’extensió virtuals per a multiplicador, timeout o comportament de decay.

  • Character — Cicle de vida de personatge basat en estat (Spawning → Active → Dying → Dead) amb gestió de punts de vida, enums d’estat heretables i snapshots immutables.

  • GameplayEntity — Identitat d’entitat basada en GUID amb classificació semàntica i referències lleugeres entre sistemes.

  • GameSpawner — Spawning d’entitats rastrejades per handle i gestió d’estat de pool amb un factory port per a l’estratègia d’instanciació.

  • Stage — Cicle de vida d’stage de nivell superior (NotStarted → InProgress → Completed/Failed) amb resolució de spawn-point i contractes d’autoria de rail-path.

  • Wave — Progressió seqüencial de waves amb detecció automàtica de clear i senyals de cicle de vida en cascada.

  • Timer — Gestió de timers amb nom amb modes countdown, elapsed i repeating, progrés normalitzat i senyals de cicle de vida.

  • GameMode — Màquina d’estats de mode d’aplicació (Menu, Game, Pause) amb estratègies de pausa pluggables i transicions guiades per senyals.

  • GameSession — Seguiment de cicle de vida per sessió amb fonts de temps agnòstiques del motor i acumulació de temps transcorregut basada en ticks.

  • AudioPlayer — Reproducció d’àudio multicategoria amb encaminament per gateway, pooling de canals i operacions guiades per casos d’ús.

  • MusicPlayer — Gestió de música de fons amb operacions play, stop, fade i crossfade.

  • SoundMixer — Gestió de volum i mute basada en grups amb integració reactiva de game settings.

  • GameGraphics — Gestió reactiva de nivell de qualitat, resolució i fullscreen guiada per canvis de game settings.

  • SystemConfiguration — Detecció de capacitats de hardware amb generació de perfil de qualitat recomanat.

  • PlayerInput — Abstracció d’input agnòstica de plataforma amb canvi d’action-map i contractes de binding d’input-action.

  • Ui — Jerarquia de vistes, sistema de theme/style i model de components per a construcció UI composable i independent del motor.

  • Menu — Sistema de menú basat en navigation-stack amb configuració per menú i senyals de cicle de vida.

  • Modal — Diàlegs modals configurables amb factories de botons, resultats basats en callbacks i senyals de confirmació preconstruïts.

  • GameUi — Gestió abstracta d’estat de HUD i results-screen amb delegació presenter-port.

  • ViewBrowser — Navegació de pantalla forward/back amb consultes d’estat.

  • Localization — Gestió de llengua de joc i veu amb canvi automàtic guiat per settings.

  • SequencePlayer — Motor genèric d’orquestració d’execució ordenada per iteració d’stage basada en completament.

  • CutscenePlayer — Reproducció cinemàtica amb stages temporitzats (fade, timeline, wait, dialog) construïda damunt l’orquestració de seqüències.

  • GameRail — Registre de rail-paths amb nom i seguiment de progrés normalitzat per a moviment on-rails.

  • GameWeapon — Mecàniques de trigger, canvi de fire-mode i seguiment de magazine/ammo amb snapshots només de lectura.

  • ProceduralExpression — Sistema d’animació procedural basat en dades amb composició de poses per capes, animació de material/transform, activació basada en regles, accions discretes i suport de tuning en temps real.

  • Shared — Constants transversals (noms de serveis, labels de mòdul, identificadors de context) i classes d’utilitat (parsing, reflexió, generació de GUID).

🛠️ Eines

  • Generador de documentació d’API basat en DocFX. Un builder de documentació integrat accessible des de Tools → Serenity → Docs compila tots els assemblies amb documentació XML de Roslyn i genera un lloc estàtic navegable d’API mitjançant DocFX — amb instal·lació automàtica, generació de configuració i suport de plantilla amb marca.

  • Eina de configuració de Procedural Expression. Un assistent one-click (Tools → Serenity → Procedural Expression → Setup Minimal Idle) autodetecta ossos de l’esquelet, genera tots els assets de configuració necessaris i connecta un perfil d’animació procedural a qualsevol prefab — suportant personatges riggejats, objectes simples, props i elements UI.

  • Inspector de diagnòstics d’Asset Prefetcher. Un inspector personalitzat d’Editor per al servei de prefetch ofereix refresh de cache, clear, exportació al clipboard, visualització de diagnòstics, polling d’auto-refresh i visualització d’asset categories amb codi de colors.

  • Inspector de System Configuration. Un inspector personalitzat per als settings de configuració del sistema ofereix una interfície completa per al timing de recollida de dades, scope i ajust d’heurístiques.

  • Inspectors de Menu i Modal. Inspectors personalitzats d’Editor per a vistes de menú i components modals ofereixen visualització de configuració només de lectura, gestió de bindings de senyal i interfícies de configuració de botons.

  • Configuració basada en ScriptableObject. Perfils de política de prefetch, perfils de procedural expression, state keys, layers, actions, rules, audio settings, definicions de game settings i taules de localization s’autoritzen tots com a assets ScriptableObject — permetent configuració per part de no programadors i presets versionats.

  • Patró d’instal·lador abstracte per al cablejat de plataforma. Cada agregat defineix un instal·lador abstracte amb dependències explícites; els instal·ladors concrets específics de Unity gestionen la creació de MonoBehaviour, la integració d’Addressables i el registre al service locator.

  • Panell de debug de Procedural Expression. Un overlay GUI runtime (alternat amb F12) mostra valors de state-key en viu amb sliders amb codi de colors, pistes de rang i controls de reset per a tuning en temps real en Play Mode.

  • Property drawers personalitzats de Procedural Expression. Drawers de referència de Bone ID amb selecció dropdown conscient del perfil, editors de regles amb configuració inline de condicions i editors de perfil amb validació i visualització de propietats derivades.

🎯 Propòsit

Serenity existeix per eliminar el boilerplate recurrent que acompanya cada projecte Unity: cablejat de persistència, gestió de settings, encaminament d’àudio, seqüenciació d’inicialització, transicions de mode i fontaneria d’esdeveniments. En lloc d’oferir sistemes de gameplay opinats, proporciona l’esquelet arquitectònic — contractes nets, límits en capes i mòduls composables — sobre el qual es construeix el codi específic de cada joc.

En imposar aïllament estricte del motor a les capes core, Serenity garanteix que la lògica business sigui testejable fora de Unity, portable entre plataformes i resilient als canvis de l’API del motor. El patró d’instal·lador abstracte significa que canviar un backend de persistència o un sistema d’input requereix implementar una sola interfície, no refactoritzar un arbre de dependències.

Cada mòdul segueix les mateixes convencions estructurals: entitats de domini amb transicions d’estat protegides, snapshots immutables per a consultes segures, classes de cas d’ús amb entrades tipades i punts d’integració basats en senyals. Aquesta coherència redueix el temps d’onboarding i fa que els patrons entre mòduls siguin immediatament recognoscibles.

Serenity no és una plantilla de joc. No proporciona personatges, ni nivells, ni condicions de victòria. Proporciona la foundation que fa que aquests sistemes siguin més nets, més ràpids de construir i més fàcils de mantenir durant tota la vida del projecte. ºº