Files
super-auto-pets-board-game/CLAUDE.md
T

61 lines
3.3 KiB
Markdown

# Super Auto Pets: The Board Game
Go backend (pure rules engine in `internal/game`, WebSocket rooms in
`internal/server`, computer opponent in `internal/ai`) + React frontend in
`web/`. See README.md for the full layout and rules summary.
- `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
entries, or views — make sure the computer opponent accounts for it.** The
AI plays from the same information a human sees, so changes ripple into it
in specific ways:
- **Battle rules**: `internal/ai` evaluates moves by running the real
resolver (`game.SimulateBattle`), so battle changes are picked up
automatically — but re-check the hand-written heuristics that summarize
battle wisdom: `leadScore`, `keepValue`, `deckValue` (eval.go) and the
food-placement strategies / synergy pet list (arrange.go).
- **New or changed cards/effects**: shop-time deck effects are mirrored in
`applyTemplateShopEffects` (shop.go); a new shop-time trigger or action
must be added there or the bot will misvalue it.
- **New public actions or log changes**: the bot tracks the opponent via
structured tags on public log entries (`LogBuy`, `LogSell`, `LogTrade`,
`LogTradePick`, spawn counts — see log.go). New public actions need tags
plus handling in `Observe` (memory.go). Tags must only ever duplicate
facts the entry's text already states publicly.
- **View changes**: the AI decides from `game.View` only — never hand it
the `Game`. If a field is added to the view, confirm it doesn't leak
hidden information (deck order, trade options, shop decks), because the
AI (and any client) would legitimately see it.
- **Phase/flow changes**: the server's bot driver (`internal/server/bots.go`)
must know when a bot owes an action (`ai.Pending`) and have a legal
fallback (`botFallback`) for any new phase or forced decision.
After any such change, run `go test ./internal/ai/` — it plays complete
bot-vs-bot games and fails on any illegal or missing bot action.