games: a blackjack table you can actually sit down at
The engine, the escrow and the wire were all in place; nothing had a browser on the end of it. This is that end: a lobby, a table, and the five endpoints between them. The browser holds no game. It sends intents and gets back a view — the cards it is entitled to see, and the script of how they arrived, one event per card off the shoe. The dealer's hole card is not in the payload at all until the reveal, because a field the client is told to ignore is a field somebody reads in devtools. The shoe lives in game_live_hands, which also means a redeploy mid-hand no longer costs a player their stake: the hand is still there when they come back. The money is ordered so nothing can be spent twice. The stake leaves the stack in the same statement that checks it exists, before a card is dealt. Every new hand is seated with a plain INSERT, so a double-clicked Deal is decided by the primary key rather than by a read that raced — it loses, gets its chips back, and the hand in progress is untouched. A double takes its raise up front and hands it straight back if the engine refuses the move. Cards are dealt rather than swapped in — they fly out of the shoe and turn over, which was a requirement and not a flourish. The faces and the chips are still plain; that's next.
This commit is contained in:
@@ -225,6 +225,23 @@ CREATE TABLE IF NOT EXISTS game_hands (
|
||||
CREATE INDEX IF NOT EXISTS idx_game_hands_user ON game_hands(matrix_user, played_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_game_hands_played ON game_hands(played_at);
|
||||
|
||||
-- The hand a player is in the middle of. One per player: you cannot be dealt a
|
||||
-- second hand while chips are riding on the first.
|
||||
--
|
||||
-- The state column is the engine's State, serialized whole — shoe included. It
|
||||
-- lives here rather than in memory because Pete redeploys often, and a player
|
||||
-- whose stake has already been taken must find their cards where they left them
|
||||
-- rather than a table that has forgotten them. It is also why the deck never
|
||||
-- goes to the browser: the authoritative shoe is this row, on the server.
|
||||
CREATE TABLE IF NOT EXISTS game_live_hands (
|
||||
matrix_user TEXT PRIMARY KEY,
|
||||
game TEXT NOT NULL, -- 'blackjack'
|
||||
state TEXT NOT NULL, -- JSON: the engine's State
|
||||
seed1 INTEGER NOT NULL, -- carried to the audit log when it settles
|
||||
seed2 INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_post_log_guid_channel ON post_log(guid, channel);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_log_event_id ON post_log(event_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_post_log_channel_posted ON post_log(channel, posted_at);
|
||||
|
||||
Reference in New Issue
Block a user