Fairness
The bot rolls the dice, so you have every reason to want proof rather than a
promise. Here is the proof, and how to check it without trusting us.
What is actually in doubt
Not the quality of the random numbers. They come from the operating system's
cryptographic source, and we measure them: a million rolls of 1–100 land
exactly where a fair die lands, neither player in a duel wins more often
than the other, and no roll gives away the next.
The real question is different, and fair to ask of any bot: could
whoever runs it make it roll a 1 for you? Measurements cannot
answer that. A rigged bot would post the same cards as an honest one. So
every game of chance here commits to its numbers before they are known, and
publishes the secret behind them afterwards.
How a game is played, from the proof's point of view
-
Before play, the bot commits. It draws a secret, and
posts a fingerprint of it — a SHA-256 hash — on the challenge card, below
the buttons, before anybody has accepted. The numbers are fixed from that
moment, though nobody can read them yet.
-
You contribute. When a player accepts, their click
supplies a second value, published on the next card. The bot could not
have known it when it committed — which is what stops it drawing secrets
over and over until one pays out.
-
Every number carries its range, and its place in the order.
Each roll is sealed into the channel showing what it was rolled from —
rolled between 1–42 — and they appear in the order they were
drawn, so the first is draw 1. The proof panel says how many draws there
were, so a number generated and quietly thrown away would leave the count
higher than the rolls you can count.
-
When the game ends, the secret is published. Every
ending — someone wins, a challenge is declined, an organizer clears a
stuck game. Anyone can now hash the secret, compare it with the
fingerprint posted before play, and recompute every roll.
A plain roll
/roll dice and /roll dice max:48484 are one instant each —
there is no challenge card to commit on before anybody plays. So each roll's
card carries the fingerprint for the next roll in that channel,
under next roll here. When somebody rolls, the bot uses that
secret, takes the id of their /roll dice as the player seed, draws
one number from 1 to the max, and publishes the secret on the new card.
To check one, follow the link on its card to the card before it. The
fingerprint printed there must match the hash of the secret this card
reveals, and it must have been posted before this roll — Discord's
own timestamps say so. The number is draw 1, over 1 to the max
printed beside it.
The first roll in a channel cannot be checked, because no
card came before it. Its card says so instead of showing a link, and so does
any roll whose card-before landed after the roller pressed. A raffle host
who wants every roll provable can make one throwaway roll first.
The method, in full
Published because a proof you can only check on our website is not a proof.
Each number is:
block(n, c) = HMAC-SHA256(key = secret,
message = "<game>:<code>:<player seed>:<n>:<c>")
value(n) = walk block(n, 0) four bytes at a time, big-endian, then block(n, 1), …
take the first word below floor(2^32 / range) * range
value = (word mod range) + min
n is the draw number and range is
max - min + 1 for the range printed beside the roll. The
rejection step — skipping words at or above that limit — is what keeps the
result even; reducing a 32-bit number into a range that does not divide it
would quietly favour the low end.
Checking a game yourself
Every result card carries a 🔒 Provably fair button. Press
it and the bot shows you — privately — the commitment, your seed, the
revealed secret and the commands below. /verify code:K4M2QP
prints the same thing for any game, at any time.
If you would rather not take the bot's word for its own arithmetic, these
are the two commands, and they need nothing but OpenSSL:
# 1. does the secret match the fingerprint posted before play?
printf '%s' "$SECRET" | openssl dgst -sha256
# 2. does draw #1 follow from it? (range 1-100, as printed beside the roll)
printf '%s' "deathroll:K4M2QP:<player seed>:1:0" \
| openssl dgst -sha256 -mac HMAC -macopt hexkey:"$SECRET"
Take the first four-byte group of that output, read as a big-endian number.
If it is below floor(2^32 / 100) * 100, then
(word mod 100) + 1 is the roll. Otherwise skip to the next four
bytes.
What this proves, and what it does not
| Proves | Does not prove |
| The numbers came from a secret fixed before anyone knew the outcome. |
That the game is a good bet. That is what the odds below are for. |
| No roll was swapped, and none was generated and discarded. |
That the operator is honest in every other way — they can still refuse
to run games, or switch the bot off. That is visible, at least. |
| The player's contribution was fixed before any roll was made. |
Anything about a game that never finished. An unpublished secret
proves nothing, which is why unfinished games are counted openly. |
The odds, published
Death Roll is not a symmetric game, and pretending otherwise would be its
own kind of dishonesty. The player who rolls first is more likely to
lose, because they face the full range before it collapses:
| Starting number | Chance the first roller loses |
| 2 | 66.7% |
| 6 | 52.4% |
| 100 (the default) | 50.01% |
| 1000 | 50.0001% |
Which is exactly why the order is drawn rather than given to the
challenger: both players get the same coin flip for a seat that is not
equal. Win the roll-off and you have, very slightly, drawn the short straw.
Games nobody finishes
A duel with no roll for a day is closed by the bot. Nothing
settles — no score moves, no result is recorded against anyone —
but the secret is published, so the rolls that did happen can still be
checked. A challenge nobody accepts is closed the same way.
This exists because of the promise above: a game that hung open forever
would be one whose secret was never published, and "every game can be
checked" would quietly stop being true. Walking away from a duel costs you
nothing here — it simply cannot leave an unfinished proof behind.
Games played before this existed
They have no commitment and cannot be checked. Nothing is being hidden —
there is simply nothing to check, and claiming otherwise would be the exact
dishonesty this page exists to avoid.