Files
initiative/specs/012-turn-navigation/contracts/domain-api.md

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: () => void
  • onRetreatTurn: () => 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