Fair dice roller
Every roll on this site is generated in your browser by the same cryptographic generator used for security keys. Here is exactly how, so you can check rather than trust.
Ready to roll 1d20
Die
Quantity
Modifier
1d20 · Twenty-Sided Die
Generated locally in your browser
Results come from crypto.getRandomValues(), drawn with rejection sampling so no face is favoured. The number is decided before the animation starts, and nothing about the dice on screen can change it.
The generator
Most dice rollers use Math.random(). It is a pseudorandom generator: fast, perfectly adequate for a game, and explicitly documented as unsuitable for anything where predictability matters. Its output is determined entirely by an internal seed.
This site uses crypto.getRandomValues() instead, the browser’s cryptographic generator. It draws on genuinely unpredictable physical sources gathered by your operating system, and it is designed so that seeing past output tells an attacker nothing useful about future output. It is the same facility used to generate encryption keys.
Removing the bias almost everyone ships
Turning a random 32-bit number into a die roll is where most implementations go quietly wrong. The obvious approach is to take the remainder after dividing by the number of faces. The problem is that 232 does not divide evenly by six, so the lowest faces get one extra chance each and come up slightly more often.
The effect is far too small to see. That is exactly why it survives. We remove it with rejection sampling: any value landing in the uneven tail of the range is discarded and a fresh one drawn. The expected number of redraws is under two for every die we offer, so it costs nothing measurable.
The animation does not decide anything
This is the part worth being clear about. In a physics-driven roller it is tempting to let the simulation produce the result: tumble the dice, see where they land. That would make the result a product of the physics engine, which is not a random number generator and was never designed to be one.
Here the order runs the other way. The generator produces the number first, and the animation is then shown resolving to that number. The dice are a representation of a decision already made, which is why turning animation off changes nothing about the fairness of the outcome.
Nothing is sent anywhere
Rolls are generated on your device and stay there. No result is transmitted to a server, and there is no account, so your history, saved rolls and DM bags are stored in your own browser and nowhere else. This also means the roller works with no connection at all.
What we do not claim
We do not claim to have proven the output is random. Nobody can prove that from the outside, and any site that says otherwise is overselling. What we can tell you is the method, which is checkable, and that the code is tested: a suite of automated tests asserts that every die stays inside its range, that keep and drop rules keep the right dice, that modifiers apply once rather than per die, and that every probability distribution sums to 1.
Those tests catch programming mistakes, which is the failure that actually happens. They are not evidence of randomness, and we do not present them as such.
Compared to a physical die
A resin die from a game shop is very slightly unfair, because moulding, sanding and the pips on opposite faces all shift the weight a little. How dice are made covers why. Neither that nor this is worth worrying about at the table, but it is worth knowing that "physical" and "fair" are not the same word.
If the rolls simply feel wrong, that is worth reading about too. Why dice feel unfair works through why streaks are normal, and what randomness actually means covers the generator side in more depth.