Debugging Godot

Symptom / cause / fix / lesson for real errors from this project.

stablegodotdebugging
On this page
Debug draw overlay used to verify collision and rooms
Headless/windowed harnesses drew overlays like this to catch bad stand slots and missing wall openings.

Use this as a searchable catalogue. Each entry is something we actually hit or narrowly avoided while building Night Audit.

Null node / null instance

Symptom

Invalid access to property or key 'position' on a base object of type 'null instance' (or .text, .texture, …).

Cause

$Path/To/Node or @onready path no longer matches the scene after a restructure.

Fix

Update the path; verify in the remote scene tree; prefer groups for cross-scene finds.

Lesson

Node paths are strings, not binding contracts.


Autoload missing under --script / --check-only

Symptom

Compile Error: Identifier not found: GameState — or guest instantiates as bare CharacterBody2D and assigning guest_data fails.

Cause

Those CLI modes do not initialize autoloads; scripts referencing them fail to attach.

Fix

Run a real .tscn as main scene. Ignore --check-only false positives for autoload ids.

Lesson

Headless verification must boot the project normally.


Typed Array[T] assignment

Symptom

Assignment errors or empty dialog lines when setting Array[Dictionary] / Array[String] from a generic Array.

Cause

GDScript typed arrays reject many bare = copies.

Fix

typed_array.assign(source) — used in dialog_box.start_dialog.

Lesson

.assign() is the safe fill API.


Dialog index / first line repeats

Symptom

lines.size() is correct but the second line never appears, or line 1 shows twice.

Cause

Same interact press opens and advances; or current_line not reset; or show/increment order wrong.

Fix

Reset index on open; is_open mutex; set_input_as_handled() on both guest and dialog.

Lesson

One input event → one handler.


Control anchored to the wrong edge

Symptom

Dialog (or HUD) stuck at the top after layout changes.

Cause

Default top-left anchors + offsets meant for bottom placement; or UI not on CanvasLayer.

Fix

Bottom anchors (anchor_top = anchor_bottom = 1.0) + negative offsets; keep UI on CanvasLayer.

Lesson

Do not position Control like Node2D.


Screenshot / capture lag

Symptom

Saved PNGs show the previous camera position; looks like level misalignment.

Cause

get_viewport().get_texture().get_image() before the renderer catches up. physics_frame is not enough.

Fix

for i in 8:
	await RenderingServer.frame_post_draw

Lesson

Sync captures to the renderer.


Headless hang on parse error

Symptom

Godot runs forever with an empty scene; real error scrolled off.

Cause

Main script failed to parse; no --quit-after.

Fix

Always pass --quit-after N (frames). Read the head of the log.

Lesson

Unattended runs need an exit valve.


Type inference on untyped nodes

Symptom

Cannot infer the type of "x".

Cause

var x := node.state when node is Node.

Fix

var x: int = node.state.


Station enum id collision

Symptom

Guests fail schedule steps for ELEVATOR after renaming enum entries; or two stations share one id.

Cause

.tscn stores enum as integer; inserting values shifts indices; register_station overwrites dictionary keys.

Fix

Reassign exported id on every Station node after enum edits.

Lesson

Treat enum order as serialized data.


Props with centered = true on full-canvas art

Symptom

Desk / stairs / carpet appear shifted by hundreds of pixels.

Cause

Art is authored on the full room canvas; default centered sprites offset by half size.

Fix

centered = false on room props and backgrounds.


Input map empty for WASD

Symptom

Arrows work (ui_*) but WASD does nothing.

Cause

Custom actions never created, or keys not added to ui_left etc.

Fix

Project Settings → Input Map (we bound WASD onto existing ui_* actions).


Symptom

Guests fail to path right after scene load.

Cause

Navigation map syncs a frame later.

Fix

await get_tree().physics_frame before GuestManager.start_arrivals in game.gd.