# Host Game Loop

## Purpose
This document defines host-side game loop authority and the state-machine flow for match progression.

## Authority map
- Host loop authority: `Code/Game/Round/GameMode.cs`
  - Owns state transitions and dispatch order for all round/game listeners.
- Join/network bootstrap authority: `Code/Game/Host/Network/GameNetworkManager.cs`
  - Owns `ConnectedClient` + `PlayerComponent` creation/binding and initial spawn entry.
- Listener contract authority: `Code/Game/Round/Interfaces.cs`
  - Defines `IGameStartListener`, `IRoundStartListener`, `IRoundEndListener`, `IGameEndListener`, conditions/listeners.
- Round timing/conditions authority: `Code/Game/Round/RoundRulesSystem.cs`
  - Owns waiting thresholds, prepare windows, haste timing, and round/game-end condition checks.
- Cleanup barrier authority: `Code/Game/Round/RoundCleanupSystem.cs`
  - Owns pre-round cleanup barrier before `OnRoundStart`.
- Transition phase authority: `Code/Game/Round/RoundGateSystem.cs`
  - Host-authored phase tracking for round transitions (`PreRoundTransitionLock -> PreRoundAdmission -> PreRoundCleanup -> PreRoundRespawn -> PreRoundLive -> RoundStartCommit -> RoundLive -> RoundEndGrace`).
- Transition ordering authority: `Code/Game/Round/Transitions/TransitionOrchestrator.cs`
  - Host-first sequencing for inter-round lock entry, settle waits, ownership reassert, map-switch recovery, and map-switch post-commit straggler policy.

## State flow
`GameMode` drives:
1. `GameState.WaitingForPlayers` -> runs `StartGame()` listener pipeline.
2. `GameState.Starting` -> runs round start pipeline (with cleanup barrier).
3. `GameState.Started` -> checks round-end conditions each tick.
4. `GameState.Ending` -> runs round-end listener pipeline.
5. `GameState.Ended` -> runs game-end listener pipeline, then stops loop.

Round winner path:
- `GameMode.OnTeamWin(...)` forces `State = GameState.Ending` and shows status/toast.

## Dispatch model
- Dispatch order is always `Pre* -> On* -> Post*`.
- `IRoundStartListener` dispatch includes a host-only cleanup barrier before `OnRoundStart`.
- `SpawnSystem` now stages participants in `PreRoundStart` and executes reset/respawn in `OnRoundStart`, so map cleanup completes before players are physically respawned.
- `GameMode.DispatchRoundStartWithBarrier` also advances `RoundGateSystem` phases in deterministic order:
  - `PreRoundTransitionLock` when the host enters `GameState.Starting`,
  - `PreRoundAdmission` before listener pre-pass,
  - `PreRoundCleanup` before map/entity cleanup,
  - `PreRoundRespawn` before listener `OnRoundStart`,
  - `PreRoundLive` once pre-round spawn/countdown is live,
  - `RoundStartCommit` before listener `PostRoundStart`,
  - `RoundLive` after `OnRoundStartComplete`,
  - `RoundEndGrace` when a winner is declared (`GameState.Ending`).
- `TransitionOrchestrator` inserts host settle points between major phases:
  - after cleanup barrier completion: fixed settle + map mutation quiet wait,
  - before respawn wave: host ownership/pawn-binding reassert pass,
  - after respawn wave and before commit: post-respawn settle wait.
- Inter-round lock semantics:
  - lock begins as soon as round-end delay completes and host enters inter-round transition,
  - lock covers admission/cleanup/respawn staging,
  - lock releases at `PreRoundLive` (prepare timer active).
- Late joins during `GameState.Starting` are routed through `RoundGateSystem`:
  - Safe window: spawn immediately in pre-round.
  - Unsafe window / transition phases: queue for commit spawn and consume in `SpawnSystem.PostRoundStart`.
- End conditions are additive:
  - `IRoundEndCondition.CheckRoundEnd()` is evaluated across all conditions.
  - `IGameEndCondition.ShouldGameEnd()` decides if end-of-round advances to `Ended`.

## Join/bootstrap flow
On connection activation (`GameNetworkManager.OnActive`):
1. Spawn `ConnectedClient` container.
2. Spawn player pawn object.
3. Bind ownership/pawn contract (`ConnectedClient.SetPawn(...)` + guards).
4. Initialize player.
5. Route spawn through lifecycle authority (`PlayerState.SpawnPlayerHost(...)`).

## Related docs
- Lifecycle/participation: `Code/Core/Documentation/lifecycle.md`
- Spawning authority: `Code/Core/Documentation/spawning.md`
- Teams/rules/rewards: `Code/Core/Documentation/teams-rules-rewards.md`
