Inspiration

Everyone knows the feeling of refreshing a tracking page that says "Out for delivery." We flipped it around: you are the driver. We wanted a game anyone on the couch could pick up in seconds, with no app to install and no controller to pair, on the biggest screen in the house.

What it does

  • Scan and play. The TV shows a QR code and a 4-letter room code. Scan it, and your phone opens a landscape gamepad in the browser: d-pad on the left, a big action button on the right, with haptic taps on every turn and buzz patterns for game events. No install. The Fire TV remote works too, so nobody is left out.
  • Fast and accurate delivery. Parcels carry colored address stickers. Your van stacks up to 12 of them, and every parcel has to reach the front door of its color. Each door takes only its own color, so every trip earns points and a growing streak multiplier, up to 3x. Get hit by a hazard and you lose your stack, a life and the streak.
  • A delivery window. Each route runs on a 9 AM to 5 PM clock. Finish early for up to three stars and a time bonus, or arrive "Late!".
  • Four worlds, played in order or from a picker in the lobby: a Fulfillment Center with runaway forklifts, Suburbia with neighborhood dogs (and a porch pirate who steals your whole stack), Downtown with taxis and buses, and a snowy Holiday Rush.
  • Surprises: Priority badges that speed up the van and make hazards pull over, drone drops carrying mystery boxes (magnet, doorbell cam, bubble wrap, turbo, bonus), traffic raids, Rush Hour 2X and Golden Boxes.
  • Sound you control: subtle 16-bit effects and an original background theme, with a Sound On/Off switch on the title screen.
  • An honest leaderboard. Every run is replayed on the server from its seed and the inputs, so the score on the board is the score the game actually produced. Players can claim their name once with a 6-digit email code from their phone, sent from the game's own domain.

How we built it

  • TV app: React Native for Vega (React Native 0.83, new architecture, React 19) on Vega SDK 0.24. Native screens for the title, leaderboard and results, plus the Vega WebView 4.0 (Chromium 144) for the 60 fps canvas game. The remote's D-pad reaches the game page directly, and Back stays in React Native.
  • The game: a deterministic, fixed-tick (60 Hz) engine in plain JavaScript with a seeded random number generator. It never reads the clock or Math.random, so a run can be replayed exactly from its seed and a tick-stamped input log.
  • 16-bit art drawn in code, at 32x32 source pixels per tile with shade ramps and outlines, pre-rendered once so each frame stays cheap. Key art for the title and world cards was generated as 16-bit illustrations.
  • Phone controller: a plain web page with pointer events, the Screen Wake Lock API and haptics (the Vibration API on Android, a native-switch tap on iOS where Safari allows it).
  • Real-time link: a Cloudflare Worker with one Durable Object per room, holding the TV's and the phone's WebSockets (hibernation API). Measured round trip phone to TV to phone was about 90 ms, so a press reaches the TV in about 45 ms.
  • Leaderboard: D1, with server-side replay of every submitted run using the same engine file the TV runs, plus email-code sign-in for names.
  • Fair play: on top of the replay, every submit stores its input log and a few input counts, and the server flags runs that look scripted: synthetic input events, a machine-steady input rhythm, or more direction changes per second than a thumb can make. Those runs are held for review instead of posting. Outlier scores and many names from one connection are noted for review. Obvious script clients (curl, headless browsers) can't start or post runs, and hashed network addresses are deleted after 30 days.
  • Operator console: outfordelivery.tv/admin, behind Cloudflare Access, lists every run with its flags and replays any of them on the same engine, frame by frame, checking that the replay matches the stored score before an operator approves or hides it.
  • Tests: 217 engine and web tests (node --test), 223 server tests (Vitest on the Workers runtime), 39 TV app tests (Jest), and headless browser smoke tests that pair a real phone page with the TV page through the relay. The app was tested end to end on the Vega Virtual Device, driven by inputd-cli inside the device; the gameplay in the demo video is the real TV page, captured headless.
  • Production hardening: before submitting, two independent AI code reviews (Claude Opus 5.5 and GPT-6.1, each run through OpenTalon, our proprietary meta harness) read the whole repository and proved their findings with local reproductions, without touching production. They agreed the core was sound (server replay, hashed single-use codes, no injection paths, a deterministic engine replayed identically in Node, Chrome and the Workers runtime) and we fixed what they found: per-IP admission limits on rooms, joins, run starts and submits; per-socket frame budgets and a cap of 8 phones per room; runs that expire after 6 hours, a timing check before any replay and at most 3 replays per run; a review hold for scores above 100,000; an engine fingerprint so a stale TV page can't post; idempotent submits when a response is lost; IPv6 limits by /64; atomic email admission and a daily email cap; TV submit tickets scoped to one room for 2 hours; covering database indexes; demo and bot runs that never post; and a TV that pauses when its own connection drops.

Challenges we ran into

  • One input path. React Native's TV event handler and the WebView both see every remote press, so forwarding keys from React Native would double every turn. We measured on the Virtual Device that D-pad and Select reach the page as normal keydown events exactly once, so the app forwards nothing.
  • The Select press that ends a run starts in the WebView, and its key-up landed on the native initials screen and saved "AAA". The native screen now accepts only a press it saw start.
  • Determinism across two runtimes: the Fire TV WebView and the server have to produce identical scores, so the engine uses only integer-friendly math, a seeded RNG and a fixed tick, with a test that replays bot games across 20 seeds and all four worlds.
  • iOS Safari has no Vibration API, so phone haptics on iPhone depend on a workaround that newer iOS versions have closed. A thin native wrapper is next.

Accomplishments that we're proud of

  • Zero-install, real-time second-screen play on Fire TV: scan, steer, feel it.
  • A leaderboard you can trust, because the server re-plays every run.
  • Four distinct 16-bit worlds on one deterministic engine.

What we learned

  • The Vega WebView is a strong place to run a canvas game, and the bridge (postMessage and injectJavaScript) is all a hybrid app needs.
  • inputd-cli plus the emulator console make a fully scripted test and capture loop for TV apps.

What's next for Out for Delivery

  • Two-player co-op: a second phone joins as another van.
  • A native phone app (Expo) for full haptics on every phone.
  • Room-owned runs: the room issues the seed and records the relayed inputs, so a submit has to match what the phone actually sent.
  • More worlds, daily routes with a shared seed, and the Amazon Appstore release (the package, listing, store art, privacy policy and support page are ready).

Built With

  • claude-code
  • cloudflare-access
  • cloudflare-d1
  • cloudflare-email-service
  • cloudflare-workers
  • durable-objects
  • headless-chrome
  • higgsfield
  • html5
  • javascript
  • jest
  • node.js
  • opentalon
  • react-native
  • react-native-for-vega
  • typescript
  • vega-sdk
  • vega-virtual-device
  • vega-webview
  • vitest
  • web-audio
  • websockets
  • workers-rate-limiting
Share this project:

Updates

Submission history