baldrick

Entity-component-system (ECS) framework, based heavily on edge


Keywords
cross, utility
License
Apache-2.0
Install
haxelib install baldrick 1.2.0

Documentation

baldrick

GitHub license Build Status

So, in other words, the Turnip Surprise would be… a turnip.

baldrick the turnip

Documentation

Manual

This package is my own ECS, based very heavily on edge. I really like the edge framework, but I keep running into small issues with it:

  • It requires thx.core, which pulls a lot of code I don't need
  • It hasn't been updated in a long time, and has been superceded by the author by edge2
  • Does a little bit too much behind-the-scenes with macros (ex: auto-creating views based on update function parameters)
  • Always fully processes macros, even if display is defined (when using completion), slowing down completion
  • Isn't under my control so isn't easily extendable for my personal uses

So, I wrote this library by copying a lot of the basic functionality of edge, but writing it in a way that makes sense for me—so consider this a fork of edge.

The key features of this library include:

  • "Pure" ECS philosophy—all data is stored in components, all logic is written in processors
    • entities are a unique ID number coupled with an array of components
    • phases group processors together in logical units (updating, rendering, etc)
    • universes group entities and phases
  • Components stored in an IntMap (rather than a StringMap like in edge)
    • Components have typeIDs which are auto-generated by macros at build time. This has the potential to cause issues between release versions, but I'm still exploring this as it has the potential to be faster than StringMaps.
  • Just about fully behaviour-tested: https://travis-ci.org/FuzzyWuzzie/baldrick
  • Profiling built in
    • Add the define -D profiling to your build process to enable profiling individual processors & overall phases
    • Still experimental, but seems to work without issue
  • Processors work on explicit views
    • Processors define View variables, with anonymous types referring the components that view is interested in
    • Macros then build the code to populate and manage views
    • The processor is then responsible for iterating over views, which iterates over matched entities with references to the components of interest extracted out
    • See the samples & API docs for more clarification
  • Universe-entity serialization
    • Using the built-in Haxe serializer / unserializer, universes can store and load their entity states using strings
  • Integration with turnip
    • turnip is an addon for Blender which allows you to use Blender as a level editor (so you can be lazy and not write your own level editor / rely on writing levels in code or text)
    • Add the define -D turnip to generate a turnip.json file, which contains definitions of all the components and processors available in your game. turnip then can load the turnip.json to enable game-specific level editing in Blender!
    • This feature is still very much under development (as is turnip itself), so ¯\_(ツ)_/¯

Why "baldrick"? Well, I tend to use an ECS in a lot / most of my projects (as a lot / most of my projects with Haxe are game-related), so this library could be called my dogsbody, so I named it after the best dogsbody in all of history.

API

API documentation is available here: https://FuzzyWuzzie.github.io/baldrick/

Samples

package components;

import baldrick.Component;

class Position implements Component {
    public var x:Float = 0.0;
    public var y:Float = 0.0;

    public function new(x:Float, y:Float) {
        this.x = x;
        this.y = y;
    }
}
package processors;

import baldrick.Processor;
import baldrick.View;
import components.Position;

class PrintProcessor implements Processor {
    var prints:View<{pos:Position}> = new View<{pos:Position}>();
    public function new(){}

    public function process():Void {
        for(view in prints) {
            trace('Entity ' + view.entity.hashCode() + ' position: (' + view.data.pos.x + ', ' + view.data.pos.y + ')');
        }
    }
}
import baldrick.Universe;
import baldrick.Phase;
import components.*;
import processors.*;

class Main {
    public static function main() {
        var universe:Universe = new Universe();
        var render:Phase = universe.createPhase();
        render.addProcessor(new PrintProcessor());

        universe.createEntity([
            new Position(0, 0)
        ]);

        render.process();

        trace('state: ' + universe.saveEntities());
    }
}

Benchmarks

Target Entity Creation (µs/entity) Processor Time (µ/iteration)
JS 1.10 0.70
HL 1.80 0.11
CPP 0.15 0.13