Character System

A character archetype system that validates every grunt, heavy and boss as data, tracks each live instance through its full lifecycle, and pairs with a pure weapon state machine for combat.

What the system is for

Every enemy in a wave-based or action game is a variation on the same idea: an archetype with a prefab, hit points and a move speed, spawned many times over, each instance tracked from the moment it appears to the moment it dies. Wiring that by hand means scattering health fields, spawn bookkeeping and prefab references across MonoBehaviours with no single source of truth.

Serenity's Character System splits that cleanly into an archetype you author once and a runtime service that tracks every live instance. A grunt, a heavy and a boss are each a validated CharacterConfigSO; ICharacterService takes it from there, moving every spawned instance through spawn, active, dying and dead while emitting the signals Score and Combo react to.

The Unity problem

Enemy definitions that live as loose fields on a prefab's MonoBehaviour are easy to duplicate incorrectly and hard to validate — nothing stops a designer from shipping an archetype with zero hit points or a missing prefab reference until it fails at runtime. There is no single place that answers how many enemies of this kind are alive right now.

Combat state compounds the problem. Ammo counts, reload flags and fire modes bolted directly onto a character's MonoBehaviour mix whether the actor is alive with whether the weapon can fire right now — two lifecycles that should be independent become entangled, and testing one means dragging the other along.

How Serenity approaches it

A CharacterConfigSO defines an archetype's prefab, max health and move speed, validated on import — max health below one is rejected outright. ICharacterService is the single object that registers, activates, hits and despawns every live instance, moving each one through CharacterState from Spawning to Active to Dying to Dead, and emitting CharacterSpawnSignal, CharacterHitSignal, CharacterKilledSignal and CharacterAttackSignal as it does, feeding Score and Combo without either system reaching into character internals.

Combat readiness is a separate, independent concern handled by IGameWeaponService — a pure runtime state machine for trigger, reload, fire mode and magazine, tracked through WeaponState, MagazineState and WeaponSnapshot. It enforces its own invariants, like no firing while reloading and no firing on an empty magazine, and deliberately leaves projectiles, targeting and damage to the rest of your game.

How it fits into Serenity

Character composes with Wave and Stage for spawning: a wave's spawn entries name an archetype and a stage spawn point, and the wave service instantiates the archetype's prefab there before registering it with ICharacterService. Discovered CharacterConfigSO assets are tagged with an Addressables type:character label so the installer can auto-discover every archetype at boot without a hand-maintained registry.

GameWeapon is a structurally independent aggregate with no configuration asset and no signal contract of its own — every weapon is registered and driven entirely through IGameWeaponService method calls. It composes with Character only through gameplay code you write, keeping ammo and fire-mode bookkeeping decoupled from health and death tracking.

Practical workflow

  1. Open Tools ▸ Serenity ▸ Create ▸ Character ▸ Create Character and step through Intent ▸ Configure ▸ Mount ▸ Preview ▸ Done to author one archetype — prefab, max health, move speed.
  2. On the 1.3.0 Mount step, choose how the archetype's prefab moves: mount it on a Game Rail follower, or point it at referencing a Stage spawn point through wave data.
  3. Check the inline Addressables tag status in the archetype's inspector and use the one-click Fix (retag) button if the type:character label is missing before boot.
  4. Reference the archetype from a Wave spawn entry so the wave service instantiates its prefab and calls RegisterCharacter at the right spawn point.
  5. Subscribe to CharacterKilledSignal from Score or Combo to react to kills without either system depending on Character internals directly.
  6. For combat, call IGameWeaponService.RegisterWeapon with a magazine capacity and fire mode, then drive TriggerPressed, TriggerReleased and ReloadRequested/ReloadComplete from input.

What you get

  • CharacterConfigSO archetypes with prefab, max health and move speed, validated on import (max health must be at least one)
  • ICharacterService lifecycle covering spawn, active, dying and dead for every live instance, keyed by CharacterId
  • CharacterSpawnSignal, CharacterHitSignal, CharacterKilledSignal and CharacterAttackSignal feeding Score and Combo
  • Create Character wizard — Intent ▸ Configure ▸ Mount ▸ Preview ▸ Done — with the 1.3.0 Mount step for Game Rail or Stage spawn point binding
  • Inline Addressables tag status with a one-click Fix (retag) button directly in the archetype inspector
  • Auto-discovery of every type:character-labeled archetype at boot, with no hand-maintained registry
  • IGameWeaponService weapon state machine — WeaponState, MagazineState, WeaponSnapshot and FireMode — for trigger, reload and magazine tracking
  • Weapon invariants enforced in the domain: no firing while reloading, no firing on an empty magazine, deliberately leaving projectiles and damage to your game

When to use this

  • Wave-based or action games that need multiple validated enemy archetypes — grunts, heavies, bosses — tracked from spawn to death.
  • Projects that want kill signals feeding Score and Combo without coupling either system to character internals.
  • Teams that want the Addressables tagging step for new archetypes caught in the inspector, before it becomes a silent boot-time zero-archetype bug.
  • Games that need a player or enemy weapon's ammo, reload and fire-mode state tracked independently of the character's health and lifecycle.

Related systems

Use Serenity when you want enemy archetypes authored as validated data, tracked through a full spawn-to-dead lifecycle with signals Score and Combo already know how to consume, and a weapon state machine that stays out of your way on projectiles and damage.

Back to the home page