-
Notifications
You must be signed in to change notification settings - Fork 58
Casino
Four solo games played against the house — Slots, Roulette, Dice and Crash.
Every wager the house wins is destroyed. The Casino is a currency sink: it exists to take currency out of an inflated economy, never to put currency into it. That is the opposite of the Coinflip addon, which is player-versus-player and simply moves currency between two players.
Addon — drop
X-Prison-Casino-<version>.jarintoplugins/X-Prison/addons/and restart. Requires the Currency module to be enabled. Requires X-Prison2026.3.2.0or newer.
| File | Purpose |
|---|---|
plugins/X-Prison/addons/Casino/casino.yml |
Games, odds, wager limits, house edge |
plugins/X-Prison/addons/Casino/casino-gui.yml |
Every menu — slots, items, titles, animation targets |
plugins/X-Prison/addons/Casino/casino-messages.yml |
Every message, raw MiniMessage |
Each game works out a fair payout multiplier from its own odds, then scales it down by
house-edge. An edge of 0.05 means players get back 95% of what perfectly fair odds would pay.
| Game | Fair multiplier |
|---|---|
| Slots | the payout configured for the symbol combination that landed |
| Roulette |
pockets ÷ winning-pockets for the bet that was backed |
| Dice | 100 ÷ win chance |
| Crash | baked into the crash-point distribution itself |
The resulting return to player (RTP) is printed in the console when each game is enabled, and
listed by /casino rtp.
A game configured with an RTP of 100% or more pays out more than it takes in — it would create
currency instead of destroying it. The Casino refuses to enable such a game and prints an error
naming it, rather than quietly running it. Lower its payouts or raise its house-edge and reload.
This is why house-edge: 0 is not a valid setup for Dice or Crash: with no edge they return exactly
100%, and they will not start.
Every reel is drawn from the same weighted symbol pool. A symbol's chance is its weight divided by the total of all weights.
slots:
reels: 3
symbols:
CHERRY: 40
SEVEN: 1
payouts:
all-matching: # every reel showing the same symbol
CHERRY: 2.0
SEVEN: 15000.0
two-matching: 1.2 # exactly two reels match; 0 disables itHow each symbol looks is configured separately, in casino-gui.yml under result.slots.symbols.
The RTP is computed by enumerating every possible combination exactly. If your table has more combinations than can be checked (symbols raised to the power of reels), the game refuses to load and asks you to reduce one of the two.
One pocket is drawn from 0 to pockets - 1. Each bet declares how many of those pockets win it.
roulette:
pockets: 37
default-bet: "red"
bets:
red:
winning-pockets: 18 # an 18-in-37 chance
payout: 2.0555 # fair, because 37 ÷ 18 = 2.0555
green:
winning-pockets: 1
payout: 37.0The player picks a win chance; the payout scales inversely with it. A 5% shot pays roughly twenty times the stake, a 90% shot barely more than the stake.
dice:
min-chance: 1
max-chance: 95 # must stay below 100, or the game could not lose
default-chance: 50A multiplier climbs from 1.00x. Cash out before it crashes or lose the wager.
crash:
max-multiplier: 100.0
tick-interval: 4 # ticks between steps — lower is faster and tenser
growth-per-tick: 0.04Crash is the only game that settles while its menu is open, which makes it the only one that can be interrupted. Two safeguards cover that:
- Closing the menu cashes out at the multiplier that was on screen. Logging out, dying or walking through a portal can never strand a wager.
- A server crash refunds the wager. Open rounds are recorded in the database and refunded on the next startup, with a line in the console saying how many.
defaults:
currencies: [ "Tokens" ] # which currencies may be wagered
min-wager: 1000
max-wager: 0 # 0 = no upper limit
house-edge: 0.05
cooldown-seconds: 0
permission: "" # extra permission on top of xprison.casino.game.<id>Anything under defaults can be overridden per game under games.<id>.
limits:
daily-net-loss-cap: 0 # stop a player once they are this far down today; 0 = no cap
bypass-permission: "xprison.casino.bypass.limits"The daily tally is kept in memory and survives a relog, so reconnecting cannot reset a player's limit. It does reset when the server restarts, and at midnight in the server's timezone.
All amounts are exact BigDecimal values end to end — OP-scale balances above 10²⁴ wager and pay
out without losing a single digit.
animation:
enabled: true
duration-ticks: 40
frame-interval-ticks: 2
skippable: true
remember-skip-choice: trueThe round is already settled before its menu opens — the animation is pure display. Skipping it, closing the menu, or logging out mid-spin cannot change or lose the result.
With remember-skip-choice: true, clicking the skip button also skips future animations for that
player. /casino skip toggles it back on.
| Command | Permission | What it does |
|---|---|---|
/casino |
xprison.casino.use |
Opens the casino hub |
/casino <game> [wager] |
xprison.casino.game.<game> |
Opens that game's bet menu |
/casino open <player> |
xprison.menu.other |
Opens the hub on another player's screen (NPC support) |
/casino stats [player] |
xprison.casino.use |
Wins, losses and net result |
/casino top [currency] |
xprison.casino.use |
Players who are up on the house |
/casino skip |
xprison.casino.use |
Toggles animation skipping |
/casino rtp |
xprison.casino.admin |
Prints each game's configured return to player |
/casino reload |
xprison.casino.reload |
Reloads all three config files |
The command name and its aliases are set in casino.yml under command.
Requires PlaceholderAPI.
| Placeholder | Value |
|---|---|
%xcasino_wins% |
Rounds won |
%xcasino_losses% |
Rounds lost |
%xcasino_rounds% |
Rounds played |
%xcasino_wagered% |
Total wagered |
%xcasino_net% |
Net result against the house |
%xcasino_biggest_win% |
Largest single payout |
%xcasino_net_<currency>% |
Net result in a specific currency |
%xcasino_wagered_<currency>% |
Total wagered in a specific currency |
%xcasino_biggest_win_<currency>% |
Largest payout in a specific currency |
%xcasino_rtp_<game>% |
A game's configured return to player |
%xcasino_min_wager_<game>% |
A game's minimum wager |
stats:
enabled: true
retention-days: 30 # prune round history older than this on startup; 0 = keep foreverRounds are written to the X-Prison database as an audit trail, and running totals are kept per player
per currency for /casino stats, /casino top and the placeholders. Amounts are stored as text
rather than numbers, because SQLite has no exact decimal type and would round OP-scale wagers.
broadcast:
big-win-threshold: 10000000 # announce payouts at or above this; 0 = neverThe message itself is big_win_broadcast in casino-messages.yml.
The Casino is built around a CasinoGame interface. A new game is one class, one registry line and
one config block — no existing code is edited. Developers can also listen for CasinoWagerEvent
(cancellable, with a mutable amount) and CasinoRoundSettledEvent.
- Currencies
- Ranks
- Prestiges
- Rebirths
- Mines
- AutoSell
- AutoMiner
- Enchants
- Pickaxe Levels
- Pickaxe Skins
- Pickaxe Quality
- Pickaxe Settings
- Gangs
- Multipliers
- Blocks
- Bombs
- History
- Mining Stats
- Nicknames
- Battle Pass
- Quests
- Daily Rewards
- Milestones
- config.yml
- autominer.yml
- autosell.yml
- block-rewards.yml
- enchants.yml
- currencies.yml
- multipliers.yml
- ranks.yml
- prestiges.yml
- pickaxe-levels.yml
- pickaxe-skins.yml
- pickaxe-quality.yml
- gangs.yml
- mines.yml
- bombs.yml
- blocks.yml
- history.yml
- logging.yml
- mining-stats.yml
- rebirths.yml
- battlepass.yml
- quests.yml
- dailyrewards.yml
- milestones.yml
- efficiency.json
- fortune.json
- unbreaking.json
- haste.json
- speed.json
- fly.json
- nightvision.json
- jumpboost.json
- autosell.json
- tokenfinder.json
- gemfinder.json
- salary.json
- charity.json
- blessing.json
- gangvaluefinder.json
- prestigefinder.json
