Skip to content
Development
Skill

/addon-development

Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels

From plugin
godot-prompter
54157 skills9 agents1 hook
Install
$ npx -y skills add jame581/GodotPrompter --skill addon-development --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/addon-development

Context preview

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

Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels

SKILL.md

addon-development.SKILL.md
name: addon-development
description: Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels

Addon Development in Godot 4.3+

Editor plugins extend the Godot editor itself: custom node types, inspector panels, dock widgets, 3D gizmos, and toolbar buttons. All examples target Godot 4.3+ with no deprecated APIs.

> **Related skills:** **resource-pattern** for custom Resource editors, **godot-ui** for editor panel UI, **csharp-godot** for C# plugin development.

---

1. Plugin Structure

Every plugin lives inside `addons/` at the project root. Godot discovers plugins by scanning for `plugin.cfg` files.

res://
└── addons/
    └── my_plugin/
        ├── plugin.cfg          # required — plugin metadata
        ├── plugin.gd           # main EditorPlugin script (named in plugin.cfg)
        ├── my_inspector.gd     # optional — EditorInspectorPlugin
        ├── my_dock.tscn        # optional — dock panel scene
        └── icons/
            └── my_node.svg     # optional — custom node icons

`plugin.cfg` is a plain INI file. Godot reads it when scanning `addons/`. The `script` key must point to the main plugin script relative to the plugin folder.

Enable the plugin: **Project → Project Settings → Plugins** → tick the checkbox next to your plugin name.

---

2. @tool Annotation

`@tool` makes a GDScript (or its C# equivalent) run inside the editor process as well as at runtime. Without it, the script only runs when the game is playing.

GDScript

@tool
extends Sprite2D

# Engine.is_editor_hint() is true when running inside the editor,
# false during a running game. Use it to guard editor-only logic.
func _process(delta: float) -> void:
    if Engine.is_editor_hint():
        # This block runs in the editor viewport — safe to call editor APIs.
        update_configuration_warnings()
    else:
        # Normal game logic here.
        pass


# _get_configuration_warnings() returns an array of strings shown as
# yellow warning icons on the node in the Scene panel.
func _get_configuration_warnings() -> PackedStringArray:
    var warnings := PackedStringArray()
    if texture == null:
        warnings.append("Texture is not set. Assign a Texture2D in the Inspector.")
    return warnings

C#

#if TOOLS
using Godot;

[Tool]
public partial class MyToolSprite : Sprite2D
{
    public override void _Process(double delta)
    {
        if (Engine.IsEditorHint())
        {
            // Editor-only logic — safe to call editor APIs here.
            UpdateConfigurationWarnings();
        }
        else
        {
            // Normal game logic.
        }
    }

    public override string[] _GetConfigurationWarnings()
    {
        if (Texture == null)
            return new[] { "Texture is not set. Assign a Texture2D in the Inspector." };
        return System.Array.Empty<string>();
    }
}
#endif

> Wrap C# tool scripts in `#if TOOLS` / `#endif` to prevent the class from being included in exported builds. GDScript `@tool` scripts are excluded from exports automatically.

**Key rules:**

  • Add `@tool` / `[Tool]` at the top of every script that needs editor access.
  • Always guard runtime-only code with `Engine.is_editor_hint()` to avoid crashing the editor when processing begins before the scene is fully loaded.
  • Call `update_configuration_warnings()` whenever a property changes that might affect the warning state.

---

3. EditorPlugin Base

The main plugin script extends `EditorPlugin`. Godot calls `_enter_tree()` when the plugin is enabled and `_exit_tree()` when it is disabled or the project is closed. **Everything added in `_enter_tree()` must be removed in `_exit_tree()`.**

GDScript

# plugin.gd
@tool
extends EditorPlugin


func _enter_tree() -> void:
    # Register a custom node type. The editor shows MyNode in the
    # "Add Node" dialog under the chosen base class, with a custom icon.
    add_custom_type(
        "MyNode",                              # name shown in editor
        "Node2D",                              # base class to extend
        preload("res://addons/my_plugin/my_node.gd"),
        preload("res://addons/my_plugin/icons/my_node.svg")
    )

    # Add a menu item to the Project menu (top toolbar).
    add_tool_menu_item("My Plugin Action", _on_tool_menu_item)


func _exit_tree() -> void:
    remove_custom_type("MyNode")
    remove_tool_menu_item("My Plugin Action")


func _on_tool_menu_item() -> void:
    print("My Plugin Action triggered")

C#

// Plugin.cs
#if TOOLS
using Godot;

[Tool]
public partial class MyPlugin : EditorPlugin
{
    public override void _EnterTree()
    {
        AddCustomType(
            "MyNode",
            "Node2D",
            GD.Load<Script>("res://addons/my_plugin/MyNode.cs"),
            GD.Load<Texture2D>("res://addons/my_plugin/icons/my_node.svg")
        );

        AddToolMenuItem("My Plugin Action", new Callable(this, MethodName.OnToolMenuAction));
    }

    public override void _ExitTree()
    {
        RemoveCustomType("MyNode");
        RemoveToolMenuItem("My Plugin Action");
    }

    private void OnToolMenuAction()
    {
        GD.Print("My Plugin Action triggered");
    }
}
#endif

**add_custom_type parameters:**

| Parameter | Description | |---|---| | `name` | The name shown in the Add Node dialog | | `base` | String name of the Godot base class | | `script` | The GDScript / C# script resource | | `icon` | A `Texture2D`, typically a 16×16 SVG |

**add_tool_menu_item** adds an entry under **Project** in the top menu bar. Pass a `Callable` that takes no arguments.

Unsaved-State & Script Editor Control (Godot 4.7+)

Godot 4.7 adds file-management APIs useful for build/export tooling — check for unsaved work before running an action, or refresh scripts changed by an external tool.

func _run_pre_build_check() -> void:
    var unsaved_scenes := EditorInterface.get_unsa
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