Add support for up to 6 players.

This commit is contained in:
Greyson Parrelli
2026-07-28 07:36:09 -04:00
parent e542118175
commit a4f5f6910d
38 changed files with 2306 additions and 713 deletions
+22
View File
@@ -6,6 +6,28 @@ Go backend (pure rules engine in `internal/game`, WebSocket rooms in
- `mise run test` — Go tests · `mise run check` — go vet + frontend tsc
## Seats, sides, and packs
Three distinctions are easy to conflate and worth keeping straight:
- **Seat vs. side.** A game seats 2, 4, or 6 players, and each round pairs
them off into simultaneous battles (`schedule.go`). Inside a
`BattleResult` everything is indexed by *side* — 0 or 1 within that one
battle — including `BattleEvent.Seat`/`Target`, `Lineups`, `Survivors`,
and `ManaAfter`. `Seats` maps side → seat, and `Side(seat)` maps back.
`WinnerSeat` is the deliberate exception: it's a real seat, because it's
the only field that means anything outside the battle. When adding a
per-side field to a battle, index it by side and say so.
- **One battle vs. the round.** `resolveBattles` loops the round's pairings;
`runBattle(first, second)` resolves one of them and mutates no persistent
state. Anything that should happen once per round rather than once per
battle (clearing per-round banks, say) belongs in `resolveBattles`, not
`finalizeBattle`.
- **Packs are plural.** `Game.Packs` is a list whose tier decks shuffle
together. Anything reading printed card data must go through
`TierContentsForPacks` / `CatalogForPacks` / `g.packList()`, never a
single pack — a game can hold Trumpets, Mana, and Ailments at once.
## Keep the AI in sync with game behavior
**Whenever game behavior changes — rules, cards, effects, phases, log