ECX is Entity Component System framework for Haxe
Branch: develop
Clone or download
eliasku Merge pull request #22 from MangelMaxime/patch-1
Use synthax highlights in the file
Latest commit 7b2fbf3 Jan 8, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
make fix CArray for HashLink Sep 25, 2018
test include `power-of-two` utility May 15, 2018
.gitignore update May 15, 2018
.travis.yml [ci] disable HL target for a while Sep 25, 2018 hl tests, flash target tests separated Sep 25, 2018
test.node.js.hxml fix CArray for HashLink Sep 25, 2018


Lang Version Dependencies License

Build Status Build Status

ECX is Entity Component System framework for Haxe

Libraries (work in progress):



var config = new WorldConfig([...]);
var world = Engine.createWorld(config, ?capacity);


Entity is just integer id value. 0 is reserved as invalid id.


All services are known at world creation. World provides possibility to resolve services. World::resolve use constant Class<Service> for resolving. At compile-time these expressions will be translated to lookup array access by constant index with unsafe cast (pseudo example: cast _services[8]). For hxcpp poiter trick is used to avoid generating dynamic_cast.


Each service could have dependencies on different services. With Wire<T:Service> you could inject your dependencies to instance fields.

For example we need to inject TimeSystem system to our MovementSystem

class MovementSystem extends System {
    var _time:Wire<TimeSystem>;
    override function update() {
        var dt = _time.dt;


For all System types. For example we need to track all active(live) entities with components: Transform, Node and Renderable.

class MovementSystem extends System {
    var _entities:Family<Transform, Node, Renderable>;
    override function update() {
        // Note: typeof _entities is Array<Entity>
        for(entity in _entities) {
            // only entities with required component will be displayed

Sometimes it could be useful to mark some optional component in Family declaration just for readability. You can wrap each optional Component type in parentheses () and it will be ignored by Family, but will be notated.

var _entities:Family<Transform, Node, Renderable, (Scissors)>;

System Flags

  • IDLE: System doesn't override update method. Should not be updated.
  • CONFIG: System is defined with @:config meta. This system is just configurator. It will be deleted after World initialization phase.


Component is a way to associate [data] per Entity. You could just use component-builders to define your own components.

class Position extends AutoComp<Point> {}

/// later just use it like Point class per entity
_position.get(entity).x = 10;

Or you could create any custom crazy ComponentStorage / ComponentManager.

class Color extends Service implements Component {
    // BitmapData is used just to demonstrate that you are not limited to anything to store <component data> per <entity>
    // Each pixel is color for entity
    var _colors:BitmapData;


    inline public function get(entity:Entity):Int {
        _colors.getPixel32( % _stride, / _stride));


Injection: World Component is Service, so you are able to invoke all messages directly to other services. Implementation: Component is just interface, you could iterate all registered components and access their base API per entity. It's handy for automatically cloning or serialization.


ServiceType, ServiceSpec, ComponentType, ClassMacroTools


TypeManager (WIP)


-D ecx_debug for debugging

-D ecx_macro_debug for macro debugging

-D ecx_report to get and analyse ecx_wires.html and ecx_matrix.html report files generated during compilation


  • Rethink world initialization:
    • Are we are ok that instance of service could be created outside by default?
  • Rethink system-flags
  • Delete configurator services
  • Add more information on specific cases of AutoComp
  • Pack for dense storage
  • Entity Generations