Building · Side Project · 2026

I built a physics game with my design vocabulary

A few weeks, zero lines of code written by me, and two very demanding customers under five feet tall.

See the finished game
One of Ian's sons playing Moto Hill Rider on an iPhone, mid-run through the jungle level
Role Designer, in the loop
Stack Swift · SpriteKit · Claude Code
Lines of code I wrote Zero
QA team Two kids, brutal

My sons and I love Hill Climb Racing. What stands out the most is the physics engine. At some point I started wondering: could I build something like it? Not a clone. Just something in that spirit, with our own weird ideas in it.

A few years ago the honest answer would have been no. But the latest AI tools have made new environments approachable to everyone. I've coded plenty, mostly front-end, mostly prototypes. But a native iOS game with a real physics engine sat firmly on the other side of a line I'd never crossed.

So I opened Claude Code and started.

A prototype that refused to stay a prototype

Moto Hill Rider is a SpriteKit side-scroller written in Swift. A motorcycle with a physics body rides procedurally generated terrain. Over a few weeks of sessions it grew into something much bigger than the prototype I'd planned:

Five levels, each with its own terrain generator and art: mountain, desert, water (with a jetski and buoyancy physics), Saturn (lower gravity, crater jumps), and an Amazon jungle. A garage of vehicles, including a hover bike that glides like it's on ice and a dune buggy with a roll cage. A monster chasing you on every level (a big feature my youngest son added), from a kraken with animated tentacles to a smoke-bodied specter with mechanical arms. Ragdoll crashes with a cinematic camera. Haptics tuned to landing force. A local leaderboard. An app icon. All of it running on a real phone, pushed over WiFi at the end of each session.

I never wrote a line of it. That's not the interesting part, though. The interesting part is what I did instead.

Feel is a spec

I started with some hand sketches and a plan to feed Claude, as well as a fresh game environment within Xcode. The first experiments, right off the bat, were laughably bad. In the beginning I was speaking in feelings, describing what I was experiencing to Claude and working back and forth as if I'd hired an engineer.

"When I hit the gas, it moves forward, but really slow and only on the front wheel. The back wheel pops up and it slowly pushes forward, like its really heavy."

No stack trace. No code reference. Just a description of what felt wrong. Claude diagnosed it: the propulsion code was applying torque to a rigid body, which rotates the chassis instead of driving the wheels. It swapped in a forward force. The bike drove, but there was always a surprise after the build.

That became the entire working method. I described symptoms in the language I'd use with an engineer across a desk. "The front wheel bounces up and down." "It flops around, let's revert." "Softer landings, like suspension." Every one of those sentences was a complete, executable spec.

But this wasn't sustainable. I needed a better way to communicate.

Five builds, oldest to newest. They get progressively better, and the early ones are honestly the best part.

Attempt one. Proof of life. A physics body, a terrain, and a bike that moves in a way no motorcycle ever has. This is the thousand-pound front-wheel era.
Attempt two. This one made me spit my coffee out. The physics on the single wheel was actually quite good, though.
Attempt three. We now have a bike that stays in one piece and respects the terrain boundary, but lacks any sense of traction. This was a tough hurdle to move past.
Attempt four. Ok, we've got forward movement, but the power is being generated from the chassis and not the wheels?
Attempt five. Progress! Things are starting to come together. This is technically working. Minimum embarrassing product?

Speaking in numbers

Describing feel worked for most problems. But at one point it hit a wall. The bike simply wouldn't move, and "it doesn't move" wasn't enough signal for either of us. I couldn't see into the code. Claude couldn't see my screen.

So we built an instrument. Claude swapped the distance counter for a live readout at the top of the screen: three numbers showing horizontal velocity, world position, and whether the physics body had fallen asleep. Then it gave me a decoding table. Each combination of numbers pointed to a different diagnosis.

The live readout at the top of the game screen showing v103 x99 r0 The live readout, top of the game screen: velocity, world position, rest state
What the numbers show What it means
v↑ x– r0velocity climbs, position flat Something is resetting the bike every frame
v0 x– r1velocity zero, body asleep Input is being ignored. The physics body checked out
v↑ x↑ r0velocity climbs, position climbs It's moving. The camera is the liar. That's the state in the screenshot: v103, x99, wide awake.

I rebuilt, held the gas, and read three numbers back. That was the whole conversation. We were finally looking at the same gauge.

What started as a debugging trick became our main channel for tuning. Once the numbers were on screen, I could watch velocity change while feeling the acceleration under my thumb, and report both at once. That's how we landed the friction and velocity formula. Not by Claude guessing at constants, and not by me describing vibes into the void, but by iterating against shared data until the numbers and the feel agreed.

Designers already know this pattern. It's instrumentation. It's the same reason we watch session replays instead of asking users what they did. When you and your collaborator can't see through each other's eyes, you build a shared view and point at it together. It just turns out that works when your collaborator is an AI, too.

The instincts transfer

Here's the thing I didn't expect. When Claude added suspension, it handed me tuning knobs: stiffness, damping, rebound, travel. I knew exactly what to do with those. They're the same parameters as a spring in Framer or Principle. I've been tuning them for fifteen years, just never on a rigid body with real gravity.

That's the real story of this project. AI tools didn't teach me game physics. They made the judgment I already had usable in a domain that used to require a specialist. The problem space was new. The instincts weren't.

At one point I asked, just for fun, what would happen if we set the top speed to 1,000,000. Claude made the engine exponential so we could actually get there, predicted what would break, and let me run the experiment. It played better with no speed limit. We kept it. That's playtesting instinct beating spec, and it's a decision I made in exactly the way I'd make it in a design review.

Two customers, under five feet tall

I wasn't building this in a vacuum. My sons were the customers, and they are brutal ones. No politeness bias. If a feature is boring they hand the phone back.

So the loop looked like this: build in a session, push to the phone over WiFi, hand it over, watch. What made them laugh got amplified. What they ignored got cut or reworked. Ragdoll crashes exist because crashing was funnier than riding. The crash got floppier because they wanted more cinema. Monsters chase you because being chased is scarier and scarier is better. "Bigger crashes" was the most consistent piece of user feedback I've ever received, and we shipped it repeatedly.

It's the full product loop, compressed: real users, direct observation, same-day iteration, on-device releases. The tools changed. The craft didn't.

The finished game: five levels, a full garage, and every monster the QA team demanded.

The gap between designing something and building it is closing fast.

A few weeks of sessions, mostly evenings. Zero dollars beyond subscriptions I already had. The expensive part was never the code. It was the judgment about what to build next and whether what we'd built was right, and that part still belongs entirely to the human in the loop. This project moved my sense of where the edge is. Physics engines, native iOS, real devices. All of it turned out to be reachable with the vocabulary I already had.

If you're a designer, your version of "motorcycle physics" is out there. The thing you assumed was specialist territory. It probably isn't anymore.

0 Lines of code written by me
5 Levels, each with its own terrain generator
$0 Beyond subscriptions I already had
2 Very demanding customers under five feet tall