Documentation
R_Casino

r_casino Games

Tune odds, bet limits and payouts for all six r_casino games: Coinflip, Mines, Crash, Plinko, Blackjack and Cases, validated on the server.

All game settings live under R.Games in config.lua. Every bet and outcome is validated on the server against these values. The UI can't be tricked into different limits or payouts.

All outcomes (case rolls, mine boards, crash points, plinko drops, blackjack hands) are generated server-side. The UI only animates what the server already decided.

Coinflip

R.Games.Coinflip = {
    MinBet = 100,
    MaxBet = 10000,
    WinChance = 48.5,     -- % chance the player wins the flip
    Payout = 2.0,         -- winnings = bet * payout
}

A won flip pays bet * Payout. The house edge is 100 - WinChance * Payout percent. The default 48.5 with a 2.0 payout keeps 3% over time, in line with the other games. Lower WinChance for a bigger edge, or move it toward 50 for a near-fair flip.

Mines

R.Games.Mines = {
    MinBet = 100,
    MaxBet = 10000,
    MinMines = 1,         -- 5x5 board = 25 tiles
    MaxMines = 24,
    HouseEdge = 3,        -- % kept by the house
    MaxMultiplier = 1000, -- the multiplier never grows past this
}

The multiplier is the true odds of the tiles revealed so far, minus the house edge:

multiplier = (1 - HouseEdge / 100) * C(25, revealed) / C(25 - mines, revealed)

So with 3 mines the first safe tile pays 1.12x, the third 1.45x, and every cash-out returns HouseEdge percent less than a fair game would. Whatever the mine count. Players can cash out at any time; hitting a mine loses the bet. Clearing every safe tile cashes out automatically. MaxMultiplier caps the payout on high mine counts (a full clear with 10 mines would otherwise pay millions).

Crash

R.Games.Crash = {
    MinBet = 100,
    MaxBet = 10000,
    HouseEdge = 3,        -- % kept by the house
    GrowthRate = 0.1,     -- multiplier = e^(GrowthRate * seconds)
    MaxMultiplier = 1000, -- the round always crashes here at the latest
}

The multiplier starts at 1.00x and climbs exponentially. With GrowthRate = 0.1 it reaches 2x after ~7 seconds and 10x after ~23 seconds. The crash point is rolled on the server when the bet is placed and stays secret until the round ends:

chance the round reaches X  =  (1 - HouseEdge / 100) / X

That gives the same house edge whatever multiplier a player aims for, and HouseEdge percent of rounds crash instantly at 1.00x. Players cash out manually, or set an auto cash-out multiplier. The server honours it even if their game lags. After cashing out the round keeps running on screen until it crashes, but the player is free to bet again right away.

Plinko

R.Games.Plinko = {
    MinBet = 100,
    MaxBet = 10000,
    Rows = { 8, 10, 12 },     -- selectable board sizes
    DefaultRows = 10,
    DefaultRisk = "medium",   -- low, medium, high
    Multipliers = {
        [8] = {
            low    = { 5.6, 2.1, 1.1, 1.0, 0.5, 1.0, 1.1, 2.1, 5.6 },
            medium = { 13, 3, 1.3, 0.7, 0.4, 0.7, 1.3, 3, 13 },
            high   = { 29, 4, 1.5, 0.3, 0.2, 0.3, 1.5, 4, 29 },
        },
        -- [10] and [12] tables follow the same shape
    },
}

Each Multipliers list maps landing buckets from far-left to far-right. A board with N rows has N+1 buckets, so the list length must match. The ball's path is a fair 50/50 at every peg, rolled server-side.

If you add a row count to Rows, you must also add its multiplier table. The server rejects a row/risk combination that has no table.

Blackjack

R.Games.Blackjack = {
    MinBet = 100,
    MaxBet = 10000,
    BlackjackPayout = 2.5,    -- natural blackjack pays bet * this
    WinPayout = 2.0,          -- normal win pays bet * this (push returns the bet)
    DeckCount = 6,            -- decks in the shoe
    DealerStandsOn = 17,      -- dealer draws until reaching this total
}

The server deals from a real shuffled shoe. The dealer's hole card is never sent to the client until the hand resolves. Double down takes a second bet equal to the first and draws exactly one card.

Cases

R.Games.Cases = {
    RarityChances = {
        common = 50,
        rare = 35,
        epic = 12,
        legendary = 3,
    },
}

The percentages decide which rarity tier a case roll lands on (they should add up to 100), then a random item of that rarity is picked from the case. See Creating Cases for the catalog itself.