I’m a queer Creative Programmer, with a side dish of design and consultancy, and a passion for research and artistic applications of technology. I work as a Technical Director at Flammable Penguins Games on unannounced title.
I've had a long career in games and I still love them, also spent a few years building creative tools at Adobe.
Love living in London.
When I'm not programming, playing games, roleplaying, learning, or reading, you can typically find me skating or streaming on Twitch.
There are many reasons I think that Godot is a great technical base and has a robust future, but chiefly among them is the modular way in which things are built and designed with the assumption that parts will be ripped out, replaced and improved. This is done through an easy to approach code base, modules system and robust support for addons and extensions through GDExtension (using godot-cpp) while encouraging most people to work at the scripting level.
Also importantly, you can work in this modular design without leaving scripting, using GDScript or C# through Addons.
Good reasons to move into C++ land:
* Performance
* Complex Systems with Unit Testing
* Existing Code
Then when moving into C++ you have several routes:
* GDExtension - Dynamic library style extensions that can work across multiple engine versions
* Modules - Engine modules compiled directly into specific engine versions
* Custom Engine Builds - Full engine modifications
For scripting-level extensions:
* Add-ons - Script-based extensions that integrate with the editor
* Custom Scripts - Project-specific scripting solutions
* @Tool Scripts - Single file editor extensions
Here is a graph to help visualize the various options:
https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/what_is_gdextension.html
You have some kind of tool or service you want to bring into the Godot community but you have commercial IP which you want to protect and manage? Then GDExtension is likely the best approach as it allows you to provide a closed source binary which users can easily drop into their project with no C++ work to use your service or tech.
This approach can work across multiple versions through proper version handling in your GDExtension implementation.
It is also a great way to reduce the recompilation of the engine and keep code stable. Complex systems can be built in their own project and you can also use languages other than C++ as all you need to produce is a dll to link against. There is also a very minor performance overhead.
Pros | Cons |
---|---|
Closed source distribution possible | Additional build complexity |
Cross-version compatibility | Performance overhead |
No engine recompilation needed | Limited access to engine internals |
Language flexibility beyond C++ | Must maintain versioning carefully |
Hot-reloading support | More complex debugging |
Easier distribution to users | Initial setup learning curve |
Independent development cycle | Platform-specific considerations |
Protects IP effectively | Must handle ABI compatibility |
https://docs.godotengine.org/en/stable/tutorials/plugins/editor/making_plugins.html
You are a developer who is working on an RPG game with a variety of enemies. It turns out you need to customise a lot of enemies in the world. You decide to develop some @tool scripts to make some helper functions to provide a friendlier editing workflow for your enemies. Some custom gizmos, some editor-time logic to double check stats and reduce the busy work.
You make a 3D gizmo plugin and add some additional helpers to quickly setup enemy behaviours and visually see data in the viewport for enemies while setting up scenes.
You want to use this code across more than one game because you know your studio is working on another RPG title in the near future. Or maybe you're just a nice person who wants to share their tool with the community.
The huge benefit of this approach is it requires no C++ knowledge. Your logic which is likely already in GDScript is easy to isolate and move into an add-on. The challenges with this approach are that it's still a scripting solution which means you will have less performance, less robust debugging tools and writing unit tests requires additional setup. While there are unit testing tools available like GUT (Godot Unit Test), they are not yet in the core engine. See https://github.com/bitwes/Gut
Pros | Cons |
---|---|
No C++ knowledge required | Limited performance compared to C++ |
Quick to develop | Less robust debugging tools |
Easy to modify and iterate | Unit testing requires external tools |
Simple to share and distribute | Can't access low-level engine features |
Works directly with GDScript code | May have scaling limitations |
Hot-reload support | No built-in testing framework |
Native editor integration | Script security limitations |
Cross-project compatibility | Resource-intensive for complex tools |
You have some game specific code which ties tightly into the engine. While you could make a GDExtension, the reality is this code is project specific - maybe some of it will be shared with other projects in your studio but it's fairly bespoke. It is in active development and you're not sure which parts of the engine you need to access but performance is critical. You want to avoid the abstraction of the godot-cpp extension API. In these cases, modules are often the best approach.
Modules allow you to build internal C++ changes to the Godot engine in a fashion which is isolated from the main engine code, reducing merge conflicts during engine upgrades. Sometimes an engine upgrade will break a function call because of a signature change. Modules are part of the engine so the functions you call make no promises of API stability, though in most cases this is not much of an issue.
Additionally, modules can be turned on and off easily during compilation, and adding bindings to the scripting layer is handled through a bind function and some simple macros which are fast and easy to implement. Working in this way allows us to write robust unit tests and leverage mature C++ tooling.
The major downside is you need to recompile the engine, cannot use official binaries, and any changes require rebuilding the engine. Additionally, you need to generate custom export templates. Though this is no different from working with any other C++ engine.
Pros | Cons |
---|---|
Direct engine access | Requires engine recompilation |
Best possible performance | Cannot use official binaries |
Full C++ debugging support | Need to maintain custom export templates |
Mature unit testing tools | Longer iteration times due to compilation |
Easy integration with engine systems | Can break with engine updates |
Simple binding to scripting layer | Higher technical barrier to entry |
Module-specific version control | More complex distribution |
Can modify core engine behaviour | Team needs C++ expertise |
Godot is an open source engine. You will find bugs, and you will want to fix them. After fixing the bug you are hopefully submitting a pull request back to the engine to help others. Though we all know how much time that PR will take to process and likely enter into discussions. Also your solution might not be preferred by others or they might not agree there is a problem. So maintaining your own engine fork for a commercial game is almost inevitable in some ways.
Likewise you will likely need to optimise the engine for your specific use cases or maybe you need to add support for consoles or systems which are not compatible with an MIT licence. Features that could never be in the core open source MIT lib. In these cases you can modify the engine. I would encourage you to examine the code structure and try to avoid merge conflicts down the line.
Some modifications I have made on my branch:
* Fixed some bugs (submitted PR when relevant)
* Changed XR input to present old value in signal (API change so PR turned down)
* Changed some Vulkan memory management and buffer code
* Added some rendering functionality specific to my title
* Changed some editor quality of life to my preferred workflow
Pros | Cons |
---|---|
Complete control over engine code | Requires maintaining a custom fork |
Can implement proprietary features | Most complex to maintain |
Maximum performance optimization possible | Harder to update to new engine versions |
Direct fix for engine bugs | Need strong C++ and engine expertise |
Custom platform support | Longest compilation times |
Unlimited access to internals | Most expensive in development time |
Can make deep architectural changes | Team needs deep engine understanding |
Full debugging and profiling capability | Requires careful merge management |
I hope this has provided a round trip into the various ways that Godot can be edited, taken apart and improved.
I wrote this article on the bus and then while sitting in some conference talks. Apologies for any oversights.
Social Bits and Bobs
Website: Claire Blackshaw
Flammable Penguins: Small Press Publishing
Mastodon: @kimau@mastodon.gamedev.place
Twitter: @EvilKimau
YouTube: YouTube
LinkedIn: Claire Blackshaw
Twitch: Kimau
Github: Kimau
TikTok: @EvilKimau
Tumblr: Forest of Fun
Book list: Good Reads