summaryrefslogtreecommitdiffstats
path: root/docs/GAMES.md
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-10-29 17:02:49 +0100
committersalmonik <salmonik@tuta.io>2026-10-29 17:02:49 +0100
commit3b50928cb083b104043ac65433ed090c87731eb7 (patch)
tree1d65beaaa68188c521b0d7da3f78c847540e5c32 /docs/GAMES.md
parentv1.3.1: allow = to increase the bet (diff)
downloadzagan-bet-3b50928cb083b104043ac65433ed090c87731eb7.tar.gz
zagan-bet-3b50928cb083b104043ac65433ed090c87731eb7.zip
v2.0.0: reset plays audit to a generic per-game schema
Diffstat (limited to 'docs/GAMES.md')
-rw-r--r--docs/GAMES.md74
1 files changed, 74 insertions, 0 deletions
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 @@
1# Games and the play audit
2
3## Implemented
4
5| Game | Status | Notes |
6| --- | --- | --- |
7| Slots | Done | 5 reels x 3 rows, 5 paylines, 98.6% RTP |
8
9## Planned
10
11| Game | Shape | Main open decisions |
12| --- | --- | --- |
13| Roulette | One spin, many bets | European/French/American wheel; which bet types; 35:1 straight and other payouts |
14| Blackjack | Multi-step hand | Dealer hits/stands soft 17; double/split/insurance; blackjack payout; shoe persistence |
15| Crash | Real-time round | Crash-point distribution; cashout latency; provable fairness |
16
17Roulette fits the current one-request-settle model most easily. Blackjack needs
18server-side hand state and player actions. Crash needs a timed round loop and a
19cashout action, so it should come last unless we redesign the loop first.
20
21## Audit schema
22
23Every settled play is one row in `plays`:
24
25```
26plays (
27 session_id TEXT PRIMARY KEY,
28 username TEXT NOT NULL,
29 game_type TEXT NOT NULL,
30 bet_amount INTEGER NOT NULL,
31 winnings INTEGER NOT NULL,
32 balance_after INTEGER NOT NULL,
33 details TEXT NOT NULL DEFAULT '{}',
34 created_at DATETIME DEFAULT CURRENT_TIMESTAMP
35)
36```
37
38`game_type` is the game that was played. `details` is a JSON object whose shape
39depends on the game:
40
41```json
42// slots
43{"reels":"CCCCLLCLODGSDGS","win_type":"win","win_lines":"1","win_cells":"0,3,6"}
44
45// rumoured future examples
46{"player":["AS","10H"],"dealer":["9D","7C"],"outcome":"blackjack"}
47{"bets":[{"kind":"straight","number":17,"amount":10}],"winning":17}
48{"crash_point":2.41,"cashout":1.80}
49```
50
51The balance updates and the `plays` insert happen in one transaction
52(`database::apply_play`). The slots-specific wire fields (`reels`, `win_lines`,
53`win_cells`) are still in `GAME_RESULT`, but the database no longer assumes
54them.
55
56## Protocol gap
57
58The current exchange is slots-shaped:
59
60```
61PLAY_START <game> <bet>
62GAME_RESULT <session> <winnings> <bet> <balance> <reels> <win_type> <win_lines> <win_cells>
63```
64
65Before blackjack, roulette, or crash can be added, the game session needs a
66generic state/action protocol. A possible shape:
67
68```
69GAME_START <game> <bet>
70GAME_ACTION <action> [json]
71GAME_STATE <json> # cards, bets, multiplier, legal actions, result
72```
73
74That is a wire-protocol change and will be its own major version.