Galaxy Devlog #06 · Read the Galaxy build log
I do not write code, and I cannot read it. I am building Call the Cat: Galaxy, the Unity sequel to a game I already shipped, and every line of it is written by an AI while my job is to ask for what I want and decide whether the result is actually right.
This is a direct follow-up to the last post. In Galaxy05 I showed you this screen: a night stage, a moon icon in the top corner, and a fire-type fox standing right underneath it, on a stage where fire monsters are not allowed. At the time, the whole story was “the AI says it put the code in, and I have not checked it yet.”

The same screen from the last post: night stage “4-2,” a moon icon top-right, a fire-type fox standing in front of it. This post is about what I found when I finally checked.
Then I checked. The first fix was only half done, and this post is what happened after that screenshot.
I had assumed the AI would need to change one thing: the function that filters which monsters a stage is allowed to spawn. Fix the condition there, and the wrong monster stops appearing. That assumption was wrong, and it was wrong in a way that does not show up as an error.
One rule, three call sites
The monster rule is easy to say. On a night stage, exclude fire-type monsters. On a day stage, exclude ice-type monsters. The rule itself was never the problem. The problem was that three different parts of the game ask for that filtered list, and they do not all ask the same way.
The first caller is the live battle roster — the code that actually places monsters on the planet while you are playing. The second is the planet preview, the screen that shows you a stage’s monster lineup before you enter it. The third is respawn, which rebuilds a monster after you have defeated it.
The first patch changed the condition inside the live battle roster. It did not touch the other two. And the preview caller had a specific defect: it was not passing the time-of-day value at all. The filter function takes a parameter for whether it is currently night, and that parameter has a default compiled into it — night = false, meaning “treat this as day.” The preview code and the respawn code were both calling the filter without ever telling it what time it was, so it silently used that default. The screen was night. The preview and the respawn were reading the day list.
That is why the “fix” looked fine and wasn’t. The live roster had been corrected, so a quick glance at a fresh spawn could look right — but walk into the stage preview and a fire fox was still sitting in the lineup, and any monster that died and came back came back off the wrong list.
Here is the part that makes this easy to miss entirely. None of it produces an error. Leaving out an argument that has a default is legal: the program compiles, runs, and hands you monsters. They are just the wrong monsters, on two of the three paths, some of the time. There is nothing red to catch and no stack trace to read.
Make it find before it fixes
The second time around I changed the order of operations. Before asking for any change, I asked for a list.
The instruction was: “List every call site that uses this monster-filter rule, with file path and line number. For each one, mark whether it actually passes the time-of-day value or relies on the default. Do not change anything yet.” The list came back with the three callers named and their line numbers, and with the preview and respawn entries flagged as passing nothing. Only then did we go through each one, confirm it was handing over the real PlanetIsNight value, and fix all three together.
Then a static check, because that is the check I can run without shipping a build. Under night conditions the AI ran the monster draw twenty-four times and confirmed that no hot_ (fire-prefixed) monster came out. Under day conditions it ran the same draw and confirmed no ice_ monster came out. That is a real check and it passed. What is still not done is me turning the game on, walking back into that exact stage, and watching it with my own eyes. By my own rule from the last post, until I do that, this is “code is in, statically verified” — not “fixed.”
Copy this
If you are directing an AI to change a shared condition — a monster filter, a permission check, a price calculation, a save-file validator, anything more than one screen depends on — send this before you let it touch the code:
“List every call site that uses this rule, with file path and line number. For each one, show whether it passes the state value it needs or falls back to a default. Do not edit anything yet.”
Get the list first. Then check three things against it: that no call site is missing, that no required value is being quietly replaced by a default, and that every path where the outcome actually differs — live use, preview, rebuild — runs through the same rule. The fix comes after the list, not instead of it.
Where this leaves things
“The AI only fixes one place” is not a personality flaw I uncovered. In this task the request I gave was scoped to a single function, and nobody surveyed the call sites before the edit. The AI did exactly what was asked, in the one place that was named.
What turned out to matter more than the word “fixed” was the list of paths that use the rule. I had one of the three in my head. The code had three. That gap is not something I can catch by reading — but it is something I can ask for, out loud, before anything gets changed.
Solo dev of Call the Cat, shipped after 178 days
on Google Play
and Steam.
Now building the sequel, Call the Cat: Galaxy, in public.
