Table of Contents

Namespace Core.Units

Classes

CreateUnitCommand

Command to create a new unit.

VALIDATION:

  • Province must be owned by the country
  • Country must have sufficient resources (checked by game layer command factory)
  • Unit type must be valid

EXECUTION:

  • Deduct resources (handled by game layer wrapper)
  • Create unit in UnitSystem
  • Emit UnitCreatedEvent
DisbandUnitCommand

Command to disband a unit.

VALIDATION:

  • Unit must exist
  • Unit must be owned by the executing country (checked by game layer)

EXECUTION:

  • Remove unit from UnitSystem
  • Refund partial resources (handled by game layer wrapper)
  • Emit UnitDestroyedEvent
MoveUnitCommand

Command to move a unit to a new province using time-based movement (EU4-style). Supports pathfinding for multi-province journeys.

VALIDATION:

  • Unit must exist
  • Unit must be owned by the executing country
  • Pathfinding system must be initialized
  • Unit must not already be moving (warning, but allowed)

EXECUTION:

  • Calculate path using PathfindingSystem
  • Add unit to movement queue with full path
  • Unit will automatically hop through waypoints
  • Emit UnitMovementStartedEvent
UnitColdData

Cold data for units - rarely accessed, stored separately from hot data.

DESIGN:

  • NOT in NativeArray (uses managed types)
  • Loaded on-demand (Dictionary lookup)
  • Stores optional/rare data (custom names, history, etc.)

EXAMPLES:

  • Custom unit names ("The Old Guard")
  • Combat history (battles participated in)
  • Achievement tracking (most kills, longest march, etc.)
UnitMovementQueue

Tracks units that are currently in transit between provinces. Implements EU4-style time-based movement: units take X days to move.

DESIGN:

  • Dictionary tracks moving units: unitID → MovementState
  • Each day, decrement daysRemaining for all moving units
  • When daysRemaining reaches 0, move unit to destination
  • Units can cancel movement mid-transit (return to origin)

PERFORMANCE:

  • Sparse storage: Only tracks moving units (not all units)
  • Daily tick processes O(n) where n = units currently moving
  • Typically 10-100 units moving at once (not 10k)
  • ZERO ALLOCATIONS: Pre-allocated buffers for daily tick processing
UnitSystem

Central manager for all units in the game.

ARCHITECTURE:

  • Hot data: NativeArray of UnitState (8 bytes each)
  • Sparse mapping: Province → Unit IDs (scales with actual units, not possible units)
  • Cold data: Dictionary for rare data (custom names, history, etc.)
  • Movement data: Separate NativeArray for movement points (2 bytes per unit)

PERFORMANCE:

  • 10k units × 8 bytes = 80KB hot data
  • 10k units × 2 bytes = 20KB movement data
  • Sparse collections scale with usage (not possibility)
  • GetUnitsInProvince() is O(m) where m = units in province (typically 1-10)

PERSISTENCE:

  • SaveState/LoadState for all data
  • Atomic unit ID assignment (deterministic)
  • Command pattern ensures multiplayer safety

Structs

UnitCountChangedEvent

Emitted when unit count changes (combat, reinforcement, etc.) RISK-style: Simple number changes instead of percentage-based strength/morale

UnitCreatedEvent

Emitted when a new unit is created. UI can subscribe to show notifications, update displays, etc.

UnitDestroyedEvent

Emitted when a unit is destroyed (disbanded, killed in combat, etc.)

UnitMovedEvent

Emitted when a unit moves to a new province

UnitMovementCancelledEvent
UnitMovementCompletedEvent
UnitMovementQueue.MovementState

State for a unit currently in transit

UnitMovementStartedEvent
UnitState

8-byte hot data for a single military unit.

DESIGN:

  • Fixed size (8 bytes) for cache efficiency and network transmission
  • No visual data (positions, sprites) - presentation layer responsibility
  • provinceID instead of coordinates - simulation layer doesn't know positions
  • RISK-style: Simple unit count instead of percentage-based strength/morale

MULTIPLAYER:

  • Deterministic layout (explicit struct layout)
  • No managed references (NativeArray compatible)
  • Serializable for network sync

Enums

DestructionReason

Reason for unit destruction (for statistics, events, etc.)