# 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 ## 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.