Flat betting · 49.5% chance
Fixed wager in sats: dice script with a bankroll guard (Lua)
This script reads the session balance in satoshis with Units.ToSats(balance), refuses to start below 100,000 sats, and then bets 100 sats on every roll at 49.5% for a 2.00x payout.
It ends the run itself with stop(reason): once the session is up 10,000 sats or down 20,000 sats. The reason text shows in the result strip and the console. 1 sat is 0.00000001 of the selected coin.
The script
Lua 5.4 with DiceBot-style globals. The top level runs once to set chance and the first nextbet, then dobet() runs after every roll. Every global is described in the Lua reference.
-- Fixed wager in sats, with a session guard and stop(reason)
-- The starting balance comes from Settings, not from the script: at the top level `balance`
-- IS the session bankroll. This template reads it in satoshis, refuses to start when it is
-- too small, bets a fixed number of sats, and ends the run with a reason you can read in
-- the result strip and the console. 1 sat = 0.00000001 of the selected coin.
chance = 49.5
bethigh = false
local WAGER_SATS = params.wagersats or 100 -- fixed bet, in satoshis
local MIN_BAL_SATS = params.minbalsats or 100000 -- need at least 0.001 of the coin to start
local TARGET_SATS = params.targetsats or 10000 -- stop once the session is up this much
local MAX_LOSS_SATS = params.maxlosssats or 20000 -- stop once the session is down this much
local startSats = Units.ToSats(balance)
print(string.format("session balance %.0f sats (%.8f %s), wager %d sats", startSats, balance, currency, WAGER_SATS))
if startSats < MIN_BAL_SATS then
-- Stops before the first roll: zero rolls, nothing wagered, balance and nonce untouched.
stop(string.format("needs at least %d sats, this session has %.0f", MIN_BAL_SATS, startSats))
end
nextbet = Units.FromSats(WAGER_SATS)
basebet = nextbet
function dobet()
nextbet = basebet
local pnl = math.floor(Units.ToSats(profit) + 0.5) -- whole sats (float noise would miss "== 10000")
if pnl >= TARGET_SATS then
stop(string.format("target reached: +%.0f sats after %d bets", pnl, bets))
elseif pnl <= -MAX_LOSS_SATS then
stop(string.format("loss limit: %.0f sats after %d bets", pnl, bets))
end
end
How it works
chance = 49.5andbethigh = falsewin on a roll below 49.5, paying 2.00x.- Four locals hold the settings in sats:
WAGER_SATS,MIN_BAL_SATS,TARGET_SATSandMAX_LOSS_SATS, each with aparamsoverride. - At the top level
balanceis the starting balance from Settings. The script prints it in sats and, if it is belowMIN_BAL_SATS, callsstop()with a message. That ends the run before the first roll: no wager is placed and no roll is consumed. nextbet = Units.FromSats(WAGER_SATS)converts the wager to coin, andbasebetis set to the same value.dobet()keepsnextbet = basebetand roundsprofitto whole sats. AtTARGET_SATSor above, or at-MAX_LOSS_SATSor below, it callsstop()with the profit and the number of bets.
Risk at a glance
Settings: 49.5% chance, 1% house edge, starting balance 0.001 (the template default, BTC in the simulator), base bet 0.000001 (balance / 1000.0000000000001).
A fixed wager never grows, so a losing run costs 100 sats per loss and the loss limit ends the session after 200 losses in a row from the start. Sessions normally end by drift over many bets instead. The tiles use the gambler's ruin formula for a bet that wins or loses exactly one wager, which holds at 49.5% and a 2.00x payout.
| Losses in a row | Chance of the streak | Result from a fresh start |
|---|---|---|
| 10 | 1 in 927 (0.108%) | Lost 0.00001 (1.0%), next bet 0.000001 |
| 50 | 1 in 6.8e14 (1.5e-13%) | Lost 0.00005 (5.0%), next bet 0.000001 |
| 100 | 1 in 4.7e29 (2.1e-28%) | Lost 0.0001 (10.0%), next bet 0.000001 |
| 200 | 1 in 2.2e59 (4.6e-58%) | Script stops. Lost 0.0002 (20.0%) |
Theoretical figures for a fresh start, not a simulation. The chance of N losses in a row is qN with q = 1 - chance / 100, the same formula the dice calculator uses. The stop loss and take profit figures are the gambler’s ruin formulas for a bet that wins or loses one base bet: with r = q / p, the chance of reaching the take profit first is (1 - rL) / (1 - rL+W), where L and W are the two thresholds in base bets. None of this changes the expected result: at a 1% house edge the average loss is 1% of the total wagered, whatever the progression.
Tuning it
Each setting below is read as params.name or default, so the script runs with the default until something passes a value in.
| Param | Default | What changing it does |
|---|---|---|
| params.wagersats | 100 | Bet on every roll, in sats. With the 100,000 sat default balance that is 0.1% of the bankroll. |
| params.minbalsats | 100000 | Smallest starting balance the script accepts, in sats. Below it the run stops before the first roll. |
| params.targetsats | 10000 | Session profit in sats at which the script stops. |
| params.maxlosssats | 20000 | Session loss in sats at which the script stops. |
The guard compares the Settings balance with MIN_BAL_SATS, so with the defaults the run only starts from 0.001 of the coin or more. Lower minbalsats or raise the starting balance in Settings; the script is not rewritten for you.
FAQ
Why does the run stop before the first roll?
The starting balance in Settings is below 100,000 sats (0.001 of the coin), so the script called stop() at the top level. No wager was placed and no roll was consumed. Raise the balance or pass a smaller params.minbalsats.
How likely is the loss limit compared with the target?
With the defaults the session has to move 200 wagers down or 100 wagers up. At 49.5% the loss limit comes first 86.7% of the time and the target 13.3%, over an average of 16,005 bets.
What do Units.ToSats and Units.FromSats do?
They convert between coin amounts and satoshis: Units.ToSats(0.000001) is 100 and Units.FromSats(100) is 0.000001. The script uses them so every threshold can be written as a whole number of sats.
Can I run this script in DiceBot or another Lua dice bot?
The script uses the global names from Seuntjie's DiceBot (chance, bethigh, nextbet, previousbet, win, dobet()). The params table only exists in DiceSim, so replace each params.name or value with the value before you paste it into another bot. It also reads Units.ToSats(), so check that your bot provides it. DiceSim itself never places bets on a casino.
Other scripts
Martingale
Doubles the bet after each loss and goes back to the base bet after a win.
- Chance
- 49.5%
- Type
- Martingale
Delayed escalation
Bets 3.35% for a 29.55x payout. Flat bets through 50 losses, then 4% more per loss.
- Chance
- 3.35%
- Type
- Dynamic scaling
Paroli 3-step
Doubles after a win, banks the profit after 3 wins in a row, resets on any loss.
- Chance
- 49.5%
- Type
- Paroli
Dynamic recovery
Sizes each bet so one win recovers the drawdown plus one base bet, capped at 10% of balance.
- Chance
- 33%
- Type
- Recovery
D'Alembert
Adds one unit after a loss and removes one after a win, never going below the base bet.
- Chance
- 49.5%
- Type
- D'Alembert
Labouchere
Bets the first plus the last number of a list. Wins cross numbers off, losses add one.
- Chance
- 49.5%
- Type
- Labouchere
Fibonacci
Bets follow the Fibonacci sequence: one step up after a loss, two steps back after a win.
- Chance
- 49.5%
- Type
- Fibonacci
Oscar's Grind
Plays in cycles that aim for +1 unit: same bet after a loss, one unit more after a win.
- Chance
- 49.5%
- Type
- Oscar's Grind
1-3-2-6
Bets 1, 3, 2 and 6 units on consecutive wins. Any loss, or the 4th win, resets to 1.
- Chance
- 49.5%
- Type
- Positive progression
Flat betting
Same bet on every roll, with a stop loss and a take profit at 10% of the starting balance.
- Chance
- 49.5%
- Type
- Flat betting
Martingale + vault
Martingale that moves half of every 1% profit step to the vault with vault().
- Chance
- 49.5%
- Type
- Martingale