Skip to content

Understanding BattleResult

POST /api/battle/start runs the complete battle and returns a BattleResult. Use it to identify the winner or to replay, animate, and explain how the battle unfolded.

What BattleResult contains

The response has two levels of information:

  • Battle summary: the battle ID, participants, start and end times, total turns, and winner.
  • Battle log: battle_event_logs, which records the battle in chronological order.

Start with the summary when you only need the outcome. Process battle_event_logs when you need to show or analyze what happened during the battle.

The name battle_end appears at both levels. Top-level BattleResult.battle_end is the ending timestamp, while battle_event_logs.battle_end is the final outcome record.

Looking for exact fields?

Use the OpenAPI reference for the complete response schema, field types, and validation rules.

How the battle log is organized

The battle log follows the same three phases as the battle flow:

battle_event_logs
├── 1. Preparation    preparation[]
├── 2. Battle Start   turns[]
│   ├── Turn Start
│   └── Turn End
└── 3. Battle End     battle_end
Phase Response field Purpose
1. Preparation preparation Records setup effects applied before ordinary turns
2. Battle Start turns Records every consumed turn in order
3. Battle End battle_end Records the outcome and both fighters' final states

Battle Start is the name of the battle phase. The response represents that phase with the turns array. Each item in turns then has its own Turn Start and Turn End sections.

1. Preparation — set up the fighters

Preparation happens before ordinary turns and always uses battle turn 0. During this phase, each start_of_battle passive runs its configured actions. Preparation events can therefore include attacks, healing, status application, and status removal before the first ordinary turn.

The preparation field contains ordered preparation records:

  • events contains the ordered effects applied while preparing that fighter.
  • state_after captures the fighter after those effects.
  • state_after.passive_triggers is the canonical list of passive triggers active after preparation.
  • applied_passive_trigger_ids identifies the passive triggers applied during that preparation step.

Process the entries in their returned order before starting the first turn.

2. Battle Start — process each turn

After preparation, the main battle phase is returned as the turns array. Every item identifies the acting fighter and contains a Turn Start followed by a Turn End:

turns[]
├── battle_turn
├── actor_id
├── actor_turn
├── turn_start
│   ├── start_reason
│   └── state
├── events[]
└── turn_end
    ├── end_reason
    ├── events[]
    └── state

Process turns in array order. The array is not an object keyed by turn number.

Turn start

Turn start records the state before the acting fighter's turn is resolved:

  1. Read the snapshots from turn_start.state.actor and turn_start.state.opponent.
  2. Check turn_start.start_reason to see whether the fighter's turn meter was ready or a skip_turn effect consumed the global turn.

Next, process the turn-level events array in order. It contains every effect that occurred during the turn, including skill execution, damage, healing, status changes, shields, misses, DOT effects, and passive actions processed before turn end.

Turn end

Turn end records how the turn concluded and the resulting state:

  1. Process turn_end.events in array order. Energy regeneration appears first, followed by health regeneration and any natural status-expiry events.
  2. Read turn_end.end_reason to determine whether the turn was completed, its action was skipped, or the fighter's turn was skipped.
  3. Reconcile both fighters with turn_end.state.actor and turn_end.state.opponent.

Two turn counters

Each turn carries the two counters defined in Battle Mechanics:

  • battle_turn is the global battle counter. Every consumed turn advances it, including one consumed by skip_turn.
  • actor_turn is the acting fighter's own turn counter. It advances for a normal fighter turn, but not when skip_turn consumes only a global turn. A skipped entry can therefore show 0 before that fighter's first normal turn or repeat the fighter's previous actor_turn value.

Tip

Use battle_turn to order the complete replay. Use actor_turn for fighter-specific timing, UI labels, or progression.

3. Battle End — read the outcome

battle_end is the final outcome record. It directly contains:

  • reason, which identifies a knockout or the maximum-turn limit
  • winner_id and loser_id
  • total_turns and
  • fighter_states, containing both fighters' final states.

Treat battle_end.fighter_states as the authoritative final state. The battle_end.winner_id agrees with the top-level BattleResult.winner_id.

Working with snapshots and events

The battle log provides snapshots at important points in the battle:

  • Preparation captures the prepared fighter.
  • Turn Start captures both fighters before the turn's effects.
  • Turn End captures both fighters after regeneration and status expiry finish.
  • Battle End captures both fighters' final states.

A fighter snapshot includes current and maximum health and energy, current shield value, turn meter, active statuses, and passive triggers. Shield status snapshots include each contribution's remaining_shield. Other statuses have no shield fields. Use the aggregate value for the shield bar and individual contributions for status indicators.

Combat events between those snapshots are discriminated by event_type. Branch on that value and read the matching structured data. See Battle events for their meaning.

Do not parse event descriptions

description is human-readable display text, not a machine contract. Read damage, fighter IDs, status IDs, and resource values from structured data.

Replay order

To replay or animate a battle:

  1. Process each preparation entry and its events in order, then reconcile with state_after.
  2. Process each item in turns in order.
  3. Within each turn, start from turn_start.state, apply the turn-level events in array order, apply turn_end.events, then reconcile with turn_end.state.
  4. Finish with the battle_end outcome and final fighter states.

Event data drives individual animations and updates. Fighter snapshots are the reconciliation points that keep the replay aligned with the battle result.