Provably fair Ludo dice Fair by construction
Every Ludo Vest match commits to its entire dice sequence before the first roll and hands you the proof at the end. If we ever changed a roll, anyone could catch it.

Are Ludo Vest's dice rigged?
No, and you can check it yourself. Before the first roll the server publishes SHA-256 of a secret 32-byte seed; every roll is HMAC-SHA256(seed, "matchId:n") reduced to a face from 1 to 6 by rejection sampling, and the seed is revealed when the match ends. If any roll you were dealt does not recompute from the revealed seed, or the seed does not hash to the commitment, the match was tampered with.
Read next:Is Ludo rigged? The full walkthroughHow Ludo games compare on dice fairness
Last updated
The scheme
Commit, roll, reveal, verify
This is the whole thing. It rests on one property of a hash function: easy to compute forwards, infeasible to reverse.
- 1
Before the first roll
The server draws a secret 32-byte seed and publishes only its SHA-256 hash: the commitment. You have it before anyone touches the board.
- 2
Every roll is derived
Roll number n is HMAC-SHA256(seed, "matchId:n"), reduced to a face from 1 to 6. Your device never generates a number, and the server cannot pick one.
- 3
At the end, the seed
The match-end payload carries the seed and the full roll list. A live match never leaks its seed through the API. Only a finished one does.
- 4
You recompute it
Hash the seed and compare it to the commitment, then recompute each roll. If either disagrees, the sequence was not what we published.
Fair by construction
Don't trust us. Check.
Every match commits to its entire dice sequence before the first roll and hands you the proof at the end. If we ever changed a roll, anyone could catch it.
The whole scheme
commitment = SHA-256(seed) // published before roll 1
roll(n) = HMAC-SHA256(seed, id:n) // reduced to 1-6, no bias
seed // revealed when the match endsReduction discards any byte of 252 or above before taking it modulo 6, so all six faces are exactly equally likely rather than nearly so.
Committed, seeded dice
Before roll one the server draws a 32-byte seed and publishes its SHA-256. Every roll is HMAC-SHA256(seed, match:n), reduced to a face from 1 to 6 with no bias. The seed is handed to you when the match ends.
Server authoritative
Clients send intent: roll, move, play a card. The server produces every outcome and rejects anything not on the list of legal actions. A modified client gets an error, never a state change.
Tables too
Jackaroo decks and Dominos tiles are shuffled by the same committed scheme, every position exactly equally likely, the seed revealed at the end.
Money never reaches the board
Hearts, Gems, Gold and prestige are inputs to rewards and cosmetics, never to randomness. An undo re-draws a value that was already fixed.
Structural, not promised
Four things that are true by construction
These are not policies we intend to keep. They are properties of how the code is shaped.
The generator has two inputs
The match seed and the roll index. Not your level, your league, your spending, your prestige tier or your club. There is no code path from a wallet to a die.
The server decides everything
Clients send intent: roll, move, play a card. The server produces every outcome, so a modified client asking for an illegal move gets an error rather than a state change.
Actions are sequenced
Every broadcast carries a sequence number, and a move is checked against it. A stale, duplicated or replayed action is rejected and the real board is re-sent.
A live match never leaks its seed
The match endpoint returns the seed, the rolls and the event log only once the match is no longer active. Before that, nobody (including us) can read ahead.
Verification
How to check a match
A finished match returns its seed, its full roll list and its event log. You need three things from it, and about fifteen lines of code.
Step 1: Hash the revealed seed and compare it with the commitment you were shown before the first roll. If they differ, stop. Nothing else matters.
Step 2: Recompute each roll from the seed and the match id, and compare with what you were dealt. Both halves have to pass.
Step 3: There is also a public verification endpoint that does the same thing. It is useful for debugging your own implementation, but it is our server checking our claim. The version that protects you is the one you run.
Straight answers
The questions people actually ask
- Does spending change my dice?
- It cannot. The only inputs to the generator are the match seed and the roll index. Level, league, spending, win rate and club membership are inputs to rewards, never to randomness. There is no code path from your wallet to the dice.
- Why do losing streaks still happen?
- Because real randomness is streaky. Fair dice feel less fair than rigged ones precisely because nothing smooths them out. Over 60,000 rolls the six faces come out exactly equiprobable, which is asserted in the test suite, but 60,000 rolls is not a Tuesday evening.
- Why does the "modulo 6" detail matter?
- Taking a random byte modulo 6 makes faces 1 to 4 about 0.4% likelier than 5 and 6, because 256 is not divisible by 6. We discard every byte of 252 or above before reducing, so all six faces are exactly equally likely. It is a small bias, and it is exactly the kind of thing nobody would ever notice.
- Can an undo improve my luck?
- No, and this is the clearest test of the whole design. The sequence is fixed before the first roll, so undoing re-draws the next value from a list that was already determined. An undo buys you a different move, not a different die.
- What stops someone cheating with a modified client?
- Clients send intent (roll, move) and the server produces every outcome. An illegal move gets an error, never a state change. Moves also carry the sequence number of the board they were made against, so a stale or replayed action is rejected outright.
- Does anyone at the table get better dice?
- No. Every seat at a table plays from the one sequence committed before the first roll, in turn order, whoever is sitting there. A player's level, league, Vest & Crown tier, purchases and stake are not inputs to the dice: the generator reads only the match seed and the roll index.
