A poker room that feels like a cozy cat café at 2am. Every court card is a chibi cat, the dealer button is a paw print, and chips are stacked fish tins. Friends hop into a Discord voice channel, launch the Activity, pick a variant off a dealer's-choice wheel, and play with chips that are worth exactly nothing outside the table.
Play money only. No real money, no cryptocurrency, no purchasable chips, no cash-out — ever. That's a hard invariant, not a v1 limitation.
packages/engine is a pure, dependency-free TypeScript rules engine that runs identically on the server (authoritative) and in the browser (optimistic UI), with a Discord Activity and a companion bot as thin client shells around it. Full design lives in docs/BUILD_PLAN.md.
![]() K♠ |
![]() A♥ |
![]() Joker |
![]() Back |
All art is 100% original — no franchise characters, no named-artist prompting, ever (invariant 5 below). Rank/suit indices are drawn as vector overlays at render time, never baked into the art itself.
Built milestone by milestone, in order. ✅ done · 🟦 in progress · ⬜ not started. Exact goal conditions for each are in docs/BUILD_PLAN.md §13.
| Milestone | What it is | Status |
|---|---|---|
| M0 | Scaffold — pnpm/Turborepo monorepo, strict TS, Vitest, ESLint, CI | ✅ |
| M1 | Cards, deck, CSPRNG shuffle, commit–reveal fairness, verify CLI |
✅ |
| M2 | Hand evaluator — high5 / high7 / shortdeck / a5-lo / a5-lo8 / 27-lo / badugi | ✅ |
| M3 | Betting, side pots, pure reducer | 🟦 engine done; protocol-level redaction not started |
| M4 | Tier 1 variants (Hold'em family) + headless game loop | ⬜ |
| M5 | Draw, lowball, stud | ⬜ |
| M6 | Server, WebSocket, mixed games, Chinese poker | ⬜ |
| M7 | Art pipeline & assets | 🟦 55 card faces + 10 avatars sliced and processed ahead of schedule |
| M8 | Web client + Discord Activity + bot | ⬜ |
| M9 | Casino room, video poker, chaos mode, polish | ⬜ |
packages/engine currently ships 109 passing tests across 19 files — exhaustive hand-evaluator histograms differentially tested against a naive reference oracle, a seeded chi-squared shuffle-uniformity test, and a fast-check fuzz test asserting chip conservation across 25,000 random hands, checked after every single action.
packages/enginehas zero runtime dependencies and no I/O. It runs in a browser worker.- The server is authoritative. A client never receives a card its seat isn't entitled to see.
- Randomness is the global Web Crypto
crypto.getRandomValues, with masked rejection sampling — neverMath.random(),Date.now(), or modulo. Async work is confined to the hand boundary; the reducer itself stays synchronous. - Rake is zero. There is no payment, purchase, or cash-out code path. Ever.
- All art is original. No image model is ever prompted with a franchise, character, brand, or living artist's name.
- Rank/suit indices are vector overlays, never baked into generated art.
- New variants are
VariantDescriptordata files, not new branches in the reducer. - Tests are never weakened, skipped, or stubbed to force a goal condition to pass. If a test is wrong, that's a stop-and-say-so situation.
| Layer | Choice |
|---|---|
| Language | TypeScript, strict mode, noUncheckedIndexedAccess |
| Monorepo | pnpm workspaces + Turborepo |
| Engine | Pure TS, zero I/O, zero deps, deterministic and exhaustively testable |
| Server | Node 22 + Fastify + ws |
| Client | React 19 + Vite + PixiJS v8 (table canvas) + Tailwind (chrome/UI) |
| Discord | @discord/embedded-app-sdk (Activity) + discord.js v14 (bot) |
| DB | Postgres (Supabase) + Drizzle ORM |
| Tests | Vitest + fast-check (property-based) + Playwright (e2e) |
catpoker/
├─ packages/
│ ├─ engine/ # pure rules engine — cards, RNG, evaluator, betting, pots, reducer
│ ├─ protocol/ # shared types + wire schemas, client<->server (docs/PROTOCOL.md)
│ ├─ ui-kit/ # React components
│ └─ art-pipeline/ # image slicing, background removal, atlas packing
├─ apps/
│ ├─ server/ # Fastify + ws, authoritative game state
│ ├─ web/ # React + Pixi client (standalone + Discord Activity)
│ └─ bot/ # discord.js
├─ assets/
│ ├─ raw/ # source art sheets
│ ├─ processed/ # sliced, trimmed, transparent PNGs
│ └─ atlas/ # packed spritesheets (M7)
└─ docs/ # BUILD_PLAN, PROTOCOL, ADRs
pnpm install
pnpm -r typecheck
pnpm -r test
pnpm lint
# engine-specific
pnpm --filter engine test:evaluator
pnpm --filter engine test:variants
pnpm --filter engine sim -- --variant plo8 --hands 100000
pnpm art:audit
pnpm --filter web dev
pnpm --filter server dev
pnpm --filter bot devdocs/BUILD_PLAN.md— source of truth; all milestones and their goal conditionsdocs/PROTOCOL.md— normative wire protocol (ADR-0002)docs/adr/— architecture decision recordsCLAUDE.md— invariants and working agreements for the agent building this




