Game
Purpose
Section titled “Purpose”A Game represents a board game in the Stratastax catalogue: enough information to record and interpret Matches against it, and to display it meaningfully in the archive. Where this data originally came from — a sync from BoardGameGeek, or any other future source — is an infrastructure concern, not part of this domain model. Game itself has no knowledge of any external source.
Responsibilities
Section titled “Responsibilities”A Game is responsible for:
- providing a display identity (name, description, image);
- defining the valid player-count range for a Match;
- carrying a set of Tags (categories/mechanisms) for discovery and grouping;
- defining how a Match’s results should be interpreted — its ScoreType and, where relevant, its WinCondition — so that ranking can be computed consistently;
- owning the set of Expansions available for it.
Expansions
Section titled “Expansions”A Game can have any number of Expansions — additional content that extends the base game, such as “Everdell: Pearlbrook” or “Everdell: Legendary Cards” for the base game “Everdell”. An Expansion always belongs to exactly one base Game; it has no independent meaning outside of it.
Expansions are what a Match’s Playset selects from when recording which content was used in a given play (see Playset). Game only owns and exposes the available Expansions; it plays no role in which ones a specific Match actually used.
Expansion Attributes
Section titled “Expansion Attributes”- Name — required (e.g. “Pearlbrook”).
- Description — optional.
- ImageUrl — optional.
Not Responsible For
Section titled “Not Responsible For”A Game is NOT responsible for:
- sourcing or syncing its own data, or that of its Expansions, from any external catalogue (BGG or otherwise) — that is an infrastructure/ application concern, external to this model;
- holding Playset or Loadout data — those are Match-specific and player-specific respectively, not properties of the Game itself;
- computing a Match’s ranking — Game only supplies the ScoreType and WinCondition that ranking logic reads;
- deciding which of its Expansions a specific Match used — that is recorded on the Match’s Playset.
Attributes
Section titled “Attributes”- Name — required.
- Description — required.
- MinPlayers / MaxPlayers — required;
MinPlayers >= 1andMaxPlayers >= MinPlayers. - ImageUrl — optional.
- Tags — zero or more free-form labels covering both categories and mechanisms (e.g. “Engine Building”, “Area Control”), deliberately not modeled as a fixed taxonomy.
- ScoreType — one of:
Score— a numeric value; ranking depends on WinCondition.Time— a duration; ranking depends on WinCondition.Turns— a turn count; ranking depends on WinCondition.WinLoss— a binary outcome per MatchParticipant; no WinCondition needed.- WinCondition —
HigherWinsorLowerWins; required when ScoreType isScore,Time, orTurns, and meaningless when ScoreType isWinLoss.
Invariants
Section titled “Invariants”MinPlayers >= 1andMaxPlayers >= MinPlayers.WinConditionis present if and only ifScoreTypeisScore,Time, orTurns.- A Game’s ScoreType and WinCondition determine how every MatchParticipant result for Matches referencing it should be ranked; this model does not allow a Match to override its Game’s interpretation.
- An Expansion belongs to exactly one Game, for its entire lifetime.
Lifecycle
Section titled “Lifecycle”Creation
Section titled “Creation”A Game exists once it can be referenced by a Match — whether it was pre-populated by an import process ahead of time, or added at the moment a User first records a match against it. This model treats both as equivalent; which one actually happens is an implementation decision entirely outside this model.
Evolution
Section titled “Evolution”A Game’s display attributes (Name, Description, ImageUrl, Tags) may be updated over time, e.g. by a catalogue refresh. New Expansions may be added to a Game at any time. Its ScoreType and WinCondition should be treated as stable once Matches exist against it, since changing them would change how existing historical results are interpreted.
End State
Section titled “End State”A Game is never deleted while referenced by any Match. An Expansion is never deleted while referenced by any Playset.
Relationships
Section titled “Relationships”- Game is referenced by Match.
- Game owns Expansion (0..N).
- Expansion is referenced by Playset.
Domain Events
Section titled “Domain Events”None. Game is reference/catalogue data, not a process aggregate. A domain event exists so that something else can react to it; nothing in this model needs to react to a Game (or an Expansion) simply coming into existence — it is a side effect of an import or first-use process, not a meaningful business decision. If a genuine downstream need for reacting to catalogue changes emerges later, events can be introduced then.
Aggregate Design
Section titled “Aggregate Design”Game is its own Aggregate Root, independent of Match. Expansion is a child entity within the Game aggregate — it has no identity or lifecycle independent of its Game. Game has no dependency on how or when it, or any of its Expansions, was populated — any import mechanism is a client of this model, not part of it, and no reference to any external source (BGG or otherwise) exists anywhere in this model.