Description
Godot version
4.0.dev (b770fa2)
System information
Windows 10
Issue description
On Windows, the Godot editor "locks" a DLL containing a GDExtension library and releases it only after shutdown. Native code can thus not be recompiled as long as the editor remains open.
I'm not exactly sure about the current behavior on Linux and Mac. A user reported the editor would immediately crash upon swapping a .so file (see below), but I already heard that people managed to get the launched game running with an updated library. What is the state here?
This is a considerable limitation for game developers actively using GDExtension. Unlike add-ons/tools that exist during the whole lifetime of the editor, GDExtension for games lives from being frequently updated. Requiring the user to reload the editor on every change not only makes a very common workflow impossible, but is also a regression from GDNative, where reloading (for non-tool classes) could be achieved while the editor was out of focus -- even if it had its bugs.
Now, it isn't my style to complain without trying to find a common solution 😉
I think this problem can be split into two parts, of which the first is likely easier to achieve and might already mitigate some problems:
-
Do you think it's feasible to enable a "library swap" feature that would at least let the launched game make use of recompiled native code? The extension library loaded by the editor itself could remain the same.
-
In the original GDExtension PR, hot reloading was listed under TODO. This feature has the potential to make GDExtension a true first-class citizen, and would likely encourage a huge amount of plugin and game development in the Godot ecosystem. In particular, it would make Godot much more attractive to C++ developers.
I'm fully aware that true hot-reloading is very difficult to achieve, as such I'd appreciate some insights on the topic from Godot developers. Have there already been (rough) plans or ideas how such a feature might play along with the ClassDB
? If not, would it be appreciated if I offered my help in working out a high-level design together?
Some challenges I see:
- A mechanism to mark instances of unloaded/reloaded classes.
Define their behavior when referenced from GDScript code, scenes or Godot caches. - A specified lifecycle, clarifying which role engine and extension play in the init/shutdown.
User callbacks to invoke for cleanup code. - Eventually, a safe way to reload/unload without UB.
This has been brought up before, but so far without a more detailed discussion. I'll try to use this issue also to summarize the efforts (but can also switch to godot-proposals
in case we go into design).
Godot 3 (GDNative):
- Godot 3.3 editor locks dll for writing (GDNative) #48086
- Allow manual unloading/reloading of GDNative/GDExtention lib files (DLL, etc) godot-proposals#5324
Godot 4 (GDExtension):
- [GDExtension] updating library during editor opened, crashes the engine godot-cpp#638
- Implement live reloading in GDExtension godot-proposals#4437
Steps to reproduce
Recompile a GDExtension native library while the Godot 4 editor is open.
Minimal reproduction project
No response