Skip to content
Development
Skill

/godot-debugging

Use when debugging Godot projects — remote debugger, print techniques, signal tracing, common error patterns and fixes

From plugin
godot-prompter
54157 skills9 agents1 hook
Install
$ npx -y skills add jame581/GodotPrompter --skill godot-debugging --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/godot-debugging

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when debugging Godot projects — remote debugger, print techniques, signal tracing, common error patterns and fixes

SKILL.md

godot-debugging.SKILL.md
name: godot-debugging
description: Use when debugging Godot projects — remote debugger, print techniques, signal tracing, common error patterns and fixes

Godot Debugging

This skill covers systematic debugging for Godot 4.3+ projects in both GDScript and C#. It covers print techniques, breakpoints, signal tracing, the built-in profiler, scene tree inspection, common error patterns, and a step-by-step debugging checklist.

> **Related skills:** **godot-optimization** for performance profiling, **godot-testing** for regression tests after fixes, **csharp-signals** for C# signal debugging patterns.

---

1. Print Debugging

GDScript

Godot provides several print functions with different purposes. Choose based on the severity and context of what you are logging.

# print() — general output, space-separated values
print("Player position: ", position)
print("Health: ", health, " / ", max_health)

# print_rich() — BBCode-formatted output in the Output panel
print_rich("[color=yellow]WARNING:[/color] Enemy count exceeded limit: ", enemy_count)
print_rich("[b]State:[/b] [color=green]", current_state, "[/color]")

# push_error() — logs an error with a full stack trace; does NOT stop execution
push_error("save_game: file path is empty")

# push_warning() — logs a warning with stack trace; use for recoverable issues
push_warning("AudioStreamPlayer: bus '%s' not found, using Master" % bus_name)

# print_debug() — only prints in debug builds; stripped from release exports
print_debug("Frame delta: ", delta, " | FPS: ", Engine.get_frames_per_second())

# printerr() — prints to stderr; visible in external terminals and CI logs
printerr("Critical: physics state corrupted at frame ", Engine.get_process_frames())

**Formatted output patterns:**

# String formatting with % operator
print("Actor [%s] dealt %d damage to [%s]" % [name, damage, target.name])

# String.format() with named placeholders
var msg := "Position: ({x}, {y}) at speed {spd}"
print(msg.format({"x": position.x, "y": position.y, "spd": velocity.length()}))

# Printing arrays and dictionaries — use str() for clean output
var inventory := {"sword": 1, "potion": 3}
print("Inventory: ", str(inventory))

# Conditional verbose logging using a project-level constant or autoload flag
if DebugConfig.verbose_ai:
    print_rich("[color=cyan][AI][/color] ", agent.name, " chose action: ", chosen_action)
// String interpolation
GD.Print($"Actor [{Name}] dealt {damage} damage to [{target.Name}]");

// Printing collections
var inventory = new Godot.Collections.Dictionary { { "sword", 1 }, { "potion", 3 } };
GD.Print("Inventory: ", inventory);

// Conditional verbose logging
if (DebugConfig.VerboseAi)
    GD.PrintRich($"[color=cyan][AI][/color] {agent.Name} chose action: {chosenAction}");

**When to use each function:**

| Function | Visible in Release | Stack Trace | Use For | |---|---|---|---| | `print()` | Yes (if not stripped) | No | General value inspection | | `print_rich()` | Yes | No | Categorised, colour-coded logs | | `push_error()` | Yes | Yes | Invalid state, programmer errors | | `push_warning()` | Yes | Yes | Recoverable problems | | `print_debug()` | No | No | Verbose frame-level output | | `printerr()` | Yes | No | External terminal / CI output |

C\#

using Godot;

public partial class Player : CharacterBody3D
{
    public override void _Ready()
    {
        // GD.Print — equivalent to GDScript print()
        GD.Print("Player position: ", Position);

        // GD.PrintRich — BBCode formatted
        GD.PrintRich("[color=yellow]Ready called on[/color] ", Name);

        // GD.PushError — logs error with stack trace
        GD.PushError("_Ready: required child node missing");

        // GD.PushWarning — logs warning with stack trace
        GD.PushWarning("AudioBus not found, falling back to Master");

        // GD.PrintErr — writes to stderr
        GD.PrintErr("Critical failure in _Ready");
    }

    private void HandleDamage(int amount)
    {
        // Formatted string output
        GD.Print($"[{Name}] took {amount} damage. HP: {_health}/{_maxHealth}");
    }
}

---

2. Breakpoints and the Remote Debugger

Setting Breakpoints

  • Click the gutter (left of line numbers) in the Script editor to toggle a breakpoint. A red dot appears.
  • Use `F9` to toggle a breakpoint on the current line.
  • Use `breakpoint` as a statement in GDScript to trigger a programmatic breakpoint:
func _physics_process(delta: float) -> void:
    if velocity.length() > MAX_SPEED:
        breakpoint  # execution pauses here during debug runs
    move_and_slide()
  • In C#, use `System.Diagnostics.Debugger.Break()` or attach a .NET debugger (e.g. JetBrains Rider or VS Code with the Godot extension).
public override void _PhysicsProcess(double delta)
{
    if (Velocity.Length() > MaxSpeed)
    {
        System.Diagnostics.Debugger.Break(); // pause if .NET debugger is attached
    }
    MoveAndSlide();
}

Using the Built-in Debugger Panel

When execution pauses at a breakpoint, the **Debugger** panel (bottom of the editor) provides:

  • **Stack Frames** — the full call stack; click a frame to inspect its local variables.
  • **Locals / Members / Globals** — inspect and modify variable values live.
  • **Step Into (F11)** / **Step Over (F10)** / **Step Out (Shift+F11)** — navigate execution line by line.
  • **Continue (F5)** — resume execution until the next breakpoint.

Remote Scene Inspector

While a running game is paused or mid-session:

1. Open **Debugger > Remote** tab in the editor. 2. Click **Remote** in the Scene panel (top-left toggle next to "Scene") to switch the scene tree to the live view. 3. Click any live node to inspect its current properties in the Inspector. 4. Property changes made here are applied immediately for testing.

Monitors Tab

**Debugger > Monitors** displays real-time engine metrics:

  • **FPS / Process time / P
Read more
Ships withgodot-prompter

Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.

Get the whole plugin