games: a ladder you climb against the clock
This commit is contained in:
@@ -244,9 +244,61 @@ A multi-session build. This section is the handover; read it before anything els
|
||||
hits the rack, nothing happens, and it looks like the bet is broken. Blackjack's
|
||||
action buttons are also `[data-move="stand"]`, not `[data-stand]`.
|
||||
|
||||
- **Trivia, and it plays for chips.** *(2026-07-14. Built, tested, and — say it
|
||||
plainly — **NOT YET DRIVEN IN A BROWSER**. Every Go test passes and `go vet` is
|
||||
clean, which per this plan's own hard-won rule means nothing at all about the
|
||||
table. Do that first next session; see the bottom of this entry.)*
|
||||
- **A ladder.** Stake once, then answer a run of twelve. Every right answer
|
||||
multiplies what you're holding, a wrong one loses the lot, and you may walk
|
||||
with what you've built. Clearing all twelve ends the run and banks it — a
|
||||
ladder with no top is a slot machine you can't stop playing, and eventually
|
||||
every player loses everything to one bad question.
|
||||
- **The clock is the game, and it is the anti-google mechanism.** Trivia answers
|
||||
are lookupable, so a right answer is worth what it's worth *when you give it*:
|
||||
the multiple decays from Fast to Buzzer across the tier's limit (easy 1.30→1.10
|
||||
over 20s, medium 1.55→1.20 over 18s, hard 1.90→1.30 over 15s), and running out
|
||||
of time loses exactly as much as being wrong. A timeout that merely cost you the
|
||||
speed bonus would make "look it up in the other tab" the strongest way to play.
|
||||
The countdown in the browser is decoration; the clock that scores is
|
||||
`time.Now()` against the `AskedAt` the server stamped. A reload does not restart
|
||||
it.
|
||||
- **A pure reducer still, but the time is an argument** — `ApplyMove(state, move,
|
||||
now)`. A reducer cannot own a timer, so it doesn't: the only thing that knows
|
||||
what o'clock it is remains the caller, and the engine stays value-in, value-out.
|
||||
- **You cannot walk off the first rung** (`ErrNothingBanked`). If you could, seeing
|
||||
question one and walking would be a free look: stake, peek, walk, restake, and
|
||||
reshuffle until the question is one you happen to know. The first question is the
|
||||
price of sitting down.
|
||||
- **The browser never learns which answer is right.** The four answers cross the
|
||||
wire without the index; that index is in the engine state, on the server. It
|
||||
comes back only in the event that *decides* the question, by which point knowing
|
||||
it is worth nothing. The ladder's remaining questions are never sent at all.
|
||||
- `internal/games/trivia` — engine, 11 tests. The one that matters most is the
|
||||
same one hangman needed: the number the felt quotes (`Pays()`) is asserted equal
|
||||
to the number `settle()` lands on, at every rung.
|
||||
- **The bank is prefetched, not fetched per question** (`internal/opentdb`,
|
||||
`storage.DrawTrivia`, table `trivia_questions`). A ladder asks a question every
|
||||
fifteen seconds with money on a clock the player is scored against; a live fetch
|
||||
would put OpenTDB's latency and rate limit *inside* that clock. The refill is a
|
||||
slow background drip (`StartTriviaBank`, 400 per difficulty, one request per six
|
||||
seconds, stops early when a batch adds nothing new), and a round never waits on
|
||||
it. Answers are shuffled per-game against the game's own seed, so where the right
|
||||
answer sits in the table tells a player nothing.
|
||||
- **Left to do, and it is the whole of the risk:** `PETE_DEV_CASINO=:7788 go test
|
||||
./internal/web -run TestDevCasino -timeout 0` and *play it*. Watch especially:
|
||||
the bank is empty on a fresh dev database, so the first start will 503 with "the
|
||||
question bank is still filling up" until the refill loop has run — the dev rig
|
||||
does not start that loop, so it likely needs seeding by hand or a call to
|
||||
`refillTriviaBank`. Then: does the clock bar drain honestly, does the auto-submit
|
||||
at zero land as a timeout rather than a "that move isn't legal" (the GRACE window
|
||||
in trivia.js is what defends this), does the reveal mark the right answer, and
|
||||
does the money settle onto the shared spot the way the other three tables do.
|
||||
|
||||
### Next, in order
|
||||
|
||||
1. Phase 2's other half: **trivia**. Decided but not built: the question bank is
|
||||
1. **Drive trivia in a browser** (see above) — it has never been played, and that
|
||||
means nothing about it is known.
|
||||
2. Phase 2's other half is now built but unproven: the question bank is
|
||||
**prefetched from OpenTDB into a local table** (a per-question fetch in a web
|
||||
game loop is a latency and rate-limit problem gogobee never had), through
|
||||
`internal/safehttp`. It stakes chips too. The shape that fits the room is a
|
||||
|
||||
Reference in New Issue
Block a user