This is my take on using Legion ECS with Godot and Rust.
The core premise of this is one Godot node that holds the schedules,
and executes them in
For information on how to use GDNative with Rust and Godot see the previous post: Up and running with Rust and Godot: A basic setup.
Start by adding a Godot node, and name it “GameWorld”, and attach a
NativeScript called “GameWorld”.
This is all that has to be done in Godot for now (additional nodes are added later).
Create a new file:
src/gameworld.rs and add the following code.
(and don’t forget to add the struct to the
World it’s not possible to execute the systems.
I have opted to place the world in a
Mutex so it can be accessed from other
threads if needed. For this post I ignore the
Universe but the same method of
World could be applied to the
A utility function for easily accessing the world is added as well.
This way it’s easy to work with the world
with_world(|world| /* use world
Before creating the schedules, create the
Delta resource. This is one way of
passing the delta time value from
_process to all the systems.
With access to a
World it is now possible to add resources and components,
however to run systems a
Schedule is recommended.
There are two types of schedules in this setup:
Physics (ignoring physics for now).
Process will handle all systems that run on
run all systems that will execute on
Create a new struct in
src/gameworld.rs and call it
Process struct holds all the resources that will be made available to the
systems that are registered with
execute function is called on
_process, providing the delta
resource with a new value and executing all the systems.
Note that it’s safe to touch the scene tree when adding a thread local system.
Therefore all systems that manipulate Godot nodes should be added with
add_thread_local. Components that are wrapping Godot nodes requires unsafe
Process struct to the
Finally it’s possible to call the
execute function on the process in
_process. Update the
&mut selfin the above code snippet.
At this point all the systems in
Process will execute every time
There are two types of systems that can be added in Legion (three if you
Runnable (thread local) and a
Schedulable (not thread local).
Runnableand everything that is just plain data to be
Create a system that moves a node across the screen:
Finally update the
new function inside
Process, to add the new system:
Open up Godot, load the GameWorld.tscn scene and add a
Node2D with the name:
To be able to see anything, add either a
Sprite (or in my case I added a
ColorRect) to the node.
Finally add the component to the world in the
_ready function of the
Compile (and copy the lib into Godot) and run the Godot project. The node should now move across the screen from left to right.
An example with this code is available on Github: rust-godot-legion-setup
The code in the project has been run and tested on Linux only, for Windows and
MacOS remember to update the
I have opted to keep my
process schedules separate, however they are very much identical, which is why the physics struct is omitted from this post. This means
that resources aren’t shared between them.
This can be solved by having two schedules in
Process instead (one additional
for physics) with an additional
execute_physics function for