How all eight Swivel original games decide their outcomes, what a player can independently check, and where we currently fall short of the claim.
"Provably fair" means a player can mathematically confirm we didn't rig their result — not because we say so, but because they can recompute it themselves. Swivel runs two different systems to do this: one for multiplayer games (Crash, When Moon Bro, Chart) and a separate one for single-player games (Roulette, Dice, Limbo, Hi-Lo, Wheel of Fortune). The multiplayer system is built on the right foundations but is weakened by how we rotate seeds in practice. The single-player system produces genuinely fair, deterministic results, but a player currently has no way to independently prove that — the information needed to check it is never published. This document explains both, and what we'd change.
The promise is not "our random numbers are good quality". It's stronger: the result was fixed before you bet, and you can prove it afterwards without trusting us. Every implementation of it follows the same three beats:
Before any bet, we publish a fingerprint of a secret value. The fingerprint reveals nothing about the secret, but it locks us in — we can't change the secret later without the fingerprint changing.
Each result is computed from that secret, combined with a value the player controls and a counter. Same inputs always produce the same result — no randomness at the moment of the bet.
Once the secret is retired, we publish it. Anyone can then fingerprint it themselves, confirm it matches step 1, and re-run every result from it.
Remove step 3 and the whole thing collapses into "trust us" — which is exactly the failure mode described in §7. Our public game rulebooks make the full promise to players, so the bar we're measured against is the three-step version.
Which system applies depends on whether a game resolves one player's bet instantly, or resolves one shared round for everyone at once.
| Single-player system | Multiplayer system | |
|---|---|---|
| Games | Roulette, Dice, Limbo, Hi-Lo, Wheel of Fortune | Crash, When Moon Bro, Chart |
| Where randomness comes from | A seed pair unique to each player — our server seed plus their client seed — and a bet counter that increases with every bet | A long chain of hashes generated in advance and shared by everyone; each round consumes exactly one link |
| Can the player influence it? | Yes — they choose their own client seed at any time | No, and by design: the shared seed comes from a future public event nobody controls |
| What's published in advance | An encrypted copy of the server seed | A public seeding post committing to the chain's first hash, plus the future block whose hash becomes the shared seed |
| Is the secret ever revealed? | No | No — the chain's origin value is discarded at generation |
| Can a player verify a result today? | Not independently | Partly — the chain proves itself, but rotations break it |
| Verification tool in product | None | A "Check" link per round, hosted externally |
Each player permanently holds two seed pairs: the active pair producing their results right now, and a future pair already generated and committed, waiting for them to switch. Both are visible in the game's Fairness panel.
| Ingredient | What it is | Who sets it |
|---|---|---|
| Server seed | A random secret we generate. The player sees only an encrypted form of it. | Swivel |
| Client seed | A short text value, 5–64 characters. Randomly generated for the player, who can replace it with anything they like. | Player |
| Nonce | A counter, starting at zero, that increases by one with every bet — so two identical bets never produce the same result. | Automatic |
On every bet, these three are combined into a single 64-character value using HMAC-SHA256 — a standard keyed hash. The same three inputs always produce exactly the same value, and changing any one of them by a single character changes the whole thing unpredictably. That value is then mapped onto the game's outcome (a roulette pocket, a dice number, a card) by the formulas in §4.
Changing the client seed retires the current pair, promotes the pre-committed future pair (with the player's new client seed attached), resets the bet counter to zero, and generates a fresh future pair. The retired pair is marked as revealed in our database — but, as covered in §7, nothing is actually revealed to the player at that point.
Both systems end the same way: a 64-character hash is produced, a few characters are read off the front of it as a number, and that number is scaled onto whatever the game needs — a pocket, a card, a multiplier. None of this is secret in any meaningful sense; the security comes from the hash, not from hiding the arithmetic.
| Game | Characters read | How it becomes a result |
|---|---|---|
| Roulette | first 5 | Scaled to 0–36 (European wheel, single zero). The payout multiplier is then derived from
which bets won and the configured house edge. |
| Dice | first 5 | Scaled to 0–100, then compared against the player's target and direction. |
| Limbo | first 13 | Uses the same curve as Crash (below) to roll a multiplier. The player wins if their target sits below the rolled value. |
| Hi-Lo | 5 per card | Scaled to 0–51, then split into rank and suit. Because each card reads a different slice, one
hash deals a whole sequence. |
| Wheel of Fortune | first 5 | Scaled to the number of wheel segments configured for that wheel. |
| Game | Characters read | How it becomes a result |
|---|---|---|
| Crash and When Moon Bro — same engine |
first 13 | Converted to a fraction, then run through a curve that produces mostly low multipliers and occasionally
very high ones. A proportion of rounds are forced to instant 1.00× — and that proportion
is the house edge.
|
| Chart | two slices of 5 | The first slice sets how far the price moves, the second sets the boundary for the next round. Direction (long / short / unchanged) falls out of comparing the new price to the old one. |
Never in the randomness — always in the payout or the mapping afterwards. The edge in force at the time is stored on every round and every bet, so a historical result stays reproducible even after the configuration changes.
Taking an actual spin — client seed xinUbdR5uI, spin number 520, reported result value beginning
85ce5…, landing on 19 at 1.97×:
The 1.97× multiplier is not part of this check. Once the pocket is fixed at 19, the payout follows deterministically from which bets the player placed and the house edge — there is no second random step.
It proves the number wasn't invented: the result value genuinely maps to pocket 19. It does not prove that the result value itself came from the server seed committed to the player before they started betting — that link is exactly what we can't currently demonstrate. See §7.
Multiplayer games don't generate anything at bet time. Millions of hashes are produced in advance, each one the hash of the previous, and rounds consume them one at a time — but in reverse order, so the chain is played from its end back towards its beginning.
This is a genuinely strong construction. To produce a round's hash, we'd have to reverse SHA-256 against a value already published — which is not feasible. Every round's hash is broadcast live and shown in the Hash Info panel, so a player who records one hash can check every later round against it indefinitely. Each round also deep-links to a "Check" page that recomputes the result.
The shared client seed is set by a seeding event: we publish the chain's first hash together with the number of a future, not-yet-produced public blockchain block, whose hash then becomes the seed. Nobody — including us — can know that value in advance, which is what stops the chain from being generated to our advantage.
The Multi-Player Hash Guide covers the chain end to end — generation, ordering, the seeding ceremony procedure, and the operational issues summarised below.
Measured against the three-step promise in §1, both systems complete steps 1 and 2 and neither completes step 3. The details differ.
| Single-player | Multiplayer | |
|---|---|---|
| Commit | Partial — what we show the player before they bet is an encrypted copy of the server seed, not a one-way fingerprint. Encryption can only be undone by us, so it doesn't let anyone else confirm anything. | Yes — the chain commits to itself, and the seeding post commits to its starting point publicly. |
| Play | Yes — fully deterministic, no re-rolls, the consumed record is locked to the bet. | Yes — one chain link per round, consumed in order. |
| Reveal | No — the server seed is never disclosed to anyone outside the platform, at any point in the seed's life. | No — the value the chain was built from is discarded during generation, so there is nothing left to reveal. |
| Published method | No — the formulas aren't documented for players anywhere. | Partial — a Check tool exists, hosted on a third-party sandbox we don't own or control. |
This is the issue most likely to be raised by an informed player, and it affects both systems: as soon as a seed is rotated or a new chain is generated, the history before that point becomes permanently unverifiable.
We don't wait for a chain to be used up before running a new seeding event. The shared seed is switched while millions of committed hashes remain unused, so a block of rounds ends up committed under one seed but replayed under another. Anyone who kept the original seeding post and tries to verify across that boundary gets a mismatch — not because anything was manipulated, but because the published inputs no longer describe the rounds that were played. The three multiplayer games also burn through hashes at different rates, so they are never exhausted at the same time and there is no clean moment to rotate.
Even setting rotation aside, proving a whole chain was honest requires revealing the value it was generated from, so anyone can regenerate all five million hashes and confirm not a single one was skipped or cherry-picked. That value is created during generation, used once, and discarded — it does not exist anywhere afterwards. So a retired chain can be spot-checked link by link, but never validated end to end.
Every time a player changes their client seed, their previous seed pair is retired and its entire betting history becomes permanently uncheckable: the server seed behind it is never published, and the bet counter restarts at zero so old bets can't even be located by position. A player who has changed their seed ten times has ten blocks of history, none of which can be verified — and the retired records are already flagged as "revealed" internally, which makes the missing step look like an oversight rather than a design choice.
When support is asked "can you check this round for me?", there is no tool for it. Answering requires an engineer querying the database by hand. This is the practical cost of the gaps above, and it's the reason this document exists.
None of the above says results are unfair, manipulated, or wrong. The outcomes are deterministic, the arithmetic is sound, and every input is stored. What's missing is the ability for someone outside the platform to confirm that independently — which is the specific thing the phrase "provably fair" promises. That's a documentation, product and process gap rather than a defect in how games are played.
Grouped by what they unlock. Nothing here changes how any game plays or what it pays.
This request comes up regularly and reflects a misunderstanding worth correcting gently: for these games there is no gameplay to replay. A round is a single number produced by a calculation, not a sequence of events. The right answer is to show the calculation — which is exactly what the internal verification view above would provide, and why it's the highest-value item on this list for day-to-day operations.
A small number of defence-in-depth items around database constraints and stored-data handling were noted during this review. They carry no player-facing impact and are being handled directly with the backend team rather than documented here.
| Priority | Item | Why first |
|---|---|---|
| 1 | Internal verification view | Immediate operational relief, depends on nothing else |
| 2 | Single-player fingerprint + reveal + bet data | One piece of work; unlocks every other single-player item |
| 3 | Per-chain secret + boundary-aligned rotation | Closes the multiplayer chain-break problem at its root |
| 4 | First-party verifier + published formulas | Removes the external dependency and makes the claim actionable |
| 5 | Permanent, findable commitments + archive | Makes the guarantee hold up months later, not just live |
Until the improvements land, this is roughly where the honest line sits. Anything beyond it should go to the backend team rather than being improvised.
Results are generated before the bet resolves, from inputs that are fixed in advance and stored. The player's own client seed contributes to every single-player result, and they can change it at any time. Multiplayer rounds publish their hash, and each round links to a page that recomputes the result.
For single-player games we can confirm and show the calculation internally, but we don't yet publish everything a player would need to repeat it themselves. That's a known gap with work planned — not a refusal, and not a statement about whether the result was correct.
That a player can independently verify single-player results today, that a round can be "replayed" as gameplay, or that a chain can be validated end to end across a seed rotation. None of those are true right now.
A player, partner or regulator asks for verification of specific rounds or bets, or points at a chain mismatch across a rotation boundary. These need engineering, and the mismatch may be the known boundary issue rather than anything wrong with the result.
| Topic | Where |
|---|---|
| Multiplayer chain — generation, ordering, seeding ceremony, known problems | Multi-Player Hash Guide |
| Single-player seed pairs, per-bet consumption, outcome formulas | Backend — shared single-player hash and RNG modules |
| Multiplayer round engines and result derivation | Backend — engine game services (Crash, When Moon Bro, Chart) |
| Player-facing Fairness panel and Hash Info panel | Web frontend — originals game modules |