Category Archives: Entity Systems

Eskimo ECS + Tundra Engine

A hard truth I’ve come to realize is I apparently like making tools more than games. I think I like making games, but my track record clearly shows otherwise.

On that note, while developing, I quickly came across some issues using hxE2 in terms of usability and consistency, the thing felt bloated and messy. Fixing bugs would spawn other bugs, functionality was split awkwardly and sometimes duplicated, etc.. Which is why I did what I like to do, and create yet another ECS, this time explicitly focusing on simplicity and lighter code.

Eskimo (https://github.com/PDeveloper/eskimo) is so far the best approach to an ECS I’ve made. All component access happens through an Entity object (unlike in hxE2, where you could do that, but also use a View object), and Views only manage a list of entities (they don’t store their own components, except for one, which is explicitly defined that way). Further, there are types of Views that enable specific features you might need, such as just a list of entities with certain components, or tracking added/updated/removed entities from that list. There has been no effort to unreasonably optimize parts of the system, and by design Views are meant to be single threaded, resulting in a clean and simple implementation. Multi-threading support happens through the base Context class, again, in a much clearer manner (though multi-threading support is only at a proof of concept stage right now). Check out the github repository for more details and usage!

Now with Eskimo in hand, I am much more confident that things will work correctly, so far it has had less bugs and I haven’t experienced any huge limitations.

Afterwards I devoted time to learning about CPPIA, the relatively new scripting feature in hxcpp. I should write a post on what I learned and my travels, but I’ll wait until my understanding solidifies.

I’m currently working on a tool called Tundra, which is both a tool and a (game) engine right now, though I’ll try to extract the coolest functionality out into a separate library: live code reloading. Currently it’s based on Snow from Snowkit, but that could be swapped for anything that supports file-watching. It scans your project.flow file, finds all source directories, and scans for classes implementing either IState or ISystem interfaces. Once found, it compiles each one into a CPPIA file, and loads it. Only 1 IState class is loaded at a time (the one that changed most recently will load), and reloading an IState causes the Eskimo ECS to be reset/cleared of all entities. ISystem classes are loaded and run without any interruption to gameplay, and with a meta tag, can be assigned to 1 of 4 System groups, input, logic, physics, or render. System groups are run in that order, but individual system order within those groups is not defined.

Despite some problems with CPPIA that causes a crash once in a while, I can leave the game window open and freely work on a game idea with no interruption, and nearly immediate results. Adding a new system is as easy as creating the class itself, and it will get picked up by Tundra to load.

My work isn’t public because I have yet to solve a few issues (I kind of broke it a bit before initializing git, what a great idea…), but once I’m comfortable with how it works, I’m excited to release it into the wild. It’s improved the speed at which I can prototype, and so hopefully for once, after many years, I’ll be able to make another game…maybe.

hxE2 + Entity Systems

[Update 2016.01.26] hxE2 is now deprecated in favour of Eskimo. If someone wants to try and fix issues, sure why not, but I’m not actively using or maintaining this!

[Update] hxE2 has been released in Alpha status here. It corresponds to the topics and improvements to hxE mentioned in this post. All feedback and comments are welcome! :)

I like talking about Entity Systems. And unlike most things I’ve talked about on this website, I have actually finished several implementations of different ECS designs.

My first one was pretty much a port from the Artemis ECS, which I’ve mentioned before, called hxE. But this design was very limited. Each System could only process 1 type of entity, and because of this, it could over complicate simple tasks like checking the distance between “Item” entities and “Inventory” entities. Ideally I would have looped over all <Item, Transform> entities, and checked the distance between all <Inventory, Transform> entities. Simple. The System limit of 1 entity type meant I needed to have 2 systems processing each type of entity, as well as some sort of communication between those systems, or further, generalize the concept of collisions which means more components…etc. etc.

[For those that didn’t understand much about what I just wrote, I recommend reading through the T-Machine blog posts on entity systems. He brings up the core concepts of how they work, as well as addressing common questions.]

Summed up, my ideology is a complete separation of Data and Logic. Systems are logic, and Components are data. What this means is that most components are PODs (Plain Old Data) with no functions, except where they are only helper functions in processing the data of that component. A System can be considered as anything that does work on components, though I usually formalize this concept as a class in most of my engines, simply to provide a common interface/reduce work required to have it running in the engine.

Moving onwards from hxE’s design, my current entity systems have the entity filtering detached from the systems. So now a System is just an empty shell with some function hooks to override (onWorldAdded, onWorldRemoved, process(delta:Float) … ). This means that a system can take in as many entity types as it needs to:

var items = new View2(world, Transform, Item);
var inventories = new View2(world, Transform, Inventory);
for (item in items.entities)
for (inventory in inventories.entities)
{
     var item_transform = items.get1(item);
     var inventory_transform = inventories.get1(inventory);
     var dx = item_transform.x - inventory_transform.x;
     var dy = item_transform.y - inventory_transform.y;
     if (dx * dx + dy * dy <= distance_to_pickup * distance_to_pickup) // add item to inventory and destroy item entity.
}
//var example = new View4(world, Transform, Mesh, Material, Input);

Not only does this make Systems much more flexible, but this also separates the concept of System, and a View into the World. At this point, System classes are helper classes rather than essential parts of the engine – a system can be anything the user wants it to be, interaction with the world is much more direct using Views.

Internally, things are setup to work well in a multithreaded environment. Each View holds a list of updates to process – once this point is made threadsafe, the rest of the interaction with the EntityWorld always happens through the View. This update pushing is also a slight concern for performance, but I will work on having performant, single threaded implementations at a later time if this happens impact projects more than I’m expecting it to.

Over the next few weeks I have a project that will be based on hxE2, and could be interesting to people using it. As I’m doing that, I’ll try to go into more details about specific parts of the hxE2 implementation, focusing on parts I get questions about etc., but for now, this is just a quick introductory post for hxE2 and my way of implementing an ECS!

Enjoi :)

P.