The godot-rust library uses many different approaches to store and transport data. This chapter explains high-level concepts of related terminology used throughout the library and its documentation. It is not a usage guide however -- to see the concepts in action, check out Binding to Rust code.
Godot is built around classes, object-oriented types in a hierarchy, with the base class
Object at the top. When talking about classes, we explicitly mean classes in the
Object hierarchy and not built-in types like
Color, even though they are technically classes in C++. In Rust, classes are represented as structs.
Every user-defined class inherits
Object directly or indirectly, and thus all methods defined in
Object are accessible on any instance of a user-defined class. This type includes functionality for:
- object lifetime:
- identification and printing:
- custom function invocation:
- signal handling:
Object itself comes with manual memory management. All instances must be deallocated using the
free() method. This is typically not what you want, instead you will most often work with the following classes inherited from
Reference-counted objects. This is the default base class if you don't use the
extendskeyword in GDScript. Allows to pass around instances of this type freely, managing memory automatically when the last reference goes out of scope.
Do not confuse this type with the godot-rust
Anything that's part of the scene tree, such as
Node2D(2D). Each node in the tree is responsible of its children and will deallocate them automatically when it is removed from the tree. At the latest, the entire tree will be destroyed when ending the application.
Important: as long as a node is not attached to the scene tree, it behaves like an
Objectinstance and must be freed manually. On the other hand, as long as it is part of the tree, it can be destroyed (e.g. when its parent is removed) and other references pointing to it become invalid.
Data set that is loaded from disk and cached in memory, for example 3D meshes, materials, textures, fonts or music (see also Godot tutorial).
Reference, so in the context of godot-rust, it can be treated like a normal, reference-counted class.
When talking about inheritance, we always mean the relationship in GDScript code. Rust does not have inheritance, instead godot-rust implements
Deref traits to allow implicit upcasts. This enables to invoke all parent methods and makes the godot-rust API very close to GDScript.
Classes need to be added as
NativeScript resources inside the Godot editor, see here for a description.
Variant is a type that can hold an instance of any type in Godot. This includes all classes (of type
Object) as well as all built-in types such as
Since GDScript is a dynamic language, you often deal with variants implicitly. Variables which are not type-annotated can have values of multiple types throughout their lifetime. In static languages like Rust, every value must have a defined type, thus untyped values in GDScript correspond to
Variant in Rust. Godot APIs which accept any type as parameter are declared as
Variant in the GDNative bindings (and thus godot-rust library). Sometimes, godot-rust also provides transparent mapping from/to concrete types behind the scenes.
Variants also have a second role as a serialization format between Godot and Rust. It is possible to extend this beyond the built-in Godot types. To make your own types convertible from and to variants, implement the traits
ToVariant. Types that can only be safely converted to variants by giving up ownership can use OwnedToVariant, which is similar to the Rust
Scripts are programmable building blocks that can be attached to nodes in the scene tree, in order to customize their behavior. Depending on the language in which the script is written, there are different classes which inherit the
Script class; relevant here will be
NativeScript for classes defined in Rust, and
GDScript for classes defined in GDScript. Scripts are stored as Godot resources (like materials, textures, shaders etc), usually in their own separate file.
Scripts always inherit another class from Godot's
Object hierarchy, either an existing one from Godot or a user-defined one. In Rust, scripts are limited to inherit an existing Godot class; other scripts cannot be inherited. This makes each script a class on their own: they provide the properties and methods from their base object, plus all the properties and methods that you define in the script.