Systems

The System class is another way to structure your app. It can help you manage key mechanics and concepts of your app.

Basic example

Here's an example of system not doing much, but giving you the basic structure:

An example of System subclass
import ceramic.System;

/**
 * Just an example of `System` subclass
 */
class MySystem extends System {

    /**
     * A shared instance of `MySystem` so you can
     * get the system with `MySystem.shared` from anywhere.
     */
     public static var shared = new MySystem();

    public function new() {
        super();

        // Values to tell when this system's
        // `earlyUpdate()` and `lateUpdate()`
        // methods will be called compared to
        // other systems. Lower values make the
        // methods run earlier than higher values.
        earlyUpdateOrder = 10000;
        lateUpdateOrder = 10000;
    }

    override function earlyUpdate(delta:Float):Void {
        // Do something at early update stage
        // (called at each frame)
    }

    override function lateUpdate(delta:Float):Void {
        // Do something at late update stage
        // (called at each frame)
    }
}

System classes are pretty simple: they are entity objects that have their earlyUpdate() and lateUpdate() methods called automatically by Ceramic, depending on the earlyUpdateOrder and lateUpdateOrder values.

The @lazy meta makes the field lazy loaded. The assigned value new MySystem() won't be evaluated until the first access of the field. That means the shared system instance will be created the first time we use something like: var mySystem = MySystem.shared.

Built-in system events

System classes have built-in events that allow to bind external code right before or right after earlyUpdate() and lateUpdate() calls:

Binding to system update events
var system = new System();

// Here we created a raw system instance,
// but we could also do the following with
// any other existing `System` subclass instance.
// example: var system = MySystem.shared;

system.earlyUpdateOrder = 12345;
system.lateUpdateOrder = 12345;

system.onBeginEarlyUpdate(this, delta -> {
    trace('begin early update');
});

system.onEndEarlyUpdate(this, delta -> {
    trace('end early update');
});

system.onBeginLateUpdate(this, delta -> {
    trace('begin late update');
});

system.onEndLateUpdate(this, delta -> {
    trace('end late update');
});

When and how to use systems?

It is up to you how you'd want to use systems in your code. Here are some ideas:

  • Centralize into System subclasses the main mechanics of your game, like LevelSystem, ScoreSystem, LeaderboardSystem etc...

  • When you need to update a large group of objects at each frame, using System's earlyUpdate() or lateUpdate() methods is a good alternative to binding to app.update event on each of your objects. Plus it gives you more control to when your update logic is executed relative to other systems, thanks to earlyUpdateOrder and lateUpdateOrder values.

  • If you like ECS, you can architecture your code in the Entity-Component-System fashion, where most code logic is located in System classes, and most data in Component classes.

Ceramic is using System in various situations for its internals, you can take a look at some of these:

SpineSystem used to manage Spine animation objects
StateMachineSystem used to automatically run StateMachine objects
ArcadeSystem used to update the arcade physics over time


Continue reading ➔ Inside a default project (Appendices)