.. _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 functionality. This tutorial will guide you through the creation of two simple plugins so you can understand how they work and be able to develop your own. The first will be a custom node that you can add to any scene in the project and the other will be 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 to do is to create a new plugin the editor can understand as such. You need two files for that: ``plugin.cfg`` for the configuration and a custom GDScript with the functionality. Plugins have a standard path like ``addons/plugin_name`` inside the project folder. For this example, create a folder ``my_custom_node`` inside ``addons``. You should end up with a directory structure like this: .. image:: img/making_plugins-my_custom_mode_folder.png Now, open the script editor, click the **File** menu, choose **New TextFile**, then navigate to the plugin folder and name the file ``plugin.cfg``. Add the following structure to ``plugin.cfg``: .. tabs:: .. code-tab:: gdscript GDScript [plugin] name="My Custom Node" description="A custom node made to extend the Godot Engine." author="Your Name Here" version="1.0.0" script="custom_node.gd" .. code-tab:: csharp [plugin] name="My Custom Node" description="A custom node made to extend the Godot Engine." author="Your Name Here" version="1.0.0" script="CustomNode.cs" This is a simple INI file with metadata about your plugin. You need to set the name and description so people can understand what it does. Don't forget to add your own name so you can be properly credited. Add a version number so people can see if they have an outdated version; if you are unsure on how to come up with the version number, check out `Semantic Versioning `_. Finally, set the main script file to load when your plugin is active. The script file ^^^^^^^^^^^^^^^ Open the script editor (F3) and create a new GDScript file called ``custom_node.gd`` inside the ``my_custom_node`` folder. This script is special and it has two requirements: it must be a ``tool`` script and it has to inherit from :ref:`class_EditorPlugin`. 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. You can delete the default GDScript template from your file and replace it with the following structure: .. _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; using System; [Tool] public class CustomNode : EditorPlugin { public override void _EnterTree() { // Initialization of the plugin goes here } public override void _ExitTree() { // Initialization 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. 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`` keyword, it can be added so the script runs in the editor. For this tutorial, we'll create a simple button that prints a message when clicked. For that, we'll need a simple 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(): connect("pressed", self, "clicked") func clicked(): print("You clicked me!") .. code-tab:: csharp using Godot; using System; [Tool] public class MyButton : Button { public override void _EnterTree() { Connect("pressed", this, "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.png")`). You can also use SVG icons if desired. .. 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; using System; [Tool] public 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