.. _doc_making_plugins: Making plugins ============== About plugins ~~~~~~~~~~~~~ A plugin is a great way to extend the editor with useful tools. It can be made entirely with GDScript and standard scenes, without even reloading the editor. Unlike modules, you don't need to create C++ code nor recompile the engine. While this makes plugins less powerful, there are still many things you can do with them. Note that a plugin is similar to any scene you can already make, except it is created using a script to add editor functionality. This tutorial will guide you through the creation of two plugins so you can understand how they work and be able to develop your own. The first is a custom node that you can add to any scene in the project, and the other is a custom dock added to the editor. Creating a plugin ~~~~~~~~~~~~~~~~~ Before starting, create a new empty project wherever you want. This will serve as a base to develop and test the plugins. The first thing you need for the editor to identify a new plugin is to create two files: a ``plugin.cfg`` for configuration and a tool script with the functionality. Plugins have a standard path like ``addons/plugin_name`` inside the project folder. Godot provides a dialog for generating those files and placing them where they need to be. In the main toolbar, click the ``Project`` dropdown. Then click ``Project Settings...``. Go to the ``Plugins`` tab and then click on the ``Create New Plugin`` button in the top-right. You will see the dialog appear, like so: .. image:: img/making_plugins-create_plugin_dialog.webp The placeholder text in each field describes how it affects the plugin's creation of the files and the config file's values. To continue with the example, use the following values: .. tabs:: .. code-tab:: ini GDScript Plugin Name: My Custom Node Subfolder: my_custom_node Description: A custom node made to extend the Godot Engine. Author: Your Name Here Version: 1.0.0 Language: GDScript Script Name: custom_node.gd Activate now: No .. code-tab:: ini C# Plugin Name: My Custom Node Subfolder: MyCustomNode Description: A custom node made to extend the Godot Engine. Author: Your Name Here Version: 1.0.0 Language: C# Script Name: CustomNode.cs Activate now: No .. warning:: Unchecking the ``Activate now?`` option in C# is always required because, like every other C# script, the EditorPlugin script needs to be compiled which requires building the project. After building the project the plugin can be enabled in the ``Plugins`` tab of ``Project Settings``. You should end up with a directory structure like this: .. image:: img/making_plugins-my_custom_mode_folder.webp ``plugin.cfg`` is an INI file with metadata about your plugin. The name and description help people understand what it does. Your name helps you get properly credited for your work. The version number helps others know if they have an outdated version; if you are unsure on how to come up with the version number, check out `Semantic Versioning `_. The main script file will instruct Godot what your plugin does in the editor once it is active. The script file ^^^^^^^^^^^^^^^ Upon creation of the plugin, the dialog will automatically open the EditorPlugin script for you. The script has two requirements that you cannot change: it must be a ``@tool`` script, or else it will not load properly in the editor, and it must inherit from :ref:`class_EditorPlugin`. .. warning:: In addition to the EditorPlugin script, any other GDScript that your plugin uses must *also* be a tool. Any GDScript without ``@tool`` imported into the editor will act like an empty file! It's important to deal with initialization and clean-up of resources. A good practice is to use the virtual function :ref:`_enter_tree() ` to initialize your plugin and :ref:`_exit_tree() ` to clean it up. Thankfully, the dialog generates these callbacks for you. Your script should look something like this: .. _doc_making_plugins_template_code: .. tabs:: .. code-tab:: gdscript GDScript @tool extends EditorPlugin func _enter_tree(): # Initialization of the plugin goes here. pass func _exit_tree(): # Clean-up of the plugin goes here. pass .. code-tab:: csharp #if TOOLS using Godot; [Tool] public partial class CustomNode : EditorPlugin { public override void _EnterTree() { // Initialization of the plugin goes here. } public override void _ExitTree() { // Clean-up of the plugin goes here. } } #endif This is a good template to use when creating new plugins. A custom node ~~~~~~~~~~~~~ Sometimes you want a certain behavior in many nodes, such as a custom scene or control that can be reused. Instancing is helpful in a lot of cases, but sometimes it can be cumbersome, especially if you're using it in many projects. A good solution to this is to make a plugin that adds a node with a custom behavior. .. warning:: Nodes added via an EditorPlugin are "CustomType" nodes. While they work with any scripting language, they have fewer features than :ref:`the Script Class system `. If you are writing GDScript or NativeScript, we recommend using Script Classes instead. To create a new node type, you can use the function :ref:`add_custom_type() ` from the :ref:`class_EditorPlugin` class. This function can add new types to the editor (nodes or resources). However, before you can create the type, you need a script that will act as the logic for the type. While that script doesn't have to use the ``@tool`` annotation, it can be added so the script runs in the editor. For this tutorial, we'll create a button that prints a message when clicked. For that, we'll need a script that extends from :ref:`class_Button`. It could also extend :ref:`class_BaseButton` if you prefer: .. tabs:: .. code-tab:: gdscript GDScript @tool extends Button func _enter_tree(): pressed.connect(clicked) func clicked(): print("You clicked me!") .. code-tab:: csharp using Godot; [Tool] public partial class MyButton : Button { public override void _EnterTree() { Pressed += Clicked; } public void Clicked() { GD.Print("You clicked me!"); } } That's it for our basic button. You can save this as ``my_button.gd`` inside the plugin folder. You'll also need a 16×16 icon to show in the scene tree. If you don't have one, you can grab the default one from the engine and save it in your `addons/my_custom_node` folder as `icon.png`, or use the default Godot logo (`preload("res://icon.svg")`). .. tip:: SVG images that are used as custom node icons should have the **Editor > Scale With Editor Scale** and **Editor > Convert Icons With Editor Theme** :ref:`import options ` enabled. This allows icons to follow the editor's scale and theming settings if the icons are designed with the same color palette as Godot's own icons. .. image:: img/making_plugins-custom_node_icon.png Now, we need to add it as a custom type so it shows on the **Create New Node** dialog. For that, change the ``custom_node.gd`` script to the following: .. tabs:: .. code-tab:: gdscript GDScript @tool extends EditorPlugin func _enter_tree(): # Initialization of the plugin goes here. # Add the new type with a name, a parent type, a script and an icon. add_custom_type("MyButton", "Button", preload("my_button.gd"), preload("icon.png")) func _exit_tree(): # Clean-up of the plugin goes here. # Always remember to remove it from the engine when deactivated. remove_custom_type("MyButton") .. code-tab:: csharp #if TOOLS using Godot; [Tool] public partial class CustomNode : EditorPlugin { public override void _EnterTree() { // Initialization of the plugin goes here. // Add the new type with a name, a parent type, a script and an icon. var script = GD.Load