Tools instead of Trouble: Context-Free Plugins in Godot


Hey, I’m Emil aka CookieBadger, and I’ve spent the last 6 months working on a level design and asset management plugin for Godot 4 - the AssetPlacer. I’ve been doing so next to my computer science studies, and started developing this plugin for my Bachelor Thesis “An Analysis of Level Design Tools and Development of a Godot 4 Plugin”. I’ve had the idea of making some sort of game engine addon, which my professor happily offered to supervise. With Godot 4 on the verge, the choice of engine was an easy one.

To develop this plugin, I had to find out lots of things about how the Godot Engine works (I’ve made games with it previously, but only very small tools), with the disadvantage of using an alpha/beta version and C#, which made resources scarce and frustrations frequent.

But since there are many tutorials about making plugins, what made this so hard? One of the things was, that the plugin I was planning to make - a level design and asset browsing tool - was not really tied to a Node within a scene, as most other plugins are, but should instead function independently of nodes, and the entire scene tree. This is what I refer to as a “Context-Free” plugin.

What Plugins usually look like

Most other plugins, such as the Spatial Gardener, or ProtonScatter depend on and modify a single node in the editor. The AssetPlacer does not work that way.

Why Make Tools Anyways?

From previous projects such as Dice Defense, I have learned that tools can go a long way. If you have a repetitive task, and you feel like you are performing needlessly many actions to perform them over and over, a tool can probably help. I’ve made one before, that replaces the model of a 3D tile, depending on what is selected in a dropdown, but otherwise, I was new to the concept.

When developing the AssetPlacer and my thesis, I was also testing with several people. They were given 2 screenshots of a 3D scene and had to recreate them (which took around an hour with traditional tools), both with and without the plugin. The results showed, that no matter which way they started, they were on average about 30% faster using the AssetPlacer, and also used about 30% fewer clicks and keystrokes doing so. Also, they claimed the asset placer made their work more comfortable and productive. Hence, tools can make a big difference in your work, and a good craftsman, should always be aware of that.

Test Scene

The scene that testers had to recreate with the plugin

What You Can and Can't Do With a Godot Plugin

To give you some perspective on how you could improve your workflow by making tools, I will give you some examples of what you can achieve with tools, and what is not possible.

One of the easiest things that plugins can help you with, is editing resources. Want to double a value on 10 different files, with the press of a shortcut? No problem, listen to _input() events, and use the ResourceLoader to load and overwrite a resource.

Do you need some additional user interface elements, like a Button that performs said action on resources? Or just print how many nodes you have in your scene, and what the total sum of vertices is in your level? No problem, as long as your UI doesn’t need to go in a very specific location, you can add Control nodes with a single line of code (like add_control_to_bottom_panel). But, do you need to add a button to the Editor Settings Dialog? That's gonna be difficult.

It's rather hard to modify any of the existing functionality of the Godot Engine. For example, if you want the transformation gizmos to generally behave in a different way, I don’t think an EditorPlugin will help you. You might be better off modifying the engine source code, or maybe GDExtension can help, although I have zero experience with that and thus no idea if it would actually work.

Also if you want to add some additional things to the Editor Viewport, like a new gizmo (on all nodes, not just your new, and highly specific node), this is also not going to be as easy and costs some trickery of adding ownerless nodes with special rendering properties, upon which they will still only work half the time.

While the EditorPlugin and the EditorInterface classes make it easy to access certain things, like for example the Project Settings, where you can quickly add new ones and retrieve their values with a single line, some parts of the Editor are not exposed at all. I was trying to modify the editor shortcuts or the built-in snapping settings, but none of these seem to be changeable, without diving deep down into the engine’s Node tree and reverse-engineering the exact location of that UI element, which is also not guaranteed to always hold the values you need.

Early Mockup

An early mockup showing the plugin as a 3D viewport side panel - perfectly possible in Godot

Pitfalls when making Plugins

As I was just learning how to build plugins, I was relying on the built-in EditorPlugin methods. Things such as _forward_3d_gui_input made it easy to access the viewport, and listen to events that specifically occur within them. However, some rainy afternoon, I discovered that this only works for context-dependent plugins, operating on nodes. That means, if you have no node selected in the scene tree, you would get no inputs at all.

This lead me to eventually reverse-engineer the viewport’s UI nodes, such that my contextless plugin just receives all the input, and checks whether the viewport UI is in focus and the mouse inside them. As I was hooking up events, this solved my first problem, but now I would get nasty error messages, upon disabling or rebuilding the plugin, as the event handlers would point to disposed objects.

Therefore, and to not leak your user’s memory, you need to carefully take care of cleaning up all the nodes and events that you hook up in your plugin. This is especially difficult in C#, since you have to make sure to use the right type of signals, lambdas, and data collections, but more about that in a future Devlog.

Finally, when making a solid tool, you will find out that in a complex editor, there is a buttload of edge cases. Most users use the default perspective camera. However, some might design levels with an orthogonal camera. Some people might use multiple viewports, and others will do all of that and have a preview of the current camera enabled at the same time. It might be, that you don’t even know that some of these features existed, while somebody else’s workflow relies on their flawless functionality. For the AssetPlacer, this meant that I conducted loads of tests myself, asked a friend for doing a comprehensive quality assurance test, and even tested on different operating systems to see if the shortcut layouts would make sense there as well.

Godot 3D Tools Survey

In a survey I conducted for my thesis, participants stated that Godot was lacking in asset placement and browsing tools

Takeaways

Making tools might be very hard when you begin, but once you have a nicely working tool, it might save you an amount of time much larger than its development. Plus, if you come to share your tool with others, you can all enjoy the benefits of improved workflow together. I for my part, am very curious to see, what impact the AssetPlacer will have on the production of many Indies, that now need to press two keys less, every time they place a second instance of an asset. 


You can get the plugin here on itch. If you enjoy it, please make sure to leave a review!  

PS: If you liked this post; there is also a small like button on the top of the page :) 
Also, feel free to let me know about your experiences with plugins in the comments!

Files

AssetPlacer_1.0_Godot_4.0.x.zip 85 kB
May 14, 2023

Get AssetPlacer

Buy Now$17.99 USD or more

Leave a comment

Log in with itch.io to leave a comment.