games: the money moves

The table dealt cards but settled money by editing a number. So the felt got
the two things it was missing: a bet spot in front of you, and the house's rack
beside the shoe. Every chip is now always travelling between one of those and
the other.

You build a bet by throwing chips onto the spot — the chip you clicked is the
chip that flies. The stake sits there through the hand. The house pays out of
its rack into the spot, and the pile is then swept back to your stack. A loss
goes to the rack and does not come back.

Two rules hold it together. The number under the pile is a readout of the pile,
never the other way round: the bet starts at nothing rather than at a default
nobody put down, and a settled hand leaves your stake back up on the spot,
because otherwise the panel prints "your bet: 300" over an empty circle. And
the chip bar does not move until the chips that justify it have landed — a
counter that pays you before the dealer turns over is a counter that has told
you the ending.

casino-fx.js is the engine underneath: chips fly on an arc, out of a fixed
overlay so no container clips one crossing from a button to the felt. It knows
nothing about blackjack.

Also: cards land with weight and a degree or two of tilt, so a hand looks dealt
rather than typeset; the dealer takes a beat before drawing out; and a natural
gets confetti, which is the only thing in the room that does.

Driven in a real browser, which is the only way to review an animation — and
which is what caught the verdict pill rendering white on white in a dark room,
a chip rack sitting on top of the dealer, and Hit being offered over a table
that was still being paid out. devcasino_test.go is that harness, kept.
This commit is contained in:
prosolis
2026-07-14 00:33:49 -07:00
parent b00da21a47
commit 6961f90634
8 changed files with 845 additions and 64 deletions

View File

@@ -91,16 +91,52 @@ A multi-session build. This section is the handover; read it before anything els
bottom-half pips inverted, courts as a letter with the suit over each shoulder,
and a screen-reader label that says "Queen of hearts" instead of "Q♥".
- **The money moves.** The felt grew the two things it was missing: a **bet spot**
in front of you and the **house's rack** beside the shoe, so every chip on the
table is always travelling between one of those and the other. A bet is *built*
by throwing chips onto the spot (the chip you clicked is the chip that flies);
the stake sits there through the hand; the house pays out of its rack into the
spot; the whole pile is then swept back to your pile. A loss goes to the rack and
doesn't come back. `casino-fx.js` is the shared engine — `fly`/`flyMany` (WAAPI,
on an arc, out of a fixed overlay so nothing clips them), `chipsFor` (an amount
broken into the fewest chips, capped at what's worth watching), `burst`, `count`.
Two rules hold it together, and both are load-bearing:
1. **The number under the pile is a readout of the pile**, never the other way
round. So the bet starts at zero rather than at a default nobody put down, and
a settled hand puts your stake *back on the spot* as a standing bet — otherwise
the panel prints "your bet: 300" over an empty circle.
2. **The chip bar does not move until the chips that justify it have landed.** On
a live hand the money applies immediately (your stake left your pile and is
visibly on the spot); on a settling hand `play()` holds the apply until the
payout has swept home. A counter that pays you before the dealer turns over is
a counter that has told you the ending.
Also: cards land with weight (overshoot, a shadow that takes the hit, a degree or
two of resting tilt each), the dealer takes a beat before drawing out, and a
natural gets confetti — the only thing in the room that does.
- **A way to actually look at it.** `internal/web/devcasino_test.go` is the casino on
a port with one signed-in, funded player: `PETE_DEV_CASINO=:7788 go test
./internal/web -run TestDevCasino -timeout 0`. Skipped without the env var. It
wires its own routes because `New()` decides whether the casino exists at the
moment it builds the mux, and the test rig signs the player in afterwards. **Drive
the table in a real browser before believing anything about it** — this pass found
a white-on-white verdict pill, a rack that collided with the dealer, and Hit still
being offered over a table that was being paid out, none of which a Go test can see.
### Next, in order
1. **Finish making the table lively.** Card faces are done. Still thin: chips never
physically move, and nothing celebrates. Ideas already sketched: chips that fly to
a bet spot and back on a win, cards landing with weight, a dealer beat before
drawing out, a burst on a natural.
2. **Deploy.** Add the `games.parodia.dev` redirect URI to the `pete` app in Authentik,
1. **Deploy.** Add the `games.parodia.dev` redirect URI to the `pete` app in Authentik,
point Caddy at the same port, set `[web.games]` + `web.auth.cookie_domain` on the
server. Nothing else is host-specific.
3. Then Phase 2 (trivia, hangman), 3 (UNO), 4 (hold'em) as below.
2. Then Phase 2 (trivia, hangman), 3 (UNO), 4 (hold'em) as below.
Still open on the table itself, none of it blocking: **split** isn't implemented (the
engine has no move for it), the felt is roomy at desktop widths with only one seat on
it, and the chip animations are tuned for one player — a second seat would need the
spot to be per-seat rather than the singleton it is now.
### How the browser half fits together