From better-godot-mcp
Provides decision trees to debug Godot issues in physics (collisions, stuck), signals (not firing), rendering (invisible nodes), navigation (no path), and input (ignored keys).
npx claudepluginhub n24q02m/better-godot-mcpThis skill uses the workspace's default tool permissions.
Systematic debugging using domain-specific decision trees. Start by identifying the symptom category, then follow the corresponding tree.
Debugs Godot 4.3+ projects in GDScript and C# with print techniques, breakpoints, signal tracing, profiler, scene tree inspection, and common error fixes.
Builds and optimizes Godot 4 games using GDScript, node/scene architecture, signals, resources, physics, animations, UI, tilemaps, shaders, multiplayer, and best practices from prototypes to production.
Interact with running Godot games via MCP: launch projects, capture screenshots, simulate clicks/keys, inspect/manipulate scene tree and properties. For UI testing, debugging, and state verification.
Share bugs, ideas, or general feedback.
Systematic debugging using domain-specific decision trees. Start by identifying the symptom category, then follow the corresponding tree.
Map user's symptom to the right tree:
| Symptom keywords | Category |
|---|---|
| "pass through", "no collision", "overlap", "stuck", "slides off" | Physics |
| "signal not firing", "not connected", "callback not called" | Signals |
| "invisible", "not showing", "behind", "flickering", "wrong color" | Rendering |
| "not moving to target", "path wrong", "stuck on nav", "no path" | Navigation |
| "key not working", "input ignored", "wrong button", "double input" | Input |
Check in this order -- each step is the most common cause at that point:
Collision layer/mask mismatch (most common):
nodes(action="get_property", scene="<scene>.tscn", node_path="<body>", property="collision_layer")
nodes(action="get_property", scene="<scene>.tscn", node_path="<body>", property="collision_mask")
Rule: Object A detects Object B only if A's collision_mask has a bit that matches B's collision_layer. Both must be set correctly.
Missing CollisionShape2D/3D:
scenes(action="get", scene="<scene>.tscn")
Verify every physics body and Area has a CollisionShape child. A body without a shape = invisible to physics.
Wrong body type:
StaticBody2D: immovable (walls, floors)CharacterBody2D: player/NPC movement via move_and_slide()RigidBody2D: physics-driven (projectiles, debris)RigidBody2D for a player character, then fighting the physics engineScript velocity issues:
velocity is being set before move_and_slide()_physics_process (not _process)delta is used for frame-independent movementConnection exists?
[connection] entriesconnect() callsSignature match?
signal health_changed(new_hp: int) requires handler func _on_health_changed(new_hp: int)Signal emitted?
print("signal emitted") before emit_signal() / signal.emit()Callable valid?
connect() runsVisibility:
visible property = false? Check node and ALL parents (parent invisible = children invisible)modulate.a = 0? (fully transparent)Z-index:
z_as_relative = true means z_index is relative to parentMaterial/shader:
Viewport issues:
render_target_update_modeenabled = true per viewportNavigationRegion setup:
NavigationRegion2D/3D must exist in sceneNavigationPolygon/NavigationMesh resource assignedNavigation mesh baked?
bake_navigation_mesh())NavigationAgent config:
path_desired_distance: how close before moving to next path pointtarget_desired_distance: how close to target before stoppingPath calculation:
NavigationAgent.set_target_position() then check get_next_path_position()Input Map:
project.godot for [input] sectionAction name match:
Input.is_action_pressed("jump") -- exact string match requiredEvent processing:
_input() vs _unhandled_input() -- if another node consumes the event, _unhandled_input never firesset_process_input(false) disables _input() on that nodeConflicts:
For any category:
scenes(action="get", scene="<scene>.tscn")scripts(action="get", path="res://scripts/<name>.gd")nodes(action="get_property", ...)editor(action="run_scene", scene="<scene>.tscn") and check output for errors