Learn Godot - Custom Tools & Editor Plugins
Series/Learn Godot/Episode 15
Episode 15 of 23

Learn Godot - Custom Tools & Editor Plugins

Extending the Godot editor to work for you: creating EditorPlugins, @tool scripts that run inside the editor, custom inspectors with EditorInspectorPlugin, and asset pipeline automation and reusable editor utilities for the whole team.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 14, you made a fast, measurable game. Now it's time to speed up the other side: your own workflow. Godot differs from many engines — the entire editor is built on the same nodes as your game, so you can write your own tools that run inside the editor. Episode 15 covers custom tools & editor plugins.

This episode's roadmap: the anatomy of EditorPlugin, creating your first editor menu and dock panel, @tool scripts that run in the editor, custom inspectors with EditorInspectorPlugin, asset pipeline automation, and finishing with reusable editor utility patterns.

EditorPlugin Anatomy

All editor extensions are rooted in one class: EditorPlugin. It's the entry point into the editor: from there you can add menus, create dock panels, register inspector plugins, and connect to editor signals. Plugins are declared through a plugin.cfg file in the addons/ folder:

plugin.cfg file that registers the plugin
[plugin]
 
name="Level Builder"
description="Alat untuk menyusun level lebih cepat"
author="Arman Dwi Pangestu"
version="1.0"
script="plugin.gd"

Once this file is created and its script filled in, enable the plugin via the Project → Project Settings → Plugins menu. Godot loads and runs that script inside the editor. Its two required functions are _enter_tree and _exit_tree:

PythonEditorPlugin skeleton
@tool
extends EditorPlugin
 
func _enter_tree() -> void:
    add_tool_menu_item("Buat Level Baru", _buat_level)
 
func _exit_tree() -> void:
    remove_tool_menu_item("Buat Level Baru")
_enter_tree is called when the plugin activates

add_tool_menu_item adds an entry to the Tool menu in the editor. Because plugins run inside the editor, they have access to EditorInterface — the gateway to the currently open scene, the FileSystem, and much more.

Creating Your Own Dock Panel

A tool menu is enough for one-click actions, but for tools used repeatedly, create a dock panel — a window that can be pinned to the side of the editor. The process: create a regular UI scene, save it as panel.tscn, then register it via add_control_to_dock:

PythonRegistering a custom panel as a dock
@tool
extends EditorPlugin
 
var panel: Control
 
func _enter_tree() -> void:
    panel = preload("res://addons/level_builder/panel.tscn").instantiate()
    add_control_to_dock(DOCK_SLOT_LEFT_UL, panel)
 
func _exit_tree() -> void:
    if panel:
        remove_control_from_dock(panel)
        panel.queue_free()
Docks can be placed on the left or right of the editor

Because a panel is just a regular Control node, you build it exactly like game UI: buttons, labels, and containers. The difference: it lives inside the editor and can read the currently open scene via EditorInterface.

Tool Scripts: Running Inside the Editor

Godot's most powerful feature for tooling is the @tool annotation (in Godot 3, the keyword is tool). Regular scripts only run while the game runs; @tool scripts also execute inside the editor. This opens the door for nodes that compute their own visuals when a scene is opened.

A classic example: a marker node that draws its radius circle directly in the editor, so level designers see the area without running the game:

Python@tool node that draws a gizmo in the editor
@tool
extends Node2D
 
@export var radius: float = 100.0
 
func _ready() -> void:
    if Engine.is_editor_hint():
        queue_redraw()
 
func _draw() -> void:
    draw_circle(Vector2.ZERO, radius, Color(0.4, 0.8, 1.0, 0.3))
_draw is called in the editor because of @tool

The Engine.is_editor_hint() pattern is a must-know: it tells you whether the script is being run in the editor. Use it to protect code that only makes sense when the game runs — like accessing autoloads or input — so the editor doesn't error when opening scenes.

Info

When creating @tool scripts, always ask: does this function need to run in the editor, or is running in the game enough? Careful @tool code (protected by is_editor_hint()) saves the team from confusing editor errors.

Custom Inspectors with @export_custom

Often what you need isn't a big panel, but better controls in the Inspector. @export_custom lets you provide your own control for a property:

PythonCustom export with an enum-based range
@export_custom(ProceduralType)
var tipe: ProceduralType = ProceduralType.HILL
 
func _validate_property(property: Dictionary) -> void:
    if property.name == "tipe":
        property.hint = PROPERTY_HINT_ENUM
        property.hint_string = "Bukit, Lembah, Gunung"
The editor shows a dropdown, not random numbers

_validate_property gives you full control over how a property appears in the Inspector. For truly custom controls — color sliders, graphs, action buttons — use EditorInspectorPlugin: create a subclass, register it via add_inspector_plugin(), and in parse_property you can add custom controls to the Inspector of any node of a matching type.

Asset Pipeline Automation

Editor plugins can also be pipeline automation: repetitive work that shouldn't be done by hand. A common pattern is processing assets when they're imported. Godot provides the filesystem_changed and scene_imported signals, which you can connect from a plugin to run post-processing steps.

A concrete example: a plugin that reads all level configuration files in the levels/ folder, validates their IDs, then writes the level list to a JSON file when the editor closes:

PythonRewriting the level list when files change
func _on_filesystem_changed() -> void:
    var daftar: Array = []
    var dir := DirAccess.open("res://levels")
    if dir:
        for nama in dir.get_files():
            if nama.ends_with(".tscn"):
                daftar.append(nama.trim_suffix(".tscn"))
    var file := FileAccess.open("res://levels/index.json", FileAccess.WRITE)
    file.store_string(JSON.stringify(daftar))
DirAccess and JSON make a simple pipeline

With patterns like this, designers add levels without touching code — the plugin keeps the index in sync. That's the essence of workflow automation: shifting mechanical work from humans to the editor.

Reusable Editor Utilities

A good plugin doesn't just solve one problem; it solves recurring problems for the whole team. Some patterns worth making into plugins:

  • Shortcut generator: adds frequently used action menus, like "add standard material" to all selected nodes.
  • Batch renaming: renames nodes or files in bulk according to a pattern.
  • Scene sanity check: a plugin that scans scenes for unconfigured nodes or wrong settings.

To keep plugins maintainable, store them per-feature in the addons/ folder and use version control. A clean structure looks like this:

plaintext
addons/level_builder/
├── plugin.cfg
├── plugin.gd
└── panel.tscn

Conclusion

You can now extend the Godot editor: EditorPlugin as the entry point for menus, docks, and inspectors, @tool scripts that run in the editor for direct visualization, @export_custom and EditorInspectorPlugin for clean Inspector controls, asset pipeline automation through editor signals and file IO, and small plugin patterns reusable by the whole team.

The key takeaways:

  • A plugin starts with plugin.cfg and an extends EditorPlugin script in the addons/ folder.
  • Dock panels are regular Control nodes registered via add_control_to_dock.
  • @tool runs scripts in the editor; Engine.is_editor_hint() protects game-only code.
  • @export_custom and EditorInspectorPlugin give full control over the Inspector.
  • Pipeline automation (validating and writing indexes) shifts mechanical work off humans.

In episode 16, you touch the most visual layer of a game: shaders & visual effects — Godot's shader language and material workflow, fragment shaders for 2D, spatial materials for 3D, and combining shaders with particles for stunning VFX. All the cool effects you see in commercial games start from a single shader file.

Learn Godot - Custom Tools & Editor Plugins | Learn Godot