Gameplay & Scoring Flow

End-to-end description of how a game moves from setup to final score in BattleScore.
Gameplay Scoring End-to-End

Lifecycle summary

Create Game
  → Setup Sides
  → Start Game
  → Start Turn
  → Start Player Turn
  → Record Events
  → End Player Turn
  → End Turn
  → End Game
  → Finalise Game

Step 1: game creation and setup

A game begins as a games row, normally in a setup state. During setup:

  • two game_sides rows are assigned
  • each side is linked to an army_list
  • first side and scenario/system information are established
  • optional tournament/round context may also be attached

Step 2: game start

Starting a game is not just a status change. It also instantiates runtime unit data.

army_units
  ↓ copied/snapshotted
game_units

This is one of the most important design decisions in the system: gameplay state is stored separately from army construction state.

Step 3: turn structure

The runtime turn model has two levels:

This structure matters because scoring and destruction state are often attributed to a specific side’s player turn rather than just to a whole game turn.

Step 4: event creation

The main scoring and action ledger is game_events. When something happens in the game, the app records an event with:

  • game context
  • turn/player-turn context
  • scoring side
  • event type
  • points delta
  • unit reference where relevant

Step 5: runtime unit state updates

Some state is not left purely in the event ledger. It is also applied to game_units.

Examples include:

  • destroyed state
  • below 25% state
  • which side scored the state
  • which player turn caused the state

This denormalization exists so play-state reads are simpler and faster.

Step 6: score derivation

Score is built from two related sources:

  • the event ledger for points deltas and history
  • game-unit state for runtime projection and rule enforcement

The UI page Game Play and related backend endpoints use both sources to present current state and totals.

Step 7: ending and finalising

Ending a game and finalising a game are separate concepts:

  • End game marks gameplay as complete
  • Finalise game stores final outcome and, where relevant, applies tournament round constraints

Final scores are written back to the games header as final_score_a and final_score_b.

Gameplay flow by layer

Layer Responsibility during play
App UIRender state, initiate events, show score progression
APIValidate rules, create/delete events, update runtime state
SQLPersist game header, turns, runtime units and event ledger

Why the model is strong

  • Original army data stays separate from gameplay runtime
  • Detailed event history remains available for breakdown/reporting
  • Current play state does not require full event replay for every read

Main scoring-flow risks

  • Event deletion can desynchronize runtime unit state if not handled carefully
  • Soft references in runtime fields mean integrity is partly application-controlled
  • Rule changes in event logic can affect historical interpretation if not isolated