Fairness
OPDuel Originals
Limbo
Plinko
Keno
Roulette
Mines
Blackjack
Roll
Dice
Provably Fair Plinko
Drop a ball through a field of pegs and watch it bounce left or right at each row. The final bucket determines your multiplier. Choose between 8-16 rows and three risk levels (Low, Medium, High) to control the payout spread.
Verify Game Fairness
The Algorithm
// Step 1: Generate one float per row
const floats = [];
let round = 0;
let byteIndex = 0;
let hash = [];
while (floats.length < rows) {
if (byteIndex === 0 || byteIndex >= 32) {
const message = `${clientSeed}:${nonce}:${round}`;
hash = HMAC_SHA256(serverSeed, message);
byteIndex = 0;
round++;
}
const bytes = hash.slice(byteIndex, byteIndex + 4);
let float = 0;
for (let i = 0; i < 4; i++) {
float += bytes[i] / Math.pow(256, i + 1);
}
floats.push(float);
byteIndex += 4;
}
// Step 2: Generate path (0 = left, 1 = right)
const path = floats.map(f => Math.floor(f * 2));
// Step 3: Calculate bucket (sum of rights)
const bucketIndex = path.reduce((sum, dir) => sum + dir, 0);
// Step 4: Look up multiplier
const multiplier = MULTIPLIERS[rows][risk][bucketIndex];How It Works
- Generate floats - Create one random float per row. Each float uses 4 bytes. Games with more than 8 rows require multiple hash rounds.
- Determine directions - Each float is multiplied by 2 and floored:
- Result 0 = ball goes Left
- Result 1 = ball goes Right
- Calculate bucket - The final bucket is simply the count of right moves. With 8 rows, there are 9 possible buckets (0-8). Bucket 0 means all lefts, bucket 8 means all rights.
- Look up multiplier - Each row count and risk level has a fixed multiplier table. Edge buckets (0 and max) are rarest and have the highest multipliers.
Multiplier Tables
8 Rows
| Bucket | Low | Medium | High |
|---|---|---|---|
| 0, 8 | 5.6x | 13x | 35x |
| 1, 7 | 2.1x | 3x | 3.2x |
| 2, 6 | 1.1x | 1.3x | 1.4x |
| 3, 5 | 1x | 0.7x | 0.3x |
| 4 | 0.4x | 0.3x | 0.2x |
16 Rows
| Bucket | Low | Medium | High |
|---|---|---|---|
| 0, 16 | 16x | 110x | 1000x |
| 1, 15 | 10x | 41x | 130x |
| 2, 14 | 2x | 10x | 26x |
| 3, 13 | 1.4x | 4x | 9x |
| 4, 12 | 1.4x | 2x | 4x |
| 5, 11 | 1.2x | 1.1x | 2x |
| 6, 10 | 1.1x | 1x | 0.7x |
| 7, 9 | 1x | 0.5x | 0.4x |
| 8 | 0.4x | 0.2x | 0.2x |
Higher risk = bigger edge multipliers but lower center payouts.
Example
Given these inputs:
- Server Seed:
c5e7146c5863d7d647c93ffe7d4ec13fffbb7311108fab0c067d97bcc2b32d55 - Client Seed:
LuckyClientSeed777 - Nonce:
32 - Rows:
16 - Risk:
HIGH
16 rows needs 64 bytes (2 hash rounds). The path is determined row by row:
| Row | Float | × 2 | Direction |
|---|---|---|---|
| 1 | 0.502218 | 1.00 → 1 | Right |
| 2 | 0.537929 | 1.08 → 1 | Right |
| 3 | 0.842274 | 1.68 → 1 | Right |
| 4 | 0.009487 | 0.02 → 0 | Left |
| 5 | 0.739272 | 1.48 → 1 | Right |
| 6 | 0.822282 | 1.64 → 1 | Right |
| 7 | 0.574863 | 1.15 → 1 | Right |
| 8 | 0.502282 | 1.00 → 1 | Right |
| 9 | 0.186113 | 0.37 → 0 | Left |
| 10 | 0.941259 | 1.88 → 1 | Right |
| 11 | 0.552208 | 1.10 → 1 | Right |
| 12 | 0.699841 | 1.40 → 1 | Right |
| 13 | 0.943747 | 1.89 → 1 | Right |
| 14 | 0.511669 | 1.02 → 1 | Right |
| 15 | 0.815651 | 1.63 → 1 | Right |
| 16 | 0.863896 | 1.73 → 1 | Right |
Path: R R R L R R R R L R R R R R R R → 14 rights → Bucket 14. With HIGH risk on 16 rows, bucket 14 pays 26x.

