Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Godot 4 + GDExtension support #824

Closed
Bromeon opened this issue Dec 6, 2021 · 14 comments
Closed

Godot 4 + GDExtension support #824

Bromeon opened this issue Dec 6, 2021 · 14 comments
Labels
breaking-change Issues and PRs that are breaking to fix/merge. feature Adds functionality to the library status: godot-4 Issues concerning Godot 4.0 (current Vulkan branch) tracker Groups a list of related issues and tracks progress

Comments

@Bromeon
Copy link
Member

Bromeon commented Dec 6, 2021

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.

@Bromeon Bromeon added feature Adds functionality to the library status: godot-4 Issues concerning Godot 4.0 (current Vulkan branch) breaking-change Issues and PRs that are breaking to fix/merge. tracker Groups a list of related issues and tracks progress labels Dec 6, 2021
@benbot
Copy link

benbot commented Jun 25, 2022

Any updates as to what directions are being talked about?

@Bromeon
Copy link
Member Author

Bromeon commented Jun 26, 2022

Hello! I'm surprised by the interest this issue received, despite being so vague 😀
(or: "How to create hype 101")

grafik

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:

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 of get_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!

@afpro
Copy link

afpro commented Sep 17, 2022

Godot 4.0 beta has released, any plan on GDExtension?

@ARez2
Copy link

ARez2 commented Sep 25, 2022

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.

@viktor-ferenczi
Copy link

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.

image

@parasyte
Copy link
Contributor

parasyte commented Oct 8, 2022

@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.

@Bromeon
Copy link
Member Author

Bromeon commented Oct 8, 2022

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.

@Bromeon
Copy link
Member Author

Bromeon commented Nov 6, 2022

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!

@paddy-exe
Copy link

paddy-exe commented Nov 6, 2022

@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

@Bromeon
Copy link
Member Author

Bromeon commented Nov 6, 2022

@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.

@paddy-exe
Copy link

paddy-exe commented Nov 6, 2022

@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!

@Bromeon
Copy link
Member Author

Bromeon commented Nov 6, 2022

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 🙂

@paddy-exe
Copy link

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

@Bromeon
Copy link
Member Author

Bromeon commented Nov 15, 2022

I guess we can close this 🙂
(see comment above)

@Bromeon Bromeon closed this as completed Nov 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Issues and PRs that are breaking to fix/merge. feature Adds functionality to the library status: godot-4 Issues concerning Godot 4.0 (current Vulkan branch) tracker Groups a list of related issues and tracks progress
Projects
None yet
Development

No branches or pull requests

7 participants