Building Fracer in Under an Hour with AI Coding Agents

Nov 3, 2026

On October 17, 2026, during the Devin x Supabase Vibeathon in Lima, 98 people raced against each other in a game I had built one week earlier — mostly by directing an AI coding agent. The game is called Fracer, it's a cartoon Formula 1-style race for live events, and it's still up at fracer-production.up.railway.app.

The mechanic: I open a room on the projector, attendees scan a QR code, pick a name and a car color on their phones, and when I hit "start race", everyone drives — throttle, steering, nitro, and water-balloon power-ups included — while the big screen shows the broadcast view.

I built it with Cognition's SWE-2 coding model, and this post is an honest account of that collaboration: what I delegated, what I decided myself, and what working this way taught me about agent reliability. This was a build for a live event, not a controlled experiment — so treat this as a practitioner report, not research.

Why a racing game

For community events I already had caritas, the 16-bit selfie wall — it works great, but it's a solo experience: you make your card, you leave. For a vibeathon I wanted something people would play together, live, in the same room. A race has a lobby, suspense, a finish, a podium. It turns the audience into participants for five minutes instead of thirty seconds.

How it works

Fracer is a Next.js app (Pages Router) with a custom Node server: a Socket.IO server attaches to the same process, which is the whole reason the deploy is a single Docker container on Railway (output: 'standalone', node server.js) instead of serverless functions — game state lives in memory, in one process.

The interesting engineering is in lib/game.ts. The server is authoritative: clients only send intent ({ throttle: 0..1, steer: -1..1 } and power-up requests), and a fixed 30 Hz tick integrates positions, applies collisions, projectiles, and finish detection. Clients never send positions — so nobody can teleport themselves to the finish line by editing JavaScript in the lobby.

A few details I like in the current implementation:

  • Rooms get a 6-letter code and a 4-digit password; joining mid-race is rejected, disconnects free your grid slot.
  • The grid scales to the lobby. Rows of 10 cars fill in join order, and if the row doesn't physically fit, the cars simply shrink:
export const GRID_USABLE_WIDTH = 41;
export const MIN_CAR_SCALE = 0.26;
export const GRID_PER_ROW = 10;

export function carScaleFor(count: number): number {
  const perRow = Math.min(Math.max(count, 1), GRID_PER_ROW);
  if (perRow <= 1) return 1;
  return Math.max(
    MIN_CAR_SCALE,
    Math.min(1, GRID_USABLE_WIDTH / (perRow * CAR_SLOT_WIDTH))
  );
}
  • Power-ups are server-validated: nitro (temporary top speed 98 vs the normal 62 cap, on a cooldown) and a water projectile that makes whoever it hits spin out for 1.8 seconds. A 90-second hard cap guarantees every race ends on a podium — essential when you're on stage.

What the agent built vs. what I decided

Let me be concrete about the division of labor, because "I built it with AI" means nothing without it.

Delegated to the agent: the Socket.IO room plumbing, the Three.js scene (track, lighting, broadcast cameras, the first-person cockpit view on phones), the entire game physics including power-ups, the mobile touch controls, the Docker + Railway deploy setup, and — my favorite part — the 3D models. The repo contains a blender/ directory with bpy scripts that run inside Blender through an MCP-style socket driver: build_car.py constructs the cartoon F1 car with recolorable Body/Accent materials, and build_otto.py builds Otto, the Devin otter mascot who sits in the cockpit. The scene loads the GLBs with a procedural fallback if they fail — which the agent itself wrote, correctly anticipating that generated assets are a liability.

Kept for myself: the product calls. What game to build, that the phone is a controller and the screen is the show, the pacing (lobby → countdown → ~60s race → podium), and the scope cuts — the first commit was October 10 and I deliberately shipped a smaller game rather than a bigger demo. I also made the calls on game feel: how long a slip lasts, how fast nitro decays, how big the steering deadzone should be on a phone screen. And I read the diffs — particularly the netcode, because "agent wrote it" is not a testing strategy when 98 strangers are about to connect.

The honest timeline: the first playable version — room, join-by-QR, a working race — existed after roughly an hour of that first session. The commits show what "roughly" means: it was a focused sprint, and then reality added work. Blender GLB models, car collisions, a rework of the mobile controls, and grid-scaling fixes landed on October 14–15, before Lima. After the event I added what the event taught me was missing: five-language i18n and dynamic Open Graph cards with the room code, so shared links show the lobby they're inviting you to.

What went wrong, and what I'd verify differently next time

  • The grid didn't scale. The first version lined cars up in a single endless row — fine for 5 players, broken for 98. The fix (rows of 10 + shrinking scale) came out of a real failure imagined just in time.
  • In-memory state is a feature and a liability. One process means no external state to sync and trivially low latency — and it also means one instance per deploy and no horizontal scaling. Right call for an event app; I'd never ship it for a durable product.
  • Agent output needs adversarial review exactly where it hurts. The places I read most carefully were the state transitions (waiting → countdown → racing → finished) and input validation — the classic spots where generated code is plausible but wrong at the edges, like a start-race event from a non-host client or a disconnected player holding a slot.

The lesson I keep taking to every agentic project since: agents compress implementation time, but they don't compress verification time — they just move it. The hour Fracer "took" to build was real; the days of polishing edge cases before I'd trust it on stage were also real. Knowing which is which is the skill.

Erasmo Hernández