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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
# Slots: 5 reels x 3 rows
## Grid
- 5 reels (columns) x 3 rows = 15 visible symbols.
- Six symbols, uniform: `C` cherry, `L` lemon, `O` orange, `G` grapes,
`D` diamond, `S` seven.
- The bet is the **total** bet, not a per-line bet.
- Five paylines: top, middle, bottom, V, inverted V.
- A line pays for 3, 4 or 5 matching symbols starting on reel 1 and reading
left to right.
```
line 1: top row across all five reels
line 2: middle row across all five reels
line 3: bottom row across all five reels
line 4: top, middle, bottom, middle, top
line 5: bottom, middle, top, middle, bottom
```
## Paytable
```
payout = total bet x symbol multiplier x shape multiplier
```
Symbol multipliers:
| Symbol | Multiplier |
| --- | ---: |
| C | 1 |
| L | 2 |
| O | 3 |
| G | 4 |
| D | 6 |
| S | 10 |
Shape multipliers (how many matching symbols on the line):
| Shape | Multiplier |
| --- | ---: |
| 3 of a kind | 1 |
| 4 of a kind | 3 |
| 5 of a kind | 14 |
Every winning payline is added together.
- Exact RTP: **3835/3888 = 0.986368...** (1.36% house edge).
- Maximum win: 5 lines x S(10) x 5-shape(14) = **700x total bet**.
- Chance of any win on a spin: about **13%**.
- The RTP is checked by `SlotsGame::theoretical_rtp()` and `tests/slots.rs`.
## Wire format
`GAME_RESULT` keeps its existing fields and appends the winning lines and cells:
```
GAME_RESULT <session> <winnings> <bet> <balance> <reels> <win_type> <win_lines> <win_cells>
```
- `reels`: 15 characters, **column-major**: reel 0 top/middle/bottom, then
reel 1, and so on.
- `win_type`: `none`, `win`, `big` (>= 10x total bet) or `mega` (>= 50x).
- `win_lines`: 1-based comma-separated line numbers, or `-` for no win.
- `win_cells`: 0-based column-major cell indices to highlight, or `-` for no
win. Example: `0,3,6` is the first three cells of the top row.
- Older servers may still send a 3-character `reels` string; the client
degrades it to the first row.
- Older 1.0 servers send only `win_lines`; the 1.1 client simply shows no
highlights against them.
The extra `win_lines`/`win_cells` fields are additive. The 5x3 `reels` payload
is a breaking change for pre-5x3 clients, hence `1.0.0`; highlighting is the
backward-compatible `1.1.0` release. The client never re-derives paylines: the
server sends exactly which cells won.
## Client board
The board is ten lines:
```
=== SLOTS ===
Bet: 10 Kr Balance: 1000 Kr
{ G } [ L ] [ S ] [ O ] [ G ]
[ D ] { G } [ L ] [ S ] [ C ]
[ O ] [ O ] { G } [ L ] [ O ]
Pays bet x symbol x shape
Symbol C1 L2 O3 G4 D6 S10 Shape 3:1 4:3 5:14
Won 40 Kr
Winning lines: 4 (V)
[+/-] Bet [SPACE] Spin [Q] Quit
```
The two lines above the status show the payout formula and the two multiplier
tables. Winning cells use braces and are rendered yellow/bold in the terminal.
The line list below the status names the paylines that won. Both come from the
server's `win_lines` and `win_cells`, which are already carried through the
client state for the animation pass. Multiple winning lines are summed; the
board lists all of them and highlights the union of their matched cells.
## Reading a win
A payline is one of five fixed paths across the five reels:
| Line | Name | Rows on reels 1-5 |
| ---: | --- | --- |
| 1 | top | top, top, top, top, top |
| 2 | middle | middle, middle, middle, middle, middle |
| 3 | bottom | bottom, bottom, bottom, bottom, bottom |
| 4 | V | top, middle, bottom, middle, top |
| 5 | inverted V | bottom, middle, top, middle, bottom |
A line pays only when the first **3, 4 or 5** symbols on that line match,
reading from the leftmost reel.
In the example above, line 4 (V) contains `G G G S G`:
- reels 1-3 are `G`, so three `G` symbols pay;
- reel 4 is `S`, which breaks the run, so the `G` on reel 5 does not count;
- `G` has symbol multiplier 4 and 3-of-a-kind has shape multiplier 1, so the
win is `10 x 4 x 1 = 40 Kr`.
A diagonal of `L` symbols that is not one of the five paylines does not win,
and a run must start on reel 1. That is why only the three `G` cells are
marked in the example.
|