Provably fair, by construction.
We don’t ask you to trust us — we let you check the math. The starting board for every game on the platform — Maze, Candy, Blocks, Snake, Coins, and Bubble — is derived from a seed produced by a server-seed commit-reveal protocol. You can verify any historical game in 30 seconds with the snippet below.
Commit before the match
When the terminal locks in, the platform publishes sha256(serverSeed). The server seed itself stays sealed until after the match — for every game type.
Client seed is the player set
The client seed is the sorted list of player ids in the terminal plus the game type. It's public the moment the lobby fills, so we can't swap players or change the game unnoticed.
Seed = sha256(serverSeed | clientSeed | nonce)
After the match the platform reveals the server seed. Re-derive the seed yourself, regenerate the board (maze layout, candy grid, block queue, coin/food placement, or bubble grid), and compare it to the one you played.
What this protocol prevents
The server seed is committed before any player set is known — for the maze, the candy grid, the block queue, the coin/food positions, and the bubble grid. We can’t grind seeds to land a layout that favours anyone.
The revealed server seed must hash to the commitment published up front. The operator can’t substitute a different seed after the fact.
The client seed is the sorted set of player ids, fixed when the lobby fills. Adding or removing a player changes the seed and invalidates the proof.
Every finished game publishes its revealed server seed in the match proof. No reveal, no valid result.
Verify a match yourself
Each finished game exposes its proof at GET /games/<id>. Drop the snippet below into a Node REPL with @maze/provably-fair installed:
import {
verifyServerSeedCommit,
deriveGameSeed,
fromHex,
} from '@maze/provably-fair';
const r = await fetch(`https://rivalskills.com/api/games/${id}`);
const { proof, vrfSeed } = await r.json();
const serverSeed = fromHex(proof.serverSeed); // revealed after the match
const commit = fromHex(proof.seedCommit); // published before it started
// 1) The revealed server seed hashes to the commitment shown up front
console.assert(
verifyServerSeedCommit(serverSeed, commit),
'commit mismatch'
);
// 2) The maze seed equals sha256(serverSeed | clientSeed | nonce)
const derived = deriveGameSeed({
serverSeed,
clientSeed: proof.clientSeed, // sorted player ids, public
nonce: 0,
});
console.assert(
Buffer.from(derived).equals(Buffer.from(fromHex(vrfSeed))),
'seed mismatch'
);
console.log('OK — match was provably fair.');Want to dig deeper?
- Commit-reveal:
packages/provably-fair/src/index.ts— the server-seed / client-seed / nonce scheme, fully unit-tested. - Maze generation: deterministic Wilson’s algorithm seeded by mulberry32. Given the same seed, client and server produce byte-identical mazes.
- Candy / Blocks / Snake / Coins / Bubble: each engine lives in its own package (
@maze/candy-engine,@maze/blocks-engine,@maze/snake-engine,@maze/coins-engine,@maze/bubble-engine) and pulls its initial state from the same mulberry32 PRNG seeded by the verified game seed.
Notice a discrepancy in any historical match?
Tell us — we’ll publish the audit