Wownerogue: A Provably-Fair Roguelike on Block Time
A browser roguelike whose round timer is the blockchain. How the commit-reveal fairness, the block-timing deadline, and the Monero payout batching work.
Wownerogue is a multiplayer roguelike that runs in the browser. You enter a dungeon and have until the next block to reach the exit. One monster pursues you, and an optional treasure bag raises the payout multiplier on escape. The round timer is not a countdown: it is the arrival of the next block on the Monero or Wownero chain.
It runs as two instances. play.wowne.ro runs on Wownero: free to play, with optional paid entry feeding a separate leaderboard, and payouts disabled. monerogue.app runs on Monero stagenet, where escaping pays out stagenet XMR from a house wallet. Stagenet coins have no monetary value, which makes that instance a safe environment for exercising the full payment and payout path in public.
Block time as the round timer
Block intervals are exponentially distributed. Monero targets a 120-second block; Wownero targets 300 seconds. The target is only a mean: the next block can arrive in fifteen seconds or in several multiples of the target, and the server cannot predict the interval. A round begins on one block and ends on a later one, so the deadline is non-deterministic by construction.
That non-determinism is the design, not a defect. An early build added a minimum-time floor so that no round could be shorter than a set number of seconds. It defeats the premise and was removed. The only remaining timing guard is a two-second grace at round start, which keeps a block that lands in the same instant as the start from ending the round before the first move is possible.
The two chains' different intervals have a balance consequence. A 300-second Wownero deadline is far more forgiving than a 120-second Monero deadline for an identical dungeon. Difficulty (dungeon dimensions, monster aggression, spawn distance) is a per-instance configuration value, so the two windows can and should be tuned independently rather than sharing one preset.
Commit-reveal fairness
A game that holds funds has to show the board is fixed before the player commits. Wownerogue uses commit-reveal:
- Before the round, the server generates a 256-bit seed and publishes
SHA-256(seed), the commitment. - The seed drives a deterministic RNG that generates the dungeon: walls, exit, treasure, and monster behaviour.
- At the end of the round, the server reveals the seed.
- The client hashes the revealed seed and checks it against the commitment shown earlier.
Because the commitment is published before any input, the server cannot substitute a different dungeon once the round is live. The verification endpoint takes a seed, regenerates the dungeon, and emits a layout fingerprint for comparison. Verification depends on a hash function, not on trust in the operator.
Two instances, one codebase
The two sites are the same server under different configuration, not separate forks. Environment variables select the currency, the network, the payout toggle, and the branding. The Wownero instance runs free-to-play with payouts off; the Monero instance runs with payouts on. The payout toggle has to gate the entire money path: an earlier revision disabled credit-based payouts but not direct ones, a partial gate that is unacceptable in code that moves funds. It now gates both.
Payout batching under Monero output locks
The non-trivial backend constraint is payout sequencing. When a Monero wallet spends, the change output and the spent outputs are locked for roughly ten blocks. Issuing payouts without accounting for this attempts to spend locked outputs, and the transfer fails.
Payouts are batched, and the batcher checks unlocked balance before sending. If unlocked balance does not cover the batch, the payouts are not failed: they are returned to pending and retried on the next block and the next interval. Insufficient-funds errors are classified as safe to retry because they occur before broadcast. Errors that are ambiguous about whether a transaction was broadcast are routed to manual review instead of auto-retried, so an inconclusive RPC response cannot produce a double payout.
Leaderboard integrity on free play
Free play is the obvious target for inflation: open sockets, replay, pad the board. Scores are computed server-side from authoritative game state, so a client cannot submit an arbitrary score. The rate limiter caps new connections and game starts per IP. It did not cap how many sockets one IP could hold open concurrently, so a per-IP concurrent-socket cap was added. That does not stop a distributed botnet, but it removes the cheapest single-host attack.
Stack
Node.js and Socket.io for real-time game state, chat, and spectating. PostgreSQL for durable state, with monetary values stored as integer atomic units and written in idempotent transactions. Monero and Wownero wallet-RPC for payments and payouts. The client is plain JavaScript over a tile renderer; the game is a grid and a render loop, so it does not need a framework.
The server and client are MIT-licensed: github.com/Such-Software/wownerogue.
Play it
Queue, escape before the next block, and verify the seed afterward. On the Monero instance, escaping with the bag pays out stagenet XMR.