Gridiron Duels
A real-time fantasy football draft platform — built end-to-end across web, mobile, and a service-oriented backend that runs the league.
Fantasy football lives or dies on the draft. The instant someone's connection drops, a turn timer skips, or a CPU pick feels robotic, the whole illusion collapses. Gridiron Duels is built around the idea that the draft is the product — and everything else, scoring, leaderboards, cosmetics, the meta, is scaffolding that holds the moment together.
The roster behind the roster
Two stacks under one roof. Public-facing pages — homepage, leaderboard, marketing — are server-rendered Blade for fast first paint and clean SEO. The interactive surfaces — draft room, shop, achievements — are React / Inertia, sharing auth state through middleware so users glide between server-rendered and SPA pages without ever feeling the seam.
- 01 Backend Laravel 12 · PHP 8.3 · Octane / RoadRunner
- 02 Frontend React 19 · Inertia.js · Tailwind CSS
- 03 Mobile Expo SDK 54 · React Native
- 04 Real-time Laravel Reverb (Pusher protocol)
- 05 Database PostgreSQL
- 06 Payments Stripe (checkout + virtual currency)
- 07 Infra Laravel Cloud · scheduler · queue workers
The engine that orchestrates the draft
DraftEngine is a single service class that
owns the full game lifecycle: create, join, ready-up, pick, score,
complete. Every state transition broadcasts an event —
PlayerDrafted,
TurnUpdated,
GameCompleted — through Laravel Reverb. Web
clients listen via Laravel Echo, mobile clients via
pusher-js. Same channels, identical events,
one source of truth.
A player can start a draft on their laptop and a friend can join from their phone mid-pick. Same lobby, same turn order, same animations. That parity is enforced everywhere downstream — there is no mobile version of the draft, only the draft as accessed from a phone.
- 18 NFL weeks per game
- 16 Players per league
- 09 Scheduled tasks
- 50 Battle pass tiers
Modes by composition, not by branch
Games are assembled from two pieces. GameFormat defines structure — 1v1, 2v2 teams, League up to sixteen — and decides player count, draft order, and scoring rules. Modifiers stack on top: CPU fill, Crazy Mode randomized scoring, Time Machine using past NFL seasons. Add a new modifier and the core draft logic doesn't move.
An economy split into focused services
Five services, five domains, one shared coin. Every service owns its slice and nothing else, which keeps the failure modes small and the tests narrow.
- 01
CoinService
Atomic balance transactions, wager escrow with house rake, and Stripe-powered coin purchases. Every line item logged for auditability.
- 02
BattlePassService
50-tier seasonal progression with free and premium tracks. XP funnels in from wins, drafts, and missions; resets each season with new content.
- 03
CosmeticShopService
Daily rotating shop selling name colors, titles, profile borders, and banners. Cosmetic only — no pay-to-win.
- 04
MissionService
Daily and weekly objectives that feed XP into the battle pass and coins into the wallet. Resets via the scheduler.
- 05
RankedService
Elo-based MMR across 9 tiers from Iron to Hall of Fame. Matchmaking widens the skill window every 5 seconds until a match is found.
The schedule that runs the league
Nine scheduled tasks keep Gridiron Duels alive between human inputs. They roll missions, rotate the shop, sweep abandoned games, generate weekly challenges, and snapshot leaderboards on time, every time.
One game, every device
The Expo app talks to a dedicated api/v1
route group — sixteen controllers that mirror the web experience.
Auth uses Laravel Sanctum tokens stored in
expo-secure-store; broadcasting auth has
its own endpoint, so mobile clients connect to the same Reverb
channels as web users and receive identical events.
There is no second backend, no parallel implementation, no “mobile mode.” The phone is just another window into the same draft.
Gridiron Duels is live at gridiron-duels.com. For the architectural deep-dive, read the companion essay in the blog.