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.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve one uint32 word per attempted rung: rung i lands iff (u_i mod 1000) < c_i, the player's chosen win-count for that leap (c in [50, 950], at most 15 rungs). The climb ends at the first miss; a bust — and a 0-rung round — pays nothing. A full climb of k rungs pays a SINGLE floor of the fair product: multiplier_e8 = floor(rtp_e8 · 1000^k / (c_1·…·c_k)), so every rung's fair factor is exact and the edge is charged once.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve u0 mod 1,000,000 walks the risk tier's cumulative prize weights to a prize face (e8, already a multiple of 8); u1 mod 1,000,000 walks GRIP the same way to a grip numerator f of 8; multiplier = prize_e8 · f // 8.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve each throw is two dice from the stream (die = 1 + u mod 6, 2 uints per throw, throw 0 = the come-out); field/any_seven/any_craps settle on the come-out alone, pass/dont_pass then walk the same stream from throw 1 until the point or a 7 shows (cap nPairs throws → stake back); every multiplier is read from the baked multsE8, and a push pays exactly 1.00x (not a win).
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve rocks = the first B of others[perm[i]], where others = the 15 non-start cells and perm = shuffle(15) (so the rock subset is uniform over C(15,B) and the start is always open); water floods the connected open region containing the start over the 4x4 adjacency, and the flooded size indexes the baked (density, start-class) e8 ladder.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve cell_i colour = u_i mod C (C = 2/3/4/5 by difficulty); flood-fill the 3×3 comb over the 12 undirected edges and take the SIZE of the largest same-colour cluster (ties keep the lowest-rooted one); multiplier_e8 = tableE8[size−1], the published ladder — an exact-rational rescale of the frozen base shape against the exact size distribution (sizeCounts over C^9 grids) so EV == rtp before a single floor. Small sizes are baked 0 = loss.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve species_i = u_i mod S (S = 4..8 by difficulty); a brand-new species climbs, the FIRST repeat busts; d distinct species pay multiplier = floor(rtp * S^(d-1) * (S-d)! / (S-1)!) — read off the baked fairNumer[d]/fairDenom ratio (== ladderE8[d] at the published RTP).
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve each of the `shots` words MAKES iff u < threshold (threshold = pct*2^32 // 100, so the make chance is exactly threshold/2^32, NOT pct/100); the make count then indexes the baked per-(range,shots) e8 ladder — 0 below floorMakes, a 9/5 geometric rise above it and a x4 jackpot kick on a perfect run, exact-rationally rescaled against the exact binomial so the ladder returns the published RTP.
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve one uint32 per played floor gives r = u mod D (D = 8 divides 2^32, so the reduction is exactly uniform — zero modulo bias); the lean survives iff r is in that side's baked w-residue window (left {0..w-1}, right {D-w..D-1}), the window's dead-centre residue is a 'perfect' that keeps the width while any other catch trims it to nextEdge (min 1), and the multiplier is one floor over the baked per-floor odds: floor(rtp · ∏ stepNum / ∏ stepDen) = rtp·D^k // (w_1·…·w_k).
Bias class uniform — maps words without a biased modulo reduction (bit extraction, or a uniform Fisher-Yates / without-replacement draw) — no modulo bias.
Resolve sinker-set = Fisher-Yates shuffle(15) driven by the 14 uints, first D entries (== derive_bomb_set); each leap of j clears stones [reached..reached+j-1] all-or-nothing and busts the round if ANY of them is a sinker (no partial credit); the multiplier depends only on the total stones cleared k: floor(rtp · odds[k].num / odds[k].den) = rtp · C(15,D)/C(15-k,D).
Bias class modulo — reduces a uint32 by modulo, carrying a documented-negligible bias (< ~1e-5).
Resolve die = 1 + u mod 6 for each of 3 words -> one of 216 equally-likely ordered rolls; a flat bet pays floor(216·rtp / winCount[bet][pick]) and Single pays (matches+1)·floor(216·rtp / singleWeight).