← Back to home

Nonces

An awesome dungeon master for infinite fun. A classic mud with onchain rewards

Problem Statement

This is a 100% in-browser MUD (Multi-User Dungeon), minimal and fast to play: connect your wallet, pick a class, and explore an infinite dungeon made of procedurally generated rooms, enemies, and events. It’s all text with keyboard shortcuts so the experience is snappy and accessible.The “Dungeon Master” runs server-side and orchestrates the world: it generates rooms deterministically from a seed, validates combat/actions, and issues signed proofs when you hit milestones (first boss, quest chains, deathless streaks, etc.). Those proofs let players claim on-chain rewards:Game currency (ERC-20) for progression and the leaderboardItems/badges (ERC-1155 / optional SBT) for seasonal collectibles and unique achievementsGasless first-time claims via a relayer to remove frictionKey features:Infinite, highly replayable world (seasonal seeds)Global chat and lightweight parties for co-op eventsBasic anti-cheat: rate limits, cooldowns, server-side validation before issuing proofsDemo deployed on Sepolia (L2-agnostic; easily portable to Base/OP)Hackathon goal: ship a fun, one-screen MUD with real crypto rewards, prioritizing simplicity, speed of development, and clean UX.

Solution

Stack & architecture (the smallest thing that works well):Frontend: Vanilla JS + Vite (lean HTML/CSS, no heavy frameworks). Wallet connection via ethers.js. Terminal-style UI over WebSocket for commands (/move, /fight, /cast, …). Lightweight session/preferences in localStorage.Server (Dungeon Master): Node.js + Express + ws. Simple FSM for the game loop; procedural generator using a deterministic PRNG (e.g., mulberry32) keyed by {seed, floor, roomId}. Minimal persistence in Redis (player progress, cooldowns, seasonal seeds).Smart contracts (Solidity + OpenZeppelin):LootToken (ERC-20) for rewardsDungeonItems (ERC-1155) for drops and seasonal badges (optionally soulbound for achievements)Rewards (orchestrator) with EIP-712 voucher-based claims signed by the DM key. Anti-replay via per-player nonces and expirations.Tooling: Hardhat for compile/test/deploy (Sepolia). Seeding/verify scripts. RPC via a standard provider (Infura/Alchemy).Meta-tx / UX: claim route with a server relayer (optional gasless). permit (EIP-2612) ready if LootToken needs to be spent in future features.Security / anti-cheat:“Real” combat and quest logic lives on the server.Only the server can issue valid EIP-712 vouchers.Rate-limit by IP+wallet, action cooldowns, and command consistency checks.On-chain, claims validate chainId, deadline, player, nonce, and the exact milestone completed.Reward flow (nitty-gritty):Player completes a milestone; server builds {player, milestoneId, rewardType, amount, nonce, deadline}.DM signs that payload (EIP-712).Frontend calls Rewards.claim(signature, payload); the contract verifies domain, signature, and nonce, then mints ERC-20 / ERC-1155 and emits events.The client listens to Claimed / ItemMinted via ethers.js to update the UI in real time.What was “hacky” but effective:Ultra-simple, deterministic procedural generation—no need to store the full map.A single Rewards contract for all claim logic; scarcity/drop tables live server-side for fast hackathon iteration.Leaderboard without a subgraph: read recent events directly + cache in Redis (with a clear path to The Graph later).Demo status & next steps:Live on Sepolia (addresses in the repo README).Roadmap: on-chain parties, seasonal seeds, optional L2 migration, and (time permitting) moving part of the state to an on-chain ECS-style framework.

Hackathon

ETHOnline 2025

2025

Contributors