I got bored and rebuilt Tony Hawk's Pro Skater
Claude Opus 5 came out this month, I had an evening free, and the game I wanted to play was one I last played on a PlayStation 1 in the early 2000s. So I described it in one prompt and asked for the whole thing in a single file. The first version ran. What follows is the prompt, what it got right, what it got badly wrong, and why the second part matters more than the first.
Claude Opus 5 came out this month. I had an evening with nothing booked, and the game I felt like playing was Tony Hawk's Pro Skater, which I last played properly on a PlayStation 1 sometime in the early 2000s.
I did not want to buy anything or install anything. I wanted to open a file on my laptop and skate. So I wrote one prompt describing the game I wanted, asked for the whole thing in a single HTML file, the kind of plain text file a browser can open on its own, and pressed enter.
The first version ran.
It did not need its errors cleared or its imports fixed first. I double-clicked the file, a skatepark loaded, and I could push, ollie, spin and land. There was a half pipe, two quarter pipes, a funbox with kicker ramps, three grindable rails and a chain-link fence around the lot, with trick names stacking up in chunky white type, a combo multiplier climbing above them, a two minute run timer and a score card at the end. Every sound in it was synthesised in the browser, and every texture was drawn onto a canvas when the page loaded, because I had asked for no external files and it took that literally.
The part everyone skips
Here is where most posts about this stop, because "I typed a sentence and got a game" is the fun half. The other half is what actually made it good, and it is the half worth reading.
I played it. Within about ninety seconds I found three things that a screenshot would never show you.
Riding into the two metre deck of the half pipe teleported me on top of it, because the ground was modelled as a height map and nothing stopped me from stepping up a wall. Every landing that came out of a spin counted as a bail, because the tolerance for landing sideways was set so tight that any rotation killed the combo. And there was a soft black blob sitting at the centre of the world that turned out to be an entire particle pool sitting at coordinates zero, waiting to be used.
None of those are exotic bugs. They are the bugs you get from writing a system in one pass without playing it, which is exactly what happened. A person would have made the same three mistakes.
What changed is the loop after that. I described the symptom, the model found the cause, and I checked the fix by playing. Riding into a ledge now blocks and slides along it, because movement moved to small sub-steps that refuse any step raising the ground more than 45 centimetres. Landings square the board to the direction you are travelling, the way an arcade game flatters you. Later I asked for the character to look more like a person and got jointed knees and elbows, a face, a proper skate stance, and a deck that went from a comically long 1.55 metres to a realistic 80 centimetres.
Somewhere in there a scripted test skater found two exploits I would have shipped without noticing. Mashing left and right in the window just after a landing farmed an infinite number of reverts, and one automated run scored over three hundred thousand points on a fifty-two trick combo. Holding the manual key restacked the same trick forever. Both are now fixed, and I only know about them because something played the game ten thousand times more patiently than I would have.
The prompt
This is the whole thing, unedited. It is long on purpose. The specificity is doing the work.
Build a single-file HTML game called SKATE ARCADE, a 3D skateboarding trick game
in the spirit of late-90s console skate games. Everything in one index.html using
Three.js from a CDN. No build step, no assets, no external files. It must run by
opening the file in a browser.
SCENE
- A concrete skate park: one large half-pipe, two quarter pipes, a funbox with a
kicker ramp, and three grindable rails at different heights. Enclosed by chain-link
fence walls (use a simple repeating line texture drawn to canvas).
- Low-poly PS1 aesthetic: flat/vertex-lit materials, no shadow-mapping, chunky
geometry, heavy distance fog, slightly desaturated palette (grey concrete, faded
yellow paint lines, teal sky).
- Post-processing feel without a real pipeline: subtle CRT vignette + scanline
overlay as a CSS layer on top of the canvas.
- Skater = low-poly capsule-and-boxes figure on a board. Do not use CapsuleGeometry;
build it from cylinders and boxes.
CONTROLS + PHYSICS
- WASD/arrows steer and push, Space to ollie (hold to charge, release to pop).
- Real momentum: gravity, ground friction, and speed gained from pumping down
transitions. Riding up a ramp converts speed to air.
- Airborne: A/D rotates the skater (each 180 degrees banked = points), W/S for
flip tricks, and holding Shift + a direction does a grab.
- Rails: if you land within a small tolerance of a rail, snap into a grind and ride
it. Balance meter appears, nudge left/right to keep it centered or you bail.
- Landing rotated backwards is fine (switch), landing sideways = bail.
SCORING, this is the part that has to feel good
- Trick names appear in big chunky white outlined text, stacked, with a "+"
separating each trick in the current combo: KICKFLIP + 360 SPIN + 50-50 GRIND.
- Live combo multiplier that climbs (x2, x3...) and a counter that ticks up fast
with an audible click. Combo banks on landing with a satisfying punch:
brief screen shake, a white flash, and the score sliding into the total.
- Bailing kills the combo: red text, slow-mo for 400ms, then respawn on the spot.
- 2-minute run timer. HUD: score top-left, timer top-right, combo center-bottom.
End of run shows a score card with best trick and total.
- Audio via Web Audio API only (no files): a click for pops, a low grind noise while
railing, a thud on landing.
FEEL
- Camera follows behind and slightly above with lag and a small FOV punch when
fast. Pull back in the air so the rotation reads clearly.
- Everything should look intentional in a 30-second screen recording: readable
tricks, visible combo numbers, obvious cause and effect.
Start by writing the whole thing, then run through it once and fix anything that
prevents a full 2-minute run from being playable.
Two things in there are doing more than they look.
The negative instructions are the important ones. "No build step, no assets, no external files" is what forces every texture to be drawn in code and every sound to be synthesised, which is why the finished file is portable and why it will still run in five years. "Do not use CapsuleGeometry" is me picking the look I wanted rather than accepting the default. Models are agreeable, so the constraints you do not state are the ones you get talked out of.
The last line matters as much as the rest. Asking it to run through the thing once and fix what stops a full two minute run turns a code generator into something that checks its own work. It is the difference between being handed a draft and being handed something that has been tested, even lightly.
What actually got better
The demo is fun, but the capability underneath it is the point.
That file holds a physics engine, a level built from mathematics, a scoring system with about thirty named tricks, a synthesised sound design and a camera rig, and they all have to agree with each other. The park is the clearest example. The invisible surface the skater rolls on and the visible ramp you look at are generated by the same functions, so they can never drift apart. Change the radius of the half pipe and both the collision and the geometry move together. Nobody asked for that. It is a decision a careful engineer makes on day three of a project, and it arrived in the first pass.
Not long ago the same prompt would have given me a file that looked right and fell apart under any pressure, because holding a whole system in mind at once is a different job from writing a function. That is the thing that changed, and it is why the interesting question moved from "can it write code" to "can it hold a system".
The cost of a whim
I keep coming back to what this did to the price of an idea.
Rebuilding a game I loved as a kid was, until recently, a project. It meant a weekend to learn a 3D library, another to fight the physics, a third to make it feel like anything, and realistically it meant not finishing, because the thing that dies first is always the whim. Now it costs an evening, and most of that evening is spent playing and pointing at what feels wrong.
That is available to anyone who can describe what they want in enough detail, which is a skill, and it is a skill much closer to writing a good brief than to writing code. Look at the prompt again. There is almost no computer science in it. There is a lot of knowing exactly what I wanted, including the small things I would have been embarrassed to ask a developer for, like the score sliding into the total with a white flash.
The kid playing that PlayStation would not believe you could type a skatepark into existence. I have had it open on a second monitor all week.
Get the next essay in your inbox.
Long-form on travel, AI, and the people the platforms were not built for. One email a week. No noise.