Warzones
Live · Algorand mainnet- Role
- Sole backend developer
- Timeline
- Dec 2023 → present (~28 mo)
- Chain
- Algorand (mainnet)
- Scale
- 925 commits / 1,837 all-branch · 63 models · 25 controllers · 21 route groups
- Stack
- Node · Express · MongoDB (63 models) · Redis (Socket.io adapter · Bull · Redlock) · Algorand SDK · IPFS/Pinata · PM2
Warzones (Ghetto Pigeons) is a full Algorand blockchain-gaming platform, and the single backend behind it is the largest system I've built. It puts on-chain ownership at the center of the game — NFT-gated play, with assets that carry special in-game abilities — and runs a primary mint, a secondary marketplace, live auctions, randomised "shuffle" raffles, soft-staking vaults and heists, a multi-type airdrop engine, an in-game economy with rewards and ranks, and a multi-tier whitelisting system, serving three separate frontends — all in one client's ecosystem — from a single codebase. I built and operated it in production for over two years.
The problem
People think "NFT game" and picture a mint button. Warzones is an economy. A single player can: buy a pigeon on the primary store, flip it on the secondary marketplace, snipe one in a timed auction, enter a shuffle to win a rarer one, lock NFTs into a vault to soft-stake for yield, run a heist, climb a monthly leaderboard toward Diamond Ballz rank, and collect airdrops — and every one of those moves is a real on-chain transfer the backend has to settle exactly right.
That puts three hard demands on the backend at the same time:
- Be real-time across a cluster. Auctions, bids, and shuffle states have to update instantly for every connected client — and the API runs as a multi-instance PM2 cluster, so a bid that lands on one instance has to reach a client connected to another.
- Settle on-chain reliably. Marketplace sales, auction payouts, staking yield, shuffle prizes, and airdrops are real Algorand transactions that must be idempotent and stay correct even when a node is slow to respond.
- Stay up for years. This isn't a demo — it's been continuously operated since 2023. The real engineering is in the incidents, the migrations, and the cost control, not the happy path.
It serves three frontends off one backend, all part of the same client's interconnected ecosystem: the Ghetto Warzones creator/game dashboard, the Ghetto Market marketplace, and Big Ballz, the ecosystem's meme-coin app — each hitting the same models for assets, collections, pools, and rewards.
Architecture
NFT media is stored on-chain — art is pinned to IPFS via Pinata and referenced by the asset itself. Cloudinary only holds cached thumbnails (for fast gallery lookups) and banner images; it is never the source of truth for an NFT. All on-chain operations happen server-side — clients never sign contract calls — which centralizes custody, lets me batch and retry transactions, and keeps the trust boundary in one place.
The hardest decision: real-time across a multi-instance cluster
A single Node process can hold every websocket in memory and broadcast trivially. The moment you scale to a PM2 cluster for throughput and zero-downtime deploys, that breaks: a bid on instance A has to reach a client on instance B.
Decision: put a Redis adapter under Socket.io so every instance shares one pub/sub fabric, and treat Redis as the source of truth for ephemeral real-time state. The tradeoff I accepted: every broadcast pays a Redis round-trip and the system now depends on Redis being healthy — so Redis became a first-class operational concern (it also backs Bull queues, Redlock bid locks, rate-limiting, and caching), not a "nice to have." In exchange I got horizontal scale and the ability to deploy without dropping a live auction.
On-chain settlement runs through Bull queue workers, not inline request handling. Submitting an Algorand transaction inside an HTTP request couples user-facing latency to chain latency and loses the work if the request dies. Queues give me retries, backpressure, and idempotency — the request returns immediately; the worker guarantees the payout eventually lands.
The systems inside it
- Marketplace — primary + secondary. A primary store for new mints and a secondary order book for holder-to-holder trades, with royalties and platform fees enforced server-side on every sale.
- Auctions. Timed auctions with Redlock bid locks so two instances can't accept conflicting bids on the same lot; auto-settlement pays the winner and returns losing bids.
- Shuffles. A shuffle is a randomised NFT raffle: players buy entries, and when it closes the backend draws winners and distributes the NFTs on-chain. Entry is gated by a multi-tier whitelisting system — by NFT/ASA holding, by NFD segment, or by explicit address — and paid entries are validated against Vestige price data.
- Soft-staking vaults + heists. Holders lock NFTs and tokens into vaults to earn yield without giving up custody on-chain; "heists" are a game mechanic layered on the same pool accounting.
- Airdrops, many kinds. NFD-segment airdrops (everyone holding a segment of a given NFD), trait-pool airdrops (weighted by NFT traits), and rarity- and address-targeted drops — all batched and settled through the queue layer.
- Rarity engine. Inverse trait-frequency scoring plus a trait-count meta, classifying each NFT into five tiers — which in turn feeds the trait-weighted airdrops and Diamond Ballz ranking.
- NFT-gated play + special abilities. Playing is gated by holding the project's NFTs — Ghetto Pigeons, Ghetto Pigeons V2, and Mutant Pigeons — all of which receive airdrops, and Mutants carry special in-game abilities the backend resolves at play time.
- Events out. Discord webhooks and Socket.io events fire on sales, whale moves, auction closes, and shuffle draws.
What broke (operating it for 2+ years)
The honest proof that this is a production system, not a prototype, is the incident work. Real things I designed, investigated, and fixed in the live system:
- Marketplace-sales security — investigated and hardened the sale-settlement path against exploit conditions.
- Pool auto-reactivation — reward pools that stalled now detect and reactivate themselves instead of needing a manual nudge.
- Orphaned-media cleanup — a Cloudinary cleanup pipeline reclaims storage from cached thumbnails no longer referenced, controlling cost as the collection grew.
- Log-volume reduction — cut operational log noise/cost after profiling what was actually useful for debugging vs. what was just expensive.
Results
- 925 commits (1,837 all-branch), sole backend author, over ~28 months of continuous production — the longest-running backend I've operated.
- 63 data models · 25 controllers · 21 route groups spanning marketplace, auctions, shuffles, staking vaults, pools, whitelists, rarity, airdrops, and on-chain rewards — serving three separate frontends.
- Multi-instance real-time via Socket.io + Redis adapter with Redlock bid locks and PM2 zero-downtime deploys.
- A full airdrop engine (NFD-segment, trait-weighted, rarity-targeted) and a five-tier rarity system driving rewards and ranks.
What this demonstrates
Owning a stateful, real-time, on-chain economy end-to-end for years: horizontal scaling of websockets, queue-based on-chain settlement with idempotency, a marketplace + auction + raffle + staking surface that has to stay correct to the asset, and the operational maturity to investigate incidents, restore state, and control cost in a system you can't take offline.