Release Notes: 0.9.3 - 2021-02-03

Introduction

0.9.3 is an incremental release with improvements in documentation and API completeness. Since 0.9.1 was released, we have received many great contributions that make this release possible:

@Bromeon implemented a minimal parser for Godot's custom documentation BBCode, greatly improving the readability of generated API docs. He had also made improvements to the error messages and docs on existing types, making the library much more friendly!

@extrawurst added the #[property(no_editor)] flag for the property macro, which exports properties that can be accessed from other languages like GDScript, but aren't shown in the editor.

@Aceeri implemented many standard traits for the GodotString type, making it much more useful. While GodotStrings are costly to modify, they are great for engine-related things that don't need to change, like paths, symbols, or keys.

We also have quite a few new examples: @leiter-jakab created an example for Godot networking, @CraigCiccone created an example for custom Node plugins, and @damszew added the example for exporting custom resources.

Under the hood, @halzy completed the herculean task of updating the library's many proc-macros to emit compile errors, and added build tests for them. Really awesome!

There are many more, and while only a few of them are called out here, all contributions are very appreciated!

One of the very often wanted feature from the crate is a utility function to get and cast a node from the scene tree in one call. While this has been available as an extension trait in one of the examples, it was hard to find, and it felt bad to copy-paste into projects. Now, the NodeExt trait is part of gdnative-bindings and the prelude:

use gdnative::prelude::*;
// - snip -
#[export]
fn foo(&self, owner: TRef<Node>) -> i32 {
    // `unsafe` is still needed, but a safe reference is returned directly, since it was necessary for the cast in the first place.
    let sub_node: TRef<'_, _> = unsafe {
        owner.get_node_as::<Spatial>("path/to/node").unwrap()
    };

    // Same for sub-nodes as instances of NativeScript classes.
    let sub_instance: RefInstance<'_, _, Shared> = unsafe {
        owner.get_node_as_instance::<MyScriptClass>("path/to/other").unwrap()
    };
    
    do_thing_with(sub_node, sub_instance)
}

There is also a shortcut for auto-load "singletons" under the root node:

use gdnative::prelude::*;
// - snip -
#[export]
fn bar(&self, _owner: TRef<Node>) -> i32 {
    // Same as the `get_node_as` method.
    let music_player: TRef<'_, _> = unsafe {
        autoload::<AudioStreamPLayer>("music_player").unwrap()
    };

    do_thing_with(music_player)
}

Previously, to create scripts that contain values only possible to construct in Rust, one had to declare a separate type, wrap it in Option, and implement their own error handling. Now, this pattern is supported by the library directly with the #[no_constructor] attribute and the Instance::emplace constructor:

use gdnative::prelude::*;

#[derive(NativeClass)]
#[inherit(Reference)]
#[no_constructor] // This instructs the library to not ask for a default constructor. Instead, it will fail and return an unusable instance when an attempt is made to construct it from another language.
struct MyScript {
    foo: OpaqueRustType,
}

impl MyScript {
    /// It is, however, possible to move an existing value of this type from Rust onto a new object of the base class
    pub fn create_instance(foo: OpaqueRustType) -> Instance<Self, Shared> {
        Instance::emplace(Self { foo }).into_shared()
    }
}

// One may then export operations to Godot without having to worry about potentially invalid instances themselves.
#[methods]
impl MyScript {
    #[export]
    fn exotic_operation(&self, _owner: TRef<Reference>) -> i32 {
        self.foo.exotic_operation()
    }
}

A full changelog is included down below.

This release is made from tag 0.9.3, commit 574e0f7.

Changelog

Added

Changed

Fixed