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

148 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Super Auto Pets: The Board Game — Online
A web app for playing the Super Auto Pets board game remotely. 1v1 for now;
the engine is built to grow to more players. Play a friend by room code, or
play solo against a computer opponent (easy / medium / hard).
## Stack
- **Backend**: Go (stdlib-first). Pure game engine in `internal/game`,
WebSocket sync via `coder/websocket`, persistence as JSON blobs in SQLite
(`modernc.org/sqlite`, no cgo).
- **Frontend**: React + Vite + TypeScript in `web/`. DOM/CSS card rendering
and battle animations.
- **Tasks**: [mise](https://mise.jdx.dev) (`mise.toml`).
## Quick start
```sh
mise run install-web # once: npm install
mise run serve # build frontend + server, run on :8080
```
Open http://localhost:8080, host a game, and join from another browser (or
incognito window) with the 5-letter code.
### Development
```sh
mise run dev # Go server on :8080 + Vite hot reload on :5173
mise run test # Go tests (game engine)
mise run check # go vet + frontend type-check
```
During development open the Vite URL (http://localhost:5173); it proxies
`/api` (including the WebSocket) to the Go server.
## Configuration
Set via environment or a `.env` file (see `.env.example`):
| Variable | Default | Purpose |
| ------------ | ---------- | ------------------------------------ |
| `DATA_DIR` | `data` | Directory holding the SQLite DB |
| `PORT` | `8080` | HTTP port |
| `STATIC_DIR` | `web/dist` | Built frontend to serve |
## Rules implemented
Six rounds, each with its own shop tier deck. Per round:
1. **Shop** — each player has 3 gold and players alternate actions: **buy**
one of 4 face-up cards (1 gold — the only action that costs anything);
**sell** any number of hand cards for free (each becomes an 🍎 apple, +1
power food, and Sell effects fire); or **trade in** 3 same-suit pets (the
Triple action, also free) to pick 1 of the top 2 cards of the next tier's
deck — Triple effects fire on the traded cards and the received pet's Buy
effect fires. **Passing** is a final action, only legal at 5 pets or
fewer: it forfeits remaining gold and ends that player's shopping for the
round. The shop closes once everyone has passed.
2. **Arrange** — Battle Prep effects fire first (e.g. Giraffe hands out
apples), then players secretly order their decks. Food cards apply to the
next pet after them; trailing foods are wasted. A pet only benefits from
its last-applied **perk** (e.g. Honey, Garlic).
3. **Battle** — automatic stack machine. Cards reveal off the top of each
deck until a pet is in play. Play effects fire on reveal (rocks roll a d6
with faces 0/0/1/1/2/2 and hit the opposing pet before the clash; Skunk
strips foods; Wolverine steals apples; Chili mills the enemy deck). The
two pets simultaneously deal their full power to each other as damage
markers; a pet with markers ≥ power faints (attack never drops while
wounded). Faint effects push summons onto either deck, recycle apples
(Dodo), set aside delayed/recurring/conditional rock volleys (Badger,
Blowfish, Snake, Crocodile), raise auras (Turkey, Mammoth), or arm a
team shield (Turtle). Survivors that took damage fire Hurt effects
(Peacock, Camel, Gorilla). Shields (Turtle/Gorilla/Melon) block whole
hits, Garlic shaves 1 per attack, and Scorpion KOs anything its clash
attack manages to hurt. Hippo heals when enemies faint; Rhino rocks each
enemy pet as it's played. A clash that changes nothing ends the battle
as a stalemate draw. Last player able to field a pet wins: 1 trophy for
rounds 15, 2 for round 6. Draws award nothing.
Apples and bees are **temporary**: they leave your deck after the battle.
Most trophies after round 6 wins.
## Packs
Two card packs are playable, chosen by the host in the lobby (a third,
Unicorn, is stubbed for later). Each pack is six tiers, one per round, and
every pet ships as two copies.
### Turtle pack
| Tier | Pets | Food |
| ---- | ---- | ---- |
| 1 | Ant, Cricket, Duck, Otter, Mosquito, Fish | — |
| 2 | Worm, Flamingo, Peacock, Swan, Rat, Spider | Honey |
| 3 | Dog, Dolphin, Giraffe, Camel, Sheep, Dodo, Badger | Garlic |
| 4 | Squirrel, Turtle, Rooster, Bison, Blowfish, Skunk, Hippo | Pineapple |
| 5 | Monkey, Rhino, Crocodile, Scorpion, Seal, Shark, Turkey | Chili |
| 6 | Gorilla, Fly, Leopard, Mammoth, Cat, Snake, Wolverine | Melon |
### Golden pack
| Tier | Pets | Food |
| ---- | ---- | ---- |
| 1 | Groundhog, Pied Tamarin, Chipmunk, Cone Snail, Bulldog, Opossum | — |
| 2 | Black-Necked Stilt, Lizard, Hercules Beetle, Stoat, Desert Rain Frog, Honduran White Bat | — |
| 3 | Guinea Fowl, Surgeon Fish, Osprey, Anteater, Bear, Royal Flycatcher, Flea | Avocado |
| 4 | Saiga Antelope, Vaquita, Poison Dart Frog, Manta Ray, Slug, Cockatoo, Manatee | Potato |
| 5 | Nyala, Nurse Shark, Giant Isopod, Blue-Ringed Octopus, Raccoon, Fire Ant, Macaque | Durian |
| 6 | Highland Cow, Wildebeest, Grizzly Bear, Catfish, Komodo, Bird of Paradise, German Shepherd | Tomato |
The Golden pack adds mechanics the Turtle pack doesn't have:
- **Trumpets** — an ephemeral battle resource pets earn and spend mid-fight.
- **Golden Retriever** — once per battle, a side that runs out of cards but
still holds Trumpets fields one, its power equal to those Trumpets.
- **Avocado** — a persistent set-aside token you can discard in place of gold.
- **Nurse Shark** — the one interactive battle moment: the fight pauses and
asks how many Trumpets to spend on rocks (the bot answers with a fixed
policy, so simulated rollouts stay valid).
- **Cockatoo** — a shop-time reveal, plus Manta Ray's free first buy,
Blue-Ringed Octopus' per-buy apples, and more.
## Layout
```
cmd/server/ entrypoint
internal/game/ rules engine (pure, fully tested)
internal/ai/ computer opponent (decides from a player View only)
internal/server/ HTTP + WebSocket rooms; drives bot turns
internal/store/ SQLite persistence
internal/env/ .env loading
web/ React frontend
```
## The computer opponent
Any seat can be a bot (`Player.IsBot`); humans and bots are interchangeable
to the engine, which is what will let future >2-player games mix them
freely. The AI in `internal/ai` never touches the `Game` — it decides from a
`game.View`, the same per-player state a human client is sent, plus a
persisted memory of public observations (battle lineups, the event log, shop
row changes). It cannot see your deck order, hidden trade picks, or the
shuffled shop decks. It scores candidate moves by Monte-Carlo battle
rollouts (`game.SimulateBattle`) against sampled guesses of your deck and
ordering, blended with a long-term deck-value heuristic; difficulty tunes a
softmax over the scored moves plus the rollout budget.