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
|
# Bank craps
The playable bank-craps table is in room 6185, west of single-zero roulette.
`play craps`, `watch craps`, `table`, `table rules`, and `help craps` use the
existing casino interfaces. `roll`, `autoroll` and `unbet <target>` are table actions;
`down` remains the movement command.
```yaml
casino_tables:
- id: bank_craps
game: craps
max_players: 12
min_bet: 1
max_bet: 10000
craps:
variant: bank
odds: 0
field_12: 3
```
`odds: 0` (default) means 3x on 4/10, 4x on 5/9, and 5x on 6/8.
Don't-side odds permit 6x the underlying wager **laid**, producing the same
3/4/5x maximum win. A positive integer selects uniform Nx **stake** limits
on both sides; supported values are 1 through 1,000,000. Odds are free of
commission. `field_12` is 2 (default) or 3. Field 2 always pays 2:1.
Only omitted/`bank` variants are accepted; unavailable variants fail validation.
Shared min/max limits apply to each individual wager, including odds.
## Engine policy
- Pass, don't pass (bar 12), come, don't come, true odds; place, buy, lay;
hardways; field; individual propositions, horn, and unordered hop bets.
- Multiple wagers have independent durable stake handles. Wins return the
stake and remove the wager; no automatic renewal, pressing or parlaying.
- Place/buy/hardways and come odds are off on come-out. Established come
contracts still work. Lay bets and don't-side odds always work.
- Exact payout units are required. Buy commission is 5% of the stake; lay
commission is 5% of profit. Commission is rounded up and charged only on
wins. No commission is charged for removing a wager.
- Fire pays 24/249/999:1 on 4/5/6 distinct made points, settled at seven-out.
Repeated made points do not advance it. Come-out sevens do not end Fire.
- Small (2–6) and Tall (8–12) pay 34:1; All pays 175:1. Each pays immediately
when complete. **Any** seven loses unresolved ATS and resets its tracker.
All bonus wagers must be made before the first roll of a shooter hand;
they cannot be removed or added midway, even following a come-out seven.
- Solo play has no betting delay or forced rolls. In multiplayer, every
round gives players 10 seconds before the shooter may roll, with a public
last call at 3 seconds remaining. **Bets and removals remain open until
the actual roll.** Once eligible, the shooter has 60 seconds before the
dealer rolls for them. Only connected, non-sitting-out seats count.
Without live bets the table pauses. A second active player joining gives
the table a fresh 10-second window; additional wagers never extend it.
- `autoroll` opts the player into a roll every 3 seconds while it is their
turn and they still have live bets. It respects multiplayer's 10-second
minimum and stops automatically once their bets finish. `stop` cancels
autoroll atomically and keeps them seated with their bets unchanged; a
second stop in manual mode uses the normal leave behavior.
- These durations use the configured engine cadence through
`Manager.TickElapsed`; there are no independent timers or goroutines.
`betting_ticks` is not used by craps (other games retain their rules).
- New arrivals enter at the tail of the queue. A made point retains the
shooter; seven-out rotates them to the tail. Sit-outs are skipped.
If a shooter departs, the next player completes the existing table hand;
points and bonus progress are not reset to grant free options.
- Pass/come and bonus bets are contracts. Other bets and odds may be removed
with `unbet` (or all at once with `unbet all`) before the dice roll.
In manual mode `stop`/`sitout` wait for the player's
last live bet, not merely the next roll.
- Disconnect forfeits live bets; shutdown/room eviction refunds outstanding
stakes. Failed settlements are reported as pending recovery, never as paid.
Like other casino games, table state is not persisted across restart:
the pending-stake wallet ledger provides recovery.
## Implementation and verification
`internal/casino/craps_rules.go` contains configuration, payout rules and the
pure per-bet outcome function. `craps.go` handles phases, shooter order,
bonus tracking, wallets and detached snapshots. Registration uses the existing
`tableGame`/`tableCore` seam. `internal/game/render_craps.go` draws a dark-green boxed half-table, ON/OFF
puck, and filled Fire/ATS number trackers. Pip dice honor `card_style` dark/light,
ASCII/Unicode, and terminal color preferences. Command reminders follow the art.
Each player gets a numbered-target wager summary after bets and rolls, and one
consolidated, colored settlement (not a balance repeated after every wager).
Tests cover all 36 line/come outcomes, payout examples, configurable odds,
come-out working rules, bonus sequences, shooter rotation, deadlines, removal,
queued departures, disconnect/shutdown, payout failure recovery, command target
parsing, and rendering. Run `go test ./...` and
`go test -race ./internal/casino ./internal/game ./internal/admin ./internal/validate`.
## Follow-on variants (not implemented)
Simplified, High Point, Crapless, New York, Die Rich and Diceless Craps require
separate, explicit rules and acceptance tests; names alone are not adequate
specifications because regional versions differ. Do not map them onto bank
craps silently. Before adding each, pin its come-out/point rules, supported
bets, payouts, commissions, odds limits and bonus eligibility. Diceless also
needs an explicit card model (replacement vs. finite shoe, card mapping,
shuffle policy, and card visuals). Preserve the shared wallet and queue
lifecycle while isolating these outcome and random-source differences.
|