Debug information must live in the same dimension as the problem it’s diagnosing.
Stop reading the terminal
Think about the Gatekeeper. You need a single Zealot to plug a hole in a wall to hold off a Zergling flood. It’s a high-precision move. To pull it off, you need to know exactly where your unit is standing and why it’s holding that spot.
You can’t verify spatial logic from a scrolling terminal. You have to see the unit, the gap, and the role label all in the same visual field.
This is the shift from script-level to system-level debugging. I’ll just add a print to see what value comes out is what a mechanic says when reading a diagnostic code. You’re an engineer watching a live system run.
The glass box method
You need to build a glass box.
A black box only shows inputs and outputs. That’s what print() does. It gives you raw values. The glass box method renders your system’s internal state directly into the world it operates in. You watch the agent.
Match the tool to the dimension
When your bot breaks, the bug lives in one of three native dimensions. You have to match your tool to that dimension.
1. Space: Where is the unit?
When you need to know if a unit is actually standing in the wall gap, don’t flatten a spatial problem into text with print(f”Zealot at {x},{y}”). Use debug_text_2d right on the unit’s position.
2. Time: When did the action happen?
When you need to track when a unit fired and what triggered it, don’t scatter that problem across log lines. Use chat_send to sync the event directly to your replay timeline.
3. State: What is the unit trying to do?
When you need to confirm the role a unit is playing, don’t bury a state problem in a scrolling feed. Use debug_text_screen to keep persistent labels on the screen.
If you stop flattening your bot’s thoughts into text, you’ll stop guessing what it believes.