summaryrefslogtreecommitdiffstats
path: root/docs/GAMES.md
blob: cbe355ef336bc991fd8957406b51a8d89de1c6ff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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> <bet>
GAME_RESULT <session> <winnings> <bet> <balance> <reels> <win_type> <win_lines> <win_cells>
```

Before blackjack, roulette, or crash can be added, the game session needs a
generic state/action protocol. A possible shape:

```
GAME_START <game> <bet>
GAME_ACTION <action> [json]
GAME_STATE <json>          # cards, bets, multiplier, legal actions, result
```

That is a wire-protocol change and will be its own major version.