Skip to content

Systems and queries

M.K edited this page Jul 9, 2017 · 4 revisions

Systems are places, where actual functionality of a game goes. They are used to do things, for example update positions of entities, handling user input etc.

Systems, just like entities and components, have to be registered:

game.registerSystem({
  type: 'Movement',
  onCreate() {
    this.movingEntitiesQuery = this.game.createQuery(['Position', 'Velocity']);
  },
  onUpdate(delta) {
    const movingEntities = this.game.getEntities(this.movingEntitiesQuery);

    for (let i = 0; i < movingEntities.length; i++) {
      const entity = movingEntities.entities[i];

      entity.components.postition.x += delta / 1000 * entity.components.velocity.vx;
      entity.components.postition.y += delta / 1000 * entity.components.velocity.vy;
    }
  },
});

// now we can add system to our game
game.addSystem('Movement');

To fully understand this snippet I need to tell you about one very important feature of Entropy: queries. We know how to add entities to engine, but how to retrieve them? Queries are the answer. Query describes which entities we want to retrieve. In our example, we've built a query that matches entities with Position and Velocity components. We can also build query that matches certain types of entities, for example Ball. If you want to know all possible query criteria, check out the docs. As you see, we create query only once, and then we use it multiple times in onUpdate() method to get entities. If we add new entities matching the query, we don't need to create it again, the engine will do the magic and give you all entities that you need. If you want to know more how this mechanism works internally, check out in depth articles.

But let's get back to our example. After getting all moving entities, we have to iterate over them and apply position change based on velocity and delta. We can access this components through components property of entity object. As you can see, this system has no knowledge of type of entities. We can add another types of entities to our game (Squares, Triangles, etc.), and as long as they will have position and velocity components, they will be moving. You don't have to write code that moves them for every type of entity. This is one of the greatest things about entity systems: code reuse.

Almost every game will have many systems, like rendering system, system that collects user input, collision checking system, etc. When you add system to the game, their onUpdate() methods are run every frame in order systems were added:

game.addSystem('Render') // runs first
game.addSystem('UserInput') // runs second
game.addSystem('Movement') // runs third