crystal.ecs

Overview

Entity Component System is a popular pattern to structure game programming.

In the context of Crystal, game objects like characters, enemies, collectable items, etc. should be implemented by inheriting from crystal.Entity. Crystal provides a number of components which can be added to these entities to grant them functionality, like drawing sprites or moving around the world. You can define you own components by making classes that inherit from crystal.Component. Accompanying systems can be defined by inheriting from crystal.System.

The ECS pattern is often described in contrast to Object Oriented Programming (OOP), but they are not mutually exclusive. In Crystal, you can subclass your entities, components or even systems. Crystal’s ECS module was designed with this usage in mind.

Performance

The main goals of this ECS implementation are flexibility and usability over performance. It is entirely written in Lua, does not implement SoA, and will not win any benchmark contests. However, the overhead is almost entirely frontloaded in entity/component creation.

Examples

The following example illustrates basic functionality of the Entity/Component/System trifecta. You can find more examples throughout the documentation of this module.

local Bark = Class("Bark", crystal.Component);

local Dog = Class("Dog", crystal.Entity);
Dog.init = function(self)
  self:add_component("Bark");
end

local BarkSystem = Class("BarkSystem", crystal.System);
BarkSystem.init = function(self)
  self.query = self:add_query({ "Bark" });
end

BarkSystem.run_systems = function(self) -- this function name is arbitrary but needs to match the call below to `notify_systems`
  for entity in pairs(self.query:entities()) do -- iterates on all entities with a Bark component
    print("bark bark");
  end
end

-- Outside of a toy example, this would belong in your scene's constructor
local ecs = crystal.ECS:new();
ecs:add_system("BarkSystem");

-- This could be part of a scene's constructor too, or it could happen during gameplay
ecs:spawn("Dog");
ecs:spawn("Dog");

-- This would be called every frame in your scene's update() method
ecs:update(); -- makes the query in the BarkSystem aware of the newly spawned dogs
ecs:notify_systems("run_systems"); -- prints "bark bark" 2 times

Classes

Name Description
crystal.Component Base class to inherit from to define components.
crystal.ECS Entry-point to this module. Manages a set of entities, systems and events.
crystal.Entity Base class to inherit from to define entities.
crystal.Event Base class to inherit from to define events.
crystal.Query Gives access to entities and components relevant to a system.
crystal.System Base class to inherit from to define systems.

This site uses Just the Docs, a documentation theme for Jekyll.