...

/

Managing Complexity with Systems

Managing Complexity with Systems

Learn how to manage the complexities of games and deal with multi-module systems.

Systems are a special type of function that query the ECS for data and perform operations with the results. An ECS game may have many systems. Systems can run concurrently and are managed by a Scheduler. Legion builds a schedule by examining the systems we provide to it and determines data dependencies between them.

Many systems can read data at once, but only a single system can safely write to it. The order in which we present systems is also considered: Legion will run systems in the order in which they are presented unless they can be grouped to run concurrently. The good news is that we usually don’t need to worry too much about this; Legion will take care of it.

As our game grows, we’ll keep adding systems. We need a way to organize our systems and to make adding new ones relatively painless. Generally, systems can’t see the innards of other systems, making them ideal for module-based organization.

Multi-File Modules

Rust modules aren’t limited to a single file; they can also be a directory containing a mod.rs file. That directory can then contain sub-modules which themselves may be single files or directories. This is a powerful way to organize code, but it can require a little planning.

Now, create a new directory in the src folder and name it systems. Add a new file, mod.rs, in that folder but leave it blank for now. Add the new module to the prelude in main.rs, just like other modules:

Press + to interact
mod systems;
...
mod prelude {
...
pub use crate::systems::*;
}

We use Rust’s nested modules to keep our system’s functionality separated from the rest of the program but still logically grouped. Before we implement any systems, we need a stub schedule builder that returns an empty Legion schedule. Add the following to systems/mod.rs:

Press + to interact
use crate::prelude::*;
pub fn build_scheduler() -> Schedule {
Schedule::builder()
.build()
}

This function creates a Legion Schedule (an execution plan for our systems). It follows the builder pattern: Schedule::builder starts the system building process, and build() finishes it. For now, it creates an empty schedule, it ...