跪拜 Guibai
← Back to the summary

Zero Handwritten Lines: Claude Code Built This Godot Tower Defense in 5 Days

Vibe coding a small game · Kickoff: 5 days, 8,400 lines of code, no line handwritten, and getting the AI to check its own work first

Current state of Holy Light Defense: home, campaign, battle

The image above shows what the game looks like now. It's called "Holy Light Defense", a vertical tower defense, started on October 25 — that's day 5:

All that code was written by Claude Code. I did not handwrite a single line. What I did was specify requirements, playtest, make the call, and handle things like account registration and QR code login that can only be done by a person.

This series records the entire process chronologically from kickoff to release: kickoff, gameplay, assets, packaging, WeChat mini game, versus mode, Douyin and software copyright, release. It has not been released yet; later posts will follow the progress.

This post covers day one — kickoff. Three things deserve their own discussion: what the AI asked before starting, which platform constraints it found after the engine was locked in, and why it built a toolset for the AI to inspect its own work before writing the first line of gameplay code. The ability to keep adding features over the next 5 days rests on that toolset.

The first words of kickoff: the AI asked 4 questions first

My first sentence to Claude Code was: make a tower defense game, use Godot, and reference an old game for the characters.

It did not start writing. It raised a copyright question first: the character names and art of that game belong to the original publisher. If the plan is a public release, only the gameplay and theme can be borrowed; the names, art, and data are unusable. Then it pinned down the scope with four multiple-choice questions:

Question My choice
How will the output be used? Public release
How to handle art assets? AI-generated original assets
What form of tower defense? Path tower defense (enemies follow a fixed path, player builds along the roadside)
How big is the first playable version? Minimal playable: 1 map, 3 tower types, 8 waves of undead, gold and hit points

These four questions seem ordinary, but each one mattered later. "Public release" meant copyright rules were written into the project notes from day one: no existing game names may appear in the code, data, art, or image generation prompts. "Minimal playable" meant a fully completable match existed by the end of day one, and every later change built on top of that match.

I chose Godot; the AI uncovered platform constraints

I specified the engine outright without cross-comparison. The AI didn't challenge the choice; instead, after I named the target platforms — Steam, WeChat mini game, and Douyin mini game — it checked Godot's situation on each platform. Findings:

The AI's recommendation: keep Godot, build the Steam version as planned, and after finishing the three maps, spend a day or two exporting to real devices for verification — if verification fails, consider switching engines. Later events proved this necessary: real devices got stuck loading, iPhones showed black screens — these problems only surfaced at this stage, covered in detail in part 5.

On day two, another global decision was made: unified vertical orientation across platforms, even on PC a tall narrow window. The resolution changed from 1280×720 to 720×1280; all three maps were rearranged for vertical; the top-right reserved space for the WeChat mini game capsule button. The later this decision comes, the more rework.

Build tools first, so the AI can check its own work

Using AI to write games has a natural blind spot: it cannot see the screen and never plays the game by hand. Code compiling does not mean the game is playable; tests all passing does not mean the screen has no misalignment. So on day one, before writing gameplay, a toolset for the AI to verify itself was built — all as make commands:

Command What it does Problem it blocks
make test Runs all unit tests (GUT framework), headless, non-zero exit on failure Changing one thing breaks another
make lint Treats GDScript warnings as errors Godot's CLI doesn't print warnings by default, problems silently linger
make smoke Headless game start, auto-completes a level at 8x speed, fails on any engine or script error Runtime errors unit tests don't catch
make frames Auto-plays a level, saves one PNG per game second The AI can't see the screen

The first three follow standard practice, but each has Godot-specific traps. For instance, Godot's CLI never prints GDScript warnings. Without special handling, warnings never appear in the output the AI can see. make lint works by temporarily adding a config file that escalates all warnings to errors, then deleting it after the run.

For testing, a project rule requires writing tests before writing implementation. Test count went from 118 on day one to the current 573. The AI honestly stated a limitation: GDScript has no coverage tooling, so the "80% coverage" requirement cannot be measured — the test-first habit is the only guarantee.

make frames: letting the AI see the game screen

make frames capture: AI reads images one by one to check visuals

The fourth command is the most critical of the set. Godot's built-in recording feature can output the game frame by frame as images. make frames runs the game auto-playing the first level at 4x speed for 90 seconds, saving one PNG per game second — 91 images total. The AI uses its image-reading capability to go through them, checking whether characters stand on the path, health bars are occluded, and effects sit in the right positions. The project notes put it plainly: this is the only way to see the game in a command line.

Over the next five days, it was used every time the UI or art changed. When switching to vertical, the AI used the same approach to batch-capture several aspect ratios of the interface and check each image for buttons and menus out of bounds.

The toolset had its own failures; the AI tripped over it too. Once, it redirected make smoke's output to the same file it was about to read next — reading a file that grows while it reads leads to an infinite loop. Another time, more serious: it made a startup optimization that passed verification in the editor, but once exported to an installation package, an array was cleared by the engine and clicking "Deploy" crashed outright. After that, the packaging step added: after building, automatically play one level with the exported version and check the exit code. Part 4 covers that crash in detail.

Practices from day one

Practice Reason
Have the AI clarify purpose, art source, gameplay form, and first-version scope before kickoff These answers determine copyright rules, the asset pipeline, and the day-one deliverable
After the engine is decided, research platform support and package limits first, then schedule a real-device verification Mini-game platforms have thin Godot support; problems only surface on real hardware
Decide vertical or horizontal early The later the switch, the more rework on maps, UI, and screenshots
Build test, lint, auto-play, and frame capture before writing gameplay The AI can't see or play; these tools let it find most problems itself
Turn the AI's own mistakes into an automated check in the command line The same kind of problem won't slip through twice

Next article covers gameplay: how each playtest comment became the infinite level, out-of-match progression, and reinforcement-deploy systems.