gdnative
gdnative copied to clipboard
Godot 4 + GDExtension support
This is a tracking issue for progress on support for GDExtension + Godot 4. Discussions are still ongoing, I will update this post with more concrete points.
Any updates as to what directions are being talked about?
Hello! I'm surprised by the interest this issue received, despite being so vague 😀 (or: "How to create hype 101")
So I think it's time to outline some of the plans! I have begun working on a GDExtension port and expect to have a first experimental version ready within the next 1-2 months. Note that this will be very much alpha, in the sense that it will lack a lot of GDNative's current features, but it could serve as a basis for tinkering and further design.
Functionally, there are a lot of similarities to GDNative. The idea is to provide Rust APIs to access Godot's classes, allow to register user-defined types, and export user properties/methods to be callable from GDScript. The node tree in Godot 4 is conceptually the same as in Godot 3, again with inheritance but a few renamed classes. The new "extension instance" model differs quite a bit, but a lot of those differences can be abstracted from the user.
Ergonomically, there are however some big improvements planned, most of which attempt to address two long-standing issues:
- https://github.com/godot-rust/godot-rust/issues/758
- https://github.com/godot-rust/godot-rust/issues/808
Concretely, I'll try to move away from the current strategy of Ref
/TRef
/Instance
/TInstance
based on type-states. A lot of thought went into the current type system, and there are some highly sophisticated mechanisms that exploit the limited guarantees that Godot has historically been giving -- it was definitely a great step forward from v0.8's "everything unsafe" approach. However, the system also comes at a cost: users have to conservatively use assume_safe()
and unwrap()
all over the place, even if a lot of such calls never fail. And even then we don't have a 100% guarantee, because a lot of methods can execute custom GDScript code, and running any code outside Rust means potential UB. Yet in practice, thousands of users work with GDScript without ever encountering UB (barring Thread
etc.).
So, the current plan is to address safety with a different mindset:
- Limit
unsafe
to places where Rust can directly cause UB; generally consider GDScript calls safe. - Where possible and justifiable, add runtime checks to trade potential UB against panics.
- For methods returning
Option
/Result
, determine where it makes sense to add overloads that panic with a descriptive error (thinking ofget_node
,cast
etc.) - Limit the usage of threads (one major UB source) and require explicit opt-in.
- Simplify the overall
Ref
type system based on new guarantees gained through the above points.
My hope is that this pragmatic approach will make godot-rust code more readable and suitable for fast prototyping, without sacrificing major safety considerations. The GDExtension system seems to support such an implementation rather well, but of course we'll see how it goes.
As soon as available, I will post more updates to this thread as well as the #gdext-dev
channel on Discord!
Godot 4.0 beta has released, any plan on GDExtension?
Godot 4.0 beta has released, any plan on GDExtension?
@Bromeon is planning to have a first "preview"/ alpha of godot-rust for Godot 4.0 ready sometime after the end of this month.
I'm working on a GDExtension to support fast voxel rendering. It involves some performance parts currently developed in C++, but would like to port it to Rust. Reasons: Working with a safe language, having less bugs and crashes on the way. Learning Rust in the process. Directly coupling with the Rapier physics engine instead of trying to push a lot of colliders on Godot.
I would be happy to test drive the Godot 4.0 + GDExtension port of godot-rust
as soon as it is available. I have the C++ code ready to port.
@viktor-ferenczi Really cool project! I believe it is definitely a goal of this crate to provide the full memory safety guarantees associated with Rust. But for practical reasons, it has proven a bit difficult to really do that. For instance, #808 has some context and discussion around present issues and ideas for the future.
I cannot speak to the design or challenges with GDextension, I just want to help ensure the correct expectations are set. And this should in no way be taken as criticism or an attempt to warn or caution others from using it. To the contrary, godot-rust
is still my preferred game development environment by far, thanks in part to the maturity of Godot (although that's going to change with Godot 4.0, obviously) and in part due to the crate contributors and maintainers doing exceptional work.
It's just that certain design constraints with Godot itself make it hard to leverage Rust's main selling point effectively. FWIW.
It involves some performance parts currently developed in C++, but would like to port it to Rust. Reasons: Working with a safe language, having less bugs and crashes on the way.
parasyte mentioned some very good points, and those are among the harder parts in the library design. The entire point of godot-rust is to create bindings to a C++ engine, which is built around different requirements than a typical Rust application. Add to that an entire dynamic language runtime (GDScript), where users can run unrestricted code, including code that invokes UB.
That said, it's not as hopeless as "everything unsafe". Godot developers have done a great job at object safety, for example. It's meanwhile possible to reliably check whether an object is valid, so a lot of the "access previously freed object" scenarios can be protected against. In general, it's harder to accidentally create UB. The biggest "threat" I see to safety are GDScript's Thread
API, which is mostly out of godot-rust's control. But even there, I'm confident we can establish both guidelines and best-effort sanity checks to enable safer usage.
Even beyond safety, I see benefit in using Rust -- all the non-Godot code and the crate ecosystem are statically typed and benefit from 100% "traditional" safety guarantees, and it's much easier to build scalable systems and larger refactorings. There are also loads of really useful features for everyday life, such as Rust enums or traits.
TLDR: as parasyte mentioned, it's a matter of expectation. I am going to write a page that clarifies all the safety trade-offs taken, their implications and the rationale behind those decisions.
GDExtension for Rust is now available! 🚀
Repo: https://github.com/godot-rust/gdextension
It's still too early to build complex games, but simple things like Dodge-the-Creeps are possible 🙂
Thanks to everyone for the patience and encouragement! I'm looking forward to improve documentation, CI and ergonomics over the coming weeks and months!
@Bromeon For PR CI you can take a look at my GDExtension template: https://github.com/paddy-exe/GDExtensionSummator/blob/main/.github/workflows/builds.yml. It's quite simple but I hope it helps :D
@paddy-exe Thank you! 🙂 It looks like you do not run tests against Godot engine yet? I found that very helpful to ensure that things keep working, and immediately detect when Godot changes their API.
@Bromeon No problem! And yeah I currently don't since my template is only meant for point releases which I am not sure yet how to retrieve reliably instead of always the current master. Also, I just got into GitHub actions so I am still a novice in the use. If you know how to implement the testing against the godot point releases, I would gladly add it!
since my template is only meant for point releases which I am not sure yet how to retrieve reliably instead of always the current master
Oh, we did exactly that in the GDNative version (i.e. this repo)!
https://github.com/godot-rust/godot-rust/blob/46baf14a4d35e6364daee2c841498d657d8973ce/.github/composite/godot/action.yml#L37-L40
The rest of this file does some other tasks needed for integration tests. It's a bit hackish and godot-cpp might have some different requirements, but maybe it helps 🙂
Oh, we did exactly that in the GDNative version (i.e. this repo)!
https://github.com/godot-rust/godot-rust/blob/46baf14a4d35e6364daee2c841498d657d8973ce/.github/composite/godot/action.yml#L37-L40
The rest of this file does some other tasks needed for integration tests. It's a bit hackish and godot-cpp might have some different requirements, but maybe it helps 🙂
Oh, this is great! Thank you for this :D
I guess we can close this 🙂 (see comment above)