So I Tried Making a GUI With Godot
An interesting article made its way around the internet at one point: Why not use a Godot (a 2D/3D game engine) to develop GUI applications? The author argues that the Godot designer + engine is actually a great way to develop even advanced GUI apps thanks to its ease-of-use, small footprint, and extensibility.
Why I Care
I’ve had the (dis)pleasure of fighting with several UI frameworks in my career so far: Often when interfacing with or programming directly on embedded systems, only a native app will do. I think my favorite so far is Qt, and my least favorite is Android, though in all of them I’ve found lots of things to love and hate. Therefore, I am always interested in new approaches that can get me off the ground quickly. What caught my eye is the fact that Godot can be programmed in C#, which means it could make a good alternative to WinForms or WPF (or UWP). It also supports multiple deployment targets, including the web.
What Should We Make?
For fun I had been working on an app that would solve mazes. The idea is that you load an image of a maze, pick a start and end point, and then watch it solve with a (delayed for your viewing pleasure) flood-fill algorithm. It used WinForms with C# and worked pretty well, except using a PictureBox to update the maze as it was being solved was quite CPU intensive (It really isn’t meant for frequent partial updates of the underlying image).

Another shortcoming with WinForms was trying to implement a Pan/Zoom feature for the displayed maze. The PictureBox again proved to be an Achilles’ heel, requiring me to blow up the maze to massive sizes (with massive resource usage) to simulate a zoom. Maybe a game engine could make this easier?
Downloading and Running
The author of the above article lauds Godot’s small footprint compared to other frameworks like Qt, and it’s true: The whole thing is a single executable that sits around 70MB (with Mono for C# support). I also had to download an extension for VSCode to make it into an IDE with debugging and breakpoints and whatnot, as support for Visual Studio is still pending. Of course, one could also skip all this and program it using Godot’s built-in scripting language (GDScript) instead. Either way, it blows Qt out of the water for ease of getting set up, and doesn’t require a Visual Studio installation + .NET frameworks like WinForms and WPF, etc. do. Just download the executable and let ‘er rip. Easy!

Making an App
The first thing I noticed playing around with the Godot designer is that it feels very professional. It’s a hard thing to quantify, but I often find that open-source software GUIs lack a certain level of polish or features when compared to commercial software. Godot bucks this trend as its GUI is extremely consistent and easy to use.
I got started by telling it I wanted to make a 2D “game”, and then began delving into the documentation on how to actually build an app.
A lot of things felt very familiar:
- Grabbing a reference to a UI element in the code using a dynamically generated reference (in this case it’s a string-based path);
- Different built-in controls for different UI elements (sliders, text boxes, buttons, etc);
- Layouts to automatically organize controls in a view;
- Flags to control how elements resize themselves;
- “Properties” for each control which can be set from the UI.
Some things are different:
- Being a game engine, it has a simple signal/slot system and also calls an update function every “tick”, as opposed to an event loop;
- UI controls are separate from the game engine stuff, and it’s a bit unclear how to get them to interoperate at first. For example, a sprite can’t be placed in a container meant for controls;
- Some new concepts such as textures, viewports, and cameras.
It has several things I really liked:
- Controlling window size and getting the app to support window resizing without having a seizure was a breeze;
- The node hierarchy view makes it clear what everything belongs to;
- Multiple windows are cleanly organized into “scenes”;
- Very easy to use with VSCode;
- As mentioned before, the editor is very well made and easy to figure out.
…And some things I didn’t:
- Code is placed in scripts bound to a specific node. This makes sense for a game, but for a UI it makes the code hard to organize;
- Hard to pass data between scripts elegantly;
- Nodes are referenced in code using text strings, which are error-prone (though to be fair they provide some auto-completion via the VSCode plugin);
- Setting the font for a control has many odd steps.
After some playing around, I managed to get a decent-looking interface for my maze solver:


The tricky part, of course, was how to pan and zoom the maze. The trick seems to involve taking advantage of Godot’s “cameras” to accomplish this: Imagine you were making a Super Copyright Infringement Mario game, and you wanted to make sure NotMario was always centered in the screen as he moves around the scene.
The smart fellows at Godot figured this was a common enough use case to add a “camera” feature to the engine to accomplish exactly that. Add a camera to a viewport, and only what is within the camera’s view will be drawn instead of the entire contents of the viewport. For the maze solver, it is employed in a similar fashion, except instead of following a sprite around, the camera can be zoomed or moved with the mouse, all without changing the size of or redrawing the underlying image texture.
The next challenge was to efficiently update the display image as the maze is solved. I tried using their sorta undocumented VisualServer.TextureSetDataPartial(...);
, but that didn’t work well, so I resorted to just regenerating the texture using ImageTexture.CreateFromImage
, which produced quite adequate results despite the burden of regenerating the texture several times per second (only around 10% CPU usage at full-tilt). It goes without saying that this worked out way, way better than it did with WinForms!
The Verdict
Hah! I would be definitely talking out of my butt if I said I could give an honest review of an entire framework after using a tiny bit of it once for a toy app. All I can say is it’s pretty impressive how much functionality they could squeeze into such a small package, and it’s definitely as easy, if not easier, to use than other UI frameworks I’ve encountered so far. Also, the fact that it’s a game engine gives you the tools to do any funky graphics business without having to completely rip up the UI layer or do some hacky workarounds.
Let’s talk about that binary size
So how does Godot get away with a ~70MB framework when something like Qt weighs in at ~2GB (only including libraries for one platform)? Well, you could argue that Qt has a lot of bloat having been around for so long, but I think we need to be fair here and point out that Qt does freaking everything: I mean, it practically re-implements the entire C++ STL, plays videos and audio (of many formats), handles network requests, can parse XML and JSON, has a whole JavaScript Engine and even an entire web browser!. There’s also some pretty esoteric stuff like Modbus Support and CAN Support.
Then there’s their IDE + design tool, Qt Creator, which is actually quite good even compared to other non-Qt IDEs for developing C++. And of course it provides tools for internationalization and documentation generation. Godot has an ecosystem of plugins to make up for a lot of this missing functionality, so I guess it boils down to downloading a lot of stuff you don’t need and not having to worry about it, versus only downloading the dependencies you do need. Usually I am not constantly re-downloading my development environment, so for me a large initial download is not a major concern. Your mileage may vary.
Anywho, I’ll definitely keep Godot in mind when developing UI apps in the future. Maybe one day I’ll learn how to actually make a game with it…