From 3b50928cb083b104043ac65433ed090c87731eb7 Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 29 Oct 2026 17:02:49 +0100 Subject: v2.0.0: reset plays audit to a generic per-game schema --- docs/GAMES.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 docs/GAMES.md (limited to 'docs/GAMES.md') diff --git a/docs/GAMES.md b/docs/GAMES.md new file mode 100644 index 0000000..cbe355e --- /dev/null +++ b/docs/GAMES.md @@ -0,0 +1,74 @@ +# Games and the play audit + +## Implemented + +| Game | Status | Notes | +| --- | --- | --- | +| Slots | Done | 5 reels x 3 rows, 5 paylines, 98.6% RTP | + +## Planned + +| Game | Shape | Main open decisions | +| --- | --- | --- | +| Roulette | One spin, many bets | European/French/American wheel; which bet types; 35:1 straight and other payouts | +| Blackjack | Multi-step hand | Dealer hits/stands soft 17; double/split/insurance; blackjack payout; shoe persistence | +| Crash | Real-time round | Crash-point distribution; cashout latency; provable fairness | + +Roulette fits the current one-request-settle model most easily. Blackjack needs +server-side hand state and player actions. Crash needs a timed round loop and a +cashout action, so it should come last unless we redesign the loop first. + +## Audit schema + +Every settled play is one row in `plays`: + +``` +plays ( + session_id TEXT PRIMARY KEY, + username TEXT NOT NULL, + game_type TEXT NOT NULL, + bet_amount INTEGER NOT NULL, + winnings INTEGER NOT NULL, + balance_after INTEGER NOT NULL, + details TEXT NOT NULL DEFAULT '{}', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) +``` + +`game_type` is the game that was played. `details` is a JSON object whose shape +depends on the game: + +```json +// slots +{"reels":"CCCCLLCLODGSDGS","win_type":"win","win_lines":"1","win_cells":"0,3,6"} + +// rumoured future examples +{"player":["AS","10H"],"dealer":["9D","7C"],"outcome":"blackjack"} +{"bets":[{"kind":"straight","number":17,"amount":10}],"winning":17} +{"crash_point":2.41,"cashout":1.80} +``` + +The balance updates and the `plays` insert happen in one transaction +(`database::apply_play`). The slots-specific wire fields (`reels`, `win_lines`, +`win_cells`) are still in `GAME_RESULT`, but the database no longer assumes +them. + +## Protocol gap + +The current exchange is slots-shaped: + +``` +PLAY_START +GAME_RESULT +``` + +Before blackjack, roulette, or crash can be added, the game session needs a +generic state/action protocol. A possible shape: + +``` +GAME_START +GAME_ACTION [json] +GAME_STATE # cards, bets, multiplier, legal actions, result +``` + +That is a wire-protocol change and will be its own major version. -- cgit v1.2.3