1.6 KiB
1.6 KiB
Domain API Contract: Turn Navigation
retreatTurn(encounter: Encounter): RetreatTurnSuccess | DomainError
Input
encounter: Encounter (combatants, activeIndex, roundNumber)
Success Output
{
encounter: Encounter // Updated state
events: DomainEvent[] // TurnRetreated, optionally RoundRetreated
}
Error Cases
| Condition | Error Code | Message |
|---|---|---|
| combatants.length === 0 | invalid-encounter |
Cannot retreat turn on an encounter with no combatants |
| roundNumber === 1 && activeIndex === 0 | no-previous-turn |
Cannot retreat before the start of the encounter |
Event Contracts
TurnRetreated (always emitted on success):
{
type: "TurnRetreated"
previousCombatantId: CombatantId // Was active before retreat
newCombatantId: CombatantId // Now active after retreat
roundNumber: number // Round number after retreat
}
RoundRetreated (emitted when crossing round boundary):
{
type: "RoundRetreated"
newRoundNumber: number // Decremented round number
}
Emission order: TurnRetreated first, then RoundRetreated (when applicable).
UI Contract: TurnNavigation Component
Props
encounter: Encounter (current state)onAdvanceTurn: () => voidonRetreatTurn: () => void
Behavior
- Previous Turn button: calls onRetreatTurn; disabled when roundNumber === 1 && activeIndex === 0, or combatants.length === 0
- Next Turn button: calls onAdvanceTurn; disabled when combatants.length === 0
- Displays: round number and active combatant name