Shipping Hexfall

This summer I shipped a strategy game for the iPhone. It's called Hexfall: a small 4X in the Polytopia mold, where you scout a procedurally generated island, grow cities, and take your rival's capital in about twenty minutes. Empty repo to the App Store in three weeks, 269 commits.

I should say up front how. I didn't type most of it. I decided what to build, played every build, and wrote feedback. Claude wrote the code, generated the art and sound, ran the balance sims, and drove the release. My job was taste and direction.

Hexfall main menu

I expected the code to be the hard part. It wasn't. Any one feature took an afternoon: fog of war, async multiplayer over Firestore, the whole tech tree. What ate the three weeks was everything a game studio does that isn't programming. And that was the interesting part, because I got to watch each of those jobs turn into something you invoke instead of someone you hire.

Take balance. Because the rules engine has no dependency on rendering, you can run a whole AI-vs-AI match in under a second on a laptop. So instead of arguing about whether a unit was fair, we ran tournaments. The scariest early result was that building the cheapest unit forever, warrior spam, won about 70% of matches on island maps. That looks like a broken economy. But the simulator said something more useful: the strategy only dominated because the AI never built the counter. Teach the AI to answer spam with spearmen and it collapses. So the fix wasn't a nerf, it was smarter opponents. We also got a negative result I treasure. A lever that made naval units counter harder did nothing to island balance, because the real problem was map structure, an expansion race with sparse fighting, not naval mechanics. Playtesting rarely tells you your hypothesis is wrong. A simulator does it before lunch.

What the simulator hands you is a dashboard, not a verdict. Every run reports a handful of numbers I learned to watch at once: what fraction of the units built are just warriors, how many distinct unit types the average player fields, how far cities grow, and the one that turned out to matter most, how often whoever moves first wins. You can't tune any of these alone, because they fight each other. When I added a rule tying your army size to how developed your cities are, variety and tech use climbed nicely (distinct unit types from 2.25 to 2.58, techs researched from 3.8 to 5.3 out of 8), and the same change quietly pushed first-player advantage from about 60% to 64%. Depth had gone up and fairness had gone down. So the actual work wasn't finding one good number, it was finding a change that moved the depth dials without shoving fairness past a line I'd drawn at 55%.

Balance validation report for a new unit

That report is the gate a new unit has to clear. Before the garrison knight shipped it had to pass on every map type at the same time: variety had to rise and not fall, the first player's win share had to stay under 55%, a forced warrior-spammer still had to lose to the AI that plays properly, and no map could tip into stalemates. It went in with about ten thousand simulated matches behind it instead of a hunch.

The sweeps that produce those numbers get big, so they run in the cloud. A script spins up an eight-core VM on Google Cloud, runs eight matches at once, and, the part I like most, powers the machine off the second the queue is empty. A stopped VM costs a few cents a month for its disk and nothing else, so even a ten-thousand-match sweep bills in pennies. And because the rules engine is those four dependency-free scripts, the VM pulls down about 100KB of game logic instead of the 132MB of 3D art. I once started a 5,800-match sweep across every map type from my phone on a hotspot and had the results forty minutes later. The cloud Godot is pinned to the same version as my laptop, so a given random seed plays out identically in both places. The VM is just my laptop with more cores that turns itself off when it's done thinking.

Take the assets. Sound effects, music, icons, and one 3D character that no pack sells (a knight to garrison cities) are all generated, and the pipelines are checked in as scripts. The nice part is the loop this creates. A sound is a line in a dictionary of prompts. Don't like the sword hit? Delete the file, run the script, get a new one. Sound design becomes something you do while a build compiles. It isn't free. Generated music comes with wandering intros you have to trim, and getting icons to look centered on a button took five tries and eventually a function that finds each icon's weighted center of mass, because your eye catches a five-pixel imbalance that the geometry says isn't there.

The tribe picker

Then there was the App Store, which is the actual boss level. The most expensive thing I learned: uploading a build to TestFlight and attaching it to your testers does not give it to them. There's a third step, submitting for beta review, and if you miss it the build sits in a state Apple's own UI labels "Ready to Submit," which reads like a status and not a warning. We shipped fourteen builds into that void. My dad, playtester number one, sat on an old build for a week with auto-update on, wondering why nothing changed. We chased a wrong theory about chip requirements before pulling each build's real state from Apple's API and finding the whole stack stranded in one status. After that the pattern held for the rest of the release: whenever the website confused us, the API had the answer. It even caught that the app had no price set at all, which renders as a perfectly normal page while silently blocking submission.

A battle in progress

So the three weeks felt less like programming with a fast assistant and more like being the only human employee of a company where every other role is an API. The roles didn't disappear. Sound designer, 3D artist, QA lab, release engineer, each is still a real competence with its own failure modes. They just became things you call instead of people you wait on. What didn't compress at all was the judgment: whether the sword sounds chunky enough, whether the game is fun, whether a 70% win rate is a bug or a personality.

Hexfall is on the App Store now. My dad isn't a TestFlight tester waiting on the next build anymore; he updates it from his phone like anyone else, which after the beta-review saga feels like the real finish line. He can finally see what's defending his cities.