Rust godot

Rust godot DEFAULT

Crate gdnative[][src]

This crate contains high-level wrappers around the Godot game engine's gdnative API. Some of the types were automatically generated from the engine's JSON API description, and some other types are hand made wrappers around the core C types.

Wrappers for most core types expose safe Rust interfaces, and it's unnecessary to mind memory management most of the times. The exceptions are and , internally reference-counted collections with "interior mutability" in Rust parlance. These types are modelled using the "typestate" pattern to enforce that the official thread-safety guidelines. For more information, read the type-level documentation for these types.

Since it is easy to expect containers and other types to allocate a copy of their content when using the trait, some types do not implement and instead implement which provides a method to create references to the same collection or object.

The module contains high-level wrappers for all the API types generated from a JSON description of the API. The generated types are tied to a specific version, which is currently for the version. If you want to use the bindings with another version of the engine, see the instructions here on generating custom bindings.

API types may be reference-counted or manually-managed. This is indicated by the and marker traits.

The API types can exist in three reference forms: bare, and . Bare references to API types, like , represent valid and safe references to Godot objects. As such, API methods may be called safely on them. adds typestate tracking, which enable additional abilities like being able to be passed to the engine. , or "persistent" references, have lifetime, but are not always safe to use. For more information on how to use persistent references safely, see the type-level documentation on .

Enabled by default. Includes the version of the bindings in the module.


Bindings for the Godot Class API.


Types that represent core-datatypes of Godot.


Types and functions related to the NativeScript extension of GDNative.


Curated re-exports of common items.


Marker types to express the memory management method of Godot types.


Typestates to express thread safety of Godot types.


Prints and returns the value of a given expression for quick and dirty debugging, using the engine's logging system (visible in the editor).


Print an error using the engine's logging system (visible in the editor).


Declare the API endpoint to initialize the gdnative API on startup.


Declare the API endpoint invoked during shutdown.


Declare all the API endpoints necessary to initialize a NativeScript library.


Declare the API endpoint to initialize nativescript classes on startup.


Print a message using the engine's logging system (visible in the editor).


Print a warning using the engine's logging system (visible in the editor).


Convenience macro to wrap an object's method into a function pointer that can be passed to the engine when registering a class.


Represents an explicit null reference in method arguments. This works around type inference issues with . You may create s with or .


A polymorphic smart pointer for Godot objects whose behavior changes depending on the memory management method of the underlying type and the thread access status.


A temporary safe pointer to Godot objects that tracks thread access status. can be coerced into bare references with .


Trait for Godot API objects. This trait is sealed, and implemented for generated wrapper types.


A trait for incrementing the reference count to a Godot object.


Makes a function profiled in Godot's built-in profiler. This macro automatically creates a tag using the name of the current module and the function by default.

Really positive, since I love Rust very very much. It's great to have modern conveniences but insanely fast and safe.

I switch between developing a pure simulation framework and working in Godot. The sim is 100% rust and then I have another crate which binds with Godot. There I can concentrate on updating the scene tree based on the simulation. Since only the simulation needs to be synchronized for multiplayer I expect this will work better long term.

I use these opensource bindings - Godot supports dynamically loading your game code in a DLL - Called "GDNative" - so you can use any compiled language.

For an old discussion of my Godot pros/cons see this post on Reddit. The community stepped forward and was very supportive, so I have decided to stay.

I have also tried unity, I wrote a Rust chess AI against it for the "four kings one war" variant. My experience with Rust in Unity was more painful. For instance you need to restart the unity editor to reload the DLL. It crashes painfully often. Loading and switching targets can be very slow, etc.

However, the Unity game itself works very well now and the rust story was very very good. Building on Mac after building on PC was trivial - it just worked. Setting up a new dev machine was just checkout, rustup, cargo test - it just worked.

Getting things to look nice in Godot is trivial. I really just set up basic lighting, ticked some boxes and imported some basic meshes from Blender. I'm only getting started and I think my screenshots look quite nice :D

  1. 2004 sprinter van
  2. Plantation realty group
  3. G3 phone card

Porting Godot Games To Rust (Part 1)

NOTE This guide has become obsolete. Unfortunately (for me) godot-rust came out with version 0.9-preview shortly after I wrote this blog, and large chunks of this blog are just plain..wrong. You can see 0.9 compatible code here: - as I updated the code itself. Unfortunately though the tutorial before has quite a few obsolete ways of doing things, including all the code.

Of course if you're using 0.8 of godot-rust the tutorial is still right, but Part 2 is not going to happen because sadly I was about 50% complete when the new godot-rust was released.

This guide is for people who are interested using Rust with the Godot game engine, but found the API docs to be too abstract to follow along, and the existing tutorials too shallow to accomplish much. By the end you'll be running this same game:


..only in Rust. The final version is here, but spoilers.

The game is this Godot 2D tutorial from, ported from GDScript. To follow along I recommend you either first follow the original tutorial, or if you're already familiar with Godot and GDScript then grab the original code. I won't be stepping through each bit of the original tutorial, as I don't want to copy the original work, instead I'll start with the finished version tell you how I replaced GDScript with Rust. This should help new users of get over some of the hurdles to using this uncommon stack.


In order to follow along you'll need to original source from the tutorial, as well as Godot installed. I used version 3.2 when I wrote this. You'll of course also need Rust, but if you are coming to this tutorial with no Rust knowledge I recommend working through at least some of The Rust Book before trying to follow this.

About godot-rust

To write Godot games in Rust you'll be using GDNative - which is a module for Godot that allows you to write your code in a complied library instead of its built-in GDScript language. Originally meant for using C/C++ this makes Rust an excellent candidate as an alternative language. However all GDNative does is call into your Rust library - in order to actually do anything you'll need the godot-rust bindings. The Rust bindings mostly provide a mapping from Godot classes to Rust structures, with a few notable exceptions which I'll touch on as we go through the article.

To reiterate Godot is our game engine, GDNative is the feature of Godot that allows you to use native code instead of GDScript, and godot-rust is the library you use to "talk" to Godot in Rust. I found that confusing a few times.

Creating your Rust library

I'm going to assume you have the AirCombat game from the tutorial above in some directory on your machine. To create your Rust library go ahead and use in the root directory:

This probably isn't how I'll structure my next Godot/Rust project (everything could be under src) but it's how I did this one if you're following along. Next you'll need to update the as specified in the godot-rust README:

Make sure you double-check with the README - version numbers have a habit of changing and blog posts don't. Before you can build the library you'll have to make sure you have one more dependency installed, bindgen, which I was able to do by using but you should check the directions for your system.

That done you can now build your library where the game logic will go, with . You can run that now.

Adding your library to Godot

One thing that tripped me for a long while was making sure my Godot game could actually find my Rust library. It's a two-step process. As a first step you need to create a resource that's linked to your built library. In Godot add a New Resource in the FileSystem window.


Choose a and give it the name (to match what I have). Select it in the FileSystem after you create it, and you should see the Platform window appear on the bottom of the screen. Add your built library by finding your platform (for me this is MacOSX, 64 bit) and clicking the little file-system icon. Browse to where the built rust target is, it should be in , and choose the library built for your platform. For me (OSX) it's .


WARNING You aren't done yet. After selecting the library you need to make sure to save the resource in the inspector. Otherwise you haven't updated the resource with the link. It's an easy thing to miss, and will leave you confused when your Rust code isn't being called.


Your First Rust Script

Godot programs attach scripts to nodes to customize behavior. The term script sounds a little weird when we're using a compiled library, but it's the best one we have to fit in with Godot. What we've done is attach a library to our Godot program that makes Rusts code available, but we haven't attached anything. Now we're going to start with that.

The godot-rust README and this tutorial both start with "Hello World" but we're not going to do that, after all you could just follow those other tutorials. Were going to start by taking globals.rd and moving it to a Rust struct. Given the small size of `globals` this should theoretically be easy:

This tiny script is actually going to have to force us to learn a lot of things:

  • How to export a Rust struct as a GDNative script

  • How to call Rust from GDScript

  • How to put Rust classes in the AutoLoad

    Creating a NativeScript Resource

Let's start by making a NativeScript resource - the NativeScript resource is the bridge from Godot to Rust code. It's easy to forget this step, leaving you with working code that isn't called, so I try to do it first. Again create a new resource in FileSystem window:


As you can see this is a NativeScript resource, to match what I did name this . This actually comes back to bite us later, as I didn't like the name and so I changed it to . Turns out that later we'll have a name collision caused by this.

Now we configure the new NativeScript to point at a class in our Rust library. We do this by selecting the NativeScript resource we just created and looking in the Inspector. We need to set the class name to and the library to . Again you must hit save! to update the resource file.


So where a standard GDScript resource is just a file in the file system with GDScript code in it, a NativeScript resource is a lookup that says where to find a class in a library. You can actually open if you're curious. Now all of this configuration is pointing at …nothing. We don't have a class in our Rust library yet, and there's still one more thing we need to do.

Setting up A Singleton

The original tutorial creates globals as a Singleton, and I'm trying to match the original tutorial as close as possible. Therefore we'll need to have our resource AutoLoad on the game's startup. In Project->Settings go to the autoload tab, and add the path to . You should use the browse button and select the NativeScript resource to make sure you get it right. Name the node - not - so that the original code can live simultaneously with the new code for now. Make sure you check the Singleton box too.


Everything is now ready for you create your first Rust class.

Linking Godot to Rust

You'll be exposing a GameState class in the Rust code to start, and before you can do that you need to expose the built library itself so Godot can access it. First open up the file in your Rust project. You'll replace the existing code with the following:

This code won't compile yet - it's boilerplate you need to get GDNative up and running, but it pays to go through it closely. Starting with:

The first line brings all of the library into the current scope. Some tutorials say to use here, but that's dated as the latest versions of Rust encourage the syntax for external crates. The second line brings in the module from the file in this project. No you're not crazy - we haven't created that file yet.

The function is called by Godot the start of the program, and in it you expose all the "classes" that Godot needs to use directly. So if something is going to be referenced in a NativeScript resource, it needs to be added here in the function. You'll note that even though we use the syntax the class is available as in the Godot program itself, matching the name of the class in the resource we created. Not to be confused with which will be the name of the singleton instance. Every struct we eventually export will be listed here, so that Godot can find it.

Finally these macros effectively wire the entire library up. You can look up the docs for them but it's not worth worrying about it too much - it's boilerplate. You do need to make sure the function is listed in .

Now we need to create a module in the directory named .

Exposing GameState

Finally an actually class! The GameState starts with creating the struct and exposing it. Let's start with what has in it again:

Well we can't do that in Rust. Godot wraps every script file in a kind of hidden class/struct, and we can make that more explicit here in Rust:

We start by bringing in the module. I'll be using throughout for ease of use, but in the future I'll probably start explicitly binding just the names I want.

The struct has two annotations, does the magic that lets this struct be used in Godot. The second annotation is Godot specific and maps to the in the GDScript code. You'll want to make sure this matches so that your exposed functions are passed the right node type. If you build now you'll get an error like:

Every type needs an associated function that returns . You can do that with an . Let's add that now:

Don't forget the annotation. At this point the code should build, and technically speaking it works. It just doesn't do anything, because the GDScript is still using the original globals code.

The globals code directly accesses and and updates it in place. I originally tried to mimic that in the Rust code, but I couldn't find a way to get GDScript to access fields on the struct directly. I'm sure it's possible, but since I'm intending to replace all the code anyway I went ahead and added methods for updating it.

Note how every method is annotated with , except . This is so that they can be called from your GDScript code. The second thing to note is how every method takes (naturally) and an . That is the Godot Node that the script is attached to. None of these methods use the , and indeed when we have ported all the code to Rust we won't need to actually export any of these methods or take the unused parameter. However if you expose a method with and don't have that second parameter, you will get the compiler error:

It's befuddling, and cost me hours many times, so make sure you add that field even if you ignore it.

Remember every method called from Godot (except ) will need to have the annotation, and will take an parameter. The on is not important - I used to signify that it wasn't actually being used here.

Using GameState in GDScript

GDScript accesses the Singleton(s) in the codebase by name. If you look in you'll see in its function this:

Assuming you rebuilt the Rust project and correctly wired up the library, NativeScript class, and the AutoLoad as detailed above you can replace with .

Note that is a function on the as opposed to a field. If this works then you'll be able to build and run the game. It will always show "Stage 1" because you haven't replaced with everywhere its needed.

I'm not going to go through all of those replacements. When it's complete the variable won't exist anywhere, instead reading/setting the same values . Finally you can remove from the AutoLoad tab in Project settings, and delete .

Porting Bullet

Add Bullet Script to Godot

Now that we've ported the global game state we can start working on any one of the scripts. I chose Bullet next for no particular reason, other than it's fairly small. You'll need to start by creating another class resource, make sure it refers to the Rust library and has the class name Bullet.


Make sure you save it!

Next you'll want to open the Bullet scene () and open its BulletRoot in the Inspector. Set its script file to your new resource (). This will break Bullets, as they won't have any code operating them anymore.

Expose Bullet "class" in Rust

To start you'll need to update to export a Bullet class. Those changes are small;

You add the bullet module - which doesn't exist yet - to lib so it can be accessed and then expose it to Godot via the function. From now on I'll just direct you to add the new structure to the library, so make sure you understand this part. One of the most common mistakes I made was to spend the time porting a GDScript file to Rust, only to forget to add it here and have no idea why anything worked.

Port the Bullet Code

The code we're porting is available here. It will be a little longer in Rust, actually that is a recurring theme, so let's start by just getting the class exported so this code will compile.

As before we from , but this time we extend because that's what the is. Even though the doesn't have any data we still need a structure and an method, so that Godot has something to grab onto.

has two methods: which actually makes the bullet move, and which handles collisions. Let's do those one at a time. First we'll add so we can see the bullets again.

Despite the one-line nature of this function in GDScript there's a lot going on here. First where GDScript does not explicitly use the we have to, since this is Rust. The second is that the second parameter of is now being used so it's no longer . Why is it used? Because in GDScript the directive makes all the methods on the object directly callable. Rust doesn't support that kind of inheritance. So whenever you see this:

you need to replace that with a call the . Unless the function is actually defined in Rust or a method written in a Rust implementation by you, it's probably really brought in by the object. So in the Rust code when we want to , which is a method on , we need to call that on the owner object. This means the is being changed, and needs to be declared a parameter. Finally we have the original parameter, declared as a 64 bit float. I'm not 100% certain couldn't be used here without errors, so I went ahead and used . The game is small enough that I'm not currently counting bits.

We're still not done with the function definition, you'll notice it's . Unfortunately almost all calls to Godot code are inherently , and you'll see that by straight porting this code (as opposed to writing a more Rust-like implementation) I give up a lot of safety. In a larger program I'll work to separate the safe code from the unsafe code, but that's an exercise for the reader.

Now let's look at the actual one-line function I implemented. You'll see that takes 2 parameters in Rust, but one in GDScript. That's because Rust doesn't support default parameters, but GDScript does. If you look at the docs for Node2D you'll see that the default value for the second parameter is so I pass here.

If you compile this code you should see the Bullets move across the screen again. They won't hit any of the enemies however, so let's add the collision code.

Most of what applied before applies now. The first two parameters are and , and the function is . The third parameter is the object that the signal comes from. Figuring out type info can occasionally be tricky, but you can usually get it by finding the object sending the signal in the Godot UI.

Finally the last change from GDScript is needs to be called on the not or as a global function. If you build the code and run the app you'll find that bullets….still don't hit their targets. That's because you need to update the Signal.

Update the Signal

In the Godot UI you can specify a is emitted by the node when it is entered. That's found in the Node tab when you click the node in the UI for the Bullet scene. If this is foreign to you, you should probably go back to the original AirCombat tutorial and look through that example again, as that kind of Godot knowledge is outside the (increasing) scope of this tutorial.

The Signal is currently set to but that's the name of the function in GDScript. We renamed it in Rust code to fit with convention, and we need to update that here. Recreate the signal so it looks like this, with the method name downcased.


Make sure the script you are connected to is . I flubbed this several times, so it is worth mentioning. Build and run the code and you should see Bullets hitting enemies again. You can delete .

Key Notes

Considering there were - what 3 real lines of code - we had to understand a lot to port the Bullet script. Let's reiterate them.

  • Unsafe Anything that calls into Godot is going to need to be unsafe. For the sake of this tutorial I've made no effort to separate safe from unsafe code, so at the end most of the code will be unsafe. This won't be how I structure my next project.

  • Owner GDScript uses a kind of inheritance so that methods called on the Node the script is attached to don't require specifying the Node, called instead like they are methods on the script. Rust requires you to explicitly take an owner, which will often be marked as mutable.

  • Default Params Rust does not support default parameters. You'll have to look those up in the Godot docs, and perhaps make helper functions for them.

A Note About Docs

The API docs for godot-rust are comprehensive but Rust-centric, by which I mean they tell you all the new Rust information you need to know to use the functions, but assume you're already familiar with the Godot docs. So if you want to know how to call methods from Rust you'll look in the Rust docs, but if you want to know what they do you need the Godot docs.

Fortunately the godot-rust docs have a link on every page to the corresponding Godot API docs. This is extremely useful in part because the godot-rust search is much better than the search of the Godot API docs. So I recommend searching godot-rust first, and then following the link when you need to find things like default parameters.

Porting TitleScreen

The next script to port is TitleScreen which I once again chose because it wasn't particularly large. There's two things here we haven't done before, changing scenes and accessing the Singleton for the GameState. I'll also stop taking you through some of the things we've done in detail, since you can go ahead and re-read the directions above.

Prepare Class

Start by working through the boilerplate.

  • Add the new TitleScreen struct to so it's exposed.

  • Create a new file in lib.

  • Create a new NativeScript resource in Godot referencing TitleScreen.

  • Make sure the "Control" node in TitleScreen is attached to your new NativeScript resource instead of .

Getting Global State

The TitleScreen struct is an empty type, deriving Node, so the initial setup is small:

It's the next function that is going to cause us to do a lot of typing, that is the function in the GDScript.

We can't reference in our Rust code the way that GDScript can. We have access the root Node from the Node tree, and then find the class. We also have to convert into a Script "instance" so we can call on it. That last part is confusing so we'll work through the code, where it should become clearer. Let's start by getting the Node.

The function is just like any of the other exports in a GDScript program, it's just called automatically instead of being wired to a Signal. We start by getting the tree off of the owning Node. In GDScript we'd call but of course we can't do that in Rust, instead using the parameter.

This concept is important so I'm going to reiterate it. In Godot when a Script uses the syntax it inherits all the methods on that Node type, and is able to call them as if they are methods in the Script itself. However the Script and the Node are still separate objects, and this is just a convenience GDScript can provide. Rust doesn't support that so any method you are calling on the Node you're extending must be called on the parameter.

Managing Null

In this code we call on the owner, which in Rust returns an . This is one of the philosophical difference between Rust and GDScript. GDScript has the concept of , and in the codebase we are porting the strategy is to just call methods on anything that could be and crash if it isn't present. In Rust we aren't really allowed to do that, although you'll see sample code that just uses constantly, I tried to write this Rust in a way that's a bit more Rust-like.

To that end I chain while navigating the Godot . I haven't decided on the best approach yet for handling in godot-rust, and for this exercise we're going to adopt a very noisy approach so that it's clear what we're doing.

Continuing here we get the tree off of and if it's present (it always will be) we get its root node with . Now that we have the root of the we can find the object using the function, and passing it a . In GDScript you'll frequently find Nodes in the tree this way, but using a string literal. The function expects a type, but fortunately the bindings provide a standard converter, so we can use the function to avoid noise.

Our function isn't finished yet. is now set to the Singleton Node , but we need an instance of the Script.

Converting to An Instance

The Node we just retrieved doesn't have a function on it. That's because it's a Node but we need the attached Script instance. In fact when we reference in the GDScript codebase we're actually referring to its Script, not the Node. Fortunately gives us a way to access the Script Instance. Let's update the code.

At the top of the of the file we've added statement for the module, so we can reference . Then we've added a type annotation to the :

Next we've chained our calls and added the call. What this does is takes the Node "base" and tries to convert into an , which is a template type in . An Instance is a reference to a GodotObject with a NativeClass attached. That NativeClass is the struct we wrote. We have to annotate so that can make the right conversion.

Finally cap it off with an and a custom error message. We could use here too, but the Rust Book discourages that.

Calling Reset

We still haven't called the one line function! Rust is not going to compete with GDScript on conciseness, that's for sure. It's not quite as simple as calling on the instance, as the wrapper can't just delegate to the type it includes. Instead we'll use one of the methods on , in this case , to access the script and call methods on it.

Right after you set we add the following.

The function on takes a closure with two parameters, the Script object, and the owning Node. Now, FINALLY, we can call on the Singleton . We are using here because mutates the object. The expect is required because returns a Result type. In the future I believe much of this noise can be cleaned up by moving Rust much of the code into functions that return Results and use the operator, but we'll avoid that now because too much abstraction can make it harder to follow along.

We have now ported the entire function from GDScript to Rust.

Changing Scenes

Changing Scenes in Godot is easy, get the tree and call . The same is true in but much as before we have to be a little more explicit. We'll add the following method to the TitleScreen implementation.

is just the function name we used in GDScript, only with lowercase and underscores to match Rust convention. Like other exported methods it takes and the owning Node. It's because we call methods on in it.

The first line uses the syntax of Rust to get the tree if one is present. Note that I get a mutable instance of the tree, because changing scenes mutates the tree. Finally I add the expect because the method returns a .

Quitting the Game

Quitting the game is the similar to changing the scene. You just don't need the additional expect because doesn't return a result. Like other functions in GDScript has a default parameter, and we need to pass that explicitly here .

In this case I used instead of to pull the Tree object out of an type, for no particular reason other than I haven't decided how I prefer to handle types yet.

Rewire Signals

Finally you'll need to go back into Godot and rewire the Signals on the NewGame and QuitGame buttons respectively, as they still point to the old GDScript function names. Once you do that you should be able to play the game again, as NewGame and QuitGame will both work again. A that point you can remove the file.

Key Notes

Despite the "small" size of the TitleScreen it ended up being significantly more difficult than expected. However we've covered quite a few concepts that you'll need for writing games.

  • Global State - Global State is traditionally accessed via the Singleton/AutoLoad in Godot. We can't just use the name like GDScript can, and instead need to get the Scene Tree, find it's root, and then find the attached Singleton Node. Throughout this codebase I copy/paste retrieving the global state. In your code you should probably extract a method, but I find that confusing for following a tutorial.

  • Found A Node - Finding a Node in Scene Tree by its Path works the same way as GDScript, it is just more verbose because you need to convert the NodePath to a String (with ) and you need to manage the types that are returned by many functions.

  • Calling Code In Other Scripts - To call code in other Scripts, which is what we did here when we called a method on , requires using the type in , and the functions to make those calls. It is more type-safe than GDScript at the expense of being more verbose.

  • Handling Null - GDScript uses null extensively, relying on exceptions to handle when an object isn't present. Rust does not allow that and instead uses and types to handle failure. While this approach is usually preferred in larger systems, mapping from GDScript to Rust can be tricky because of it.

Time For a Break

We've done a lot, in fact we may have covered enough that you can complete the rest of the port on your own. I'd encourage you to try, and stop if you get stuck. Part two will be ready soon, and we'll pick up with .

I made a Voxel Engine with Rust (NO GAME ENGINE)

GDNative bindings for Rust

Docs Status

Website | User Guide | Stable Docs | Latest Docs

godot-rust is a Rust library that implements native bindings for the Godot game engine. This allows you to develop games or other applications in Godot, while benefiting from Rust's strengths, such as its type system, scalability and performance.


The bindings cover most of the exposed API of Godot 3.2, and are being used on a number of projects in development, but we still expect non-trivial breaking changes in the API in the coming releases. godot-rust adheres to Cargo's semantic versioning.

Engine compatibility

We are committed to keeping compatibility with the latest stable patch releases of all minor versions of the engine, starting from Godot 3.2.

The current minimum compatible version, with replacement, is Godot 3.2. Godot 3.3 is supported as well. Changes to this will be considered a breaking change, and will be called out in the release notes.

The bindings do not support Godot 4.0 currently. Support is planned as the native extensions become more stable.


The generator makes use of , which depends on Clang. Instructions for installing 's dependencies for popular OSes can be found in their documentation:

may complain about a missing binary, but it is not actually required to build the crate. If you see a warning about and a failed build, it's likely that you're having a different problem!

'Header not found' errors

When building the library, may produce errors that look like this:

This means that was unable to find the C system headers for your platform. If you can locate the headers manually, you may try setting the environment variable so could find them. If on Windows, you may try building from the Visual Studio "developer console", which should setup the appropriate variables for you.


Godot 3.2.3-stable

After dependencies are installed, add the crate as a dependency, and set the crate type to :

[dependencies] gdnative = "0.9.3" [lib] crate-type = ["cdylib"]

Other versions or custom builds

The bindings are currently generated from the API description of Godot 3.2.3-stable by default. To use the bindings with another version or a custom build, see Using custom builds of Godot in the user guide.


The most general use-case of the bindings will be to interact with Godot using the generated wrapper classes, as well as providing custom functionality by exposing Rust types as NativeScripts.

NativeScript is an extension for GDNative that allows a dynamic library to register "script classes" to Godot.

As is tradition, a simple "Hello World" should serve as an introduction. For a full tutorial, check out "Getting Started" from the user guide!

use gdnative::prelude::*; #[derive(NativeClass)] #[inherit(Node)] pubstructHelloWorld; #[methods] implHelloWorld { fnnew(_owner: &Node) -> Self { HelloWorld } #[export] fn_ready(&self, _owner: &Node) { godot_print!("Hello, world."); } } fninit(handle: InitHandle) { handle.add_class::<HelloWorld>(); } godot_init!(init);

Further examples


Before launching the examples in the godot editor, you must first run and wait for the build operations to finish successfully.

At startup, the Godot editor tries to load all resources used by the project, including the native binary. If it isn't present, the editor skips properties or signals associated with the missing NativeScripts in the scene. This will cause the scene tree to be non-functional for any sample that relies on properties or signals configured in the editor.

The /examples directory contains several ready to use examples, complete with Godot projects and setup for easy compilation from Cargo:

Third-party resources

Tools and integrations

  • godot-egui (setzer22, jacobsky) - combine the egui library with Godot
  • ftw (macalimlim) - manage your godot-rust projects from the command line

Open-source games



See the contribution guidelines.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be licensed under the MIT license, without any additional terms or conditions.


Godot rust



The godot-rust project provides high-level Rust bindings to the Godot game engine.

The latest version on is gdnative 0.9.3. Read the release notes here.

See the list of all releases here.

Beside exposing the full range of Godot APIs, the bindings are also designed to make life easier for Rust developers, while allowing detailed control over what is done at runtime.

Accurate memory/thread safety model

Built on Rust generics, godot-rust feature a memory/thread safety model that closely matches the actual behavior of the engine, enabling users to build abstractions that push unsafe actions towards the interface, and guarantee safety in internal code. Everything is entirely static and have no run-time cost in release mode.

Convenient procedural macros

The bindings include procedural macros that automate away most of the GDNative boilerplate, from member registration to making sense of structures, to timing functions in Godot's frame profiler. They're also being constantly improved!

Comprehensive trait system

godot-rust makes full use of Rust's trait system to build nice abstractions, and allow customization of low-level behavior without incurring extra run-time cost. Traits are also used to express the class hierarchy within the Godot API, enabling static generic upcasts, and static prevention of impossible downcasts, even though there is no language-level inheritance in Rust.

Full platform support

godot-rust supports all platforms where the Rust and GDNative is available, including Windows, Mac, Linux, Android, and iOS.

To create a GDNative library using godot-rust with Godot 3.2.3-stable, install dependencies and include the dependency in a crate. To use another version, see the relevant chapter in the user guide.

The most general use-case of the bindings will be to interact with Godot using the generated wrapper classes, as well as providing custom functionality by exposing Rust types as NativeScripts.

NativeScript is an extension for GDNative that allows a dynamic library to register "script classes" to Godot.

As is tradition, a simple "Hello World" should serve as an introduction. For a full tutorial, check out "Getting Started" from the user guide!

The /examples directory in the GitHub repo contains several ready to use examples, complete with Godot projects and setup for easy compilation from Cargo.

godot-rust is licensed under the MIT License.

Godot Rust-y, Hello World! Inigmas attempts to get GDNative Rust Bindings working with ART.


You will also like:


460 461 462 463 464