Void Tactics

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

Void Tactics

Created At

ETHGlobal New York 2026

Winner of

World

World - Track C (Existing Projects integrating World ID) 2nd place

Dynamic

Dynamic - Best Wallet Glow Up

Project Description

Void Tactics

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:

  1. Dynamic — embedded wallet UX and cross-chain ship purchases
  2. World ID — anti-sybil protection for tournaments
  3. Sui Walrus — decentralized game recording and match replay

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.


Design Philosophy

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.


What Existed Before the Hackathon

Before ETH New York 2026, Void Tactics already had a playable onchain tactical game loop.

The existing system included:

  • NFT ship minting
  • 100% onchain ship art and metadata
  • Procedurally generated ship attributes
  • Fleet construction under a threat budget
  • Lobby creation and joining
  • Configurable maps
  • 17×11 tactical combat
  • Turn-based movement and actions
  • Weapons, armor, shields, and special abilities
  • Line-of-sight combat
  • Scoring tiles
  • Permanent ship destruction
  • On-chain game resolution
  • Tutorial and onboarding flow

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.


What Was Built During ETH New York 2026

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:

1. Dynamic: Embedded Wallet UX and Cross-Chain Ship Purchases

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:

  • Embedded wallet connection
  • Unified session for login, signing, and payments
  • Reduced wallet-popup friction during gameplay
  • Cross-chain payment flow for buying ships
  • Ship package purchase UX
  • Payment modal integrated directly into the game flow
  • Minting ship NFTs after successful purchase

The result is an onchain game that feels less like a DeFi app and more like a game.


2. World ID: Anti-Sybil Protection for Tournaments

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:

  • Human uniqueness requirement for tournament registration
  • World ID IDKit frontend registration flow
  • On-chain proof verification through the Base Sepolia WorldIDRouter
  • Tournament-specific nullifier storage
  • One-human-one-entry enforcement per tournament
  • Proof binding to msg.sender
  • Protection against one player entering the same bracket with multiple wallets
  • Short-lived signed RP nonce endpoint with no frontend secret exposure

The result is a tournament system where prize brackets are protected against simple wallet-based sybil attacks.


3. Sui Walrus: Decentralized Game Recording and Match Replay

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:

  • Prev
  • Next
  • Play
  • Pause
  • Exit

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:

  • Full game state snapshots uploaded after confirmed moves
  • Per-player blob ownership
  • Replay data stored outside traditional centralized infrastructure
  • HTTP-based Walrus integration from an EVM frontend
  • Live replay UI inside the game view
  • Prev / Next / Play / Pause / Exit replay controls
  • Final archive blob at game end
  • Blob ID recorded on-chain through GameBlobRegistry
  • Tournament match results linked to replay records

The result is a replay system that does not depend on a centralized backend and avoids fragile long-range browser event reconstruction.


Core Game

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.

Fleet Building

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.

Combat

Turns alternate between players. On each turn, a player selects a ship, moves it within range, and chooses an action such as:

  • Shoot
  • Use a special ability
  • Claim a scoring tile
  • Ram
  • Pass

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.

Scoring

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.

Onboarding

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.


Contracts

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.


Tournament System

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:

  • Players register with a World ID proof
  • Each tournament stores used nullifierHash values
  • The nullifier prevents the same human from entering the same tournament more than once
  • The signal is bound to msg.sender, so a proof cannot be reused across wallets
  • Registration is permissionless
  • Bracket construction, advancing, and finalization are permissionless
  • Prize pool uses a 1% protocol fee, then a 60/40 split to finalist and runner-up
  • Winnings are claimed through pull payment via claim
  • Sponsors can fund a prize pool
  • Sponsor funding is refunded automatically if the tournament is cancelled
  • Draw resolution uses creator-only resolveDraw, currently marked temporary in code
  • Draws resolve deterministically to the earlier-registered player

The tournament system turns Void Tactics from a match-based game into a competitive bracket system with prize support and explicit anti-sybil protection.


Game Blob Registry

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:

  • Each player owns their own replay slot: blobs[gameId][player]
  • Players write their own record, not a shared global record
  • Players may update their slot at any time
  • Updates can happen live during play or after the fact
  • Replay clients can call getBlob for both participants and use whichever blob is available
  • If both blobs are present, they should be equivalent
  • Winner integrity is never derived from the blob
  • The blob is only a replay pointer
  • The contract is intentionally minimal
  • A single admin function exists to rotate the authorized backend writer

This 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.


Deployed Contracts

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


Why It Matters

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.

How it's Made

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.

background image mobile

Join the mailing list

Get the latest news and updates

Void Tactics | ETHGlobal