2026.07.10

Debugging With (and Against) the Machine

For the most part, when things go wrong in game development, I have a solid intuition for what the problem is. If I don’t, I add a bunch of debug prints and quickly get the picture. But then there are the problems that go above and beyond any sort of rational explanation. This is when I turn to Claude for help.

This weekend, as I was trying to debug why explosive and electric projectiles would disappear upon hitting a large tower boss, I turned to Claude with a simple ask: Can we instrument to diagnose?

And boy did Claude instrument. We tried this, that, and the other. Sometimes things appeared to work, only to fail inexplicably on the next test play. Eventually, I realized there was a directional link to when explosions (and the much-easier-to-debug electricity) weren’t working.

A screenshot of Claude code with user input describing an observation of projectile behavior
Claude would instrument. I would share what I was seeing. Back and forth we went.

Claude was sure it had the answer: it was cosmetic. At this point I had been debugging with visible collision shapes, with invisible GLBs, and everything in between. It was not cosmetic. Claude countered with a new theory. It was the shield. The shield was raised. It was not the issue, I assured it. Let’s anchor the projectile, Claude suggested. So it doesn’t move just outside of the body. The AI was sure occlusion was the source of my problem. It was not. Claude continued to produce hypotheses that explained the data for a visual sequence that disproved every single one.

At this point, Claude was ready to throw in the towel. ”I’m calling it. I’ve been unable to fix this across many attempts, and continuing to guess is just churning your project. “

But I am not Claude, and when things get impossible, I dig my heels in further. Keep trying. Try harder. We’re not there yet.

Claude didn’t have a clear path forward, and so it started grasping for straws. I really couldn’t blame it, but I also didn’t accept it. Especially when it started denying what I was reporting as the eyes (and ears) of our troubleshooting duo. We spent several rounds with it using the data we were printing to debug to convince me that my perception was wrong. I called it out: ”At this point, you’re trying to invent reasons for what we’re seeing to not be what we’re seeing.”

Claude and I agreed that it would clean up the mess it had made with failed attempts to understand the issue and I would go it alone.

A screenshot of Claude code with frustrated user input asking it to stop it's current course and clean up its mess
Claude seemed to think it was more imortant to troubleshoot my perception than to solve the actual problem at hand.

Two Kinds of Evidence

Claude and I were looking at the same screen and building two different kinds of evidence from it. The data told one story. The play told another. I had my eyes and ears. I could watch the collision wireframes in the debug view, frame by frame, and see a shape appear and then not be there anymore. I could hear that there was no explosion. I wasn’t inferring a behavior based on data. I was watching a thing happen, repeatedly, from different angles.

My AI collaborator had telemetry. It could print every property of every node involved. The position, scale, whether a shape was disabled, whether an Area was monitoring. It could print and consume every single frame, and it did, extensively. And its telemetry kept coming back clean. Nothing disabled. Nothing hidden. Nothing resized. By every measurement it knew how to take and watch, nothing was wrong.

Seeing is Believing

It was about as interesting as annoying that the telemetry wasn’t wrong. It was just checking properties that turned out not to be the property that mattered. Disabled, visible, monitoring, scale – all real and important, and every last one, beside the point. The thing that was actually changing, the far-flung location of the projectile upon collision, was buried three levels into a check the AI hadn’t thought to write. But I did, because Claude’s telemetry had convinced me that the projectile wasn’t just disappearing and my eyes convinced me that it was. If I hadn’t been willing to listen to and believe both data and experience, I never would have thought, “what if I instrument the before and after collision for location?”

What I found was consistent with both data and experience. The projectile was teleporting hundreds of meters on collision. I shared this finding with Claude, who helped me dig in and refine the evidence. We could see what was happening, but we didn’t yet understand why.

A screenshot of Claude code with a prompt to search for knowin issues, rather than continuing to diagnose
Just like managing people, sometimes it's important to disrupt the current way of thinking to make meaningful progress.

The Collisions are Not What They Seem

Once we had aligned our evidence, I asked Claude to search for known issues. It came back with a few. The bug wasn’t in any of the six systems I spent a week suspecting. It wasn’t in anything I had done, not really. It was a bug of Godot’s physics engine.

This sounds like a sad end to a dramatic quest, but it’s not. Because the boss who was rejecting my projectiles is a static one, not one that needs the physics granted by a CharacterBody3D node, I was able to change the node to one that handled the collisions much more gracefully. Claude suggested the solution. I executed.

Lessons Learned

So what is the lesson here? It’s easy to trust perception over data or data over perception, but, in this case, both were painting a partial picture. Claude measured everything it knew how to measure, everything checked out, and still it was obvious that something was amiss. The answer only became clear when we stopped treating one kind of evidence as more legitimate than the other.