Data representations
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.
Object and class
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 String
, Vector2
, 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:
_init
(new
in Rust),free
- identification and printing:
to_string
,get_instance_id
- reflection/introspection:
get_class
,get
,has_method
, ... - custom function invocation:
call
,callv
,call_deferred
- signal handling:
connect
,emit_signal
, ...
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 Object
:
Reference
Reference-counted objects. This is the default base class if you don't use theextends
keyword 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-rustRef
smart pointer.Node
Anything that's part of the scene tree, such asSpatial
(3D),CanvasItem
andNode2D
(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 anObject
instance 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.Resource
Data set that is loaded from disk and cached in memory, for example 3D meshes, materials, textures, fonts or music (see also Godot tutorial).Resource
inheritsReference
, 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.
See Object
in
godot-rust docs,
Godot docs
See GodotObject
, the Rust trait implemented for all Godot classes, in godot-rust docs
Variant
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 int
, String
, Vector2
etc.
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 FromVariant
and ToVariant
. Types that can only be safely converted to variants by giving up ownership can use OwnedToVariant, which is similar to the Rust Into
trait.
See Variant
in
godot-rust docs,
Godot docs
Script
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.
See Script
in
godot-rust docs,
Godot docs