System Overview
What BattleScore is
BattleScore is a full-stack web application for recording tabletop game results, managing armies, tracking performance, and operating tournaments. It combines a structured relational schema, a PHP endpoint layer, and separate frontend surfaces for normal users, tournament organisers, and internal administration.
Architectural layers
Browser UI
├── App UI (/app)
├── TO UI (/TO)
└── Docs UI (/docs)
JavaScript client logic
├── page scripts
└── shared API helpers
PHP endpoint layer
├── /api/auth
├── /api/armies
├── /api/games
├── /api/tournaments
├── /api/to
└── other functional folders
MariaDB database
├── identity
├── core data
├── army system
├── gameplay runtime
├── tournament domain
└── support/diagnostics
Major domains
| Domain | Description | Main tables / docs |
|---|---|---|
| Identity | User accounts, sessions, password resets, email verification, role and subscription state | users, user_sessions |
| Core Data | Reference hierarchy for race, faction and canonical units | race, factions, faction_units |
| Army System | User-owned or TO-linked armies and their unit rows | army_lists, army_units |
| Gameplay | Games, sides, turns, instantiated units and events | games, game_events |
| Tournaments | Tournament records, entrants, linked armies and scoring systems | tournaments, tournament_entrants |
| Support | Operational diagnostics used to debug imports and data issues | import_issues |
Primary frontend surfaces
| Surface | Audience | Purpose | Docs |
|---|---|---|---|
| App | Normal users | Armies, games, gameplay, performance, profile, auth | App docs |
| TO | Tournament organisers | Events, entrants, entrant armies, scoring-system usage | TO docs |
| Admin | Internal/admin users | Reference data, tournament config, user administration | Admin docs |
Primary backend pattern
The server follows a file-per-endpoint PHP model rather than a large MVC framework. Each functional area has a folder of endpoints, and shared bootstrapping/auth helpers are pulled in as required. This makes the system explicit and easy to trace, but it means cross-cutting consistency depends heavily on disciplined patterns.
- Shared bootstrap/auth files establish DB access and request context
- Each endpoint owns its own request validation and business logic
- Frontend scripts call specific endpoints directly through shared API helpers
Data model philosophy
BattleScore separates reference data from user/runtime data:
- Reference data defines what exists: races, factions, canonical units
- User/transactional data defines what a player built: army lists and army units
- Runtime data defines what happened in play: games, turns, game units, events
This separation is one of the strongest architectural features of the platform.
Runtime gameplay model
Gameplay is event-driven. A game is created, two sides are assigned, army units are instantiated into game units, and scoring/state changes are recorded as events. Some runtime state is also denormalized onto game_units for performance and simplicity during play.
This means the system is neither purely event-sourced nor purely state-based. It is a hybrid model:
- game_events is the scoring and action ledger
- game_units stores durable gameplay state such as destroyed/below-25 markers
- games stores final header-level outcomes
Tournament model
Tournaments are layered on top of the core game model. A tournament owns entrants, entrants own linked armies, and games may be connected to tournaments by round and entrant references. Tournament standings are therefore not an isolated subsystem; they are computed from game results and tournament scoring configuration.
Main strengths of the solution
- Clear domain separation between reference, transactional, and runtime data
- Explicit PHP endpoint structure that is straightforward to trace
- Dedicated TO area rather than overloading the normal user interface
- Strong documentation coverage at file and table level
- Event-driven gameplay model suited to detailed score reconstruction
Main structural risks
- Cross-cutting rules are enforced mainly by application logic, not always DB constraints
- Some runtime relationships rely on soft links or partially constrained references
- Reference data changes can have wide effects on imports, armies, and gameplay
- Scoring-system edits can affect tournament interpretation if not versioned/locked
- Identity table is heavily loaded with auth, profile, consent and subscription responsibilities
Where to go next
- Solution Components for a deeper breakdown of each layer
- Component Interactions for how the parts work together
- Change Impact Guide for practical development guidance