Open source · MIT · offline · zero-dependency. The crypto core is one shared engine (originals-verify); each game adds a pure resolver.
Every Originals game draws its randomness from one frozen recipe (uint32 words — this differs from the Lucky Spin wheel, which uses uint64 words + rejection sampling):
commitment = SHA-256(serverSeed) # lowercase hex, shown before any bet
for cursor = 0, 1, 2, …: # advance when a game needs more words
digest = HMAC-SHA256(key = serverSeed, msg = `${clientSeed}:${nonce}:${cursor}`) # 32 bytes
consume 4 bytes at a time, big-endian, as uint32 words # u ∈ [0, 2^32)
The server publishes commitment before you bet and reveals serverSeed only
when the seed is rotated. Settlement compares integers derived from the words — no floating point.
Money is integer minor units; a payout is floor(bet × multiplier_e8 / 1e8).
?game=<id>&server=<seed>&commit=<hash>&client=<seed>&nonce=<n>¶ms=<enc>
— it reproduces the outcome entirely in your browser.serverSeed /
clientSeed / nonce / params, and press Verify. View source to confirm nothing leaves your machine.npm test (node verify.js --selftest) — it
reproduces the published known-answer vectors, which were generated by the operator's authoritative Python.Each game's odds are published at paytables/<game>.json (the analogue of Lucky Spin's
weights.maczo.json). The resolver reads only those tables — it never recomputes them — so
the odds you see are the odds that settled your bet. Two bias classes are documented per game:
modulo (a uint32 reduced by modulo; documented-negligible bias < ~1e-5) and uniform
(Fisher-Yates / without-replacement draw; no modulo bias).
Before the seed is revealed the verifier can still check the commitment (that the operator was
committed to a fixed serverSeed), but it cannot reproduce the outcome — the deep-link shows
“awaiting reveal”. After you rotate your seed (or the operator rotates theirs), the revealed
serverSeed is the exact HMAC key, and the full outcome reproduces offline.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve roll = u mod 10000 (0.00–99.99); multiplier = floor(10000·rtp / winning_outcomes).
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve crash_e8 = floor(rtp·2^32 / (2^32 − u)), clamped to [1.00×, 1,000,000×]; win iff crash_e8 ≥ target_e8; multiplier = target.
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve bomb-set = Fisher-Yates shuffle(25) driven by the uints, first `mines`; win iff no pick is a bomb; multiplier = rtp·∏(25−i)/(25−mines−i).
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve for each of `rows` pegs one bit of the stream (u & 1) is right; bucket = count of rights; that bucket's multiplier pays.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve flip_i = ['heads','tails'][u_i mod 2]. Parlay {side,flips}: win iff all match, mult = rtp·2^flips. Streak {guesses}: bust at first wrong, mult = rtp·2^wins.
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve Fisher-Yates shuffle(40) → first 10 drawn; multiplier = perHit[matches] where spots = len(picks).
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve slot = u mod segments; the fixed arranged[slot] multiplier pays. The arrangement is deterministic per (risk,segments).
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve per row: shuffle(tiles) → first `eggs` are eggs; climb while the picked column is safe; multiplier = rtp·tiles^k/(tiles−eggs)^k.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve card_i = (u_i mod 13, (u_i div 13) mod 4), ace low. Guess hi/lo/same; edge cards use strict hi/lo. multiplier = rtp·13^k / ∏ win_counts.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve gem_i = u_i mod 7; multiplicity pattern (sorted desc, joined by '-') selects the multiplier; e.g. '2-1-1-1' = one pair.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve landed_e8 = floor(rtp·2^32/(2^32−u)) clamped [1.00×,1e6×]; win iff landed ≥ target; multiplier = target. Same model as Limbo.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve pocket = u mod 37. Each bet's multiplier = floor(37·rtp / |winning pockets|); straight = {number}. Felt bets settle per stake_minor against the one pocket.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve cards dealt (value = rank+1 if rank≤8 else 0, from u mod 13); standard third-card rules pick the winner. tie mult = rtp·pScale/P(tie); player/banker mult = (rtp·pScale − P(tie)·1e8)/P(side), push on tie.
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve death-set = shuffle(20)[:deaths]; cross lanes 0..k−1 until a death index is hit; multiplier = rtp·∏(20−i)/(20−deaths−i).
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve crash_e8 = floor(rtp·2^32/(2^32−u)) clamped [1.00×,1e6×]; win iff crash ≥ cashout; multiplier = cashout.
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve 24 ranks drawn (u mod 13); player=[0,2] dealer=[1,3]; hit/stand/double; dealer draws to 17. Fixed pays: lose 0, push 1×, win 2×, blackjack 2.5×; double ×2; insurance +1.5× on dealer natural.
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve deck = shuffle(52); deal order[:5]; holds keep, others draw from order[5:]; final 5-card hand pays payoutMultiplier[category]× (multiplier_e8 = that × 1e8).
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve deck = shuffle(52); player = [0..2], dealer = [3..5]; 3-card ranks (SF>trips>straight>flush>pair>high). Play or fold; settle ante/play + ante bonus. multiplier_e8 = total return per ante.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve house_i = ['rock','paper','scissors'][u_i mod 3]. Auto {guesses}: any loss zeroes, else mult = rtp·2^wins (ties ×1). Ladder {throws}: bust at first loss, ties replay. Legacy {throw}: win = 3·rtp−1×, tie push.
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve pop-set = shuffle(25)[:pops]; pump slots 0..k−1 until a pop index is hit; multiplier = rtp·∏(25−i)/(25−pops−i).
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve slot = u mod 1,000,000; walk cumulative weights (cum) to the tier; that tier's multiplier pays.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve distance_u = uints[0]; region = first i with distance_u < thresholds[i]; that region's multiplier pays. rotation_u = uints[1] is visual only.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve middle draws MAJOR by CDF over (u0 mod 9800); left/right draw MINOR over (u1,u2 mod 10000). multiplier_e8 = rtp·middle·left·right·1e8 / (99e6·100^3). ids: u3..u5 (display only).
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve each of 5 cards: tier = first index t with u ≤ thresholds[t] (bisect_right); card multiplier = tiers[t].cardE8; pack multiplier = sum of the 5.
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve per row: shuffle(7)[:moles] are moles; whack a hole WITH a mole to climb, an empty hole busts; multiplier = rtp·7^k/moles^k.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve 3 lanes each draw a Limbo multiplier lane_i = floor(rtp·2^32/(2^32−u_i)); your shape's lane must reach target; multiplier = target.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve die = 1 + u mod 6 (two per roll); tile value by sum (mirror s→14−s, snake sums pay 0); after the first roll the lowest tier upgrades. multiplier_e8 = rtp·∏tiles_e3·1e8/(99e6·1000^k).
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve each of 30 cells: slot = u mod 1e6, tier via cumulative weights (cum), value = perPicks[K][tier] (K = number of picks). payout multiplier = sum over picked cells.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve 15 cells drawn by weight (index 0 rarest-last); each of 3 rows pays its left-aligned run≥3 of matching symbols via runMultiplierE8[symbol][run]; rows add up.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve cells drawn by weight (reel-major); left-aligned line pays with WILD substitution (wild has its own paytable, substituted combos may double); scatter pays by count; ≥fsTrigger scatters trigger free spins. multiplier_e8 = floor(scale · rel · 1e8) with rel a rational over the active line count.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve cells drawn by weight (reel-major); left-aligned line pays with WILD substitution (wild has its own paytable, substituted combos may double); scatter pays by count; ≥fsTrigger scatters trigger free spins. multiplier_e8 = floor(scale · rel · 1e8) with rel a rational over the active line count.