I Cloned Paperboy in an Afternoon With Claude
One prompt turned into a playable Paperboy clone in under two hours.
I Cloned Paperboy in an Afternoon; the Useful Part Was Where Claude Stopped
Build-in-public notes on shipping a playable game with a coding agent, and the one decision it wouldn’t make for me.
I’ve wanted to make PizzaBoy for a while: Paperboy’s NES loop, reskinned as a gig economy delivery sim. You ride down a street, sling pizzas at the porches of people who ordered, dodge dogs and hydrants, and try to keep your star rating alive. Five shifts of escalating chaos, from a rural town to a metropolis on Super Bowl Sunday. Browser only for now but maybe it’ll make its way to iOS later.
I opened an empty repo, pointed Claude Code at it and typed roughly one paragraph. Then I hung out.
Roughly two hours later I had a game that runs start to finish: title screen, shift briefing, full ride down Pine Hollow, bonus obstacle course, score tally, and the next shift; five levels deep to a “Career Complete” screen(I still haven’t beat the game), or a gameover when you get fired. 202 passing tests. A 62 kB bundle, 22 kB gzipped. Six commits on a local branch.
Claude asked three questions before writing the entire codebase
The three questions were the right three:
- Perspective. Faithful oblique 3/4 scroll (the authentic Paperboy diagonal), a top-down runner, or a side-scroller. I went with authentic. It’s the hardest to render, and it’s the whole reason the game feels like Paperboy at all.
- Fail model. Star ratings and tips, with customers who churn to a dark house at zero stars and “fired” once they’ve all left. Very Paperboy very DoorDash.
- Which iconic bits to keep. The vandalism bonus for beaning a non customer’s window, the end-of-level obstacle course, the perfect run bonus. All of them.
The architecture bet
One rule shaped everything else: the core/ folder is pure TypeScript. No DOM, no canvas, no browser APIs. The simulation runs in world coordinates and only gets projected to the screen at draw time.
While that sounds fussy for a pizza game. It buys me two concrete benefits:
- The rules are unit tested in isolation, which is how a solo afternoon build ends with 202 passed tests instead of none.
- The eventual iOS port swaps the
platform/andrender/layers without touching a single rule. Touch controls slid right in during an early milestone as a peer of the keyboard: not bolted on at the end.
The hard part was a camera angle
Paperboy’s diagonal view is deceptively nasty. The obvious way to sort sprites back-to-front is by their Y position on screen. But that’s wrong: it confuses how tall a house is with how far away it is, so every tall house sorts into the wrong place.
The fix was to solve the actual view ray instead of eyeballing it, which produces three facts the renderer leans on: further things carry a bigger depth value, nearer things sit lower on the street, and taller things read as nearer because the camera angle looks down at you. A pleasant side effect falls out of the same math: only three faces of a box ever point at this camera so a house is just three quads.
That same angle produced my favorite detail. A house on the near side of the street physically cannot show you its front wall. The roof is in the way. So the delivery target can’t be a door. It’s a low porch out on the lawn: one spot that reads from both sides of the road.
Two bugs it found by playing, not testing
Tests are great at rules but they’re useless at “does this feel unfair.” Both real balance problems surfaced only when it drove a full route and watched:
- The unavoidable dog. Riding dead center, touching nothing, still..CRASH! Dogs chase you and their position along the street is fixed while you approach, so they always had the full run up to sprint across the entire road and take you out. No input could dodge it. The fix was to leash each dog to 22 units from its home: a clean center-line run now finishes with zero crashes.
- The bonus stage that broke the economy. The end-of-level course had a guaranteed payout (finish it, collect the time bonus, touch nothing at all) that outscored an entire street shift. That inverts the game entirely: why deliver pizzas when the victory lap pays better? The floor got cut roughly in half so the gates, ramps, and targets are where the points live.
Neither of those is a bug a test would have caught, because neither one is technically wrong. They’re just not fun and you only see them by playing.
Notes from a vibe coder
At the end instead of calling the game finished, Claude told me where it wasn’t.
The star system is only half alive. Each customer gets ridden past exactly once per route, so their rating can only change once, which means the churn mechanic (the entire fail state) barely fires unless a single bad throw nukes a customer’s rating. Claude patched the tuning enough to make it function, then named the honest fix and declined to ship it: let customers place more than one order per route. That changes how a route is paced, not just a number in a config file, so it left the call to me.
It also left, on purpose and in writing:
- Levels 2 through 5 as untuned data. They generate and play; only Pine Hollow got a real balance pass.
- The Capacitor iOS wrapper unwired, with all the groundwork already in place: fixed internal resolution, touch as a first class input, and a fixed timestep so the feel is identical at 60 and 120 Hz.
In the end I ran through an entire sessions worth of Claude tokens. I fired up Cursor to finish the job: added music, tuned the camera angle/graphics some more and fixed some of the assets/elements so the game didn’t look so repetitive.
Try it yourself would love to know what you think: