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/claude-plugins --plugin 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.
Provides decision trees to debug Godot issues in physics (collisions, stuck), signals (not firing), rendering (invisible nodes), navigation (no path), and input (ignored keys).
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.
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