Dice roller

Any number of dice, any number of sides, drawn without the modulo bias that makes a naive twenty-sided die 8% unfair — with the exact distribution of the total underneath. Nothing you type here leaves your browser — it is worked out on your own device, so there is nothing to send and nothing to log.

This page will not fall back to Math.random(). Everything here is drawn from crypto.getRandomValues(), which the browser backs with the operating system's cryptographic source. If that is unavailable the page says so and produces nothing — because output from a weak source looks exactly like output from a strong one, and that is the whole problem.

Why this rejects numbers instead of taking a remainder

The obvious way to turn a random byte into a die roll is byte % 6. It is also biased, and by more than people expect.

A byte holds 256 values. 256 is not a multiple of 6: it is 6 × 42 + 4. So four of the faces get 43 of the 256 values and two of them get 42 — the favoured faces come up 2.381% more often, for ever.

Range256 splits as Favoured by
1–66 × 42 + 42.381%
1–1010 × 25 + 64.000%
1–2020 × 12 + 16 8.333%
a card, 1–5252 × 4 + 48 25.000%
1–100100 × 2 + 56 50.000%

Fifty per cent, from one line of code that looks perfectly sensible. And notice the trap: a range that is a power of two has no bias at all, so anyone who tests with 1–16 or 1–256 finds nothing wrong.

The fix is to throw away the ragged tail. Draw a value, and if it falls in the part of the range that does not divide evenly, discard it and draw again. That is what this page does, and it is why the answer is not merely nearly fair.

Math.round is not how you roll a die either

Math.round(Math.random() * 6) is the other common attempt. It returns seven different values — 0 to 6 — because rounding sends everything below 0.5 to zero. And the two end values sit in half-width buckets, so 0 and 6 each come up half as often as 1 through 5.

Random does not mean uniform

One die is flat: every face equally likely. The moment you add dice together it stops being flat, and people who expect otherwise design games badly.

Three six-sided dice have 216 outcomes. A total of 10 or 11 can happen 27 ways each; a total of 3 or 18 can happen exactly one way. The middle is twenty-seven times as likely as the ends. That is why 3d6 feels so different from a single d18, even though both run from 3 to 18.

The table under your roll is the exact distribution, counted rather than simulated.

Where the randomness comes from

From crypto.getRandomValues(), backed by the operating system. If that is missing this page produces nothing rather than falling back to Math.random(), and nothing here is a physical die: real dice have drilled pips, so the six face is lighter than the one, which is why casino dice are filled flush.

Where to go next