33 lines
2.0 KiB
Markdown

## Context
The game page (`+page.svelte`) hardcodes the `trainingMix` preset at initialization. The setup page saves user-selected config to `sessionStorage`, but nothing reads it. The bot timer uses a `$effect` that re-runs on every reactive update, resetting the countdown. Card visibility only checks `isHuman`, ignoring poker rules for showdown and all-in reveals.
## Goals / Non-Goals
**Goals:**
- Settings from `/setup` page apply to the game session
- Bot countdown timer decrements correctly (13→12→11...→0)
- Opponent cards reveal at showdown and when all-in with no further betting
**Non-Goals:**
- Persistent config across browser sessions (localStorage/database)
- Animated card reveals or showmanship
- Multi-player online gameplay
## Decisions
### Settings via sessionStorage
Using `sessionStorage` (already in use by setup page) rather than URL params or a state store. It's simple, survives the navigation redirect, and clears on tab close — appropriate for a single-session training game.
### Timer fix: $derived.timeRemaining with setInterval outside effect
The `$effect` will only anchor on `active` and `duration`, not `remaining`. The interval will update `remaining` directly. This breaks the reactivity cycle since the effect won't re-run when `remaining` changes.
### Card reveal: computed function in PokerTable, passed to PlayerSeat
Rather than passing the entire GameState to each PlayerSeat (which it already has via player prop), we add a `revealCards` boolean prop. PokerTable computes this based on betting round, player status, and all-in conditions.
## Risks / Trade-offs
[sessionStorage read fails] → Parse with fallback to default preset
[Timer still flickers in dev mode] → Svelte 5 fine-grained reactivity may need `$state.raw` for the counter
[All-in reveal timing edge cases] → The "last betting round complete" check requires knowing if any active player can still bet — we approximate by checking if all non-folded players are all-in or matched