The Rise of Provably Fair Gaming: How Blockchain Is Changing Online Casino Design

If you've ever shipped a small browser game with a deadline you couldn't move, you've already met the random number problem. You wrote Math.random somewhere, called it good, and moved on to the part of the codebase that actually mattered. That's how most games handle it. For a 13-kilobyte JavaScript jam entry that nobody is going to bet money on, Math.random is genuinely fine. The dice land where they land. The shuffle does what a shuffle does. Nobody's auditing your seed.
The interesting question is what happens when somebody does want to audit the seed. When the game becomes an economic activity rather than a puzzle. When the stakes shift from a leaderboard spot to actual money on the table. That's where the engineering gets thornier, the libraries get heavier, and a cluster of techniques borrowed from cryptography starts showing up in code that used to be a single Math.random call. So it's worth pulling that thread for the kind of developer who reads this blog. Even if you never ship anything with money attached, the cryptographic moves are interesting on their own.
To pick one production example outside the jam scene, Shuffle crypto casino publishes its server seed hashes ahead of each round and reveals the seed afterward, which lets any user re-derive the outcome from publicly visible inputs. The platform restricts United States IP addresses at registration and operates under an offshore licence, so American readers cannot access it and any reference here is a technical example only, not a recommendation. We're including it because it's the most accessible public implementation of the commit-reveal scheme any js13k veteran would recognise from cryptographic primitives, and reading how the production version is structured can sharpen how you'd think about the same problem at thirteen kilobytes.
The Math.random Problem, Stated Properly
Math.random is fine until it's not. The JavaScript spec doesn't pin down the algorithm, which means different engines use different PRNGs. V8 currently ships an xorshift128+ variant. Some older engines used multiply-with-carry. The seed is opaque to the developer and the user, the state is opaque, and the only thing you can really say about Math.random is that it produces a sequence that looks random enough for a card-shuffle in a game jam entry. None of that is a problem for js13kGames. It is a problem if the same code ever runs in a setting where someone might want to verify the outcome. The verification problem is what cryptographic RNG schemes try to solve. The simplest version is a commit-reveal, where the server publishes a hash of its seed before the round, the player contributes a seed of their own, the outcome is derived from both, and after the round closes the server reveals the seed so the player can re-derive the result.
Why the Decentralized Category Keeps Coming Back
Look at the js13kGames archive for the past few years. The Decentralized category, summarised cleanly on js13kGames decentralized category entries from the 2024 contest, has produced some of the most technically interesting entries the contest has ever seen. Most of them aren't about money. Most aren't about casinos at all. They're about how a game can run trust-minimised between two browsers, or how a shared randomness source can be derived without a central server picking the outcome. That's the same intellectual problem provably fair gaming wrestles with. The contest entries solve it inside thirteen kilobytes, which is a brutal constraint, and that constraint is part of what makes the solutions worth reading. When a developer has to fit HMAC-SHA256 into a 13K bundle, every byte of the cryptographic primitive earns its place. Compare that against a production casino backend with megabytes of dependencies and you start to see the contest entries as a useful pressure-testing ground for ideas the wider industry hasn't fully internalised yet.
The Commit-Reveal Pattern in Plain Terms
Strip out the jargon and commit-reveal is straightforward. Server picks a secret string. Server hashes it with SHA-256 and publishes the hash before any game action happens. Player picks their own string and submits it. The round runs, with the outcome derived from concatenating both strings and hashing the result a fixed number of times. After the round closes, the server publishes its original string. The player runs the same hash function locally and confirms the result matches what the server claimed. If the server cheated by picking a different string after seeing the player's contribution, the published hash from before the round won't match the string the server tries to reveal. The cheat is mathematically detectable. The protocol is so simple it fits inside a single page of a developer notebook. The hard part isn't the cryptography. It's the engineering around it, especially key rotation, replay protection, and dealing with players who claim the server cheated when actually their own client clock is wrong.
Verifiable Random Functions and the On-Chain Move
Commit-reveal solves the trust problem for a two-party game but it doesn't scale neatly to many-player or fully decentralised settings. That's where verifiable random functions, VRFs, come in. A VRF lets one party generate a random output along with a proof that any other party can verify against a known public key. Chainlink shipped a production VRF for blockchain settings. Algorithms based on RSA and elliptic-curve cryptography have been studied since the late nineteen-nineties. The output is provably unbiased and provably tied to the input, which means a game can use the VRF output as its source of randomness without anyone having to trust the operator picking the seed. For a JavaScript developer that's appealing in theory and heavy in practice, because the libraries needed to verify a VRF proof inside a browser are non-trivial. None of that is going to fit in a 13K jam entry. It does suggest a direction the contest might explore in a year or two, especially if BLS or BN254-curve verification gets a tighter browser implementation.
Where the Real-World Casino Code Actually Sits
The production crypto-casino codebases that have published their RNG schemes don't usually use VRFs. They use the simpler commit-reveal pattern with HMAC-SHA256, an iteration counter for repeated rounds, and a server seed that rotates every few thousand rounds for forward-secrecy reasons. The architecture is closer to what a competent js13k veteran could ship in a weekend than to the chainlink-style VRF setup. That's a useful piece of intuition. The fanciest cryptography is not what makes provably fair work in practice. The boring engineering around key rotation, audit logging, and clear player-facing verification UI is what makes it work. The cryptographic primitive is the easy part. Anyone reading this who has ever debugged a hash mismatch in a save-game format knows the rest of the problem.
The Open-Source Verification Tools That Now Exist
Five or six years ago a player who wanted to verify a casino round had to write their own re-derivation script in Python or Node. That's no longer true. There are now a handful of browser-based verifier tools that let a player paste in the server seed, the client seed, the iteration number, and confirm the result locally without any server round-trip. Some of those tools are operator-published. Some are independent. None of them is more than a couple hundred lines of JavaScript. The interesting question for a contest like js13kGames is whether the verifier itself can be expressed in thirteen kilobytes, including the SHA-256 implementation. A minified SHA-256 in plain ES2020 sits around 1.5K to 2K depending on golfing tolerance. That leaves enough headroom for the rest of the verification UI. Someone is going to ship that as a 13K entry in a future contest, and it will be a useful artefact for the wider industry.
What the Paradigm Research Says About On-Chain Randomness
Outside the contest scene, the most useful single piece of writing on cryptographic RNG in the past few years is Paradigm research on secure on-chain RNG which walks through SNARK-based randomness generation for Ethereum settings. It is not light reading, and it is not directly applicable to a browser game jam entry, but the framing it brings is exactly the framing a thoughtful gamedev should bring to the same problem. What is the threat model? Who is the adversary? What can they manipulate, and what can they only observe? Once a developer answers those three questions cleanly, the choice between Math.random and HMAC-SHA256 and a full VRF becomes mechanical. The Paradigm piece treats the question as a security-engineering problem first and a cryptography problem second. That's the right way around for anyone building a small game with any kind of stake attached, and the framing transfers neatly to non-blockchain code too.
A Side-By-Side Look at RNG Choices for Small JS Games
The table below stacks the five randomness sources a JS developer is most likely to consider in 2026, their typical use case, what they cost in bundle size or compute, and what their verification story looks like for a third party trying to confirm the result.
| RNG Source | Typical Use Case | Bundle or Compute Cost | Verification Story |
|---|---|---|---|
| Math.random | Game jams, prototypes, non-stake play | Free, built into the engine | None, opaque seed and state |
| Mulberry32 or xoshiro128 | Seeded replays, level generation | Tens of bytes of code | Replay-only, no third-party proof |
| HMAC-SHA256 commit-reveal | Two-party games with light stake | Around 2K minified | Player can re-derive after the round |
| Verifiable random function | Many-party decentralised settings | Significant browser-side proof work | Anyone can verify against public key |
| External oracle randomness | Production stake-bearing games | Network round-trip cost | Trusted oracle plus audit log |
Choice depends on threat model. For a contest entry the answer is almost always Math.random. For anything that will hold actual stakes, commit-reveal is the floor and a VRF is the ceiling, with the practical decision sitting between those two based on what verification UX you can afford to ship inside the browser bundle.
What All of This Means for the Next js13kGames Cohort
So where does that leave the developer about to start work on a Decentralized-category entry for the next contest? Probably with a smaller, sharper version of the same engineering decisions a production casino makes, compressed into thirteen kilobytes. The good news is that the contest format forces clarity. You don't have room for a generic cryptography library. You have to pick which primitive earns its bytes. That constraint produces some of the most readable implementations of these schemes anywhere on the web, which is part of why the decentralised category keeps drawing strong entries. The bad news is that the verification UI is where most entries fall down. A player who can't easily check the result will not trust the result, no matter how clean the cryptography. So the design problem for the next great contest entry probably isn't a fancier RNG. It's a verifier that fits inside the bundle and explains itself to a non-cryptographic player in under five seconds. Whoever solves that wins the category, and the broader industry will quietly borrow the approach the way it always does when js13kGames produces something genuinely new. That's the loop that makes the contest interesting beyond its surface novelty.
🔙 Back to Articles list.