Fair Backgammon

How the dice are proved fair

The claim is narrow and it is checkable: every roll of the match is decided before the first move, and neither the computer nor the app can change one afterwards.

Card and dice games have a credibility problem, and it is earned. Read the reviews of any popular one and you will find the same sentence in a hundred variations: the computer gets the good hands. Most of the time it is not true. There is no way for the player to find out, which is exactly why the suspicion never goes away.

This game answers it with a method borrowed from online gambling regulation, where the same problem had to be solved for money. It is called commit-reveal.

The three steps

1. Before the game: the commitment

The app generates a random server seed and immediately shows you SHA-256(server seed) — a fingerprint of it. The seed itself stays hidden. A fingerprint cannot be reversed, so it tells you nothing about the dice; but it is fixed, so the app cannot change the seed later without the fingerprint changing.

2. During the game: your own seed

You may supply a client seed of your own — any text. It is mixed into every draw. Because you chose it after the commitment, the app could not have tailored the seed to it. If you leave it alone a default is used, and the guarantee is weaker but the method is the same.

3. After the game: the reveal

The app shows the server seed. You check that its fingerprint matches the one you were given at the start, and you recompute every roll from it. If they match, the game could not have chosen them as it went along.

How a roll is derived

The stream is HMAC-SHA256(server seed, "client seed:n"), with n counting up. Bytes are taken from that stream and turned into numbers by rejection sampling: a value that falls outside the usable range is thrown away rather than folded back with a remainder. Folding it back with % would make the low numbers very slightly more likely — a bias too small to notice and too real to leave in a game whose whole claim is that it is not biased.

The position in the stream is stored as a byte offset, not a counter of draws. That means a game closed halfway through resumes on exactly the same roll, and it means anyone checking the result does not need to know how many bytes each draw happened to consume.

What this does and does not prove

It provesIt does not prove
The dice was fixed before play started That the game is fun, or that the opponent is strong
Nothing was changed once play began That the random source is unpredictable to someone who has the seed
The opponent had no advance knowledge Anything about a game you did not check

The point is that you do not have to take our word for it. The check is arithmetic anyone can repeat, and the app shows you every number it used.

The rule behind it

There is one rule this whole project is built on: a harder opponent plays better, it never gets better rolls. The levels differ in how far ahead they look and nothing else. That is not a promise in a marketing page — the test suite refuses to build if any part of the opponent can see the random source, and it checks over tens of thousands of games that the levels get the same distribution.