Debugging Godot
Symptom / cause / fix / lesson for real errors from this project.
On this page
- Null node / null instance
- Symptom
- Cause
- Fix
- Lesson
- Autoload missing under --script / --check-only
- Symptom
- Cause
- Fix
- Lesson
- Typed Array[T] assignment
- Symptom
- Cause
- Fix
- Lesson
- Dialog index / first line repeats
- Symptom
- Cause
- Fix
- Lesson
- Control anchored to the wrong edge
- Symptom
- Cause
- Fix
- Lesson
- Screenshot / capture lag
- Symptom
- Cause
- Fix
- Lesson
- Headless hang on parse error
- Symptom
- Cause
- Fix
- Lesson
- Type inference on untyped nodes
- Symptom
- Cause
- Fix
- Station enum id collision
- Symptom
- Cause
- Fix
- Lesson
- Props with centered = true on full-canvas art
- Symptom
- Cause
- Fix
- Input map empty for WASD
- Symptom
- Cause
- Fix
- Navmesh path requested too early
- Symptom
- Cause
- Fix
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).
Navmesh path requested too early
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.