A satirical AI-themed tower defense: you don't shoot users, you serve them. Seven markets, 140 levels, 600+ generated art assets, built in about three weeks - as an honest test of how far AI-assisted development actually goes.
A game is a brutal test case. It needs working code, hundreds of coherent art assets, level design that stays fun for twenty hours, and jokes that land. Miss on any one and the whole thing falls over. So we built one and wrote down what happened.
One person, three weeks, 580 commits. A real game shipped to a real URL - not a prototype, not a demo reel. Campaign mode, endless survival, a meta-progression tree, a knowledge base, saved progress, and an Android build.
Every decision, dead end and revert written up publicly while it happened.
Further than expected on volume - code, art and levels came fast enough that scope stopped being the constraint. Not as far on taste. The AI could tell whether a level was survivable; it could not tell whether it was boring.
The interesting work turned out to be building the tools that let a human judge quickly, then judging.
Four different kinds of output, four different pipelines - each one turned into a repeatable process rather than a lucky prompt.
Phaser 3 and TypeScript, around 17,000 lines across 54 modules: two-camera HUD, isometric projection maths, projectile ballistics with tile-ring blast falloff, wave generation, boss abilities, save system, procedural audio. A type-check gate has to pass before every single commit.
Every level gets its own funnel, generated by a script and frozen into the build. Entrances rotate across all four edges, a minimum-corner count rises as you progress, and length is bounded to what that market can afford to defend. The build aborts if any level misses its floor.
Towers, users, bosses, decor, tiles, UI icons and comic panels - all generated, then background-removed by a segmentation model, trimmed to content, logged and installed. The prompt, seed, resolution and model for all 551 generations sit in a JSON file in the repo, so any asset can be reproduced or reverted.
USA, Europe, China, Africa, Earth, Space and Rogue. Each market applies a lens that rewrites what a good answer is worth - Europe makes privacy king with a red-tape floor, China's firewall censors cheap answers. Same towers, completely different puzzle.
Satirical breaking-news interstitials between levels, taunts from thinly-veiled tech-titan bosses, and a chatbot tower that pops a different smug reply on every hit. Written to a tone spec, then filtered by a human for the ones that actually landed.
Music and effects are synthesized in code rather than sampled - menu theme, UI clicks, serve hits, explosions. Nothing to license, nothing to download, and it tunes like any other data file.
Wrapped for Android with orientation locking and a splash screen, after a performance pass that found the frame budget going to a HUD redrawing itself sixty times a second - not to the game.
Difficulty tuning is the slowest loop in game development: change a number, replay the level, guess. So the loop got handed to a headless autoplayer that drives the real game engine in a tight loop and reports how close it came to losing.
Not a dumb script. It places towers by marginal coverage using each tower's actual range, weights tiles toward the exit where leaks really happen, reads the market lens when choosing what to buy, banks currency, builds labs and spends on upgrades - because a real player does all of that, and a bot that doesn't will fail levels that are actually fine.
Running it across every level exposed problems no amount of staring at a spreadsheet would: a difficulty wall driven by damage-per-cost rather than raw damage, and bosses that leaked unserved because they trailed behind their own escort and the towers shot the escort instead.
Once it could play well, hand-tuned difficulty knobs became noise. Level design was handed over: each wave grows until the bot barely survives it. All 140 levels are tuned by something that actually played them, not by a designer guessing.
The failures are the useful part of this experiment. Every one of these is in the devlog, because a case study that only lists wins isn't worth reading.
The bot proved every level was winnable. It could not tell that some of them were dull. Three deliberately overpowered towers went in and it never even noticed - the economy absorbed them. "Survivable" is measurable; "worth twenty minutes of your evening" is not.
A whole feature - per-stat tower upgrades - shipped and was deleted the same day. It worked perfectly and made the game worse to play.
Regenerating a cohesive set one asset at a time quietly destroys it - each render drifts in scale, perspective and framing until the collection stops matching itself. The tower set got measurably worse that way and was restored from git.
A whole world shipped as another world with a red filter over it. Flat colour isn't art direction, and only a person looking at it said so.
The lesson isn't "AI builds games now." It's that generation is cheap and judgement is not, so the leverage sits in the scaffolding around the generation: a logged, reproducible asset pipeline; invariants written down where they can't be forgotten; a bot that measures the thing you actually care about; and a human whose whole job is deciding what's good. Overserved is where we built and stress-tested that scaffolding - on our own time, on a project where a bad call costs nothing.
Notes from building it - what was tried, what broke, what it taught. A sample:
The pipelines behind Overserved - reproducible generation, written-down invariants, bots that measure what matters - are the same ones we bring to client work. Go and play the result first.