Flecs 2.1 is out!

Sander Mertens
5 min readSep 1, 2020

It has only been one month since version 2.0 came out, and yet Flecs 2.1 has lots of improvements that makes building games with C and C++ easier than ever! Let’s go over some of the new developments, starting with:

Flecs Hub

This is not strictly part of the Flecs core, but still worth noting as a lot of progress has been made on several flecs modules, like the new sokol-based renderer, object transforms, window creation and a Lua binding. The long term goal is to show how to implement a basic modular ECS engine, as many users end up integrating ECS in their own game engines.

240.000 bouncing boxes rendered with Flecs and Sokol

Improved C++ API

The C++ API received a big facelift, which makes coding in C++ much more pleasant. Not only have many functions been added to the API, the API itself has also become a lot less verbose. Applications no longer have to register their components, and creating new objects requires less typing. An example:

struct Position {
float x;
float y;
};
struct Velocity {
float x;
float y;
};
int main(int argc, char *argv[]) {
flecs::world ecs;
ecs.system<Position, const Velocity>()
.each([](flecs::entity e, Position& p, const Velocity& v) {
p.x += v.x;
p.y += v.y;
});
ecs.entity()
.set<Position>({0, 0})
.set<Velocity>({1, 1});
while (ecs.progress()) { }
}

The new API does not break backwards compatibility, which means that existing C++ Flecs applications will still work.

Faster data structures

One of the major data structures in Flecs has been reimplemented which improved performance across the board by almost 20%! Flecs 2.0 used the combination of a sparse set and a hash map to store entity information. In 2.1 this dual approach has been replaced by a single paged sparse set. This simplified the code and improved performance in various areas.

The new data structure was specifically implemented because a faster mechanism was required to recycle ids in bulk. The new implementation can, in a stable system, recycle any number of identifiers in an O(1) operation! At the same time it provides stable pointer access to its contents, which allows the rest of the framework to cache pointers more often. This lead to the performance improvements, as less lookups were required, and lots of branches could be removed.

State machines

State machines are a common approach to implementing complex behavior in games, and up to this point implementing them with ECS was clunky, for reasons described in this post. Flecs 2.1 comes with a new mechanism called “switchable tags”, which makes integrating state machines with ECS a lot easier. An example:

struct Walking { };
struct Running { };
int main(int argc, char *argv[]) {
flecs::world ecs;
auto Movement = ecs.type()
.add<Walking>()
.add<Running>();
auto e = ecs.entity()
.add_switch(Movement)
.add_case<Walking>();
// Remove Walking, add Running
e.add_case<Running>();
}

The trick with switchable tags is that only one tag of a “switch” can be active at the same time. This makes implementing state machines easier, as you don’t have to separately remove the previous state and add the new state. The API also protects you from accidentally adding a state that does not belong to the state machine.

It’s not a full-fletched state machine (that is still up to the application) but it definitely makes it easier to integrate one with ECS!

Subqueries

Flecs queries are fast data structures that cache the archetypes that they match with. This makes queries extremely fast to evaluate, but not so fast to create as it requires iterating over and matching with all existing archetypes. Subqueries address this problem by creating queries that only match with the archetypes of their parent query. An example:

auto q_parent = ecs.query<Position>();
auto q_sub = ecs.query<Position, Velocity>(q_parent);

The second query (q_sub) is only matched against the archetypes that q_parent matched with. Not only does this reduce the cost of creating the subquery, it also reduces the memory overhead in the framework as a whole as subqueries have a much lighter footprint than their regular counterparts. Aside from the way they are created, queries and subqueries can be iterated and used in the exact same way.

This only covered a small set of the total number of changes in 2.1. For a full list of all the changes, see the release page.

Looking ahead…

It is always difficult to predict what the next release will include, but a few ideas are worth mentioning as they are exciting, and push the boundaries of ECS even further.

Visual (graph) programming - One area where ECS is lacking is in how temporary data, like intermediate results of a complex calculation, are treated. Currently applications have to store this data in temporary components, or run all logic in a single system, neither of which are ideal. Graph based programming can provide an outcome. If systems can be connected like nodes in a graph where each node writes its result in a temporary buffer, it would relieve the application from manually managing these resources, and provide a nice boost in performance as well.

Ontologies - AI systems often require some kind of knowledge representation so that they can perform basic reasoning. Examples of this are GOAP, or SHRDLU. Such knowledge is often represented in semantic triples that take the form of [Subject Verb Object]. The new Flecs traits API allows applications to store such triples, like:

Alice.add_trait(HasHusband, Bob);

However, the underlying storage of these triples can be improved. Triples are unique in that relationships are, contrary to components, extremely sparse (Only Alice has Bob as husband). With the right data structures, an ECS could allow for efficient storage and retrieval of such relationships, which could make it easier to implement AI systems directly on top of ECS.

Developer tools - A new Flecs dashboard has been in development for a while, and is almost ready to be released. Just like the old dashboard, you will be able to monitor performance, and much more. A sneak preview:

Getting started

If you’d like to get started with Flecs, check out the repository: https://github.com/SanderMertens/flecs

Join the Flecs discord if you have questions, or would like to see what other Flecs developers are up to: https://discord.gg/MRSAZqb

More reading:

--

--

Sander Mertens

Author of Flecs, an Entity Component System for C and C++