Tactical onchain fleet combat: Dynamic Flow purchases, World ID sybil resistance, Walrus game replay


Hackathon Live Deployment: https://void-tactics-fe-eth-ny-26.vercel.app/ Original Live Deployment: https://www.voidtactics.xyz Contracts: https://github.com/briandoyle81/warpflow-contracts
Void Tactics is a fully onchain turn-based tactical space combat game where players build fleets of NFT ships and fight on a 17×11 grid. Every ship, move, combat result, tournament entry, match outcome, and replay pointer is resolved or recorded on-chain.
The core game existed before ETH New York 2026. It already included NFT ships, fleet building, lobbies, maps, turn-based movement, weapons, special abilities, scoring, permanent ship destruction, and on-chain game results.
The hackathon work focused on three major sponsor integrations that extend that existing game into a more accessible, competitive, and durable onchain game protocol:
The frontend is a Next.js 16 App Router application using wagmi, viem, TanStack Query, Tailwind, Dynamic, World ID, and Walrus. The backend is not a traditional game server. The Solidity contracts are the game engine, deployed on Base Sepolia, with frontend support for wallet UX, payment onboarding, tournament registration, replay storage, and live gameplay.
Void Tactics is built to be unkillable and composable.
Every core rule, asset, result, and tournament lives on-chain with no proprietary backend required to play. The contracts are the game. If the original team stops supporting it tomorrow, the deployed system keeps running. Anyone can build a new frontend, tournament organizer, ship marketplace, analytics layer, replay viewer, or entirely new game mode on top of the same contracts without asking permission.
This extends to the assets themselves. Every ship’s art is generated and stored 100% on-chain. There are no IPFS metadata links, hosted image servers, or CDN dependencies for the NFT ships. The NFTs are self-contained: metadata and artwork live in the contracts permanently.
That is the practical difference between a game that is merely using a blockchain and a game that is actually on-chain.
Before ETH New York 2026, Void Tactics already had a playable onchain tactical game loop.
The existing system included:
The hackathon project was not about creating the base game from scratch. It was about using sponsor technologies to solve real problems in an already-playable onchain game: wallet friction, tournament sybil attacks, and durable match history.
The pre-hackathon contract repo is here:
https://github.com/briandoyle81/warpflow-contracts
During the hackathon, Void Tactics added three equal top-level sponsor integrations:
Void Tactics is fully onchain, which means game actions are transactions. Before this integration, players had to manually approve wallet popups for game activity. That is technically correct for an onchain game, but it is a poor experience for players.
Dynamic embedded wallets make transaction submission feel like part of the game UI instead of a separate crypto workflow. The same Dynamic session powers login, signing, payments, and game actions, reducing the number of separate wallet and authentication steps a player has to manage.
Dynamic is also used for ship purchases. Players need ships in order to play, and the new purchase flow allows them to buy ship packages using multiple tokens on multiple chains through Dynamic’s Flow payment SDK.
The player chooses a ship package, Dynamic opens a payment modal, the transaction routes through Flow’s cross-chain payment rails, and the contract mints the ship NFT. The user does not need to manually swap, bridge, or reason about chain-specific payment steps.
This creates a cleaner path from “I want to play” to “I own ships and can enter a match.”
Dynamic’s role in the hackathon build:
The result is an onchain game that feels less like a DeFi app and more like a game.
Void Tactics tournaments use World ID to enforce one human entry per tournament.
This solves a specific competitive fairness problem. In a prize tournament, wallet-based registration alone is not enough because wallets are free to create. Without anti-sybil protection, one person could register multiple wallets, buy several bracket slots, and gain an unfair advantage over honest players.
World ID prevents this without requiring KYC. The game does not need to know who the player is. It only needs to know that the same human is not filling multiple tournament slots.
When a player clicks “Register,” the frontend opens the World ID IDKit widget. The player generates a proof from World App, and that proof is verified on-chain against the Base Sepolia WorldIDRouter.
The tournament contract checks the proof, stores the tournament-specific nullifierHash, binds the signal to msg.sender, and only then accepts the entry fee. The stored nullifier prevents the same human from registering again in the same tournament, while the msg.sender binding prevents a proof from being reused across wallets.
The frontend also includes an /api/world-id/rp-context endpoint that issues a short-lived signed nonce using a managed relying-party signing key. No frontend secret is exposed, and there is no server-side wallet.
World ID’s role in the hackathon build:
WorldIDRoutermsg.senderThe result is a tournament system where prize brackets are protected against simple wallet-based sybil attacks.
Void Tactics uses Sui Walrus for decentralized game recording and match replay.
Every confirmed move uploads a full game state snapshot to Walrus, a decentralized blob store that is chain-agnostic and Sui-based. Void Tactics accesses Walrus entirely over HTTP from an EVM application.
Each player maintains their own blob. When a player submits a move, the upload also includes the opponent’s last move, which is already in client memory at submission time. As a result, either player’s blob can contain the complete match record.
This solves a real browser-based onchain game problem: EVM RPC providers often cap historical event log queries to limited block ranges. Reconstructing long move-by-move game histories from on-chain events in the browser becomes unreliable because of pagination limits, provider limits, and rate caps. Walrus sidesteps this by allowing one blob fetch to return the full recorded state.
The replay UI is built directly into the game view. During any live game, a “Replay” button appears. It fetches the current snapshot from Walrus, loads it into memory, and lets the player step backward and forward through every move with:
Exiting replay returns the player to the live board exactly where the game currently stands.
At game end, a final archive blob is uploaded with a one-month TTL, and the blob ID is recorded on-chain through GameBlobRegistry.record(). Tournament matches additionally call Tournament.recordResult().
After that, the replay can survive independently of any server run by the original team.
Walrus’s role in the hackathon build:
GameBlobRegistryThe result is a replay system that does not depend on a centralized backend and avoids fragile long-range browser event reconstruction.
The core game described in this section was built before the hackathon. It is included for context so judges and reviewers can understand what the Dynamic, World ID, and Walrus integrations extend.
Players build fleets from their owned NFT ships while staying within a threat budget. Ships have procedurally generated stats and equipment, including accuracy, hull, speed, weapon, armor, shield, and special ability.
More expensive ships are individually stronger but consume more of the fleet budget. Cheaper ships allow larger fleets but are individually weaker. This creates a tactical tradeoff between elite ships and numerical advantage.
Fleets are committed before the match starts.
Turns alternate between players. On each turn, a player selects a ship, moves it within range, and chooses an action such as:
Line of sight is enforced for weapons, though not for special abilities. Damage is calculated from weapon stats minus armor reduction. When a ship reaches 0 HP, it is destroyed permanently.
Destroyed ships remain NFTs, but the destroyed flag is set in the contract and the ship becomes ineligible for future fleets. This creates real strategic weight: players must decide whether a ship is worth risking to win the current match or whether it should be preserved for future games.
Certain map tiles award victory points to the first ship to occupy them, and some tiles continue awarding points on later turns. A player wins by reaching the victory point threshold or by destroying the opposing fleet.
Maps are configurable, and the scoring geometry is part of pre-game lobby setup.
Void Tactics includes a fully scripted tutorial that runs locally with no gas. It walks new players through movement, shooting, specials, scoring, and retreat before they commit an NFT ship to a real match.
Tutorial completion unlocks a claimable reward on Base Sepolia.
The Solidity contracts form the game engine. They handle NFT ships, attributes, fleets, lobbies, maps, games, results, tournaments, blob records, and game currency.
The system uses Hardhat and Ignition deployment modules. The hackathon deployment is live on Base Sepolia.
A new Tournament.sol contract adds full single-elimination tournaments with World ID anti-sybil protection at the registration gate.
World ID is used at Orb level, with on-chain verification through the Base Sepolia WorldIDRouter. Each tournament stores used nullifierHash values to enforce one entry per human per tournament.
Key properties:
nullifierHash valuesmsg.sender, so a proof cannot be reused across walletsclaimresolveDraw, currently marked temporary in codeThe tournament system turns Void Tactics from a match-based game into a competitive bracket system with prize support and explicit anti-sybil protection.
A new GameBlobRegistry contract stores each player’s Walrus blobId for every completed game.
During a match, each player’s client continuously uploads the current game state to Walrus and updates that player’s on-chain blob slot. This means the replay record is live throughout the game, not only written once at the end.
The registry intentionally treats the blob as an opaque replay pointer. Winner integrity never comes from Walrus. The authoritative game result always comes from on-chain game and result contracts.
Key properties:
blobs[gameId][player]getBlob for both participants and use whichever blob is availableThis design allows replays to exist without a traditional backend. As long as either player’s Walrus blob survives, anyone can reconstruct the match from on-chain data plus the stored state.
In the future, players could control how long their own records are retained and pay to extend storage themselves.
Base Sepolia chain ID: 84532
| Contract | Address |
| ------------------ | -------------------------------------------- |
| Game | 0x5801c1303e13899FCbC6702b16B77183F1ddB8f4 |
| GameResults | 0x1f341c690C5AaA61D06736AD67937385a76f1FE2 |
| Tournament | 0xF9d579915fc22bCbd2B67bF14Bb8FD75232E97DC |
| GameBlobRegistry | 0xDab9f61b7243b37E9B1f471d0f18ef758AABDF0E |
| Lobbies | 0xf0Aa01DfF32F2F83e885DF9E637C7875916B04aB |
| Fleets | 0xF37D64C7FD867eF7BFDb1b52b6bcc449cD866135 |
| Ships | 0xD36B2D129fb48c488cA5cE00e2941995FB9C6D74 |
| Maps | 0xAcEB0a35132a111BA3D3816c5EA6D62AeFa9a86A |
| ShipAttributes | 0x00e4068255Abf416086f7bF6c507bc36B7a232E7 |
| UniversalCredits | 0x86161787160F5A54F1424B7F7119247352DE215e |
Full address list:
ignition/deployments/chain-84532/deployed_addresses.json
Void Tactics began as a complete onchain tactical game. The ETH New York 2026 hackathon work used three sponsor technologies to solve three concrete problems in that game.
Dynamic makes the game easier to enter and play by improving wallet UX and enabling cross-chain ship purchases.
World ID makes prize tournaments fairer by preventing one person from entering the same bracket through multiple wallets.
Sui Walrus makes match history durable by storing replay data outside centralized infrastructure and avoiding fragile browser-based event reconstruction.
Together, these integrations turn Void Tactics from a playable onchain game into a more accessible, more competitive, and more durable public game protocol.
The pre-hackathon game made Void Tactics playable. The hackathon work made it tournament-ready, easier to onboard into, and more resilient.
Void Tactics is a fully on-chain tactical strategy game — ship NFTs, game logic, match results, tournaments, and all artwork live in Solidity contracts on Base Sepolia. No game server. No hosted assets.
Partner upgrades for the hackathon include: =
World ID: Tournament registration calls IWorldID.verifyProof directly on-chain against the Base Sepolia testnet router (Orb level, groupId=1). The nullifierHash is stored per-tournament, binding one verified human to one entry per bracket. No backend proof relay — the contract is the gate.
Walrus: During a match, each player's client continuously uploads the live game state to Walrus and commits the resulting bytes32 blobId to our GameBlobRegistry contract. Replays need no backend — just fetch either player's blob from the Walrus aggregator. Players will eventually control their own retention. Winner integrity always comes from GameResults on-chain; the blob is a pure replay pointer.
Dynamic: Handles wallet connection and auth in the frontend, including the Flow payment rail for ship purchases.

