Changelog

Latest updates and improvements to Serenity.

Back to home

1.3.0 — Leaderboards, Game Saves, Data-Driven HUD & the Rebuilt Serenity Hub

This release is about your players' data: putting it on screen and keeping it safe. A complete leaderboard stack, a full game-save system with slots and permanent progress, and an authorable HUD with a visual builder and its own animation system — plus gamepad motion (gyro) support, the Serenity Hub rebuilt as a searchable workspace, and new wizards that configure all of it without touching code.

Added

  • Leaderboards (new module) — a complete high-score stack, end to end. The five-step Create Leaderboard wizard (Tools ▸ Serenity ▸ Create ▸ Leaderboard ▸ Create Leaderboard) walks you through it: pick a preset ("High Score", "Best Time"…), pick the score your game already tracks, pick where the data lives — device storage, human-readable JSON files, an embedded SQLite database, your own HTTP service, or a direct Postgres/MySQL/MongoDB connection — and optionally get a ready-to-navigate leaderboard screen wired into an existing menu. Ranking is deterministic with proper tie handling, all 8 shipped themes render the board in their own visual language, and a misconfigured backend never breaks your game: it logs a warning and falls back to device storage.
  • Game saves & permanent progress (two new modules)GameSave gives your game a configurable number of save slots, each an extensible document of typed sections (inventory, milestones, completion — plus anything your game registers). Save-slot menus list label, timestamp and completion instantly, without loading whole saves. GameProgress keeps what must survive slot deletion — completion counts, unlocked extras — so wiping a playthrough never erases what the player has earned. Checkpoint quicksaves travel inside the active slot automatically, cloud saves are a backend choice rather than extra code, and two wizards (Create Game Save Settings, Create Game Progress Settings) configure everything, backend included.
  • Data-driven HUD with a visual builder — health bars, ammo counters, timers and any live stat, authored as data instead of hand-wired scripts. Elements anchor to nine screen positions with independent grow direction, bind to live game data, and draw through seven display styles — text, number, time (including the arcade MM'SS"CC style), stack, segmented, gauge and icon set. Author for player 1 and get player 2 mirrored automatically. HUD Builder guides the data binding so only valid chains can be authored, and HUD Preview is a true editing surface: drag to move, pull handles to scale, rotate Photoshop-style, snap with Ctrl — every gesture is a single undo step, at any resolution and theme. A dedicated validator flags bindings broken by renames before your players ever see a blank element.
  • HUD elements nest and animate — elements can be grouped inside layout boxes that arrange their children automatically (spacing, alignment, padding), a number can split into a big integer part and a small fraction part, and everything animates through fifteen ready-made presets — Punch, Pulse, Heartbeat, Blink, Wiggle, Spin, Shake, Slide in, Fade in, Damage flash, Ghost pulse and more — covering scale, rotation, position, visibility and color. Animations trigger on value changes, signals or on show, with per-entry cooldowns, all authored in the builder's new Animation tab and validated like everything else.
  • Animation Hub (Tools ▸ Serenity ▸ Browse ▸ Animation ▸ Animation Hub) — one searchable window for every animation in the project: model-embedded clips, standalone clips, animator controllers with their states and transitions, and procedural animation. Create and edit clips and controllers in place, preview a clip live on the actual model with play and scrub controls, and simulate procedural profiles against real state values — without ever touching your scene or your assets.
  • Gamepad motion (gyro) support — DualSense, DualShock 4 and Switch Pro now expose gyro and accelerometer readings, with drift calibration built in. The Controls settings menu gains Gyro Aim and Gyro Sensitivity options your players can use out of the box, and the new Gamepad Motion Monitor window shows live motion values per connected pad for tuning.
  • Score, leveled up — declare score metrics on a settings asset instead of registering them in code (the new Score Settings wizard authors it), feed a metric from how far something travels with the new Transform Distance Meter component, and award fixed amounts from any trigger with the new AddScoreSignal — all zero-code. Score also now installs through the Initialization Pipeline like every other system.
  • Leaderboards meet the HUD, no code required — show a board's #1 entry or the local player's personal best directly on the HUD through bindable services and a best-entry cache component; submit the current score from any trigger — a button, a signal reaction — through the new submit component's single SubmitNow() call; and render any decimal precision a score needs.
  • Database Drivers window (Tools ▸ Serenity ▸ Validate ▸ Database Drivers) — choosing a real database backend requires hand-installed driver DLLs; this window lists exactly which files each backend needs, marks what is already installed, links every missing one to its exact NuGet package and version, and only offers to enable the backend once the set is complete. No more discovering dependencies one error at a time.
  • The Serenity Hub, rebuilt from the ground up — the package's front door is now a full workspace: six views (Home, Create, Validate, Browse, Advanced, Learn), a card grid where every tool shows its icon and description, favorites and recents pinned to Home, and Ctrl+K global search across all 89 tools. Validation never runs behind your back anymore: results are cached with their timestamp, and scans run only when you ask.
  • AI Prompt Builder (Tools ▸ Serenity ▸ AI ▸ Prompt Builder) — a wizard that interviews you about what you want to build and generates the optimal prompt for your AI agent. It scans the project so the prompt extends your real assets instead of creating from scratch, keeps a personal library of reusable instructions, and delivers the result to the clipboard, a file, or straight into your agent as a slash command. Its intents now include a free-form request — describe anything in plain language and the prompt routes the agent to the right modules — and a dedicated HUD design intent.
  • Add Language wizard — add a locale to your existing translation tables in one guided pass: filterable, paged grids with a reference-language column for context, optional wiring into your language settings, and atomic rollback if anything fails. It never invents new keys.
  • Documentation that wears your game's brand — the generated docs site now takes its title, logo text, tagline, footer and accent color from your Player Settings automatically, and the new Docs Branding window (Tools ▸ Serenity ▸ Docs ▸ Docs Branding) lets you customize all of it with a live preview.
  • Sample scene generator (Tools ▸ Serenity ▸ Create ▸ Samples ▸ Generate Sample Scene) — generates the demo scene on demand: canvas, diagnostics HUD, a toast host and a button wired to show a toast. Safe to re-run.
  • New validatorsAddressable Keys catches stored asset paths that would silently fail to load at runtime, with a one-click fix; Localization Keys gains a live locale preview and per-locale warnings for keys that exist but have no translation yet.
  • The Signal Flow Browser now sees everything — signal emitters and reactions placed in prefabs and scenes, action definitions, and menu or modal option signals all show up as dispatchers and reactions. A signal fired only from a menu option no longer misreports as "Unused".

Improved

  • Every signal picker is searchable — the long flat menus for choosing a signal type are replaced by a searchable dropdown, everywhere.
  • Every wizard, one experience — all creation wizards now share the same step engine, so the breadcrumb is freely navigable in both directions in every one of them: any step you've already visited is one click away.
  • Fire Now in the Modal Builder — preview the modal you're authoring while Play Mode runs, before creating any asset.
  • Create Player Input can author the Input Actions asset — the wizard now offers "Create New…" instead of requiring an existing .inputactions file.
  • Rails can be bound at runtimeBindRail(railService, railId) on the rail follower and driver enables per-instance rails, for example pooled NPCs each following their own path.
  • Bring your own adaptive-trigger backend — register a custom backend from your own code (for example a licensed console SDK) and it survives package updates; a failing backend falls back gracefully instead of breaking feedback.
  • HUD Builder arguments are type-aware — board ids, score keys and field selections render as dropdowns populated from your project's own assets instead of free-text fields, and they refresh live as you add boards or metrics.
  • Positioned sounds are audible by default — a one-shot played at a world position without authored spatial settings now gets a sensible rolloff instead of Unity's default, which made a cue fired from twenty meters away practically inaudible.
  • Editor text fields commit when you click away — typing a value and clicking Create or Next no longer discards the edit still sitting in the field; sustained typing still collapses into a single save and a single undo step.
  • A cleaner Tools menu — internal development-only tooling no longer appears in your project.

Fixed

  • Time values with hours now format like a clock: 3600 seconds renders as 1:00:00.
  • All Addressables operations now run on the Unity main thread, eliminating rare, hard-to-diagnose errors when entering Play Mode while assets load during boot.
  • Retag All (Plugin) no longer registers file types the Addressables build cannot pack, and now also cleans up entries that no longer belong — running it once repairs an already-affected project.
  • Starting a wave no longer releases pooled actors that other systems spawned through the same service.
  • A Signal Emitter can now be wired directly into a Button's On Click (new DispatchSignal methods usable from UnityEvents).
  • The asset-path field in the Inspector no longer breaks a valid Addressables address when you edit it.
  • A gamepad whose connection fails now degrades to silence instead of surfacing errors mid-game.
  • Package upgrades are more resilient: a stale development marker accidentally copied into a game project is detected and cleaned automatically, and project validation no longer reports false branding errors on clean projects.
  • Generated docs now apply the configured accent color, and the docs landing page no longer links to a page that doesn't exist in game projects.
  • Leaving pause through Resume, Back to menu or Restart now notifies pause listeners exactly once — anything tracking pause state through signals no longer gets stranded in a paused state.
  • Reading a BOOL game setting with an authored default no longer throws.
  • Performance: steady per-frame allocations in the HUD and procedural-animation path were cut by roughly two thirds, and a diagnostic-logging hitch during pooled enemy spawn bursts is gone.

Upgrade notes

Most projects update with a regular package import. If you've extended Serenity, a few API changes may need a small touch:

  • Custom IServiceLocator implementations must add the non-generic TryGet(Type, out object) member — for a dictionary-backed locator it's a one-line delegation.
  • Custom IUiThemeComponents implementations must add a HudElementTemplate property; returning null is valid and simply skips HUD theming.
  • Custom sequence player subclasses that branched on stage.StageType must compare stage.Kind (a string) instead. Existing sequence assets migrate automatically on first load — no manual step required.
  • Custom initialization pipeline profiles must add the four new install tasks (InstallScore, then InstallLeaderboard — before InstallMenu — plus InstallGameSave and InstallGameProgress), and game installers should resolve IScoreService, ILeaderboardService, IGameSaveService and IGameProgressService lazily, since they now register during the pipeline.
  • The ProceduralExpression module is now called ProceduralAnimator — update using Serenity.ProceduralExpression... directives, asmdef references to the old assembly names, and any recipe or serialized type string that names the module. Scenes, prefabs and assets keep resolving without reimport, since script identities are preserved.
  • Custom procedural layer subclasses declare which channels they write through a one-line DrivenChannels override, and RegisterTransformTarget now takes an explicit allowPositionOverride argument.
  • Several designer-facing asset types now generate a stable internal Guid on first load — re-save those assets once to persist it.
  • If the very first import of 1.3.0 reports "multiple assembly definition files": delete the duplicate .asmdef file whose .meta GUID differs from the same-named one shipped by the package, let the editor recompile, and the package's self-cleaning completes the rest automatically. This can only happen once, on the import that delivers the fix — later updates reconcile renamed modules and folders on their own.

1.2.2 — Effortless, Self-Cleaning Package Updates: One Import, Zero Leftovers

Improved

  • One-import updates — moving up to the latest Serenity is now a single, clean import. The package tidies up after itself automatically, so files retired in newer versions don't linger in your project or get in the way.
  • Hands-off upgrade flow — the update applies quietly in the background and leaves everything you've configured exactly as it was, so you can grab the newest Serenity and get right back to building.

Upgrade note

Updating from any previous version is a simple package import — no manual folder deletion and, in the common case, no editor restarts required.

1.2.1 — Service Extension Creator: Extend Anything (Services, Stores, Repositories, Gateways, Factories, Installers & Your Own Classes) + Self-Cleaning Package Upgrades + Opt-In Gameplay Readiness Gate + Technical-Debt Sweep

Added

  • Service Extension Creator — a new wizard (Tools ▸ Serenity ▸ Services ▸ Service Extension Creator) that generates ready-to-use, fully wired code to extend almost anything in Serenity: services, persistence stores, repositories, gateways, factories — and even your own custom classes. No more hand-wiring boilerplate to add your own logic on top of the framework.
  • Effortless package updates — updating Serenity is now a simple, single import. The package cleans up after itself automatically, so old or renamed files from previous versions no longer stick around and cause conflicts.
  • AI agent skills installer — a new tool to install Serenity's AI coding assistant skills directly into your project for Claude Code, Cursor, GitHub Copilot, and other AI coding tools.

Improved

  • Smoother loading screens — the loading progress bar now animates cleanly to 100% before the game reveals, instead of feeling abrupt on fast loads.
  • Gameplay readiness gate is now opt-in — projects that don't need to wait for extra gameplay setup before showing a level no longer pay any unnecessary loading delay.
  • Sound pooling, split-screen camera shake, menu alignment, and rail movement all received polish and correctness improvements under the hood.

Fixed

  • Menu and modal show/hide sounds now play correctly.
  • Backing out of a menu now plays the proper "cancel" sound instead of the wrong one.
  • Minor gameplay session and weapon-reload edge cases were tightened up.

Cleanup

  • Removed unused, non-functional legacy code to keep the framework lean.

Upgrade note

Updating from any previous version is now a simple package import — no manual folder deletion or editor restarts required in the common case.

1.2.0 — Game Camera System, Theme Builder, Setup Assistant, Serenity Hub, Safe Asset Delete, Live Cutscene Preview & Visual Signal Flow

This release is about two things: getting you from an empty project to a running game faster than ever (Serenity Hub, Setup Assistant, Theme Builder) and protecting your project while you work (Safe Asset Delete, Validate Everything, live previews). It also ships a brand-new Game Camera module with local-multiplayer split-screen, and Serenity's entire business core is now engine-agnostic — your game rules no longer depend on Unity types.

Added

  • Game Camera system (new module) — a complete camera management layer behind one service, IGameCameraService. It keeps a registry of every camera in the game (auto-discovered on scene load, even inactive or unreferenced ones), switches the active camera without breaking your rigs — only the Camera component is toggled, never the GameObject, so a CinemachineBrain or any sibling script keeps running — and gives you local-multiplayer split-screen out of the box, with automatic viewport layouts that recalculate as players join and leave. Register cameras with zero code via UnityGameCameraRegistrar, or exclude one from discovery with a UnityGameCameraExclude marker.
  • Theme Builder wizard (Tools ▸ Serenity ▸ UI ▸ Theme Builder) — a complete, ready-to-run UI theme from scratch in one pass. Pick three colors, a font, a background and a selection style, and it generates the theme asset plus 20 prefabs (buttons, sliders, dropdowns, toggles, labels, loading bars, modals, toasts and more) — including generated show/hide and selection animations with None / Subtle / Elegant / Energetic presets and live previews. Everything is auto-registered into Addressables and can be set as your active theme immediately. No sample themes required, no cloning, no manual wiring.
  • Setup Assistant (Tools ▸ Serenity ▸ Setup Assistant) — from an empty project to a playable boot → main menu → gameplay → pause loop in five guided steps. It validates your choices live, shows a real dry-run preview before writing anything, and every asset it creates is idempotent — re-running never duplicates your work.
  • Serenity Hub (Tools ▸ Serenity ▸ Hub) — the package's "start here" front door: a status dashboard for required Unity packages, installer wiring and overall project health, plus a categorized launcher for the 50+ Serenity tools. Every row deep-links into the real tool that fixes it. Opens automatically on first import.
  • Safe Asset Delete — deleting an asset that other assets still reference no longer leaves silent dangling references behind. A review window lists every affected asset (click to inspect it), and Delete & Clean removes the asset and nulls out every stale reference for you, logging exactly what was cleaned.
  • Signal Flow Browser, redesigned as a visual diagram — see your event flow as a node diagram that reads cause → signal → effect, with color-coded cards, filter chips (In Use / Unused / Dispatcher / Modal / Reaction), click-to-highlight connections and jump-to-asset or jump-to-script from every node. Finding the signals your project no longer uses is now one click.
  • Live cutscene preview — the Cutscene Outline now previews your cutscene inside the editor window: scrub the timeline, press play, and watch fades and Timeline stages rendered through the rig's own camera — no Play mode, no changes to your open scene.
  • Validate Everything (Tools ▸ Serenity ▸ Validate Everything) — one dashboard aggregating every project validator, including two new ones that catch assets missing their Addressables labels and audio definitions missing from their registries — the classic "why doesn't my sound play?" gaps. Fixable findings get one-click Fix buttons with a confirmation naming exactly what will change.
  • Inline post-creation checklists — audio clip and music track assets now show their Addressables-tagging and registration status directly in the Inspector, each with a one-click fix — so a missing registration surfaces while you author, not at runtime.
  • Installer status at a glance — the Serenity Installer inspector now groups its fields into Required and Optional and shows live status under each one: green when assigned, red when the game cannot boot without it, yellow when leaving it empty silently disables a feature.
  • Safer wave authoring — a wave spawn entry's actor slot now only accepts prefabs and warns when it's empty, instead of letting you author a wave that silently spawns nothing.
  • Engine-agnostic core — Serenity's entire business layer now compiles without Unity. Your game rules, settings and flows are written against pure C# contracts: easier to test today, portable tomorrow.

Fixed

  • The pause menu no longer stays visible behind other menus when navigating from pause to another view (for example Options).
  • Four shipped modals (End Game Session, Exit Application, Reset Settings, Restart Game) had their signal references silently broken by an earlier internal rename; they resolve again and stay visible to the Signal Flow Browser.
  • Audio registration validation no longer falsely flags every registered clip and track, which also restores the one-click Fix (register) buttons.
  • Dropdowns generated by the theme tooling now wire their selected value correctly, including its runtime translation.
  • A handful of leftover Spanish editor labels and log messages were translated to English.

Upgrading from 1.1.x

This release includes breaking API changes (that's why it's 1.2.0). You don't have to hunt them down by hand: run Tools ▸ Serenity ▸ Migration ▸ Migrate to 1.2.0 — it scans your project's code, shows a before/after preview of every change with checkboxes, and applies only what you approve; anything ambiguous is reported instead of rewritten, and re-running it is always safe. An upgrade guide ships in the package for the few manual cases. Existing character config assets need a one-time retag and re-save — Validate Everything points at each one and fixes the tags for you.

1.1.4 — Feedback System (Vibration, LED, Adaptive Triggers, Screen Shake/Flash, Hit-Stop, Audio), Linux USB & Bluetooth + Windows Bluetooth Gamepad Output, GNOME/KDE Wayland Monitor Detection, Cutscene Wizard, Looping Cutscenes, No-Code Cutscene Triggers & Typed Cutscene Recipes

Added

  • Bluetooth gamepad output on Linux (DualSense & DualShock 4) — vibration, LED and adaptive triggers drive the pads over Bluetooth as well as USB. The raw-HID writers detect each pad's transport from the hidraw HID_ID bus field and emit the report that bus requires: over Bluetooth the reframed, CRC32-checksummed reports (DualSense report id 0x31 with a rolling sequence tag; DualShock 4 report id 0x11), over USB the plain 0x02/0x05 reports. The checksum is a PlaystationHidChecksum helper — a reflected CRC-32 over an 0xA2 seed plus the report body, matching the kernel hid-playstation driver. The Switch Pro's 0x10 report is identical over both buses. RawHidDevice exposes a GetBusType query and a HidBusType enum for the transport selection.

  • Bluetooth PlayStation output on Windows (DualSense & DualShock 4) — vibration and LED now drive a DualSense or DualShock 4 over Bluetooth on Windows, which previously did nothing: Unity's built-in PlayStation output is inert over Bluetooth, and Serenity's Windows path only carried the USB report through ExecuteCommand. Each writer now sends the same Bluetooth report Linux uses (DualSense 0x31, DualShock 4 0x11, both CRC32-suffixed) through a raw Windows HID handle (RawHidDevice) — USB stays on ExecuteCommand, Bluetooth is routed through the shared GamepadHidrawTransport. RawHidDevice (Windows) gained three fixes this required: it matches the Bluetooth device-path spelling (vid&0002054c_pid&0ce6) as well as USB (vid_054c&pid_0ce6); it resolves a pad by serial or, when the serial isn't in the path (as over Bluetooth), the single unambiguous VID/PID match; and it pads each write to the device's OutputReportByteLength (read once via HidP_GetCaps), which Windows requires for HID WriteFile. The DualSense additionally needs a one-time RELEASE_LEDS report before the first colour report, or its lightbar ignores colour and stays in its power-on state (the DualShock 4 lightbar responds to its flags byte directly). Validated on hardware over Bluetooth (both pads). (Bluetooth input on Windows is Unity's own HID backend — it works once Windows finishes installing the pad's HID interface; a half-installed pairing shows the controller but streams no input, fixed by removing and re-pairing it.)

  • GNOME & KDE monitor detection on WaylandLinuxSystemMonitorsProvider detects the multi-monitor layout across the major Wayland compositors by trying several backends in priority order and taking the first that returns data: swaymsg (wlroots/Sway), wlr-randr (other wlroots compositors such as Hyprland/river), kscreen-doctor -o (KDE Plasma / KWin) and the org.gnome.Mutter.DisplayConfig.GetCurrentState D-Bus method via gdbus (GNOME). GNOME and KDE Wayland sessions get correct per-monitor position, resolution, refresh rate and primary-display flag. EDID-based identity (manufacturer/model/serial) comes from /sys/class/drm for every backend.

  • Feedback system — a new module for game feel, with one caller-facing entry point, IFeedbackService (Serenity.Feedback.Application). A piece of feedback is a definition (a list of effects authored as one asset) played by id: Play("Hit") fires it on the pad that most recently acted, and global enable and intensity scaling live in exactly one place (SetGlobalEnabled / SetGlobalIntensity, applied to every impulse). Targeting is multiplayer-aware — the same definition can be addressed at the acting pad, a specific joined player (PlayForPlayer), a specific PlayerInput (PlayForPlayerInput), or a specific device (PlayForDevice) — and StopAll cuts every channel and pad at once. The core (definitions, effects, intensity math, scaling) is engine-agnostic (Serenity.Feedback.Domain / Serenity.Feedback.Application, deliberately no UnityEngine types); the Unity side (Serenity.UnityFeedback.Infrastructure) provides the channels, gamepad output, settings and editor tooling.

  • Eight feedback effects — a definition composes any of: Gamepad Vibration (dual low/high-frequency motors with a hold duration), Gamepad LED (DualSense light-bar colour), Gamepad Adaptive Trigger (DualSense; Resistance, Weapon or Off mode with start/end travel and strength), Screen Flash (full-screen colour flash with an authorable alpha-over-time envelope, on unscaled time so it survives a hit-stop), Gameplay Hit Stop (brief time-scale dip on impact), Screen Shake (Camera) and Screen Shake (UI) (decaying positional shake, world-space and screen-space), and Audio (Sound) — play an authored sound (referencing a UnityAudioPlayerClipDefinition) through the audio player as part of the same cue, so a single definition fires rumble + flash + a sound together. Effects are authored inspector-side via [SerializeReference] FeedbackEffectAuthoring blocks (the layer that holds Color, [Range] and tooltips) and converted to the pure effects; each effect is handled by its own channel, and every haptic/visual impulse is scaled by the global intensity before output. Audio is the exception — it is independent of the vibration enable/intensity settings (it plays even when controller vibration is off and its volume is never attenuated), expressed through a per-effect BypassesGlobalGate opt-out on the effect contract so the service gates each effect individually rather than the whole definition.

  • Cross-platform gamepad output (DualSense / DualShock 4 / Switch Pro) — Serenity drives vibration, LED and adaptive triggers by owning the controller's HID output report directly. The DualSense writer carries vibration, LED colour AND both adaptive triggers in a single USB report, so a vibration or colour update no longer clobbers an active trigger effect (it keeps per-device state as the single source of truth and re-emits the whole report on every change); the DualShock 4 writer combines vibration and light-bar colour the same way; and a streaming Switch Pro service drives HD vibration and the Home-button LED over a raw HID handle (the pad's vibration is not latched, so it is streamed at ~100 Hz on a background thread, with intensity mapped through a perceptual curve). Feedback routes to the device that actually triggered the action via an acting-device tracker, so in local multiplayer each player's effects land on their own pad, and identical pads are disambiguated by serial.

  • Linux gamepad support — on Linux, Unity's input backend cannot send HID output reports, so Serenity writes LED / vibration / adaptive-trigger reports straight to the controller's /dev/hidrawN node (the same path the Switch Pro uses on every OS), covering DualSense, DualShock 4 and Switch Pro over both USB and Bluetooth (the per-bus report selection is detailed above). The Switch Pro face buttons are also mapped on Linux's SDL backend (which exposes them by Nintendo label rather than physical position) so buttonSouth = the physical bottom button as on every other platform.

  • No-code feedback triggerPlayFeedbackSignal is the event-dispatcher bridge to the service: dispatch it (e.g. from the existing no-code SignalEmitterComponent, or any EventDispatcherAction) with a definition id and optional player/device targeting, and the feedback plays — so "when signal X happens, vibrate / flash / shake" needs no hand-written code. A FeedbackDefinition ScriptableObject (Serenity ▸ Feedback ▸ Feedback Definition) holds the authored effect list, and a worked StartGameFeedback example (StartGameFeedbackAction reacting to StartGameFeedbackActionSignal) ships under EXAMPLES.

  • Menu feedback — menu navigation plays feedback no-code: a configured definition fires when the selected option changes (MenuTickDefinitionId) and when an option is submitted (MenuSubmitDefinitionId), both read from the feedback settings asset, so menus give haptic/visual response on a controller without any per-menu wiring (and stay silent when no defaults are configured).

  • Feedback Builder & inspectorsTools ▸ Serenity ▸ Feedback ▸ Create Feedback opens a Feedback Builder window that authors a FeedbackDefinition (pick effects, set their fields) and creates the asset; the FeedbackDefinition inspector renders the effect list through a dedicated effect-list GUI (add / remove / reorder effect blocks), and a UnityFeedbackSettings asset (Serenity ▸ Feedback ▸ Settings) configures the global defaults including the menu tick/submit definitions.

  • No-code feedback trigger from the builder + typed feedbacks recipe sectionCreate Feedback now also emits a UnityEventDispatcherSignalDefinition (<Name>Trigger.asset) pre-wired to dispatch PlayFeedbackSignal for the new definition, so a designer drops it on a SignalEmitterComponent and plays the feedback with zero code and no generated script (independent of, and alongside, the existing Signal+Action code path — both are now optional toggles). FeedbackDefinition also becomes a first-class typed feedbacks recipe section (importer/exporter/template-generator/discovery), round-tripping its polymorphic [SerializeReference] effect list through the shared codec, with an optional generateTrigger flag that creates the same no-code trigger on import. A full Feedback aggregate cookbook (Documentation/Cookbooks/Gameplay/Feedback.md, the 12-section template) ships alongside it, and the Cookbooks README module-map + SO index, ConfiguringSerenitySystems, the docs root, and the serenity-cookbooks skill router were updated to route Feedback.

  • Installer & DI wiringUnitySerenityInstaller.InstallFeedback() registers the feedback service (UnityFeedbackInstaller, depending on the game-settings and event-dispatcher services) and is run from the boot initialization pipeline (a new InstallFeedback task). The module ships its own Addressables label (module:feedback) so its assets load at boot like every other Serenity module. Adaptive-trigger output is pluggable behind a backend interface — a PC HID backend drives the DualSense over USB on desktop, with a PS5-SDK backend scaffolded for console.

  • Cutscene Wizard (Tools ▸ Serenity ▸ Cutscenes ▸ Cutscene Wizard) — a stepped IMGUI builder for cutscenes (Template → Stages → Rig → Trigger → Create), modeled on the Settings Wizard. It seeds the stage list from a preset (Splash FadeIn→Wait→FadeOut, Timeline cutscene FadeIn→PlayTimeline→FadeOut, or Blank), lets you edit each stage (type, duration, fade colour, Timeline) with reorder/add/remove, optionally creates a rig prefab (a GameObject with a PlayableDirector, playOnAwake off) or assigns an existing one, and on finish registers the new UnityCutsceneDefinition into the project's UnityCutscenePlayerSettings.Definitions — finding or creating that settings asset — which closes the silent "authored a cutscene but it never loads because it wasn't added to the settings" gap. The window (CreateCutsceneWindow) only collects input; a pure CutsceneCreator does every asset mutation with rollback on failure (mirrors ModalCreator / GameSettingCreator), and CutscenePresetLibrary holds the templates.

  • Boot / init-pipeline task generation — the wizard's Trigger step can also create a Play{Name} UnityReflectionCallTaskDefinition that plays the cutscene from the initialization pipeline (the boot-splash path). It mirrors the shipped PlayCompanySplashScreen task — an instance call to UnityCutscenePlayerService.PlayAsync, resolveFromServices: true, the cutscene Id as the single string arg — at Degradable criticality so a failed splash never halts boot. The task is created next to the definition but not auto-inserted into a profile; add it to a UnityInitializationPipelineProfile after InstallCutscenePlayer.

  • No-code cutscene play trigger — the wizard's optional Trigger step generates a {Name}ActionSignal + an [AutoRegisterEventAction] {Name}Action (via the same SerenityEventDispatcherActionScriptCreator the Modal Builder uses, with a cutscene-specific Execute body in CutsceneTriggerScriptCreator). The action resolves ICutscenePlayerService from the ServiceLocatorBridge — the service is already registered in the ServiceLocator by UnitySerenityInstaller.InstallCutscenePlayer — and fires PlayAsync(id) fire-and-forget (safe: the service self-bounds each stage and the whole cutscene with hard wall-clock timeouts). A designer then dispatches the generated signal with the existing no-code SignalEmitterComponent, so "when signal X fires, play cutscene Y" needs no hand-written code. Cutscenes previously had no signal-driven trigger — only direct ICutscenePlayerService.PlayAsync injection.

  • Looping cutscenesICutscenePlayerService gains PlayLoopingAsync(id) / Stop(id) / IsPlaying(id): a cutscene can now run as a persistent, looping background sequence (menu backdrops, ambient scenes) instead of the one-shot staged pipeline. PlayLoopingAsync instantiates the definition's rig under the cutscene service (so it survives scene loads), sets the rig's PlayableDirector to Loop wrap mode and returns immediately; it is idempotent — re-playing an already-looping key is a no-op, never a duplicate rig — Stop tears the rig down, and looping playback deliberately bypasses the one-shot pipeline's per-stage and wall-clock timeouts (a loop has no end to time-bound). The Cutscene Wizard's Trigger step gained a Trigger kind choice: Play once (the existing PlayAsync action) or Play looping, which generates a Play{Name}Action and a Stop{Name}Action signal/action pair so a looping cutscene can be started and stopped no-code.

  • Timeline auto-create in the Cutscene Wizard — a PlayTimeline stage can tick "Create a new Timeline for this stage" and the wizard creates an empty TimelineAsset next to the cutscene and assigns it, and bakes the first stage's Timeline into a newly created rig's PlayableDirector so the rig opens ready to author in the Timeline window (harmless at runtime — playOnAwake is off and the service re-assigns per stage). Gated behind a SERENITY_TIMELINE version define (com.unity.timeline in the editor asmdef) so the assembly compiles when the Timeline package is absent.

  • Typed cutscenes recipe section — cutscenes are now a first-class typed section of a .serenity-recipe.json (like menus/modals/audioClips) instead of riding the generic assets codec. A RecipeCutsceneDto carries id/output/rigPrefab and an ordered stages[] (id, stageType — a CutsceneStageType name, duration, fadeColor as {r,g,b,a}, and timeline as a PlayableAsset path). CutsceneRecipeImporter (reflection-discovered, ordered between menus and modals) writes the private stage fields through a SerializedObject and resolves the rig/Timeline by path; CutsceneRecipeExporter round-trips them back. The template generator emits a realistic FadeIn→PlayTimeline→FadeOut stub, the discovery registry exposes the CutsceneStageType vocabulary, and example.serenity-recipe.json gains a worked cutscene. A PlayTimeline stage with no Timeline imports but is reported as a warning.

  • Cutscene documentation — the Cutscenes & Sequences cookbook (Documentation/Cookbooks/Narrative/CutscenesAndSequences.md) was expanded from a field stub to the full 12-section aggregate template (domain model + hard-timeout bounds, the three authoring paths incl. the Wizard, the typed recipe section, installer/DI + service registration, the no-code trigger contract, ID contracts, a worked example, verification, and a source map). The recipe schema reference, the AI asset-generation guide, the docs README, and the Cookbooks SO catalog were updated to list the new cutscenes section and the Cutscene Wizard.

  • Scene-scoped hierarchy queriesUnityHierarchyUtils gains multi-root, scene-wide search: GetSceneRoots, FindInSceneWithTag / FindAllInSceneWithTag, and FindInScene<T> / FindAllInScene<T>, each with an overload taking a specific Scene and a no-arg overload defaulting to the active scene. They walk every root GameObject of the scene and include inactive objects — the scenarios the existing single-root find helpers didn't cover.

  • Claude Code skills shipped in-package — Serenity now bundles LLM-first Claude Code skills under Assets/Serenity/Documentation/Skills/ (so they ship in the .unitypackage) plus an installer that activates them: Tools ▸ Serenity ▸ AI ▸ Install Claude Skills (SerenityClaudeSkillsInstaller) copies each bundled skill folder into the project's .claude/skills/, where Claude Code actually discovers skills — a SKILL.md left under Assets/ is inert, because Claude Code only scans <project>/.claude/skills and ~/.claude/skills. The first skill, serenity-cookbooks, is a router that makes an AI agent read the matching per-module Aggregate Cookbook before authoring or wiring any Serenity system (with hard rules to pull exact fields from the Project Recipe Template Generator and to retag Addressables + register audio after import). The installer skips Unity .meta files and lives in the existing Serenity.PackageBootstrapper.Editor assembly alongside the package exporter; the regenerable install output (.claude/skills/) is git-ignored.

Changed

  • The Cookbooks SO catalog now lists UnityCutsceneDefinition under the typed cutscenes section (was assets) with the Cutscene Wizard as its authoring tool.

Fixed

  • Signal emitter never recovered from an early service lookupSignalEmitterComponent latched its event-dispatcher and logger lookups as "resolved" before checking they succeeded, so an emitter that fired before boot finished registering the services (e.g. a logo-animation event during the splash) cached the failed null lookup permanently — and since SetActive(false/true) doesn't reset private fields, disabling and re-enabling the object didn't recover it: the trigger stayed silently dead (warnings included) for the whole session. The latch is now set only on a successful resolution, so the next dispatch retries and picks the service up once it's registered.
  • Primary input prompt ignored Screen Shake (UI)UnityPrimaryInputPromptViewFactory created the prompt's container as a plain Transform, but UnityUiShakeReceiver only offsets the anchoredPosition of RectTransform direct children of the root canvas, so the input prompt never moved during a UI screen-shake feedback. The container is now a full-stretch RectTransform (anchored to fill its parent), which also makes it a spec-correct UGUI element.

Infrastructure

  • Added the Serenity.Feedback test suites (EditMode) covering the engine-agnostic core: FeedbackIntensity clamping, FeedbackScaler global-intensity scaling, per-effect Scaled output, and the feedback-target / definition-data DTOs. Extended with the audio gating contract: AudioEffect reports BypassesGlobalGate and Scaled returns it unchanged, while the haptic effects stay gated.
  • Added CutsceneRecipeRoundTripTest (EditMode) to the Serenity.ProjectRecipe.Tests.Editor suite: import → assert the definition and its stages, export → assert the DTO, and an export → re-import-into-a-new-root round trip. Added a new Editor-only Serenity.UnityCutscenePlayer.Installation.Editor assembly for the wizard.
  • Added UnityHierarchyUtilsSceneTests covering the new scene-scoped queries — roots-only enumeration, tag and component search across multiple roots (hit and miss), inactive objects, and empty/invalid scenes — against both an isolated freshly created scene and the active scene for the no-arg overloads.

1.1.3 — Cascade Menus, Theme-Driven Toasts & Project Recipe System focused on AI generation

Added

  • Cascade menus — a multi-column, drill-down menu system where selecting an option opens a sub-column to its side. The engine-agnostic navigation model + builder lives in Serenity.Menu.Application.Cascade (CascadeMenuModel, CascadeColumn, CascadeMenuPage, CascadeOption, ICascadeMenuContext); the Unity side (Serenity.Menu.Infrastructure.Cascade) adds the renderer, a pointer proxy for mouse, and three ScriptableObject definitions — OptionsCascadeMenu (static authored options with a per-leaf [SerializeReference] OnSelectSignal), DynamicCascadeMenu, and TargetCascadeMenu. UnityCascadeViewDefinition (Serenity/Menu/Cascade/Cascade View) makes a cascade a router-resolvable transition target like any composite view, so a menu option can transition into it; it builds under the canvas via UnityCascadeViewFactory / UnityCascadeViewService (IViewProvider) / UnityCascadeViewInstaller, wired from UnitySerenityInstaller.InstallCascadeViews(). DefaultCascadeMenuContext runs a static cascade with no game code (a leaf's optional signal is dispatched on resolve, then the view returns to its opener). ICascadeMenuContext.Dispatch + OptionsCascadeMenu.OptionDefinition.KeepOpenOnSelect let a terminal option fire its signal without closing the cascade.
  • Themed cascade rendering — the cascade menu renders through a designer-authored, per-theme CascadeView.prefab (a new CascadeViewTemplate slot on the theme, authored for all 8 themes from each theme's own background + title font) instead of a hardcoded procedural panel, so it matches the active UI theme. UnityCascadePanel (modeled on UnityModalComponent) provides header + options-root slots, SetTitle/SetInteractable/SetOptions, ConfigureScroll (clamp to a visible count behind a mask), and AdaptWidth (auto-fit to the widest label, clamped to [MinWidth, MaxWidth], longer labels wrap). UnityCascadeViewDefinition replaces the inert PanelWidth with MinWidth/MaxWidth + VisibleOptionsCount. The cascade also plays the theme's IUiThemeSounds on navigate / submit / cancel and supports mouse hover-to-focus + click-to-select (a procedural fallback remains when a theme has no cascade template). A game-agnostic TESTING cascade sample (MENU → First Action / Submenu One → Choice A,B / Submenu Two → Choice C,D) and a "Cascade Menu Test" option in TestingMenu exercise it end to end.
  • Serenity UI widgetsSerenityButton, SerenityGauge, SerenityImage, SerenityLabel, SerenityStatusPanel and SerenityUiContext (Serenity.Ui.Infrastructure.Widgets), runtime wrappers over the themed UI components; SerenityUiContext.CreateOptionComponent is what the cascade renderer uses to fill panels with theme-native submit components.
  • Project Recipe system (Tools ▸ Serenity ▸ Project Recipe Importer / Exporter / Template Generator) — author Serenity content as human-readable .serenity-recipe.json files and turn them into real ScriptableObjects through the Unity Editor API (no hand-written .asset/.meta/GUIDs). The importer does idempotent create/update with Validate / Dry-Run / Import, covering typed sections (audioClips / musicTracks / menus / modals) plus a generic SerializedObject codec that round-trips every other Serenity SO including [SerializeReference] signal graphs; the exporter turns an existing project back into a recipe; the template generator emits the exact, drift-free recipe stub for any authorable SO. All three ship as an EditorWindow plus a headless CLI entry point, in a new Serenity.UnityProjectRecipe.Infrastructure.Editor assembly.
  • Theme-driven toast notificationsUnityToastComponent (Add Component ▸ Serenity ▸ UI ▸ Toast), a transient, non-blocking notification that spawns a short message, holds, and removes it (unlike a modal, it never steals input). The visual is the active theme's toast prefab (composed from each theme's own Background + Label and wired into a new ToastTemplate slot on the UI theme), so toasts inherit the project's fonts/look; when no per-component prefab is assigned it falls back to the active theme's ToastTemplate via the service locator. The toast can fit-to-content or use a fixed size (a bool), and animation is fully prefab/Animator-driven — the component only spawns and toggles the prefab's isShowing parameter (no code-based fade), so five themes (Serenity, Animated, Animated2, Futuristic, Writings) unfold via their own controller mirroring each theme's modal while themes without an Animator simply appear/disappear. The toast host lives in the UI root prefab (UnityUiSettings.Ui) on a high-sorting nested canvas, so it is present wherever the UI is instantiated. Fully no-code to trigger: Show(string) is wirable from any UnityEvent, and ShowToastSignal + UnityToastSignalReactionComponent carry the message as an event-dispatcher payload — so "when signal X happens, toast 'Saved!'" needs no script.
  • Cutscene Player Settings inspectorUnityCutscenePlayerSettingsEditor (a FoundationEditor) so the cutscene-player settings asset shows the standard Serenity inspector (header, Id validation, Guid, Definitions list) instead of Unity's default, and fills the asset's blank Id/Guid.
  • "Import → press Play" — self-registering project services + project-extensible Addressables — removes the two manual steps that remained after recipe import. [AutoRegisterService] (in Serenity.ServiceLocator.Application) marks a class exposing public static void Install(IServiceLocator); AutoRegisterServiceBootstrap discovers these across the loaded assemblies (mirroring [AutoRegisterEventAction]) and runs them late in UnitySerenityInstaller's bootstrap (per-installer try/catch — a bad service logs but never aborts boot), so a game's services self-register with no bootstrap MonoBehaviour in the scene. [SerenityAddressable("label")] (in Serenity.Shared) opts a project (non-Serenity) ScriptableObject type into the auto-labeler, making its assets Addressable under the given label(s); the project loads them at boot with UnityAssetUtils.LoadAllFromAnyBlocking<T>("label")no hand-wired Inspector reference. Together: a project can be authored by recipes and run with just import → press Play.
  • Headless project validation (Tools ▸ Serenity ▸ Validate Project (JSON), or headless SerenityProjectValidationRunner.ValidateFromCommandLine -validationKind all -validationResult <path>) — runs the three project-integrity validators (Health Check empty/duplicate Id/Guid, Missing References dangling object references, and Localization Keys) and emits the findings as JSON so an AI agent or CI can confirm a project is correctly wired — not just that a recipe imported — and self-correct. The exit code is 1 when there are errors (duplicate ids, dangling references) and 0 otherwise (localization gaps are warnings, so partial translation doesn't fail a build). Each validator's scan logic was extracted from its editor window into a shared, GUI-free engine (SerenityHealthCheckValidator / SerenityMissingReferenceValidator / SerenityLocalizationKeyValidator) over a common SerenityValidationReport, so the windows and the headless runner report identically.
  • Discoverability registry (Tools ▸ Serenity ▸ Project Recipe Registry, or headless SerenityDiscoveryRegistry.DumpFromCommandLine -registryOutput <path>) — a machine-readable "what exists" dump so an AI agent references real ids/types/enums instead of guessing them: every concrete event signal (with both full name and assembly-qualified name), every authored action id (the StartGame-style targets of a menu/modal ACTION option, scanned from UnityActionDefinition assets), the code reactions ([AutoRegisterEventAction]), the authorable ScriptableObject types and their recipe section, the recipe enum vocabularies, the recipe sections, and a curated list of the semantic ID contracts (e.g. InitialViewId must equal a menu id). Discovery is reflection-based and decoupled (types resolved by name), so the dump stays correct as code changes; it's the lookup that prevents the silent <Invalid: …> failure an unresolved action id produces.
  • Headless recipe import + machine-readable reportSerenityRecipeEngine.ImportFromCommandLine runs the full Validate / Dry-Run / Import loop with no Editor GUI (the symmetric counterpart to the existing export/template CLIs): -recipeFile (required), -recipeMode Validate|DryRun|Import (default Import), -recipeOutputRoot (optional override), and -recipeResult <path> (writes the report as JSON, even on failure). It exits with code 0 on success and 1 when there are blockers or errors, so CI or an AI agent can branch on the result. The report now also serializes via SerenityRecipeReport.ToJson() — counts (created/updated/skipped), flags (hasErrors/hasBlockers), and per-item messages/actions with enums written as their string names — so an agent reads outcomes and per-item problems directly and self-corrects. This closes the author → validate → import → read-result → retry loop end to end without a human in it.
  • Typed menu/modal signal wiring in recipes — the menus/modals recipe sections now wire [SerializeReference] EventDispatcherSignals directly, no longer deferring them: per-option submitSignals[] (→ UiOption.OnSubmitSignals) on both menus and modals, plus menu-level onShow/onHide/onCancel (lists) and onSubmit (→ EventToDispatchOnSubmit). A new RecipeSignalDto describes each signal as a type (the .NET FullName, matching the discovery registry) with optional fields (a RecipeNode[] for a signal carrying serialized data — parameterless markers need only type). The new RecipeSignalCodec applies and captures them by reusing RecipeSerializedPropertyCodec's managed-reference path (newly exposed as ApplyProperty/CaptureProperty), so signals — including a signal's nested field graph — round-trip through both importer and exporter. A null slot leaves the existing value untouched; a non-null list replaces it; an unresolvable type is reported in validation and left unset (never a null list entry). The Action system (valueType: ACTION) remains the recommended route for cross-system flow.
  • Localization recipe section — the localization section of a .serenity-recipe.json now generates real Unity Localization content (previously deferred/reported-only): it ensures the requested locales exist, creates or finds the String Table Collection, and upserts inline key/value entries ({ "key": …, "values": [ { "locale": …, "text": … } ] } — an array of pairs, since JsonUtility can't deserialize a map), idempotently and dry-run-aware. String tables with inline entries are covered; CSV import and Asset tables remain future additions. The importer (LocalizationRecipeImporter) ships in the localization assembly and is discovered by reflection, so the core recipe engine gains no dependency on the Unity Localization package — recipes without localization still build. SerenityRecipeEngine.CreateImporters() now auto-discovers section importers (sorted by a new Order) instead of a hardcoded list.
  • Serenity documentation set (Assets/Serenity/Documentation/) — recipe schema reference, an AI-agent asset-generation guide, per-system configuration docs, a Serenity application-flow + first-iteration bootstrap walkthrough, an MCP-automation guide, a wiring cookbook, and per-ScriptableObject cookbooks (Audio, Cutscenes, Events, GameMode/Boot, GameSettings, Gameplay, Localization, Logging, PlayerInput, System/Assets, UI).
  • Aggregate Cookbooks (Assets/Serenity/Documentation/Cookbooks/) — 21 end-to-end, AI-facing docs, one per module, that document a whole system rather than a single ScriptableObject's fields: Character, Wave, Stage, ProceduralExpression, GameplayEntity, GameSpawner, Checkpoint, GameSession, Score, Combo, GameWeapon, GameRail, GameUi, GameMode (Gameplay), Ui, ViewBrowser (UI), AssetPrefetcher, ServiceLocator, Timer, Task, Persistence, FilePersistence (Core). Each follows a fixed 12-section template — What it is · Domain model & lifecycle · Authoring surface (Recipe SO vs scene MonoBehaviour vs runtime-only) · Config · Scene authoring · Installer/DI wiring · Signal contract · ID & cross-reference contracts · Composition · Worked example · Verification · Source map — written from the actual source, so they answer "how does an AI build a Wave system / manage a Character" (config + scene placement + DI + signals + cross-aggregate composition), the parts a per-SO field reference can't. Infrastructure modules with no asset (ServiceLocator, Timer, Persistence…) mark the N/A sections explicitly and document the service/DI API instead. The cookbooks are organized into category subfolders Cookbooks/{Gameplay, UI, Audio, Settings, Narrative, Core}/.
  • Complete 38-module map — the master Cookbooks/README.md now links every Serenity module to its authoritative doc (the aggregate cookbooks plus the per-system reference docs for the rest), with a composition diagram showing how GameMode → GameSession → Stage → Wave → Character → Score/Combo/GameUi fit together. Nothing in the module list is undocumented.

Changed

  • Media asset reorganizationAssets/Media moved under Assets/Serenity/Media (themes, prefabs, fonts, generated views, sample menus); references bind by GUID, so the move is transparent.
  • Mixer Topology window overhaul — the routing diagram now auto-sizes multi-line cards, draws per-type icons and a legend, supports selectable nodes with a detail panel, and highlights/pulses connectors, replacing the earlier clipped fixed-size boxes.

Fixed

  • Gamepad double-submit on menu transitionsSetActionMap switched the PlayerInput map unconditionally, so a UI Show (e.g. a menu→menu transition) re-switched to the already-current "Menu" map, and SwitchCurrentActionMap's disable→re-enable ran the Input System's initial-state check, which re-fired performed for any control still actuated — a Submit press held across the transition was processed twice, landing on the freshly shown view's selected option. The switch is now skipped when the requested map is already current. (The cascade renderer applies the same press-release gate so the Submit that opened it doesn't immediately submit its focused option.)

Infrastructure

  • Added the Serenity.ProjectRecipe.Tests.Editor suite (44 EditMode tests) covering the recipe importer/exporter round-trip, the generic SerializedObject codec, the template generator, recipe validation, the SerenityRecipeReport.ToJson() machine-readable report, the SerenityDiscoveryRegistry discovery dump, and typed menu/modal signal wiring (per-option + menu-level, parameterless and payload-carrying signals, with an export→re-import round trip).
  • Added GameModeMusicBinderComponent, UnityToastComponent, and UnityAudioPlayerService placement PlayMode tests.
  • Added the Serenity.UnityValidation.Tests.Editor suite covering the shared SerenityValidationReport.ToJson() output and a SerenityProjectValidationRunner.RunAll() smoke test (all three validators run; selectable by kind).

1.1.2 — Authoring Tools (Modal / Game-Settings / Audio), Rich Modal Options, Addressables Retagging, Input Action Invoker & Comprehensive Test Coverage

Added

  • Modal Builder tool (Tools ▸ Serenity ▸ Modal ▸ Create Modal) — generates a Signal + Action script (reusing the shared Action Script generator) plus a UnityModalSettings and a UnityActionDefinition asset, all referencing the same generated signal. The signal type string is built deterministically (UnityActionDefinition.Signal = Type.FullName; UnityModalSettings.signalTypeName = full assembly-qualified name) so the signal picker matches them exactly. The modal button inspector was extracted into a shared ModalButtonsInspectorGUI used by both the editor and the tool.
  • Modal title/text runtime translationIsTranslatingTitle / IsTranslatingText on UiShowModalParameters flow through to UnityModalComponent, which get-or-adds a UnityUiTMP_TextLocalizationUpdaterComponent on the title/text TMP at runtime (no prefab edit). Previously modal titles/text were never translated — only buttons were.
  • Show modal by id — modals can be shown by their configured id, complementing the parameter-driven show path.
  • Rich modal options — modals now render the full menu UiOption[] model instead of the submit-only button model. A modal carries UiOption[] Options, ModalDirection Direction, OptionsGap, Scrollable, and VisibleOptionsCount, configured just like a menu — with per-interaction component construction (SUBMIT / SLIDER / TOGGLE / SELECTOR), runtime layout-group swap for direction, and a ScrollRect viewport clamped to VisibleOptionsCount. Legacy modal Buttons are lazily migrated to UiOptions (InteractionType = SUBMIT) with all their signals preserved. ModalDirection.HORIZONTAL = 0 (the opposite of MenuDirection.VERTICAL) so every existing modal asset deserializes unchanged.
  • Multi-signal option submitUiOption now carries a List<EventDispatcherSignal> OnSubmitSignals (read via UiOption.GetSubmitSignals()), so a single menu or modal option can dispatch several signals in order. The legacy single OnSubmitSignal is kept for back-compat and lazily migrated. New options default to an empty ACTION (a no-op that just dispatches the option's submit signals).
  • Game Settings Wizard (Tools ▸ Serenity ▸ GameSettings ▸ Settings Wizard) — a stepped IMGUI wizard that authors UnityGameSettingsDefinition assets, with a preset library, live option auto-fill (from QualitySettings / Screen.resolutions / Locales / AudioMixer), opt-in service wiring, and a "generate full recommended set" action. The wiring step writes the setting Id onto the matching service-settings key (graphics / localization / UI / sound-mixer) so the setting actually takes effect at runtime.
  • Batch audio import toolsTools ▸ Serenity ▸ Audio ▸ Batch Import Sound Effects generates one UnityAudioPlayerClipDefinition per selected file; Batch Import Music Tracks generates one UnityMusicTrackDefinition per file with shared fields plus a per-track Advanced loop foldout (tail-preserving, time/bar region, fade).
  • Audio Channel Manager (Tools ▸ Serenity ▸ Audio ▸ Audio Channel Manager) — a mixer ↔ Serenity relationship view that analyzes inconsistencies, creates channels/groups, and deletes them with a dry-run plan + Undo.
  • Addressables Retag Selected window (Tools ▸ Serenity ▸ Addressables ▸ Retag Selected…) — lists retag-eligible assets under any dropped/browsed folder, previews the labels each would receive, lets you choose which to retag (Select All / None / Invert), and applies them. Ineligible files (excluded extensions, docs/manual segments, localization assets) are hidden; assets outside the Serenity plugin roots are accepted (address falls back to stripping a leading Assets/).
  • Remove GUID Labels tool (Tools ▸ Serenity ▸ Addressables ▸ Remove GUID Labels) — purges stale GUID-shaped Addressables labels from all entries and the settings label table, leaving module:*, type:*, and Locale* labels untouched.
  • Input Action InvokerUnityInputActionInvoker (Add Component ▸ Serenity ▸ Input ▸ Input Action Invoker), a drop-in component that maps Input System actions to parameterless public methods on referenced scripts and calls them when the input fires — Serenity's reflection-based equivalent of Unity's PlayerInput → Invoke Unity Events mode. A custom inspector reads the action maps/actions from an assigned InputActionAsset (or a sibling PlayerInput's asset) and lists each target's invokable methods in dropdowns. Each action entry has its own trigger phase (Started / Performed / Canceled) and any number of method calls. Actions are bound from the sibling PlayerInput's per-player action instance when present (keeping local-multiplayer callbacks isolated), falling back to the assigned asset for standalone use.
  • Signal Reaction componentSignalReactionComponent (Add Component ▸ Serenity ▸ Events ▸ Signal Reaction), the no-code counterpart to SignalEmitterComponent: where the emitter dispatches a signal without code, this component reacts to one. A custom inspector lists each reaction as a searchable dropdown of every concrete EventDispatcherSignal type in the project plus a response UnityEvent, so a designer can wire "when signal X is dispatched, do Y" entirely in the Inspector — the first no-code way to react to a signal (previously only the code-defined EventDispatcherAction<TSignal> could). Subscriptions go through the shared IEventDispatcherService (resolved via ServiceLocatorBridge); the component waits for the service to be registered before binding and unsubscribes cleanly when disabled. The parameterless UnityEvent answers "react to this signal happening" — reactions that need the signal's payload still belong in an EventDispatcherAction<TSignal>.
  • Missing References report (Tools ▸ Serenity ▸ Validate Missing References) — a one-click editor window that scans every IFoundationSettings ScriptableObject (clips, tracks, menus, modals, definitions, settings…) for references that were assigned but can no longer be resolved (a deleted/moved clip, table, prefab or definition), and lists each offending asset and field with a Ping button. Only missing references are reported, not empty fields. Designer-facing "what's broken?" tooling that surfaces the silent null-reference failures the architecture is prone to.
  • Health Check dashboard (Tools ▸ Serenity ▸ Validate Health Check) — a single "is my project wired correctly?" window for non-programmers. Runs new integrity checks over every IFoundationSettings asset — empty Id/Guid, duplicate Id within a definition type, and duplicate Guid across the project (the keys Serenity services resolve by) — each with a Ping button, and gathers the previously-scattered validators (Validate Installation / UI Theme Prefabs / Branding / Find FoundationSettings / Missing References) behind one-click launch buttons rather than re-implementing them.
  • In-editor audio audition — the AudioClip definition and Music Track inspectors now have Play / Stop preview buttons (SerenityEditorAudioPreview, a shared editor helper that drives Unity's internal AudioUtil by reflection, tolerant of version differences and failing soft), so audio designers can hear a clip or track without entering Play mode.
  • Localization key validator (Tools ▸ Serenity ▸ Validate Localization Keys) — scans every Serenity asset for translation keys (any field whose IsTranslating… toggle is on — menu/modal titles, option labels, modal text, game-setting values…) and validates each against the project's Unity Localization string tables, reporting missing keys (which silently fall back to the raw key at runtime) and translating-but-empty fields, each with a Ping button. The scan is convention-based (IsTranslating<Field> → sibling <Field>), so it covers any future translatable field automatically.
  • Game Mode Music BinderGameModeMusicBinderComponent (Add Component ▸ Serenity ▸ Game Mode ▸ Game Mode Music Binder), the no-code way to play different music per game mode (previously this needed a code-defined EventDispatcherAction<GameModeChangedSignal>). For each GameMode a designer assigns a Signal Definition asset (typically a PlayMusicTrack signal authored in the Signal Definition inspector); on entering that mode the binder dispatches it through the same Dispatch(IEventDispatcherSignalDefinition) path SignalEmitterComponent uses — building no payload itself, so it works for any signal type. Subscribes to GameModeChangedSignal via ServiceLocatorBridge, waits for the service before binding, and unsubscribes when disabled.
  • Modal button presets — the Modal Builder (Tools ▸ Serenity ▸ UI ▸ Modal Builder) now offers one-click presets (OK · OK/Cancel · Yes/No · Confirm/Cancel) that populate the modal's options with SUBMIT buttons (built exactly like ModalButtonToUiOptionConverter, with no signals yet so the designer just wires each button), so common dialogs no longer start from a blank button list.
  • Cutscene Outline (Tools ▸ Serenity ▸ Cutscenes ▸ Cutscene Outline) — a read-only outline + validator for UnityCutsceneDefinition assets: it lists the stages in order with their type, duration and key reference (Timeline asset / fade colour), shows the total run time, and flags problems — most importantly a PlayTimeline stage with no Timeline assigned (which would play nothing at runtime). Reads everything through SerializedObject, so it gives narrative designers a no-code "what happens, in what order, and is anything missing?" view without entering Play mode. The structural-preview slice of the roadmap's Cutscene preview (a live scrubbable Timeline preview is a later addition).
  • Cutscene stage scrubber — the Cutscene Outline window gained a scrub timeline: a proportional stage bar with a draggable playhead that highlights the active stage at any scrubbed time, plus per-stage start–end times and active-stage highlighting in the list. PlayTimeline stages use their assigned PlayableAsset's real duration so the layout is accurate. This is the stage-level slice of the roadmap's "cutscene scrub" — it does not play the Timeline's content (a frame-accurate PlayableDirector preview remains a later addition).
  • Toast notificationsUnityToastComponent (Add Component ▸ Serenity ▸ UI ▸ Toast), a non-blocking notification that fades a short message in, holds, and fades out (unlike a modal, it never steals input). The visual is a designer-assigned prefab carrying a TMP_Text, so toasts inherit the project's fonts/theme; spawned toasts parent to a configurable container (add a VerticalLayoutGroup to stack them) and animate on unscaled time so they work while the game is paused. Fully no-code to trigger: Show(string) is wirable from any UnityEvent — a Button's onClick, a SignalReactionComponent response (with the message typed into the inspector), an animation event — so "when signal X happens, toast 'Saved!'" needs no script.
  • Signal Flow Browser (Tools ▸ Serenity ▸ Events ▸ Signal Flow Browser) — a read-only view of the event graph: for every EventDispatcherSignal it shows who dispatches it (authored Signal Definition assets), what listens for it (modal settings), and what reacts to it in code ([AutoRegisterEventAction] actions), each pingable, with a search box. Authored assets are discovered generically via SerializedObject and reactions from the attribute + EventDispatcherAction<T> base, so the otherwise-invisible no-code event wiring is browsable in one place.
  • GameMode Overview (Tools ▸ Serenity ▸ GameMode ▸ Transition Overview) — a read-only view of a UnityGameModeSettingsDefinition: one card per GameMode listing the signals dispatched on enter and on exit, plus the shared action-map/pause configuration, and a reminder that the service also dispatches GameModeChangedSignal(previous → new) on every transition. Reads through the IGameModeSettingsDefinition accessors so it always lists every mode (flagging ones with no wiring), giving designers a no-code picture of "what happens when each mode is entered/left."
  • Init Pipeline Overview (Tools ▸ Serenity ▸ Init ▸ Pipeline Overview) — a read-only outline + validator for UnityInitializationPipelineProfile assets: it lists the boot tasks in run order with their criticality and weight, shows each task's share of the progress bar and the total weight, and flags problems — most importantly empty task slots (which would throw at boot) and empty Ids. Reads through SerializedObject, so designers can sanity-check the startup flow (and see how many critical tasks can halt boot) without entering Play mode. The structural slice of the roadmap's Init pipeline simulator.
  • Init Pipeline Simulator (Tools ▸ Serenity ▸ Init ▸ Pipeline Simulator) — a dry-run boot simulator for UnityInitializationPipelineProfile assets: tick the tasks you want to fail and Run to see how the criticality rules cascade — a critical failure halts boot and skips the remaining tasks, while a non-critical failure is logged and boot continues — with per-task outcomes (ok / failed / skipped) and a simulated progress bar showing how far boot gets. Models the criticality handling of InitializationPipelineService.RunAsync without executing the tasks; the dynamic half of the Init Pipeline item (the read-only Overview is the structural half).
  • Diagnostics overlayUnityDiagnosticsOverlayComponent (Add Component ▸ Serenity ▸ Debug ▸ Diagnostics Overlay), an on-screen play-mode HUD showing FPS / frame time, time scale, the current and previous GameMode with pause state, and the number of joined players — a designer-facing "what is the game doing right now?" panel for the common "why isn't this working?" questions. It reads only through service interfaces (IGameModeService via ServiceLocatorBridge) and degrades to "n/a" when a service isn't up, toggles via a configurable key or no-code Toggle()/Show()/Hide() methods (wirable to a UnityEvent or input action), and hides itself in non-development player builds unless explicitly enabled.
  • Player Join OverlayUnityPlayerJoinOverlayComponent (Add Component ▸ Serenity ▸ Debug ▸ Player Join Overlay), an on-screen panel that lists the players currently joined via the Input System — each slot's player index, control scheme and devices — so a designer can see local-multiplayer joins happen while testing instead of reading the Console. Self-contained (reads only PlayerInput.all, no services), toggles via a configurable key (default F4, alongside the F3 Diagnostics Overlay) or no-code Toggle()/Show()/Hide(), and hides itself in non-development builds unless enabled.
  • Mixer Topology (Tools ▸ Serenity ▸ Audio ▸ Mixer Topology) — a read-only visual routing diagram for an AudioMixer and the Serenity sound config: it draws each Serenity audio channel wired to its mixer group (right-angle connectors), marks groups whose volume is exposed and which are effect-loop groups, and lays out each effect loop's source groups feeding its loop group via sends. Reuses AudioMixerRelationshipScanner, so it stays consistent with the Audio Channel Manager but is a pure viewer ("how does my audio route?") rather than the manager's analysis/repair tool.
  • Positional / 3D audio authoringAudioPlayerClip now carries spatialBlend, minDistance, maxDistance, spread and dopplerLevel, applied to the AudioSource at play time by UnityAudioPlayerService. Because these are constructor parameters (with [FloatRange] sliders), they are authorable no-code in the Signal Definition inspector when building a PlayAudioClip signal — combined with the existing AudioWorldPosition playback position, a designer can place and shape a 3D sound without code. Zero-regression: the settings are applied only when spatialBlend > 0, so existing clips (which default to 0 = 2D) leave the AudioSource's own/prefab min-max distance, spread and Doppler untouched and behave exactly as before.
  • Input rebinding componentUnityInputRebindComponent (Add Component ▸ Serenity ▸ Input ▸ Input Rebind), no-code interactive rebinding for a single Input System binding (the classic "press a key to rebind" settings row). Wire a button to StartRebind() and another to ResetBinding(); the current binding text is pushed through a UnityEvent<string> (wire it to a TMP/UI text's text setter) and onRebindStarted/onRebindStopped drive a "Press any key…" prompt. Wraps PerformInteractiveRebinding (disabling the action during the rebind as the Input System requires) and, when persist is on, saves the asset's binding overrides to PlayerPrefs and reloads them on enable so rebinds survive restarts. By default it rebinds the referenced asset's binding (shared-asset/single-player settings menu); enable usePlayerInput for local multiplayer to rebind the per-player action instance resolved from a parent PlayerInput and persist per player index instead.
  • Designer Quick Start guide (Assets/Documentation/DESIGNER_QUICKSTART.md) — a no-code onboarding tour: a first-run checklist (the four validators), a map of every Tools ▸ Serenity tool and Add Component ▸ Serenity component, and step-by-step recipes ("show a toast when something happens", "different music per game mode", "let players rebind a key", "why isn't this working?").

Changed

  • Deterministic editor-menu ordering — every [MenuItem("Tools/Serenity/…")] now carries an explicit priority (Setup 0–99, Project/Build 100–199, Authoring 200–299, Validate/Find 300–399, Docs 400+) and every [CreateAssetMenu] carries an order from a curated 100-wide-block scheme, so Serenity's context menus render the same way on every machine instead of in arbitrary compile order.
  • Menu path normalizationSerenity/UiSerenity/UI (UiTheme → UI Theme, CompositeView → Composite View) and Serenity/Settings/Unity UI SettingsSerenity/UI/UI Settings. Existing assets bind by script GUID, so renames are safe.
  • Shared option inspector — the menu's option ReorderableList was extracted into a reusable UiOptionListInspectorGUI, now used by both UnityMenuSettingsDefinitionEditor and UnityModalSettingsEditor (identical ValueType / UI Element / Id / Label / Value / Translate-Label + per-option signal-list UI).
  • Option value-type enum renameUiComponentValueType.MENU_TRANSITIONTRANSITION and MENU_ACTIONACTION (ordinals unchanged, so serialized assets are preserved).
  • UnityModalController.Navigate is now direction-aware: HORIZONTAL modals navigate options with left/right and edit values with up/down; VERTICAL modals keep the previous up/down navigation + left/right value editing.

Features

  • Modal dialogs can now be authored with the same rich, multi-option, scrollable, horizontally- or vertically-laid-out model as menus, and can run a list of signals per option — not just a single confirm/cancel button each.
  • Common authoring flows are now one-click editor tools: scaffolding a modal (signal + action + settings), authoring game-settings definitions with live presets and automatic service wiring, batch-importing SFX/music, and managing audio channels against the mixer.
  • Addressables labels can be re-applied to a hand-picked subset of assets under any folder, and legacy GUID-shaped labels can be purged project-wide.

Fixed

  • The Directory Cloner no longer propagates stale, GUID-shaped Addressables labels: UpdateAddressablesEntries skips GUID-like labels when copying a source entry's labels, and the new Remove GUID Labels tool cleans up labels left over from the old cloner behavior.
  • Resolved several pre-existing latent bugs surfaced while building out test coverage: ComponentLogger's self-recursive Id/Guid setters, TimerFormatterService.FormatTimeInSeconds using a /120 instead of /3600 hour divisor, AudioWorldPosition.ToString formatting non-invariantly, and UnityGameSettingsOptionResolver.ResolveSelectable throwing an NRE on an empty option set (now guarded).

Infrastructure

  • Comprehensive automated test coverage. Behavioral tests were added across every pure Domain + Application module, taking the pure suite from 1,742 → 3,508 green tests, then across the testable Unity glue layer (≈28 Unity* assemblies, ~1,130 new PlayMode tests) and the OS file-persistence I/O services (0% → covered), taking the full PlayMode suite from 4,131 → 5,334 tests. All 36 pre-existing PlayMode failures were resolved (real bugs fixed + stale tests updated). Coverage also reached the Unity editor-tooling layer (docfx / generators / importers / validators) in EditMode and the Unity installers (15 modules) in PlayMode.
  • A standalone net8.0 NUnit harness (a UnityEngine shim with real Vector/Mathf arithmetic) runs the entire pure Domain + Application suite in under a second without launching the Unity editor or requiring a license — the fast verify loop that drove the coverage work.
  • Added PlayMode tests for UnityInputActionInvoker using the Input System InputTestFixture (Performed / Started / Canceled phases, the standalone-asset and PlayerInput paths, multiple methods per action, invalid-method resilience, and disable-stops-invoking) — the first InputTestFixture-based test in the repo. Added the Unity.InputSystem.TestFramework reference to Tests.asmdef, along with the other cross-assembly references the new coverage required.
  • Added pure-logic tests for the Addressables retag eligibility / address-building rules and the GUID-label invariants, the modal rich-option builder and Buttons → Options migration, the Game Settings Wizard writers, and the audio relationship analyzer / channel-deletion planner.
  • Added SignalReactionComponent tests (real UnityEventDispatcherService + ServiceLocatorBridge): a matching signal invokes the response, a different signal type does not, and disabling unsubscribes.

1.1.1 — Composite Views, Horizontal Menus, Inspector Signal Authoring, View Preview, Input-Gate Return & Music Start-Point Controls

Added

  • Composite Views — a flexbox screen-composition system. UnityCompositeViewDefinition (Serenity/Ui/CompositeView) composes any IViewBase children (menus or nested composites) into one screen with CSS-style per-child sizing (Fixed px / Flex fr / Percent % / Auto, with min/max), Row/Column direction, alignment, padding and gap, and two content modes: STACK (all children visible) and SWITCHER (one active child). Backed by a pure FlexboxSolver domain service and a layout model (LayoutDirection, LayoutSizeUnit, LayoutAlignment, LayoutScrollAxis, LayoutSize, LayoutPadding, LayoutConfig, ContainerContentMode). Direction reads in table/grid sense: ROW = stacked horizontal bands, COLUMN = side-by-side columns.
  • Menu hosting inside composites — a menu can render into a composite region (IHostableView). Each composite slot that references a menu builds its own instance (UnityMenuService.CreateHostedInstance), decoupling the per-instance routing id from the shared definition id, so the same menu can appear in several regions at once without being stolen from standalone use.
  • View RouterIViewRouter / ViewRouter / IViewProvider (Global.Application). The initial screen moved off the menu-service settings onto IUiSettings.InitialViewId (a picker that accepts a menu or a composite). The router tracks the current top-level view, auto-hides the previous one, and shows the initial view at boot and on return from gameplay. Menu transitions route through it (RouterMenuTransitionateToView).
  • Scrollable viewsScrollable + ScrollAxis on UnityViewDefinition, with programmatic scrollbars (UnityScrollbarBuilder). Menus scroll with a Visible Options Count clamp (MenuScrollPolicy) and auto-scroll to keep the selected option in view.
  • Cross-menu focus traversal — stacked menus in a composite pass keyboard/gamepad focus between each other at their boundaries (ICrossMenuHost / IFocusableMenuView), with an optional wrap-around. Input control follows the active SWITCHER child (ICompositeViewService.GetActiveInputView).
  • Composite View Builder wizard (Tools ▸ Serenity ▸ UI ▸ Composite View Builder) — pick a parametric template (N columns, N rows, single scrollable column, navbar+content, navbar+columns/rows, sidebar), name the sections, and Generate creates the composite + menu .asset tree with navigation auto-wired (no manual :: path plumbing). Per-section and navbar layout direction are selectable.
  • View Preview tool (Tools ▸ Serenity ▸ UI ▸ View Preview) — a live, themed render of a menu or composite built from the real theme prefab templates at a chosen device resolution, plus a structural wireframe mode. Includes selected-option highlight, click hit-testing, fit-to-view zoom, edit-mode localization (real translated labels instead of raw keys), and an optional backdrop image.
  • Horizontal menusMenuDirection (Vertical / Horizontal) on menu definitions lays options out side by side. HorizontalOptionWidthMode (Content / Uniform / Fill / Explicit) with HorizontalOptionWidth controls column width; OptionsGap and Visible Options Count apply horizontally, with a horizontal scrollbar.
  • Inspector-authored signal dispatch definitionsUnityEventDispatcherSignalDefinition (Serenity/EventDispatcher/Signal Definition): pick a concrete EventDispatcherSignal type, choose a constructor, and populate its parameters entirely from the Inspector; IEventDispatcherService.Dispatch(IEventDispatcherSignalDefinition) builds and emits it. Supports primitives, Unity math types, enums, UnityEngine.Object references, ScriptableObject-backed interface parameters, recursively nested DTO/value-object parameters (up to 6 deep), and nullable optionals.
  • Signal-parameter authoring attributesFloatRangeAttribute (range + percentage slider + reset button), AssetPathReferenceAttribute (draws an asset object field for a string path), and FoundationIdReferenceAttribute (settings-id picker). Applied to AudioPlayerClip (volume as a 0–100% slider, panStereo with reset, filePath as an AudioClip field) and AudioPlayerPlayClipInput (serviceId).
  • SignalEmitterComponent — a MonoBehaviour holding signal-definition assets; Dispatch(id) / DispatchFirst() emit a configured signal from collision/trigger callbacks, animation events, input, or UnityEvent wiring. Failures are logged and swallowed so gameplay flow is never broken.
  • Audio rolloff mode — engine-agnostic AudioRolloffMode domain enum (Logarithmic / Linear / Custom) plus RolloffMode on AudioPlayerClip, controlling 3D distance attenuation (values mapped to Unity at the boundary).
  • Per-view OnCancel signals — an OnCancel signal list on IMenuSettingsDefinition / UnityMenuSettingsDefinition, authored through a reorderable inspector list, dispatched when a cancel input reaches that menu.
  • Return to the primary input gateReturnToPrimaryInputGateSignal. Authored on the main menu's OnCancel, it tears down the menu input context, unpairs the device (IPlayerInputService.ReleasePrimaryDeviceIUiInputRouter.Unpair), and re-arms the device-selection gate so a fresh device can join.
  • Start From Loop PointStartFromLoopPoint on UnityMusicTrackDefinition / IMusicTrackDefinition / MusicTrack. When enabled, a track's first playback begins at the loop start time instead of 00:00:000, skipping the intro. Applies to any track with a loop region — tail-preserving (the first voice and its seam start at the loop point) and native/one-shot tracks (cut/fade/cross-fade all honor the offset). The music track inspector's Loop section was reworked: the loop region stays editable whenever either toggle consumes it, and the tail fade-out controls are gated to tail-preserving looping.
  • Ignore If Already PlayingIgnoreIfAlreadyPlaying on UnityAudioPlayerSettings / IAudioPlayerSettings. When enabled, a request to play the song that is already playing is ignored so it keeps playing uninterrupted instead of audibly restarting (music player). Default off preserves the always-restart behavior.

Changed

  • The first screen is configured on UnityUiSettings.InitialViewId (menu or composite) instead of the menu-service settings; InitMenuId was retired from the menu-service settings definition.
  • UI authoring tools are grouped under Tools ▸ Serenity ▸ UI (Composite View Builder, View Preview).
  • UnityMenuController routes Navigate/Submit/Cancel through the active composite input view when one is shown, falling back to the current menu otherwise.

Features

  • Multiple existing menus and nested composites can be composed into a single screen (e.g. a nav rail + scrollable settings content + detail region) with flexbox sizing, scrolling, and cross-region keyboard/gamepad focus traversal — authored visually with the Composite View Builder and previewed live in the editor.
  • The same menu can be hosted in several composite regions simultaneously, each with its own selection/focus state, while sharing the underlying game setting.
  • Menus can be laid out horizontally with selectable column-width behavior and horizontal scrolling.
  • Authoring and dispatching event-dispatcher signals — including signals with complex nested DTO parameters — entirely from the Inspector, and trigger them from the scene via SignalEmitterComponent.
  • A cancel input that no option consumes now dispatches the view's OnCancel signals and then navigates back; composites use a two-tier go-back (close the open detail region, or leave the whole composite). From the main menu, cancel can return the player to the press-to-start device-selection gate.

Fixed

  • The primary input gate (device-selection prompt) now completes the join on button release rather than press, so the joining press no longer leaks into the menu shown immediately after joining (e.g. instantly submitting its focused option). The press latch resets if the latched device is disconnected mid-hold, and the gate re-arms cleanly when re-shown.
  • UI input routing now applies control-scheme masks so a paired gamepad's bindings resolve, and pairs keyboard + mouse as one unit when they are not configured to split — fixing input not reaching the UI after joining with those devices.
  • SignalEmitterComponent (and any other Unity-side ServiceLocatorBridge consumer) can now resolve IEventDispatcherService at runtime, so Dispatch(id) / DispatchFirst() emit instead of logging "no IEventDispatcherService is registered yet." UnitySerenityInstaller.RegisterService now mirrors every service into the runtime IServiceLocator (not just the init-time container), with last-wins overwrite semantics that match the dual ILogService install.
  • Audio clips built from a IAudioPlayerClipDefinition (e.g. an Inspector-authored PlayAudioClipSignal dispatched through SignalEmitterComponent) now play audibly. The AudioPlayerClip(IAudioPlayerClipDefinition, AudioPlayerType) constructor previously left volume and pitch at C#'s 0 default, so the clip played at volume 0 / pitch 0 — silent, with no error. It now initializes volume, pitch, loop, pan, reverb mix and rolloff to the same defaults as the other constructors.

Infrastructure

  • Added tests for the FlexboxSolver, UiAnchorMapper, Composite View Builder + generator, composite cross-navigation / host-path / hosted-size paths, layout and scrollbar builders, and the menu scroll policy.
  • Added tests for the event-dispatcher signal builder and dispatch-from-definition flow, configured-signal parameters, the AudioPlayerClip authoring attributes, the menu OnCancel definition, the primary input gate, and the view-model routing-id setter.
  • Updated assembly definitions for the new cross-layer references introduced by composites, the editor preview/builder, horizontal menus, and the signal-definition editor.
  • Added tests for MusicTrack.StartFromLoopPoint (default and custom), AudioPlayerClip audible playback defaults when built from a definition, and extended the audio-player settings test double with the IgnoreIfAlreadyPlaying member.

Changed

  • The first screen is configured on UnityUiSettings.InitialViewId (menu or composite) instead of the menu-service settings; InitMenuId was retired from the menu-service settings definition.
  • UI authoring tools are grouped under Tools ▸ Serenity ▸ UI (Composite View Builder, View Preview).
  • UnityMenuController routes Navigate/Submit/Cancel through the active composite input view when one is shown, falling back to the current menu otherwise.

Features

  • Multiple existing menus and nested composites can be composed into a single screen (e.g. a nav rail + scrollable settings content + detail region) with flexbox sizing, scrolling, and cross-region keyboard/gamepad focus traversal — authored visually with the Composite View Builder and previewed live in the editor.
  • The same menu can be hosted in several composite regions simultaneously, each with its own selection/focus state, while sharing the underlying game setting.
  • Menus can be laid out horizontally with selectable column-width behavior and horizontal scrolling.
  • Authoring and dispatching event-dispatcher signals — including signals with complex nested DTO parameters — entirely from the Inspector, and trigger them from the scene via SignalEmitterComponent.
  • A cancel input that no option consumes now dispatches the view's OnCancel signals and then navigates back; composites use a two-tier go-back (close the open detail region, or leave the whole composite). From the main menu, cancel can return the player to the press-to-start device-selection gate.

Fixed

  • The primary input gate (device-selection prompt) now completes the join on button release rather than press, so the joining press no longer leaks into the menu shown immediately after joining (e.g. instantly submitting its focused option). The press latch resets if the latched device is disconnected mid-hold, and the gate re-arms cleanly when re-shown.
  • UI input routing now applies control-scheme masks so a paired gamepad's bindings resolve, and pairs keyboard + mouse as one unit when they are not configured to split — fixing input not reaching the UI after joining with those devices.

Infrastructure

  • Added tests for the FlexboxSolver, UiAnchorMapper, Composite View Builder + generator, composite cross-navigation / host-path / hosted-size paths, layout and scrollbar builders, and the menu scroll policy.
  • Added tests for the event-dispatcher signal builder and dispatch-from-definition flow, configured-signal parameters, the AudioPlayerClip authoring attributes, the menu OnCancel definition, the primary input gate, and the view-model routing-id setter.
  • Updated assembly definitions for the new cross-layer references introduced by composites, the editor preview/builder, horizontal menus, and the signal-definition editor.

1.1.0 — Positional & Priority Audio, Music Loop Tails, Mixer Effect Loops, Lazy Menus & GameMode Input Gate

Breaking Changes

  • SpawnPose no longer exposes the seven flat float fields (PositionX/Y/Z, RotationX/Y/Z/W). It is now backed by Position (System.Numerics.Vector3) and Rotation (System.Numerics.Quaternion). Construction is unaffected — the seven-float constructor and FromPosition(x, y, z) remain — but code that read the individual float fields must now read pose.Position.* / pose.Rotation.*.

Added

  • Primary input gate as a GameMode — a PrimaryInputGate value on the GameMode enum lets the primary-input prompt reuse the existing per-mode enter/exit transition-signal machinery (serialized storage, retrieval, and the reorderable inspector enter/exit lists are generated automatically for the new mode).
  • Tail-preserving music loopsStartTime, EndTime, TailPreservingLoop, TailFadeOutDuration, and TailFadeOutCurve on IMusicTrackDefinition / MusicTrack / UnityMusicTrackDefinition. A second voice carries the previous pass's reverb/ambience tail across the loop seam, scheduled sample-accurately via AudioSettings.dspTime / PlayScheduled so the loop never clicks. Loop points are authored as HH:MM:SS:MMM time codes or in DAW terms (tempo, time signature, start/end bar) via MusicBarTimeCalculator; the tail fade follows a Linear/Exponential/Logarithmic/S-Curve/Custom curve.
  • Positional audio playbackAudioWorldPosition value object and an optional PlaybackPosition on AudioPlayerPlayClipInput; a clip played with a position is 3D at that point, without one it stays 2D. Works from both a direct use-case call and a PlayAudioClip signal (no gateway/service signature changes).
  • Audio sound-priority allocation — when the AudioSource pool is full, a clip can take over a lower-priority playing sound instead of being dropped, governed by per-clip Priority / PriorityPolicy / CanBeReplaced and an AudioPriorityCandidateSelector (AudioPriorityPolicy: IgnoreIfNoSourceAvailable / ReplaceLowerPriority / ReplaceLowerOrEqualPriority / AlwaysReplace). Serenity priority semantics (higher = more important) are mapped to Unity's inverted AudioSource.priority only at the boundary.
  • AudioMixer Effect Loop authoring tool (Tools ▸ Serenity ▸ Audio ▸ Create Audio Mixer Effect Loop) — creates a mixer group with a Receive → effects → Attenuation chain and a reusable UnitySoundMixerEffectLoopDefinition asset describing it.
  • Effect Loop sync window (Tools ▸ Serenity ▸ Audio ▸ Sync Effect Loops) — reconciles the AudioMixer and SoundMixerSettings to the project's effect-loop definitions: creates a per-source Send into the loop's Receive, exposes it as {Source}_{Loop}_Send, and registers the definition. Idempotent and additive.
  • Source-group selection in the Create tool — choose which sibling groups feed the loop, with Select All / None.
  • Auto-generated enable/disable action scripts — for each selected source group, generates an Enable + Disable EventDispatcher action/signal pair (reusing the shared Action Script generator) pre-filled to apply/clear the loop for that group, written to a configurable Events folder.
  • Runtime effect-loop apply/clear: ISoundMixerService.ApplyEffectLoop / ClearEffectLoop, SoundMixerApplyEffectLoopSignal / SoundMixerClearEffectLoopSignal, their use cases, intent-only DTOs, and a pure engine-agnostic SoundMixerEffectLoopRouteResolver.
  • UnitySoundMixerEffectLoopDefinition / UnitySoundMixerEffectLoopSource ScriptableObjects with a custom inspector, plus an EffectLoops registry on SoundMixerSettings.
  • Editor-only AudioMixerYamlReader (reads .mixer structure) and AudioMixerEffectLoopReflectionAdapter (isolates the internal UnityEditor.Audio API behind one class).
  • Per-menu instantiation modeMenuInstantiationMode (PreloadOnStartup / LazyOnFirstOpen) on IMenuSettingsDefinition and UnityMenuSettingsDefinition, editable under an Advanced section in the menu settings inspector.
  • Lazy menu instantiation pipeline: IMenuInstanceGate, MenuLifecycleResolver, EnsuringMenuTransitionateToView, UnityMenuLazyBuildContext, UnityMenuLazyRegistration, and IUnityMenuViewInstanceFactory / UnityMenuViewInstanceFactory.
  • Per-mode exit transition signalsIGameModeSettingsDefinition.GetExitSignalsForGameMode; the GameMode settings inspector now renders separate reorderable enter/exit signal lists per mode.
  • Pause-during-scene-load — a PauseDuringSceneLoad GameMode setting (default on) with a settings-editor toggle, freezing the game clock while the additive gameplay scene loads and restoring it (via try/finally) once the load completes, so newly instantiated objects do not simulate behind the loading overlay.
  • First-run config generation — on a fresh install the detected OS/browser language is now persisted to gameSettings.cfg at detection time (standalone via UnitySystemConfigurationSnapshotStore; WebGL/ResourcesOnly via SerenityFallbackLocalizationService), guarded by a file-existence check so a returning player's saved preference is preserved.

Changed

  • SpawnPose is now backed by System.Numerics Vector3 Position + Quaternion Rotation (replacing the seven flat floats), matching GameRail's RailNodePosition value-object pattern; it stays pure C# (no engine dependency). UnityWaveService reads pose.Position.* / pose.Rotation.*. See Breaking Changes.
  • UnityAudioPlayerService.ApplyPlaybackPlacement is now the single source of truth for AudioSource.spatialBlend (with a position → 1 and the emitter is moved there; without → 0 and the emitter is left in place); ApplyClipToSource no longer applies the clip's spatial blend.
  • UnityGameModeService dispatches the exited mode's signals after OnExitMode, mirroring the existing enter signals; entering PrimaryInputGate fires its enter signals and leaving it fires its exit signals through the same SetMode dispatch.
  • The pause mixer effect loop is now driven by GameMode enter/exit signals (Enable on Pause enter, Disable on Pause exit) instead of dedicated action classes.
  • UnityMenuService builds LazyOnFirstOpen menus on first show (cached and reused); PreloadOnStartup menus stay eager. Initial and pause menus configured lazy are treated as preload to avoid first-open hitches. Default behavior is unchanged (PreloadOnStartup remains the default).
  • UnitySoundMixerSettingsEditor now reads exposed parameters live from the in-memory AudioMixer (auto-updates as you edit, no save needed) and labels the registered-definitions list distinctly from the section header.
  • Effect-loop definitions use a single normalized DefaultWet (dry is its complement, 1 - wet), shown as a "Dry/Wet" slider; the Create tool takes separate Media and Events destination folders.
  • The loop's output level is treated as a static mixer trim (not an exposed runtime parameter); the source Send tracks the source group's current level.
  • UnityYamlUtils was kept a generic YAML helper — all AudioMixer-specific YAML knowledge moved into the SoundMixer module.

Features

  • The device-selection prompt is now an observable GameMode (PrimaryInputGate) that fires signal-driven enter/exit side effects without transitioning game modes itself — on device selection it raises OnPrimarySelected and the composition root dispatches EnterMenuSignal, letting the EnterMenu action change the mode.
  • Music can loop between authored start/end points while a second voice carries the previous pass's reverb tail across the seam, with a bounded, curve-shaped tail fade-out (a 0 duration cuts cleanly at the loop point).
  • Sounds can be played at a world position (3D) and can reclaim a busy pool slot from a lower-priority sound instead of being dropped.
  • An effect loop can be authored, wired, registered, and toggled from gameplay (e.g. a pause low-pass/reverb on Music) end-to-end from the editor, without hand-writing routing or action scripts.
  • Menus can opt into lazy creation on first open, reducing startup work, while preserving eager startup for menus that need it.
  • Game modes can run signal-driven side effects on both entering and exiting a mode.

Fixed

  • Menu value changes now apply to the option that actually changed (not the currently selected one) and resolve the selected option by its logical GetIndex() rather than hierarchy position, fixing entwined slider values where two options aliased one UiOptionValue (e.g. master/ambient).
  • ISoundMixerService is now registered in the runtime ServiceLocator, so EventDispatcher actions can resolve it.
  • Per-source Send mix-level GUIDs are pre-allocated when the Send is created, so exposing each source's Send level now succeeds.
  • Removed dangling [SerializeReference] references to deleted action signal types from sample assets (an unknown managed type was nulling the other valid signals on entering Play).

Removed

  • Redundant EnablePauseMixerEffectLoopAction / DisablePauseMixerEffectLoopAction classes and the PauseEffectLoop sample asset (superseded by GameMode exit signals and the action-script generator).
  • A bogus SoundMixerSettings mapping (Music_SucutruleLoop_SendAudio_MasterVolume) that referenced a non-existent exposed mixer parameter.

Infrastructure

  • Added tests for the SoundMixer effect-loop route resolver, effect loop, installer, use cases, and coverage.
  • Added tests for the Menu lifecycle resolver, the ensure-transition use case, and the menu instantiation-mode enum.
  • Added tests for the music bar/time calculator, fade-curve evaluator, and music-track getters; audio world-position and placement; audio priority candidate selection and clip priority; SpawnPose construction; and the GameMode primary-input-gate actions/signals.

1.0.12 — WebGL Support, Serenity Theme & Runtime Localization

Added

  • Serenity Theme — a complete new UI theme with a full component set (Background, Title, Label, Input, Dropdown, Selector, Slider, Toggle, Submit, Modal, PrimaryInputPrompt, Highlight), including animator controllers for the highlight color loop and modal show/hide transitions.
  • WebGL build support — the first WebGL build target for Serenity.
  • WebGL Resources export toolingSerenityWebGLResourcesExporter, SerenityWebGLResourcesCleaner, SerenityWebGLResourcesValidator, SerenityWebGLResourcesPaths, and SerenityWebGLExportManifest for exporting Serenity assets into a consumer's Resources tree for WebGL builds.
  • Runtime localization fallbackSerenityFallbackLocalizationService loads per-(table, locale) JSON from Resources and answers a new ILocalizationService.TryTranslate(key, out value), enabling translation and live language switching in ResourcesOnly (WebGL) mode.
  • Per-theme loading-progress bar — a LoadingProgressTemplate slot on the UI theme components and a LoadingBar prefab variant for every theme (Default, Alternative, Alternative2, Animated, Animated2, Futuristic, Serenity, Writings).
  • SerenityAssetLoadingMode enum and IAssetLoadingModeProvider / UnitySerenityAssetLoadingModeProvider to select how assets are loaded (Addressables vs Resources-only).
  • ILocalizationService.GameLanguageChanged event, fired on real language-value changes.
  • Editor menu command (Serenity ▸ UI ▸ Generate LoadingProgress Prefabs) that generates the per-theme loading-bar prefab variants and wires them into the theme definitions.
  • "Loading Progress Prefab" field in the UI theme definition inspector.
  • Inter font family (variable + static weights with SDF assets) and supporting images (WhiteBackground, square-roundborder).

Changed

  • The gameplay loading overlay now builds its progress bar from LoadingProgressTemplate, falling back to SlideableTemplate when no dedicated prefab is assigned.
  • UnityUiTMP_TextLocalizationUpdaterComponent now calls TryTranslate in fallback mode, caches the original localization key across language switches, and re-captures it when the displayed text diverges from the last translation.
  • UnityLocalizationService keeps GameLanguageChanged as a no-op, deferring refresh to Unity Localization's own OnSelectedLocaleChanged chain.
  • UnityPrimaryInputPromptView behavior corrected for WebGL builds.
  • InitializationPipelineService, UnityCutscenePlayerService, ReflectionCallTask, AddressablesAssetLocator, UnityAddressableUtils, UnityAssetUtils, AudioMixerDependencyCache, and UnityMainThreadDispatcher updated to support Resources-only loading and WebGL constraints.
  • The Serenity Addressables group and addressable settings were updated to register the new assets.

Features

  • ResourcesOnly mode now performs real translation and supports switching language at runtime through the settings UI language selector.
  • WebGL Resources export uses move semantics during export and falls back to the browser language as the initial locale.
  • Localization JSON is loaded via a recursive Resources.LoadAll<TextAsset>("") scan with a string-table shape filter, requiring no Unity.Localization.Editor asmdef coupling.

Fixed

  • Fixed the loading bar's selector disappearing on mouse-exit by sourcing the bar from a dedicated loading-progress prefab instead of reusing the interactive slider template.
  • Fixed ResourcesOnly builds previously showing raw localization keys on screen with no way to switch language at runtime.
  • Fixed the language selector (whose values are themselves localization keys) translating the stale cached key instead of the current one.

Infrastructure

  • Added editor tooling for WebGL Resources export, cleanup, validation, and manifest tracking.
  • Reflection-based localization export avoids Unity.Localization.Editor asmdef coupling.
  • Added tests for localization use cases and the localization installer.

1.0.8 — Editor Pickers, Addressables Auto-Labeling & TMP Essentials Validation

Added

  • SerenityTmpEssentialsValidator, an editor-only validator that detects missing TextMeshPro Essential Resources and attempts to import them automatically when possible.
  • Play Mode protection for missing TMP Essentials, cancelling Play Mode entry before Unity/TMP runtime errors can occur.
  • Manual TMP Essentials recovery dialog with options to open the TMP importer, ignore the warning for the current session, or recheck.
  • Serenity import postprocessor that schedules a TMP Essentials check whenever Serenity assets are imported into an already-open Unity editor session.
  • SerenityAddressablesAutoLabeler, an editor-only postprocessor that automatically registers newly imported Serenity ScriptableObject assets as Addressables.
  • Automatic Addressables label assignment for Serenity ScriptableObject assets based on exact type mappings and namespace-prefix fallback rules.
  • Centralized ModuleLabels constants for all Serenity module labels and type labels.
  • ModuleLabels.Types constants for type-based Addressables labels such as font, image, audio, and character assets.
  • Additional module labels for Character, GameMode, SequencePlayer, and Wave systems.
  • Additional common label combinations for GameSettings + Localization and GameSettings + UI.
  • RenderIdObjectField<TAsset>(...) helper in FoundationEditor for rendering Unity ObjectFields backed by serialized string ids.
  • EventDispatcherSignalTypePicker, a shared searchable selector for concrete EventDispatcherSignal subtypes.
  • EventDispatcherSignalTypeAdvancedDropdown, an AdvancedDropdown-based searchable picker for signal-type string fields.
  • module:game-mode Addressables label.
  • Addressables registration and labeling for GameModeSettings.

Changed

  • SerenityPackageDependencyInstaller now treats TextMeshPro as satisfied when the TMP runtime types are available, even if com.unity.textmeshpro is not listed as a standalone package.
  • TextMeshPro dependency detection now supports Unity 6 / UGUI 2.0+ setups where TMP is bundled with com.unity.ugui.
  • Addressables label strings are now routed through Serenity.Shared.Constants.ModuleLabels instead of hard-coded string literals.
  • InstallationConstants.ModuleLabels now acts as a compatibility shim that re-exports the canonical ModuleLabels values.
  • InstallationConstants.TypeLabels now acts as a compatibility shim that re-exports ModuleLabels.Types.
  • UnityAddressablesLabeler now uses centralized ModuleLabels constants for managed labels, path rules, and type rules.
  • UnityAddressablesLabeler now manages additional Serenity labels for Character, GameMode, SequencePlayer, and Wave modules.
  • UnityAudioPlayerInstaller, UnityMusicPlayerInstaller, UnityGameSettingsInstaller, UnityLocalizationInstaller, UnityMenuInstaller, UnityModalInstaller, UnityPlayerInputInstaller, UnitySoundMixerInstaller, UnitySystemConfigurationInstaller, UnityCharacterInstaller, and Cutscene/Sequence related services now use centralized module label constants.
  • AudioMixerDependencyCache now defaults to ModuleLabels.AUDIO_MIXER instead of a hard-coded Addressables label.
  • UnityUiSettingsEditor now renders ScaleKey and FontSizeKey as Unity ObjectFields backed by UnityUIGameSettingsDefinition assets.
  • UnityGameGraphicsSettingsEditor now renders QualityLevelKey, ScreenResolutionKey, and IsFullScreenKey as Unity ObjectFields backed by UnityGraphicGameSettingsDefinition assets.
  • UnityLocalizationSettingsEditor now renders GameLanguageKey and VoiceLanguageKey as Unity ObjectFields backed by UnityLocalizationGameSettingsDefinition assets.
  • UnityMenuServiceSettingsDefinitionEditor now renders InitMenuId as a Unity ObjectField backed by UnityMenuSettingsDefinition assets.
  • UnityGameModeSettingsDefinitionEditor now renders PauseMenuId as a Unity ObjectField backed by UnityMenuSettingsDefinition assets.
  • UnityActionDefinitionEditor now renders Signal through a searchable signal type selector instead of a plain dropdown.
  • UnityModalSettingsEditor now renders SignalType through a searchable signal type selector instead of a plain dropdown.
  • UnityModalSettingsEditor now shares signal type discovery through EventDispatcherSignalTypePicker, avoiding duplicated reflection logic.
  • UnityMenuSettingsDefinitionEditor now uses centralized module label constants when resolving game settings and menus.
  • UnitySoundMixerSettingsEditor now uses centralized module label constants when resolving audio game settings.
  • Serenity sample menu assets were reserialized to include explicit ViewId values on options and values.
  • Serenity sample menu assets now include explicit empty OnShow and OnHide arrays.
  • GameModeSettings sample asset now includes transition signal entries for the newer GameMode enum values.

Features

  • Newly created Serenity ScriptableObject assets can now be automatically added to the Serenity Addressables group with the correct module labels.
  • Addressables auto-labeling now supports exact type mappings for known Serenity assets and namespace fallback for future assets inside existing modules.
  • Editor selectors for string-id-backed ScriptableObject references now support drag-and-drop from the Project window.
  • Editor selectors for string-id-backed ScriptableObject references now support Unity's standard Object Picker search flow.
  • Signal type fields now provide searchable selection while preserving the original serialized string contracts.
  • UnityActionDefinition.Signal continues to store Type.FullName.
  • UnityModalSettings.SignalType continues to store Type.AssemblyQualifiedName.
  • UnityModalSettings.SignalType keeps the <None> option, storing an empty string for no selection.
  • TMP Essentials validation runs both on editor startup/import and synchronously when entering Play Mode.
  • TMP Essentials auto-import attempts to locate the package through TMP editor utilities, Package Manager metadata, or Library/PackageCache.

Improved

  • Inspector UX is now closer to standard Unity workflows for asset-backed references.
  • Reduced accidental invalid selections caused by long non-searchable dropdowns.
  • Reduced duplicated dropdown and reflection code across custom editors.
  • Addressables label management is now safer and easier to maintain through a single source of truth.
  • Addressables auto-labeling is idempotent and non-destructive: it does not remove existing labels and only adds known Serenity labels.
  • TMP package detection is more robust across Unity versions.
  • TMP Essentials detection now distinguishes between the TMP runtime being installed and the actual TMP Essential Resources being present in Assets/.
  • TMP Essentials diagnostics now log TMP font asset hits without treating them as proof that Essentials are installed.
  • Installer and editor code now avoids scattering hard-coded Addressables labels across the codebase.
  • Assembly definitions were updated where needed so modules can reference the shared label constants.

Fixed

  • Fixed false missing-dependency detection for TextMeshPro in Unity versions where TMP is bundled through UGUI rather than installed as com.unity.textmeshpro.
  • Fixed missing module:game-mode labeling for GameModeSettings.
  • Fixed several editor fields that previously required dropdown selection even though they represented asset-backed ids.
  • Fixed UnityActionDefinition.Signal and UnityModalSettings.SignalType remaining as non-searchable dropdowns after the initial picker refactor.
  • Fixed duplicated signal type discovery logic between modal signal selection and modal button signal menus.
  • Fixed hard-coded Addressables label usage across several installers and editor utilities.
  • Fixed Addressables managed label coverage for newer Serenity modules such as Character, GameMode, SequencePlayer, and Wave.

Infrastructure

  • Added editor utilities for automatic Addressables registration and label assignment.
  • Added editor utilities for TMP Essentials validation and recovery.
  • Added shared editor picker infrastructure for signal type selection.
  • Added shared editor helper for ObjectField-to-string-id bridging.
  • Added assembly definition references to Serenity.Shared.Constants where centralized label constants are now used.
  • Updated Addressables settings to remove stale labels and include the new module:game-mode label.
  • Updated the Serenity Addressables group so Media/GameMode/GameModeSettings is labeled with module:game-mode.
  • Updated sample serialized assets to match the current menu and game mode data model.

1.0.5 — Music Player Transitions, GameMode Signals & Menu Integration

Added

  • MusicPlayerTransitionType enum with three transition strategies: CUT, FADEIN_FADEOUT, and CROSS_FADE.
  • Configurable transition parameters on IMusicPlayerService.PlaySong(...) and new PlaySongById(...) method.
  • MusicPlayerPlaySongById use case and MusicPlayerPlaySongByIdInput DTO for playing specific tracks by identifier with explicit loop and transition control.
  • PlaySongById gateway method on IMusicPlayerGateway.
  • SetGameModeService(IGameModeService) contract on IMenuService for cross-service coordination.
  • GetSignalsForGameMode(GameModeEnum) contract on IGameModeSettingsDefinition for per-mode signal configuration.
  • Initialization and Cutscene values to the GameMode enum, establishing Initialization as the default starting mode.
  • Per-mode EventDispatcherSignal transition sequences to UnityGameModeSettingsDefinition.
  • DispatchModeTransitionSignals(...) orchestration in UnityGameModeService that fires configured signals after every mode change.
  • Full ReorderableList-based inspector for per-mode transition signals in UnityGameModeSettingsDefinitionEditor.
  • ServiceLocator registration for IMusicPlayerService during music player installation.

Changed

  • UnityGameModeService now initializes in Initialization mode instead of Menu, deferring the first real mode transition until the menu system is ready.
  • UnitySerenityInstaller.ShowMenu() now wires the resolved IGameModeService into the menu service before invoking ShowInitialMenu(), ensuring the game mode is synchronized on startup.
  • UnityMusicPlayerInstaller now receives ServiceLocatorInstaller for runtime service discovery.
  • Serenity.GameMode.Domain.asmdef reference format standardized to GUID.
  • Production-ready asset naming: Audio_SoundToTestAudio_SoundToTrigger, Audio_TrackToTestMusic_TrackList.
  • AudioTestingMenu settings updated to reference the renamed production assets.

Features

  • Music playback now enforces a single active track rule through coroutine-based volume lerping.
  • Rapid-fire playback requests safely supersede previous transitions ("latest request wins") preventing orphaned audio sources.
  • CROSS_FADE automatically falls back to CUT when insufficient audio channels are configured.
  • GameMode transition signals are dispatched in exact inspector-configured order, with null entries safely skipped and logged.
  • GameMode.Menu is now automatically asserted whenever ShowInitialMenu() is executed, keeping the menu system and mode state in sync.

Improved

  • UnityGameModeSettingsDefinitionEditor inspector now renders one dedicated reorderable signal list per GameMode value with subtype selection dropdowns and drag-and-drop ordering.
  • Signal list elements display the concrete EventDispatcherSignal subtype name for at-a-glance identification.
  • Serenity.Menu.Application and Serenity.UnityMenu.Infrastructure assembly definitions now reference GameMode contracts for cross-layer coordination.

Fixed

  • Prevented potential recursive mode transitions by relying on SetMode short-circuit when the target mode matches the current mode.
  • Music player gateway stub signatures updated to maintain interface compatibility with the new transition-enabled contract.

Infrastructure

  • New assembly definition references added to bridge MusicPlayer, Menu, and GameMode layers without circular dependencies.
  • Tests assembly definition extended to include Serenity.UnityMusicPlayer.Installation for installer-level validation coverage.

1.0.3 — Menu Lifecycle Signals & Inspector Improvements

Added

  • Added OnShow and OnHide lifecycle signal collections to UnityMenuSettingsDefinition.
  • Added menu lifecycle signal support to IMenuSettingsDefinition.
  • Added runtime lifecycle signal dispatching for menu visibility transitions.
  • Added lifecycle signal wiring in UnityMenuViewFactory.
  • Added SetLifecycleSignals(...) support to UnityMenuView.

Features

  • Menus can now dispatch custom EventDispatcherSignal sequences when shown or hidden.
  • Lifecycle signal execution order now follows the exact order configured in the inspector.
  • Lifecycle signal collections now support drag-and-drop reordering through standard Unity reorderable lists.

Improved

  • Enhanced UnityMenuSettingsDefinitionEditor with a dedicated Lifecycle Signals section.
  • Lifecycle signal lists now provide:
    • add/remove controls,
    • drag-and-drop ordering,
    • subtype selection menus,
    • consistent inspector styling with the rest of Serenity editors.
  • Improved inspector UX consistency by reusing the same signal creation patterns already present in other Serenity systems.

Fixed

  • Fixed lifecycle signal inspector rendering so EventDispatcherSignal implementations can be selected correctly.
  • Fixed serialization flow for polymorphic lifecycle signals using Unity managed references.
  • Ensured legacy menu assets continue working safely with empty lifecycle signal collections.

Infrastructure

  • Reused existing EventDispatcherSignal infrastructure and dispatch flow without introducing parallel lifecycle systems.
  • Kept Clean Architecture boundaries intact by exposing lifecycle signals through read-only business-layer abstractions.

1.0.2 — Editor & Localization Inspector Improvements

Added

  • UnityLocalizationLocaleEditorUtils, a reflection-based editor helper for safe Unity Localization locale discovery without assembly dependency overhead.

Changed

  • Enhanced LocalizationSettingsDefinitionEditor to improve the UX for UnityLocalizationGameSettingsDefinition assets.
  • Hardened Serenity import workflow and localization recovery process.
  • Refactored modal settings editor button signal flow for cleaner editor interactions.

Features

  • Locked the ValueType field to SELECTABLE with automatic normalization and safety validation to prevent configuration errors.
  • Replaced the free-text "Key" input in the Options table with a dynamic dropdown populated from Unity Localization locales.

Improved

  • Added fallback support for unknown keys and informative HelpBoxes to guide users when Localization settings are missing or unconfigured.
  • Package initialization stability after importing Serenity into a fresh Unity project.

Fixed

  • Loading overlay background color resolution when using rendering cameras.

Infrastructure

  • Reused existing FoundationEditor and UnityGameSettingsDefinitionEditor UI utilities to maintain visual and functional consistency.

1.0.0 — Initial Release

✨ Features

  • Decoupled game logic with zero engine dependencies in core layers. All domain and application code compiles under noEngineReferences: true, ensuring business rules are fully portable, testable, and free of Unity coupling.

  • Extensible, layered persistence system. A unified storage hierarchy supports key-value stores (backed by PlayerPrefs), file-based blob stores with atomic writes, and append-only streams — all behind swappable contracts that can target local files, cloud services, or custom backends.

  • Advanced asset preloading with memory budgets. A priority-aware prefetch engine with LRU eviction, configurable memory budgets, sliding-window and on-demand strategies, and Addressables-based label resolution provides predictable asset availability with controllable resource pressure.

  • Typed, repository-persisted game settings. A generic settings system supports Boolean, Integer, Float, and Selectable option types with value-change notifications, automatic persistence, and reactive integration with audio, graphics, and localization modules.

  • State-driven character management. Characters follow a well-defined lifecycle (Spawning → Active → Dying → Dead) with hit-point tracking, immutable snapshots, and virtual extension points for game-specific specialization.

  • Game-agnostic combo counter. A pure counting model with immutable snapshots that imposes no gameplay semantics — timeout, multiplier, and scoring logic remain the consuming layer's responsibility.

  • Opaque checkpoint persistence. Named save slots with extensible metadata (timestamp, label, stage) store arbitrary binary payloads without interpreting or validating their contents, leaving serialization strategy to consumers.

  • Configurable initialization pipeline. An ordered phase-and-task startup system with weighted progress tracking, per-task criticality (Critical vs. NonCritical), and pluggable execution policies (sequential or parallel per phase).

  • Complete procedural animation system. A data-driven, key-based procedural expression engine supports layered pose composition (oscillation, drift, noise, impulse), material property animation, transform scale animation, discrete one-shot actions (flinch, recoil, stumble), rule-based activation with hysteresis conditions, and real-time tuning — all fully product-agnostic.

  • Type-safe publish/subscribe event system. A centralized event dispatcher with auto-registering actions, typed signal classes, and attribute-based discovery enables decoupled inter-module communication.

  • Multi-category audio playback. A gateway-routed audio system supports SFX, Music, Voice, Ambient, Environment, and UI channels with per-category pooling and settings-driven clip configuration.

  • Dedicated music player with crossfade support. Background music management provides play, stop, fade-in, fade-out, and crossfade operations independently from the short-form audio system.

  • Audio mixer abstraction. Group-based volume and mute management (Master, Music, SFX, Voice, UI) with automatic persistence through game settings integration.

  • Stage lifecycle management. A top-level stage aggregate tracks start, completion, and failure states with signal-based notifications consumed by downstream modules such as waves, timers, and scoring.

  • Sequential wave progression. Wave-by-wave stage structure with automatic clear detection and cascading signals for wave start, wave cleared, and all-waves-cleared events.

  • Dynamic multi-metric scoring. An unbounded scoring model addressed by named keys supports runtime metric registration and full arithmetic operations (add, subtract, multiply, divide, set, reset) with repository-backed persistence.

  • Application mode management. A game-mode service coordinates transitions between Menu, Game, and Pause states with pluggable pause strategies, input action-map switching, and signal-driven coordination.

  • Session lifecycle tracking. Per-session state management with engine-agnostic time sources, frame-by-frame tick accumulation, and immutable session snapshots.

  • Timer management system. Named timers with countdown, elapsed, and repeating modes provide normalized progress, pause/resume control, and signal-based lifecycle notifications.

  • Menu navigation with stack support. A navigation-stack-based menu system supports show, hide, push, pop, and peek operations with per-menu configuration and lifecycle signals.

  • Modal dialog system. Configurable modal dialogs with button factories, callback-based result handling, and pre-built signals for common confirmations (exit application, restart game, reset settings).

  • Platform-agnostic UI foundation. A view hierarchy, theme/style system, and component model enable composable UI construction without engine dependencies in the domain layer.

  • Game UI state management. Abstract HUD and results-screen state models with presenter-port rendering delegation enable testing UI logic in isolation from rendering infrastructure.

  • Localization with settings integration. Game and voice language management with automatic language switching driven by persistent game settings changes.

  • Graphics settings management. Reactive quality level, screen resolution, and fullscreen mode management driven by game settings value-change events.

  • System configuration detection. Hardware capability queries (memory, GPU, display) with recommended quality profile generation for automatic configuration.

  • Generic spawning and pooling model. Handle-tracked entity creation and destruction with pool-state queries, decoupled from instantiation mechanics via a factory port.

  • Gameplay entity identity. GUID-based entity identity with semantic classification (Player, Character, Hazard) provides a shared reference vocabulary across gameplay systems.

  • Rail-based movement model. Named rail paths with normalized progress tracking enable externally-driven on-rails motion without coupling to interpolation or easing logic.

  • Weapon state management. Trigger mechanics, fire-mode switching, and magazine/ammo tracking with read-only snapshots — independent of visual representation or projectile systems.

  • Sequence orchestration engine. A generic ordered-execution system provides completion-based stage iteration consumed by vertical aggregates such as the cutscene player.

  • Cinematic cutscene playback. Timed stage execution with fade, timeline, wait, and dialog stage types built on top of the sequence orchestration foundation.

  • Structured logging with category-based verbosity. A configurable logging system with severity levels, per-category overrides, log routing profiles, and component loggers consumed by every module.

  • View browser navigation. Forward/back screen browsing with navigation state queries for UI-driven browsing flows.

  • Minimal service locator. A dictionary-backed service resolution contract for narrow use cases where constructor injection is impractical (e.g., reflection-instantiated event actions).

  • Composable task system. Async work-unit contracts with criticality levels, reflection-based method invocation, service-aware argument resolution, and main-thread dispatching support.

  • File-based persistence with atomic writes. A file-system blob store with write-then-rename safety, platform-specific path resolution, and append-only stream support.

🧱 Architecture

  • Clean Architecture enforcement. Every aggregate follows a strict Domain ← Application ← Installation layering with inward-only dependency arrows. Domain layers have zero or minimal external dependencies; application layers depend only on domain contracts and cross-cutting foundation services; installation layers wire platform-specific implementations.

  • Engine isolation via assembly definitions. Core business assemblies declare noEngineReferences: true, guaranteeing compile-time enforcement that no Unity API leaks into domain or application logic.

  • SOLID principles throughout. Single-responsibility aggregates, interface-segregated service contracts, open/closed extension via abstract installers and factory ports, and dependency inversion through platform-agnostic interfaces.

  • Domain-Driven Design vocabulary. Entities carry mutable state with guarded transitions, value objects provide immutable identity and snapshots, and aggregates define bounded contexts with explicit integration points.

  • Use-case-driven API design. Consumer-facing operations are encapsulated in typed use-case classes with dedicated input DTOs, bundled into injectable containers for clean dependency graphs.

  • Immutable snapshot pattern. All stateful aggregates expose read-only snapshots for queries, ensuring consumers cannot inadvertently mutate internal state.

  • Abstract installer pattern. Each aggregate defines an abstract installer that declares the wiring contract; concrete platform layers (Unity, tests, or custom targets) provide implementations without modifying business code.

  • Signal-based inter-module communication. Typed event signals flow through a centralized dispatcher, keeping aggregates decoupled while enabling reactive coordination.

📦 Modules

  • Global — Foundation contracts, lifecycle events (exit/restart), use-case interface hierarchy, component model for UI composition, and the abstract installer base consumed by every other aggregate.

  • EventDispatcher — Type-safe publish/subscribe event system with auto-registering actions, typed signal classes, and attribute-based discovery.

  • Logging — Configurable logging with severity levels, category-based verbosity overrides, log routing profiles, component loggers, and file/console output support.

  • ServiceLocator — Minimal typed service resolution with a dictionary-backed default implementation.

  • Task — Async work-unit contracts with criticality, reflection-based method invocation, and extensible argument resolution.

  • InitializationPipeline — Ordered phase-and-task startup system with weighted progress tracking, criticality-based failure handling, and pluggable execution policies.

  • Persistence — Layered storage hierarchy: key-value stores, stream-based blob stores, and append-only stores — all behind swappable platform contracts.

  • FilePersistence — File-system blob store with atomic write-then-rename safety and platform-specific path resolution.

  • PlayerPrefsPersistence — Lightweight Unity PlayerPrefs-backed key-value store with Base64 encoding.

  • GameSettings — Typed settings system (Boolean, Integer, Float, Selectable) with repository persistence and value-change notifications.

  • Checkpoint — Opaque binary checkpoint persistence with named slots (Slot1–3, Auto, Quick) and extensible metadata.

  • Score — Dynamic multi-metric scoring model with unbounded key-based metrics, full arithmetic operations, and repository persistence.

  • Combo — Game-agnostic combo counter with immutable snapshots and virtual extension points for multiplier, timeout, or decay behavior.

  • Character — State-driven character lifecycle (Spawning → Active → Dying → Dead) with hit-point management, inheritable status enums, and immutable snapshots.

  • GameplayEntity — GUID-based entity identity with semantic classification and lightweight cross-system references.

  • GameSpawner — Handle-tracked entity spawning and pool-state management with a factory port for instantiation strategy.

  • Stage — Top-level stage lifecycle (NotStarted → InProgress → Completed/Failed) with spawn-point resolution and rail-path authoring contracts.

  • Wave — Sequential wave progression with automatic clear detection and cascading lifecycle signals.

  • Timer — Named timer management with countdown, elapsed, and repeating modes, normalized progress, and lifecycle signals.

  • GameMode — Application mode state machine (Menu, Game, Pause) with pluggable pause strategies and signal-driven transitions.

  • GameSession — Per-session lifecycle tracking with engine-agnostic time sources and tick-based elapsed time accumulation.

  • AudioPlayer — Multi-category audio playback with gateway routing, channel pooling, and use-case-driven operations.

  • MusicPlayer — Background music management with play, stop, fade, and crossfade operations.

  • SoundMixer — Group-based volume and mute management with reactive game settings integration.

  • GameGraphics — Reactive quality level, resolution, and fullscreen management driven by game settings changes.

  • SystemConfiguration — Hardware capability detection with recommended quality profile generation.

  • PlayerInput — Platform-agnostic input abstraction with action-map switching and input-action binding contracts.

  • Ui — View hierarchy, theme/style system, and component model for composable, engine-independent UI construction.

  • Menu — Navigation-stack-based menu system with per-menu configuration and lifecycle signals.

  • Modal — Configurable modal dialogs with button factories, callback-based results, and pre-built confirmation signals.

  • GameUi — Abstract HUD and results-screen state management with presenter-port delegation.

  • ViewBrowser — Forward/back screen navigation with state queries.

  • Localization — Game and voice language management with automatic settings-driven language switching.

  • SequencePlayer — Generic ordered-execution orchestration engine for completion-based stage iteration.

  • CutscenePlayer — Cinematic playback with timed stages (fade, timeline, wait, dialog) built on the sequence orchestration foundation.

  • GameRail — Named rail-path registration with normalized progress tracking for on-rails movement.

  • GameWeapon — Trigger mechanics, fire-mode switching, and magazine/ammo tracking with read-only snapshots.

  • ProceduralExpression — Data-driven procedural animation system with layered pose composition, material/transform animation, rule-based activation, discrete actions, and real-time tuning support.

  • Shared — Cross-cutting constants (service names, module labels, context identifiers) and utility classes (parsing, reflection, GUID generation).

🛠️ Tooling

  • DocFX-based API documentation generator. An integrated documentation builder accessible from Tools → Serenity → Docs compiles all assemblies with Roslyn XML documentation and generates a navigable static API site via DocFX — with automatic installation, configuration generation, and branded template support.

  • Procedural Expression setup tool. A one-click setup wizard (Tools → Serenity → Procedural Expression → Setup Minimal Idle) auto-detects skeleton bones, generates all required configuration assets, and wires a procedural animation profile to any prefab — supporting rigged characters, simple objects, props, and UI elements.

  • Asset Prefetcher diagnostics inspector. A custom Editor inspector for the prefetch service provides cache refresh, clear, clipboard export, diagnostics display, auto-refresh polling, and color-coded asset category visualization.

  • System Configuration inspector. A custom inspector for system configuration settings provides comprehensive interface for data collection timing, scope, and heuristic tuning.

  • Menu and Modal inspectors. Custom Editor inspectors for menu views and modal components provide read-only configuration display, signal binding management, and button configuration interfaces.

  • ScriptableObject-based configuration. Prefetch policy profiles, procedural expression profiles, state keys, layers, actions, rules, audio settings, game settings definitions, and localization tables are all authored as ScriptableObject assets — enabling non-programmer configuration and version-controlled presets.

  • Abstract installer pattern for platform wiring. Each aggregate defines an abstract installer with explicit dependencies; Unity-specific concrete installers handle MonoBehaviour creation, Addressables integration, and service locator registration.

  • Procedural Expression debug panel. A runtime GUI overlay (toggled via F12) displays live state-key values with color-coded sliders, range hints, and reset controls for real-time tuning in Play Mode.

  • Procedural Expression custom property drawers. Bone ID reference drawers with profile-aware dropdown selection, rule editors with inline condition configuration, and profile editors with validation and derived-property display.

🎯 Purpose

Serenity exists to eliminate the recurring boilerplate that accompanies every Unity project: persistence wiring, settings management, audio routing, initialization sequencing, mode transitions, and event plumbing. Rather than providing opinionated gameplay systems, it supplies the architectural spine — clean contracts, layered boundaries, and composable modules — that game-specific code builds upon.

By enforcing strict engine isolation in core layers, Serenity ensures that business logic remains testable outside Unity, portable across platforms, and resilient to engine API changes. The abstract installer pattern means swapping a persistence backend or input system requires implementing a single interface, not refactoring a dependency tree.

Every module follows the same structural conventions: domain entities with guarded state transitions, immutable snapshots for safe queries, use-case classes with typed inputs, and signal-based integration points. This consistency reduces onboarding time and makes cross-module patterns immediately recognizable.

Serenity is not a game template. It provides no characters, no levels, no win conditions. It provides the foundation that makes those systems cleaner, faster to build, and easier to maintain across the lifetime of a project.

✨ Features

  • Decoupled game logic with zero engine dependencies in core layers. All domain and application code compiles under noEngineReferences: true, ensuring business rules are fully portable, testable, and free of Unity coupling.

  • Extensible, layered persistence system. A unified storage hierarchy supports key-value stores (backed by PlayerPrefs), file-based blob stores with atomic writes, and append-only streams — all behind swappable contracts that can target local files, cloud services, or custom backends.

  • Advanced asset preloading with memory budgets. A priority-aware prefetch engine with LRU eviction, configurable memory budgets, sliding-window and on-demand strategies, and Addressables-based label resolution provides predictable asset availability with controllable resource pressure.

  • Typed, repository-persisted game settings. A generic settings system supports Boolean, Integer, Float, and Selectable option types with value-change notifications, automatic persistence, and reactive integration with audio, graphics, and localization modules.

  • State-driven character management. Characters follow a well-defined lifecycle (Spawning → Active → Dying → Dead) with hit-point tracking, immutable snapshots, and virtual extension points for game-specific specialization.

  • Game-agnostic combo counter. A pure counting model with immutable snapshots that imposes no gameplay semantics — timeout, multiplier, and scoring logic remain the consuming layer's responsibility.

  • Opaque checkpoint persistence. Named save slots with extensible metadata (timestamp, label, stage) store arbitrary binary payloads without interpreting or validating their contents, leaving serialization strategy to consumers.

  • Configurable initialization pipeline. An ordered phase-and-task startup system with weighted progress tracking, per-task criticality (Critical vs. NonCritical), and pluggable execution policies (sequential or parallel per phase).

  • Complete procedural animation system. A data-driven, key-based procedural expression engine supports layered pose composition (oscillation, drift, noise, impulse), material property animation, transform scale animation, discrete one-shot actions (flinch, recoil, stumble), rule-based activation with hysteresis conditions, and real-time tuning — all fully product-agnostic.

  • Type-safe publish/subscribe event system. A centralized event dispatcher with auto-registering actions, typed signal classes, and attribute-based discovery enables decoupled inter-module communication.

  • Multi-category audio playback. A gateway-routed audio system supports SFX, Music, Voice, Ambient, Environment, and UI channels with per-category pooling and settings-driven clip configuration.

  • Dedicated music player with crossfade support. Background music management provides play, stop, fade-in, fade-out, and crossfade operations independently from the short-form audio system.

  • Audio mixer abstraction. Group-based volume and mute management (Master, Music, SFX, Voice, UI) with automatic persistence through game settings integration.

  • Stage lifecycle management. A top-level stage aggregate tracks start, completion, and failure states with signal-based notifications consumed by downstream modules such as waves, timers, and scoring.

  • Sequential wave progression. Wave-by-wave stage structure with automatic clear detection and cascading signals for wave start, wave cleared, and all-waves-cleared events.

  • Dynamic multi-metric scoring. An unbounded scoring model addressed by named keys supports runtime metric registration and full arithmetic operations (add, subtract, multiply, divide, set, reset) with repository-backed persistence.

  • Application mode management. A game-mode service coordinates transitions between Menu, Game, and Pause states with pluggable pause strategies, input action-map switching, and signal-driven coordination.

  • Session lifecycle tracking. Per-session state management with engine-agnostic time sources, frame-by-frame tick accumulation, and immutable session snapshots.

  • Timer management system. Named timers with countdown, elapsed, and repeating modes provide normalized progress, pause/resume control, and signal-based lifecycle notifications.

  • Menu navigation with stack support. A navigation-stack-based menu system supports show, hide, push, pop, and peek operations with per-menu configuration and lifecycle signals.

  • Modal dialog system. Configurable modal dialogs with button factories, callback-based result handling, and pre-built signals for common confirmations (exit application, restart game, reset settings).

  • Platform-agnostic UI foundation. A view hierarchy, theme/style system, and component model enable composable UI construction without engine dependencies in the domain layer.

  • Game UI state management. Abstract HUD and results-screen state models with presenter-port rendering delegation enable testing UI logic in isolation from rendering infrastructure.

  • Localization with settings integration. Game and voice language management with automatic language switching driven by persistent game settings changes.

  • Graphics settings management. Reactive quality level, screen resolution, and fullscreen mode management driven by game settings value-change events.

  • System configuration detection. Hardware capability queries (memory, GPU, display) with recommended quality profile generation for automatic configuration.

  • Generic spawning and pooling model. Handle-tracked entity creation and destruction with pool-state queries, decoupled from instantiation mechanics via a factory port.

  • Gameplay entity identity. GUID-based entity identity with semantic classification (Player, Character, Hazard) provides a shared reference vocabulary across gameplay systems.

  • Rail-based movement model. Named rail paths with normalized progress tracking enable externally-driven on-rails motion without coupling to interpolation or easing logic.

  • Weapon state management. Trigger mechanics, fire-mode switching, and magazine/ammo tracking with read-only snapshots — independent of visual representation or projectile systems.

  • Sequence orchestration engine. A generic ordered-execution system provides completion-based stage iteration consumed by vertical aggregates such as the cutscene player.

  • Cinematic cutscene playback. Timed stage execution with fade, timeline, wait, and dialog stage types built on top of the sequence orchestration foundation.

  • Structured logging with category-based verbosity. A configurable logging system with severity levels, per-category overrides, log routing profiles, and component loggers consumed by every module.

  • View browser navigation. Forward/back screen browsing with navigation state queries for UI-driven browsing flows.

  • Minimal service locator. A dictionary-backed service resolution contract for narrow use cases where constructor injection is impractical (e.g., reflection-instantiated event actions).

  • Composable task system. Async work-unit contracts with criticality levels, reflection-based method invocation, service-aware argument resolution, and main-thread dispatching support.

  • File-based persistence with atomic writes. A file-system blob store with write-then-rename safety, platform-specific path resolution, and append-only stream support.

🧱 Architecture

  • Clean Architecture enforcement. Every aggregate follows a strict Domain ← Application ← Installation layering with inward-only dependency arrows. Domain layers have zero or minimal external dependencies; application layers depend only on domain contracts and cross-cutting foundation services; installation layers wire platform-specific implementations.

  • Engine isolation via assembly definitions. Core business assemblies declare noEngineReferences: true, guaranteeing compile-time enforcement that no Unity API leaks into domain or application logic.

  • SOLID principles throughout. Single-responsibility aggregates, interface-segregated service contracts, open/closed extension via abstract installers and factory ports, and dependency inversion through platform-agnostic interfaces.

  • Domain-Driven Design vocabulary. Entities carry mutable state with guarded transitions, value objects provide immutable identity and snapshots, and aggregates define bounded contexts with explicit integration points.

  • Use-case-driven API design. Consumer-facing operations are encapsulated in typed use-case classes with dedicated input DTOs, bundled into injectable containers for clean dependency graphs.

  • Immutable snapshot pattern. All stateful aggregates expose read-only snapshots for queries, ensuring consumers cannot inadvertently mutate internal state.

  • Abstract installer pattern. Each aggregate defines an abstract installer that declares the wiring contract; concrete platform layers (Unity, tests, or custom targets) provide implementations without modifying business code.

  • Signal-based inter-module communication. Typed event signals flow through a centralized dispatcher, keeping aggregates decoupled while enabling reactive coordination.

📦 Modules

  • Global — Foundation contracts, lifecycle events (exit/restart), use-case interface hierarchy, component model for UI composition, and the abstract installer base consumed by every other aggregate.

  • EventDispatcher — Type-safe publish/subscribe event system with auto-registering actions, typed signal classes, and attribute-based discovery.

  • Logging — Configurable logging with severity levels, category-based verbosity overrides, log routing profiles, component loggers, and file/console output support.

  • ServiceLocator — Minimal typed service resolution with a dictionary-backed default implementation.

  • Task — Async work-unit contracts with criticality, reflection-based method invocation, and extensible argument resolution.

  • InitializationPipeline — Ordered phase-and-task startup system with weighted progress tracking, criticality-based failure handling, and pluggable execution policies.

  • Persistence — Layered storage hierarchy: key-value stores, stream-based blob stores, and append-only stores — all behind swappable platform contracts.

  • FilePersistence — File-system blob store with atomic write-then-rename safety and platform-specific path resolution.

  • PlayerPrefsPersistence — Lightweight Unity PlayerPrefs-backed key-value store with Base64 encoding.

  • GameSettings — Typed settings system (Boolean, Integer, Float, Selectable) with repository persistence and value-change notifications.

  • Checkpoint — Opaque binary checkpoint persistence with named slots (Slot1–3, Auto, Quick) and extensible metadata.

  • Score — Dynamic multi-metric scoring model with unbounded key-based metrics, full arithmetic operations, and repository persistence.

  • Combo — Game-agnostic combo counter with immutable snapshots and virtual extension points for multiplier, timeout, or decay behavior.

  • Character — State-driven character lifecycle (Spawning → Active → Dying → Dead) with hit-point management, inheritable status enums, and immutable snapshots.

  • GameplayEntity — GUID-based entity identity with semantic classification and lightweight cross-system references.

  • GameSpawner — Handle-tracked entity spawning and pool-state management with a factory port for instantiation strategy.

  • Stage — Top-level stage lifecycle (NotStarted → InProgress → Completed/Failed) with spawn-point resolution and rail-path authoring contracts.

  • Wave — Sequential wave progression with automatic clear detection and cascading lifecycle signals.

  • Timer — Named timer management with countdown, elapsed, and repeating modes, normalized progress, and lifecycle signals.

  • GameMode — Application mode state machine (Menu, Game, Pause) with pluggable pause strategies and signal-driven transitions.

  • GameSession — Per-session lifecycle tracking with engine-agnostic time sources and tick-based elapsed time accumulation.

  • AudioPlayer — Multi-category audio playback with gateway routing, channel pooling, and use-case-driven operations.

  • MusicPlayer — Background music management with play, stop, fade, and crossfade operations.

  • SoundMixer — Group-based volume and mute management with reactive game settings integration.

  • GameGraphics — Reactive quality level, resolution, and fullscreen management driven by game settings changes.

  • SystemConfiguration — Hardware capability detection with recommended quality profile generation.

  • PlayerInput — Platform-agnostic input abstraction with action-map switching and input-action binding contracts.

  • Ui — View hierarchy, theme/style system, and component model for composable, engine-independent UI construction.

  • Menu — Navigation-stack-based menu system with per-menu configuration and lifecycle signals.

  • Modal — Configurable modal dialogs with button factories, callback-based results, and pre-built confirmation signals.

  • GameUi — Abstract HUD and results-screen state management with presenter-port delegation.

  • ViewBrowser — Forward/back screen navigation with state queries.

  • Localization — Game and voice language management with automatic settings-driven language switching.

  • SequencePlayer — Generic ordered-execution orchestration engine for completion-based stage iteration.

  • CutscenePlayer — Cinematic playback with timed stages (fade, timeline, wait, dialog) built on the sequence orchestration foundation.

  • GameRail — Named rail-path registration with normalized progress tracking for on-rails movement.

  • GameWeapon — Trigger mechanics, fire-mode switching, and magazine/ammo tracking with read-only snapshots.

  • ProceduralExpression — Data-driven procedural animation system with layered pose composition, material/transform animation, rule-based activation, discrete actions, and real-time tuning support.

  • Shared — Cross-cutting constants (service names, module labels, context identifiers) and utility classes (parsing, reflection, GUID generation).

🛠️ Tooling

  • DocFX-based API documentation generator. An integrated documentation builder accessible from Tools → Serenity → Docs compiles all assemblies with Roslyn XML documentation and generates a navigable static API site via DocFX — with automatic installation, configuration generation, and branded template support.

  • Procedural Expression setup tool. A one-click setup wizard (Tools → Serenity → Procedural Expression → Setup Minimal Idle) auto-detects skeleton bones, generates all required configuration assets, and wires a procedural animation profile to any prefab — supporting rigged characters, simple objects, props, and UI elements.

  • Asset Prefetcher diagnostics inspector. A custom Editor inspector for the prefetch service provides cache refresh, clear, clipboard export, diagnostics display, auto-refresh polling, and color-coded asset category visualization.

  • System Configuration inspector. A custom inspector for system configuration settings provides comprehensive interface for data collection timing, scope, and heuristic tuning.

  • Menu and Modal inspectors. Custom Editor inspectors for menu views and modal components provide read-only configuration display, signal binding management, and button configuration interfaces.

  • ScriptableObject-based configuration. Prefetch policy profiles, procedural expression profiles, state keys, layers, actions, rules, audio settings, game settings definitions, and localization tables are all authored as ScriptableObject assets — enabling non-programmer configuration and version-controlled presets.

  • Abstract installer pattern for platform wiring. Each aggregate defines an abstract installer with explicit dependencies; Unity-specific concrete installers handle MonoBehaviour creation, Addressables integration, and service locator registration.

  • Procedural Expression debug panel. A runtime GUI overlay (toggled via F12) displays live state-key values with color-coded sliders, range hints, and reset controls for real-time tuning in Play Mode.

  • Procedural Expression custom property drawers. Bone ID reference drawers with profile-aware dropdown selection, rule editors with inline condition configuration, and profile editors with validation and derived-property display.

🎯 Purpose

Serenity exists to eliminate the recurring boilerplate that accompanies every Unity project: persistence wiring, settings management, audio routing, initialization sequencing, mode transitions, and event plumbing. Rather than providing opinionated gameplay systems, it supplies the architectural spine — clean contracts, layered boundaries, and composable modules — that game-specific code builds upon.

By enforcing strict engine isolation in core layers, Serenity ensures that business logic remains testable outside Unity, portable across platforms, and resilient to engine API changes. The abstract installer pattern means swapping a persistence backend or input system requires implementing a single interface, not refactoring a dependency tree.

Every module follows the same structural conventions: domain entities with guarded state transitions, immutable snapshots for safe queries, use-case classes with typed inputs, and signal-based integration points. This consistency reduces onboarding time and makes cross-module patterns immediately recognizable.

Serenity is not a game template. It provides no characters, no levels, no win conditions. It provides the foundation that makes those systems cleaner, faster to build, and easier to maintain across the lifetime of a project.