Changelog
Latest updates and improvements to Serenity.
1.1.0 — Positional & Priority Audio, Music Loop Tails, Mixer Effect Loops, Lazy Menus & GameMode Input Gate
Breaking Changes
SpawnPoseno longer exposes the seven flat float fields (PositionX/Y/Z,RotationX/Y/Z/W). It is now backed byPosition(System.Numerics.Vector3) andRotation(System.Numerics.Quaternion). Construction is unaffected — the seven-float constructor andFromPosition(x, y, z)remain — but code that read the individual float fields must now readpose.Position.*/pose.Rotation.*.
Added
- Primary input gate as a GameMode — a
PrimaryInputGatevalue on theGameModeenum 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 loops —
StartTime,EndTime,TailPreservingLoop,TailFadeOutDuration, andTailFadeOutCurveonIMusicTrackDefinition/MusicTrack/UnityMusicTrackDefinition. A second voice carries the previous pass's reverb/ambience tail across the loop seam, scheduled sample-accurately viaAudioSettings.dspTime/PlayScheduledso the loop never clicks. Loop points are authored asHH:MM:SS:MMMtime codes or in DAW terms (tempo, time signature, start/end bar) viaMusicBarTimeCalculator; the tail fade follows a Linear/Exponential/Logarithmic/S-Curve/Custom curve. - Positional audio playback —
AudioWorldPositionvalue object and an optionalPlaybackPositiononAudioPlayerPlayClipInput; 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 aPlayAudioClipsignal (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/CanBeReplacedand anAudioPriorityCandidateSelector(AudioPriorityPolicy: IgnoreIfNoSourceAvailable / ReplaceLowerPriority / ReplaceLowerOrEqualPriority / AlwaysReplace). Serenity priority semantics (higher = more important) are mapped to Unity's invertedAudioSource.priorityonly at the boundary. - AudioMixer Effect Loop authoring tool (
Tools ▸ Serenity ▸ Audio ▸ Create Audio Mixer Effect Loop) — creates a mixer group with aReceive → effects → Attenuationchain and a reusableUnitySoundMixerEffectLoopDefinitionasset describing it. - Effect Loop sync window (
Tools ▸ Serenity ▸ Audio ▸ Sync Effect Loops) — reconciles the AudioMixer andSoundMixerSettingsto 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
EventDispatcheraction/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-agnosticSoundMixerEffectLoopRouteResolver. UnitySoundMixerEffectLoopDefinition/UnitySoundMixerEffectLoopSourceScriptableObjects with a custom inspector, plus anEffectLoopsregistry onSoundMixerSettings.- Editor-only
AudioMixerYamlReader(reads.mixerstructure) andAudioMixerEffectLoopReflectionAdapter(isolates the internalUnityEditor.AudioAPI behind one class). - Per-menu instantiation mode —
MenuInstantiationMode(PreloadOnStartup/LazyOnFirstOpen) onIMenuSettingsDefinitionandUnityMenuSettingsDefinition, editable under an Advanced section in the menu settings inspector. - Lazy menu instantiation pipeline:
IMenuInstanceGate,MenuLifecycleResolver,EnsuringMenuTransitionateToView,UnityMenuLazyBuildContext,UnityMenuLazyRegistration, andIUnityMenuViewInstanceFactory/UnityMenuViewInstanceFactory. - Per-mode exit transition signals —
IGameModeSettingsDefinition.GetExitSignalsForGameMode; the GameMode settings inspector now renders separate reorderable enter/exit signal lists per mode. - Pause-during-scene-load — a
PauseDuringSceneLoadGameMode setting (default on) with a settings-editor toggle, freezing the game clock while the additive gameplay scene loads and restoring it (viatry/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.cfgat detection time (standalone viaUnitySystemConfigurationSnapshotStore; WebGL/ResourcesOnly viaSerenityFallbackLocalizationService), guarded by a file-existence check so a returning player's saved preference is preserved.
Changed
SpawnPoseis now backed bySystem.NumericsVector3 Position+Quaternion Rotation(replacing the seven flat floats), matching GameRail'sRailNodePositionvalue-object pattern; it stays pure C# (no engine dependency).UnityWaveServicereadspose.Position.*/pose.Rotation.*. See Breaking Changes.UnityAudioPlayerService.ApplyPlaybackPlacementis now the single source of truth forAudioSource.spatialBlend(with a position →1and the emitter is moved there; without →0and the emitter is left in place);ApplyClipToSourceno longer applies the clip's spatial blend.UnityGameModeServicedispatches the exited mode's signals afterOnExitMode, mirroring the existing enter signals; enteringPrimaryInputGatefires its enter signals and leaving it fires its exit signals through the sameSetModedispatch.- 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.
UnityMenuServicebuildsLazyOnFirstOpenmenus on first show (cached and reused);PreloadOnStartupmenus 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).UnitySoundMixerSettingsEditornow 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.
UnityYamlUtilswas 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 raisesOnPrimarySelectedand the composition root dispatchesEnterMenuSignal, letting theEnterMenuaction 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
0duration 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 oneUiOptionValue(e.g. master/ambient). ISoundMixerServiceis now registered in the runtimeServiceLocator, soEventDispatcheractions 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/DisablePauseMixerEffectLoopActionclasses and thePauseEffectLoopsample asset (superseded by GameMode exit signals and the action-script generator). - A bogus
SoundMixerSettingsmapping (Music_SucutruleLoop_Send→Audio_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;
SpawnPoseconstruction; 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 tooling —
SerenityWebGLResourcesExporter,SerenityWebGLResourcesCleaner,SerenityWebGLResourcesValidator,SerenityWebGLResourcesPaths, andSerenityWebGLExportManifestfor exporting Serenity assets into a consumer'sResourcestree for WebGL builds. - Runtime localization fallback —
SerenityFallbackLocalizationServiceloads per-(table, locale) JSON fromResourcesand answers a newILocalizationService.TryTranslate(key, out value), enabling translation and live language switching in ResourcesOnly (WebGL) mode. - Per-theme loading-progress bar — a
LoadingProgressTemplateslot on the UI theme components and aLoadingBarprefab variant for every theme (Default, Alternative, Alternative2, Animated, Animated2, Futuristic, Serenity, Writings). SerenityAssetLoadingModeenum andIAssetLoadingModeProvider/UnitySerenityAssetLoadingModeProviderto select how assets are loaded (Addressables vs Resources-only).ILocalizationService.GameLanguageChangedevent, 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 toSlideableTemplatewhen no dedicated prefab is assigned. UnityUiTMP_TextLocalizationUpdaterComponentnow callsTryTranslatein fallback mode, caches the original localization key across language switches, and re-captures it when the displayed text diverges from the last translation.UnityLocalizationServicekeepsGameLanguageChangedas a no-op, deferring refresh to Unity Localization's ownOnSelectedLocaleChangedchain.UnityPrimaryInputPromptViewbehavior corrected for WebGL builds.InitializationPipelineService,UnityCutscenePlayerService,ReflectionCallTask,AddressablesAssetLocator,UnityAddressableUtils,UnityAssetUtils,AudioMixerDependencyCache, andUnityMainThreadDispatcherupdated 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 noUnity.Localization.Editorasmdef 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.Editorasmdef 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
ModuleLabelsconstants for all Serenity module labels and type labels. ModuleLabels.Typesconstants 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 inFoundationEditorfor rendering Unity ObjectFields backed by serialized string ids.EventDispatcherSignalTypePicker, a shared searchable selector for concreteEventDispatcherSignalsubtypes.EventDispatcherSignalTypeAdvancedDropdown, anAdvancedDropdown-based searchable picker for signal-type string fields.module:game-modeAddressables label.- Addressables registration and labeling for
GameModeSettings.
Changed
SerenityPackageDependencyInstallernow treats TextMeshPro as satisfied when the TMP runtime types are available, even ifcom.unity.textmeshprois 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.ModuleLabelsinstead of hard-coded string literals. InstallationConstants.ModuleLabelsnow acts as a compatibility shim that re-exports the canonicalModuleLabelsvalues.InstallationConstants.TypeLabelsnow acts as a compatibility shim that re-exportsModuleLabels.Types.UnityAddressablesLabelernow uses centralizedModuleLabelsconstants for managed labels, path rules, and type rules.UnityAddressablesLabelernow 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.AudioMixerDependencyCachenow defaults toModuleLabels.AUDIO_MIXERinstead of a hard-coded Addressables label.UnityUiSettingsEditornow rendersScaleKeyandFontSizeKeyas Unity ObjectFields backed byUnityUIGameSettingsDefinitionassets.UnityGameGraphicsSettingsEditornow rendersQualityLevelKey,ScreenResolutionKey, andIsFullScreenKeyas Unity ObjectFields backed byUnityGraphicGameSettingsDefinitionassets.UnityLocalizationSettingsEditornow rendersGameLanguageKeyandVoiceLanguageKeyas Unity ObjectFields backed byUnityLocalizationGameSettingsDefinitionassets.UnityMenuServiceSettingsDefinitionEditornow rendersInitMenuIdas a Unity ObjectField backed byUnityMenuSettingsDefinitionassets.UnityGameModeSettingsDefinitionEditornow rendersPauseMenuIdas a Unity ObjectField backed byUnityMenuSettingsDefinitionassets.UnityActionDefinitionEditornow rendersSignalthrough a searchable signal type selector instead of a plain dropdown.UnityModalSettingsEditornow rendersSignalTypethrough a searchable signal type selector instead of a plain dropdown.UnityModalSettingsEditornow shares signal type discovery throughEventDispatcherSignalTypePicker, avoiding duplicated reflection logic.UnityMenuSettingsDefinitionEditornow uses centralized module label constants when resolving game settings and menus.UnitySoundMixerSettingsEditornow uses centralized module label constants when resolving audio game settings.- Serenity sample menu assets were reserialized to include explicit
ViewIdvalues on options and values. - Serenity sample menu assets now include explicit empty
OnShowandOnHidearrays. GameModeSettingssample 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.Signalcontinues to storeType.FullName.UnityModalSettings.SignalTypecontinues to storeType.AssemblyQualifiedName.UnityModalSettings.SignalTypekeeps 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-modelabeling forGameModeSettings. - Fixed several editor fields that previously required dropdown selection even though they represented asset-backed ids.
- Fixed
UnityActionDefinition.SignalandUnityModalSettings.SignalTyperemaining 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.Constantswhere centralized label constants are now used. - Updated Addressables settings to remove stale labels and include the new
module:game-modelabel. - Updated the Serenity Addressables group so
Media/GameMode/GameModeSettingsis labeled withmodule: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
MusicPlayerTransitionTypeenum with three transition strategies:CUT,FADEIN_FADEOUT, andCROSS_FADE.- Configurable transition parameters on
IMusicPlayerService.PlaySong(...)and newPlaySongById(...)method. MusicPlayerPlaySongByIduse case andMusicPlayerPlaySongByIdInputDTO for playing specific tracks by identifier with explicit loop and transition control.PlaySongByIdgateway method onIMusicPlayerGateway.SetGameModeService(IGameModeService)contract onIMenuServicefor cross-service coordination.GetSignalsForGameMode(GameModeEnum)contract onIGameModeSettingsDefinitionfor per-mode signal configuration.InitializationandCutscenevalues to theGameModeenum, establishingInitializationas the default starting mode.- Per-mode
EventDispatcherSignaltransition sequences toUnityGameModeSettingsDefinition. DispatchModeTransitionSignals(...)orchestration inUnityGameModeServicethat fires configured signals after every mode change.- Full ReorderableList-based inspector for per-mode transition signals in
UnityGameModeSettingsDefinitionEditor. ServiceLocatorregistration forIMusicPlayerServiceduring music player installation.
Changed
UnityGameModeServicenow initializes inInitializationmode instead ofMenu, deferring the first real mode transition until the menu system is ready.UnitySerenityInstaller.ShowMenu()now wires the resolvedIGameModeServiceinto the menu service before invokingShowInitialMenu(), ensuring the game mode is synchronized on startup.UnityMusicPlayerInstallernow receivesServiceLocatorInstallerfor runtime service discovery.Serenity.GameMode.Domain.asmdefreference format standardized to GUID.- Production-ready asset naming:
Audio_SoundToTest→Audio_SoundToTrigger,Audio_TrackToTest→Music_TrackList. AudioTestingMenusettings 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_FADEautomatically falls back toCUTwhen insufficient audio channels are configured.- GameMode transition signals are dispatched in exact inspector-configured order, with null entries safely skipped and logged.
GameMode.Menuis now automatically asserted wheneverShowInitialMenu()is executed, keeping the menu system and mode state in sync.
Improved
UnityGameModeSettingsDefinitionEditorinspector now renders one dedicated reorderable signal list perGameModevalue with subtype selection dropdowns and drag-and-drop ordering.- Signal list elements display the concrete
EventDispatcherSignalsubtype name for at-a-glance identification. Serenity.Menu.ApplicationandSerenity.UnityMenu.Infrastructureassembly definitions now reference GameMode contracts for cross-layer coordination.
Fixed
- Prevented potential recursive mode transitions by relying on
SetModeshort-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.Installationfor installer-level validation coverage.
1.0.3 — Menu Lifecycle Signals & Inspector Improvements
Added
- Added
OnShowandOnHidelifecycle signal collections toUnityMenuSettingsDefinition. - 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 toUnityMenuView.
Features
- Menus can now dispatch custom
EventDispatcherSignalsequences 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
UnityMenuSettingsDefinitionEditorwith a dedicatedLifecycle Signalssection. - 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
EventDispatcherSignalimplementations 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
EventDispatcherSignalinfrastructure 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
LocalizationSettingsDefinitionEditorto improve the UX forUnityLocalizationGameSettingsDefinitionassets. - Hardened Serenity import workflow and localization recovery process.
- Refactored modal settings editor button signal flow for cleaner editor interactions.
Features
- Locked the
ValueTypefield toSELECTABLEwith 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
FoundationEditorandUnityGameSettingsDefinitionEditorUI 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.
English
Español
Català