GithubHelp home page GithubHelp logo

godot-rust / book Goto Github PK

View Code? Open in Web Editor NEW
16.0 16.0 29.0 329 KB

Documentation and tutorials for gdext, the Rust bindings for Godot 4

License: Mozilla Public License 2.0

CSS 91.60% Shell 8.40%

book's Introduction

GDNative bindings for Rust

crates.io stable docs master docs book website

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.

Note: if you are looking for a Rust binding for GDExtension (Godot 4), checkout gdext.

Maintenance Policy

gdnative is considered mostly feature complete, and is maintained with a focus on API stability. We try to avoid unnecessary breaking changes, and try to limit their end-user impact to a minimum whenever we have to make them.

We adhere to Cargo's semantic versioning as the means to convey changes in the public API between versions. Future releases are planned publicly on GitHub, with the milestone feature. Note that we use the breaking-change label to indicate the existence of any technical breakage, regardless of the expected impact on end user programs.

If you are looking to contribute, but are not sure if what you want to do falls in the scope of the project and is permitted by our maintenance policy, feel free to get in touch with the project maintainers before you start.

Toolchain compatibility

gdnative currently has a minimum supported Rust version (MSRV) of 1.70. We use the Rust 2021 Edition.

Warning: Linux users: Be aware of the source of your Godot binary! Binary distributions of Godot using a container-based format may ship versions of dependencies that may not be compatible with GDNative libraries built directly from your base system. Examples of such formats include Flatpak, Snap, and AppImage.

As of 2023, some package managers might silently install one of these instead of a normal package when Godot is requested, which can then cause bizarre compatibility issues with your GDNative libraries. We recommend using the official binaries from godotengine.org for both the editor and the export templates.

Due to GDNative API not strictly following SemVer and some concepts not mapping 1:1 to Rust (default parameters), it is difficult for a godot-rust version to remain compatible with multiple Godot versions simultaneously.

However, we support the latest stable Godot 3 minor release out-of-the-box, and allow to easily use custom engine versions using the custom-godot feature flag (see below).

Compatibility list:

  • Godot 3.5.1 (works with gdnative 0.11)
  • Godot 3.4 (works with gdnative 0.10, custom build for 0.11)
  • Godot 3.3 (custom build)
  • Godot 3.2 (custom build)

The bindings do not support Godot 4. If you are looking for a Rust binding for GDExtension (Godot 4), checkout gdextension.

Getting started

Detailed setup is explained in the Getting Started section of the book. In case of problems, consider also reading the FAQ.

Latest released version

This is the recommended way of using godot-rust. After bindgen dependencies and a current Godot version are installed, add the gdnative crate as a dependency, and set the crate type to cdylib:

[dependencies]
gdnative = "0.11"

[lib]
crate-type = ["cdylib"]

Latest GitHub version

If you would like to benefit from cutting-edge features and bugfixes, you can use the GitHub version. We have a relatively sophisticated CI and test suite for basic stability, but the GitHub version is typically more experimental and less battle-tested than a crates.io release. We also do not guarantee any SemVer compatibility here.

[dependencies]
gdnative = { git = "https://github.com/godot-rust/godot-rust.git" }

[lib]
crate-type = ["cdylib"]

Custom builds

To use the bindings with a different Godot version or a custom build of the engine, see Custom Godot builds in the user guide.

Async/yield support

Async support is a work-in-progress, with a low-level API available in gdnative::tasks, if the async feature is enabled on gdnative. See this page in the book for an introduction to use the async feature with Tokio.

Example

A typical use case is to expose your own Native Class, a Rust API that can be invoked from the Godot engine. The resulting native script can be attached to the scene tree, just like GDScript (.gd files).

This happens via dynamic libraries and the GDNative interface, which will be loaded from Godot. The necessary wiring is done behind the scenes by godot-rust. A simple "Hello world" application could look like this:

use gdnative::prelude::*;

#[derive(NativeClass)]
#[inherit(Node)]
pub struct HelloWorld;

#[methods]
impl HelloWorld {
    fn new(_base: &Node) -> Self {
        HelloWorld
    }

    #[method]
    fn _ready(&self, #[base] _base: &Node) {
        godot_print!("Hello, world.");
    }
}

fn init(handle: InitHandle) {
    handle.add_class::<HelloWorld>();
}

godot_init!(init);

Further examples

Important note:

To run or edit an example, you need to build the native library for it first. Otherwise, the project will be broken. You can do so manually with cargo build, or use the example.sh shell script for convenience: ./example.sh run hello-world or ./example.sh edit hello-world for the editor.

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

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

Third-party projects

To see a list of games and integrations developed on top of godot-rust, have a look at our list of third-party projects in the book.

Contributing

See the contribution guidelines.

License

Any contribution submitted for inclusion in the work by you shall be licensed under the MIT license, without any additional terms or conditions.

book's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

book's Issues

Cheatsheet / translation table

It was brought up on Discord that sometimes, it's not clear how an existing GDScript concept maps to Rust. This is especially true for all the domain-specific syntax, like $Node, export, etc.

The format could be a simple table with a left column GDScript and a right one Rust. This would not replace the tutorial parts of the book, as it wouldn't contain explanations (except maybe very brief ones). Deeper explanations of concepts should be elsewhere. If the table grows, it could be split in separate tables depending on category.

Markdown linter

Use a Markdown or mdBook linter, for uniform formatting. All PRs must pass this validation step.

License header validator

Make sure all Markdown files have the necessary MPL-2.0 license headers.
We can reuse Apache Skywalking Eyes from the main repo.

Reentrant &mut self calls breaks hello world example

I am under the impression that godot-rust/gdext#501 broke the Hello World example.

I am getting the following compilation error:

error[E0599]: no method named `rotate` found for struct `godot::prelude::Base` in the current scope
  --> src/godot/mod.rs:30:19
   |
30 |       self.sprite.rotate((self.angular_speed * delta) as f32);
   |                   ^^^^^^ method not found in `Base<Sprite2D>`

I'll submit a PR to the doc if I get through a solution.

Candidates for FAQ

It's not yet clear whether we'll have an FAQ section in the book and if yes, how we are going to structure it. One idea would be to have 100% of the information as part of the tutorial, and use the FAQ only to refer to different chapters and sections. This way, people reading the book from A-Z would not miss anything, and we don't have to duplicate content.

This issue tracks potential candidates for often-asked questions. Once more basic parts of the book are done, we can decide what to do with these. Very basic questions such as "how can I use Gd" or "how do I export an enum" should NOT be part of the FAQ, these should be covered in the tutorial.


Questions, by category

Classes and objects

  • Can init take parameters?
  • How do I get a T from a Gd<T>?
  • Can I attach Rust scripts to a node?
    What do I do if one Rust class should be used by differently typed nodes in the tree?
  • How do I create a singleton?
  • Can I store references/lifetimes in a GodotClass?
  • GDExtension entry point 'gdext_rust_init' not found in library
    Typically indicates that lib.rs is not compiled, or the cdylib is created in a different path.

Tooling

MIT -> MPL-2.0 relicense

Since the license was changed to MPL-2.0 in accordance with the gdext main repo and its API docs, we need to get permission from existing book contributors to re-license their past contributions for the gdext parts, or rewrite their texts.

This issue is solely to collect approvals for the re-licensing process. For questions/discussion, please contact me on Discord. Off-topic comments and discussion in this issue will be removed.

Contributors, in alphabetical order:

Please copy-paste verbatim the following statement into a reply to this issue, or express if you do not want to re-license (which would mean we need to remove your text). Thanks a lot! ๐Ÿ˜Š

I license my past contributions to the godot-rust book under the dual MIT/MPL-2.0 license, allowing licensees to chose either at their option.

Common idioms

Repeating patterns that make using gdext more productive:

  • Polymorphism and upcasting
  • Helpers like get_node_as, load, etc.
  • Default parameters with _ex
  • ...

GDScript syntax highlighting

It would be nice to have ```gdscript code tags.
We currently use ```php for some, which works somewhat due to overlap in keywords, but it's not ideal ๐Ÿ˜€

The mdBook docs contain some more information on the topic; we would likely need our own highlight.js.

Registering Rust symbols

A chapter about #[derive(GodotClass)] and everything around it, that goes through options step by step.

  • Registerable symbols
    • Classes
    • Methods
    • Overriding virtual methods
    • Properties (var + export)
    • Signals, constants
  • Customization
    • Conversions (ToGodot, FromGodot)
    • Enums
    • Variant type, meta, advanced export flags, ...

Tutorial

A more elaborate tutorial to get started with the gdext library.

  • Getting started
    • Setup
    • Hello World
  • The Godot API
    • Scalar and builtin types
    • Classes*
    • Enums, flags, constants
    • Variants

* partly available under Managing objects in Rust, could be improved.

New Topic: Tooling Resources

Hey (just was talking with @Bromeon on the discord)

I think adding a section dedicated to tooling available through godot-rust would be helpful for people who want to make plugins, tools, and such. For example a breakdown of Engine Singletons, EditorPlugins, and simple type definitions.

I would be happy to work on this myself as it is something I am more passionate about. In the meantime, I've started a small knowledge base wiki for myself so I can search through things that I "know" but may have forgotten.

I am open to suggestions, critiques, etc.

Also I was tempted to open a new issue about this, but is there a style guide for the book that I should follow when writing? Without trying to follow a guide I tend towards less professional and more personal speech patterns.

Trait `Default` is not implemented for EditorPlugin

When following the godot-rust book to create an editor plugin, the GodotClass derive macro throws an error while trying to compile

Code: Copied from Godot-rust book page on EditorPlugins

use godot::prelude::*;
use godot::engine::{EditorPlugin, IEditorPlugin};

#[derive(GodotClass)]
#[class(tool, init, editor_plugin, base=EditorPlugin)]
struct MyEditorPlugin {
    base: Base<EditorPlugin>,
}

#[godot_api]
impl IEditorPlugin for MyEditorPlugin {
    fn enter_tree(&mut self) {
        // Perform typical plugin operations here.
    }

    fn exit_tree(&mut self) {
        // Perform typical plugin operations here.
    }
}

#[derive(GodotClass)]
the trait Default is not implemented for godot::prelude::Base<godot::engine::EditorPlugin>

Problem with singleton unregister in singleton register chapter

Problem with current singleton unregistering method at https://godot-rust.github.io/book/recipes/engine-singleton.html#registering-a-singleton

    fn on_level_deinit(level: InitLevel) {
        if level == InitLevel::Scene {
            // Unregistering is needed to avoid memory leaks and 
            // warnings, especially for hot reloading.
            Engine::singleton().unregister_singleton(
                StringName::from("MyEditorSingleton")
            );
        }
    }

The thing I've observed during my playing with singletons, the unregister_singleton call doesn't actually free the object. Correct implementation to avoid memory leaks would be a little more verbose:

    fn on_level_deinit(level: InitLevel) {
        if level == InitLevel::Scene {
            // Retrieve the object to free it after unregistering
            let mut my_editor_singleton = Engine.singleton().get_singleton(StringName::from("MyEditorSingleton"));

            // Unregister the singleton from Godot's singletons list
            Engine::singleton().unregister_singleton(
                StringName::from("MyEditorSingleton")
            );

            // Free the object itself
           my_editor_singleton.free();
        }
    }

The question stands if this isn't possibly linked with RefCounted singletons issue from gdext and will be fixed later or is the intended behaviour on upstream. The GDScript unregister_singleton() doesn't leave dangling objects, but its possible that GDScript is expected to just clean them automatically, making the problem on GDExtensions side.

Based on the question answer, the solutions would vary (maybe some other pattern would be preferred). The above works in current state of gdext. If its imperative to have this corrected for now, I could provide PR to book as soon as I figure out how built it correctly on local :)

Find or write mdbook plugin to have code blocks in tables

Problem

Neither Markdown dialect seems to support fenced code blocks in tables.
Something like this (here HTML):

GDScript Rust
class_name MyClass
extends Node
        
#[derive(GodotClass)]
#[class(base=Node)]
struct MyClass;
In mdbook, it's possible to use raw HTML, but it's also very unreadable.
This is the source for the above. Yes, the line breaks need to be like that to avoid trailing/leading empty lines.
<table>
<thead>
  <tr>
    <th>GDScript</th>
    <th>Rust</th>
  </tr>
</thead>
<tr>
    <td>
        <pre>
class_name MyClass
extends Node
        </pre>
    </td>
    <td>
        <pre>#[derive(GodotClass)]
#[class(base=Node)]
struct MyClass;
</pre>
    </td>
  </tr>
</table>

Possible solutions

With mdbook, the tag <code class="language-rust"> can be used for syntax highlighting instead of <pre>.

We should research if there is an mdbook plugin achieving something similar, or write our own.

If we do it ourselves, it doesn't necessarily need to be generic and reusable. We could just start to support the above case and take it from there. Even something simple such as

```codetable left="gdscript" right="rust"
class_name MyClass
extends Node
---
#[derive(GodotClass)]
#[class(base=Node)]
struct MyClass;
```

could be transformed into the verbose HTML above.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.