Flecs v4.0 is out!

Sander Mertens
12 min readJul 14, 2024

--

What is Flecs?

Flecs is an Entity Component System (FAQ) for C and C++ that helps with building games, simulations and more. The core features of Flecs are:

  • Store data for millions of entities in data structures optimized for CPU cache efficiency and composition-first design
  • Find entities for game systems with a high performance query engine that can run in time critical game loops
  • Run code using a multithreaded scheduler that seamlessly combines game systems from reusable modules
  • Builtin support for hierarchies, prefabs and more with entity relationships which speed up game code and reduce boiler plate
  • An ecosystem of tools and addons to profile, visualize, document and debug projects

Flecs is fully open source and licensed under the MIT license. If you’d like to support the project, consider giving it a ️️⭐️ on the Github page!

Link to the v4.0 release:

What happened?

Flecs v4.0 just got released and it’s easily the biggest Flecs release to date!

  • More than 1700 new commits got added since v3 with the repository now having upwards of 4700 commits in total.
  • More than 400 issues and PRs submitted by dozens of community members got closed and merged ❤️
  • The Flecs Discord server doubled again in size since v3 and now has over 2300 members.
  • The number of GitHub stars grew from 2900 to 5800.
  • The number of test cases grew from 4400 to 8500 since v3, with the amount of test code growing from 130K to 240K lines of code.

Who is using Flecs?

Flecs has seen a significant uptick in adoption, for both very small and very large projects! Here‘s a selection:

Hytale needs no introduction, and is easily one of the most anticipated games currently in development with Flecs. Why did they pick Flecs? Look no further than this quote:

We knew that we wanted to build Hytale around an Entity-Component-System (ECS). When we analyzed the options, Flecs rose to the top. Flecs provides the backbone of the Hytale Game Engine. Its flexibility has allowed us to build highly varied gameplay while supporting our vision for empowering Creators.
— Dan Webster, Technical Director Hypixel studios

If you’d like to know more about how Hytale is using Flecs, check out their excellent recent blog on ECS. Here’s a highlight from that same article:

In many ways, an ECS is similar to a database, and Flecs makes full use of this fact. The underlying rules engine is a powerful tool that supports querying data […] ranging from a system which updates crop growth based on a number of attached components, to complex lookups for game logic […] (e.g. find me all NPCs bearing swords that are aggressive to the player).

Welcome back commander! Fans of a certain classic RTS series will be looking forward to the release of Tempest Rising (including yours truly). Tempest Rising is built in Unreal Engine - here’s a short blurb on what the team is using Flecs for:

We are using it [Flecs] mostly to leverage high count of units. Movement (forces / avoidance), collisions, systems that rely on spatial queries, some gameplay related stuff. […] embracing ECS allowed us to scale features which once were a bottleneck. Basically we use Flecs when it makes sense for us.

If you’re more into space sims and dogfights, Extermination Shock, which just launched on Steam, has got you covered. What’s especially awesome is that the author has released the full source code on GitHub!

Not all games have to be about world domination or traveling the galaxy! Enter Tome Tumble Tournament, a small but wholesome puzzle game that uses Flecs queries for things like its movement rules.

If you’d like to see more Flecs games currently in development, make sure to check the #showcase channel on the Flecs Discord!

Let’s talk Languages

Flecs, with its core written in C, has been designed from the get go to work well across different programming languages. In the last year though the community really stepped up the language binding game:

Flecs Rust (Rust)

I’m excited to (finally) announce a brand new Flecs Rust binding:

After having worked very closely with the author (Indrab) for months, the binding is now ready for a larger audience. An enormous amount of effort went into porting over all of the APIs, including relationships, and writing the documentation, examples, and tests. The binding is still in alpha, so bear with the author as he improves it over the coming months!

Special thanks also go out to James O’Brian, Bruce Mitchener, Andrew Gazelka and iiYese for submitting PRs, trying out the binding, and providing feedback in its early stages.

Flecs.NET (C#)

BeanCheeseBurrito’s Flecs.NET has been around for about a year, and has quickly become the de facto C# binding for Flecs!

The binding closely mirrors the C++ API, and comes bundled with documentation, examples and tests. It is actively maintained with its version never trailing more than a day behind the official release!

Cross-language support will remain an important part of Flecs going forward. To better support C# and Rust developers, all of the Flecs manuals have been updated with examples for the new C# and Rust bindings!

What’s New?

Here are the most noteworthy new features in v4!

One Query Engine to Rule them All

In the past year a lot of new query features got introduced that enabled some really wild stuff. All of that goodness was tucked away behind three separate APIs however, which could be confusing for someone looking to actually put it to use.

No longer in v4! The filter, query, and rule implementations now have been unified into a single query API. Not only does this drastically simplify code, it also enables previously impossible combinations of features, which makes queries even more powerful. Last but not least, all query features are now available to systems as well!

v3 vs. v4 query feature comparison

There’s a lot more to talk about here, such as the strategies the codebase uses to keep complexity in check, new memoization caches for query traversal and smart query planning to optimize order of operations, but that’ll have to wait until a future blog post.

Explorer V4

The Explorer has become an indispensable tool for many Flecs developers. It enables them to quickly inspect scenes, entities, queries and performance statistics. With the introduction of v4 also comes a brand new Explorer that has been rewritten from scratch!

Not only does it look better (I hope you’ll agree), upgrading from vue2 to vue3 cleaned up the code and made it much easier to navigate. This really sped up new feature development, and should help anyone looking to contribute to the project.

Aside from sporting new looks and a cleaner code base, the v4 explorer has a few new tricks up its sleeve, such as a utility to capture commands, editing multiple Flecs scripts at the same time, the ability to add & remove components, and new tools to inspect queries, systems and observers:

The v4 explorer has new tools to inspect queries.

Flecs Script

Flecs Script is to ECS what HTML is to the web. Kind of. It’s a simple and convenient way to create entities and components, without having to go through slow and bothersome compilation cycles.

In v4 Flecs Script got completely overhauled, with an improved syntax, more powerful APIs and a much faster template engine. The new implementation also sets the stage for the upcoming reactivity framework, which will be a big deal for the development of UIs, assets and scenes.

// A tree template in Flecs Script
template Tree {
prop height = f32: 4

const trunk_height = $height / 2

Trunk : materials.Wood {
Position3: {0, $trunk_height / 2, 0}
Box: {0.5, $trunk_height, 0.5}
}

Canopy : materials.Leaves {
const canopy_height = $height - $trunk_height

Position3: {0, $trunk_height + $canopy_height / 2, 0}
Box: {1.5, $canopy_height, 1.5}
}
}

// Three tree instances
Tree(height: 5) { Position3: {-3, 0, 0} }
Tree(height: 4) { Position3: { 0, 0, 0} }
Tree(height: 6) { Position3: { 3, 0, 0} }

If you’d like to take a crack at Flecs Script, you can already do so without writing any C or C++ code: just fire up the playground! Not sure about the syntax? The Flecs Script manual has got you covered.

Sparse Components

Flecs v4 has a new storage mode that stores components in sparse sets! Enabling sparse storage is done by adding the Sparse trait:

world.component<Position>().add(flecs::Sparse);

Sparse components don’t move when entities are moved between archetypes. Besides being good for performance, this also means that Flecs now supports components that aren’t movable! In v4, if you register a non-movable C++ component it automatically registers as sparse.

Another feature of the sparse storage is that it provides stable component pointers. This means that it’s safe to store a pointer to a sparse component, which comes in handy in all sorts of scenarios.

Flecs Demo Updates

The Tower Defense demo has been overhauled for v4 to better showcase Flecs features, while also quadrupling the scale of the scene!

The most noteworthy change is that the tower defense code now fully relies on Flecs Script to define all of its assets. The graphics have also improved: the demo now has dynamic explosion lights and improved distance fog.

v4 (left) vs. v3 (right) tower defense demo

The City demo has also been updated with dynamic lights, which looks especially nice at twilight:

v4 city demo with dynamic lights

Inheritance

A bunch of changes were made to how inheritance works which simplify code and improve performance. The biggest difference is that inheritance is now an opt-in feature. When a prefab is instantiated in v4, components are by default copied to the instance:

flecs::entity SpaceShip = world.prefab()
.set(MaxSpeed{100});

// MaxSpeed is copied to inst
flecs::entity inst = world.entity().is_a(SpaceShip);

To opt in to inheritance, a trait can be added to a component:

world.component<MaxSpeed>().add(flecs::OnInstantiate, flecs::Inherit);

The new default means that common sources of API bloat such as always using auto-overriding, or adding .self() to query terms to avoid (sometimes expensive) query traversal are no longer necessary:

// v3
flecs::entity SpaceShip = world.prefab()
.set_override(MaxSpeed{100});

auto q = world.query_builder<MaxSpeed>()
.term_at(1).self()
.build();

// v4
flecs::entity SpaceShip = world.prefab()
.set(MaxSpeed{100});

auto q = world.query<MaxSpeed>();

Member Queries

Entity relationships are a powerful tool, but in some cases the overhead caused by fragmentation reduces their applicability. In v4 queries can directly query entity members as if they were relationship targets, which is like having relationships without the fragmentation!

Here’s a simple query for the pilot member of a Cockpit component:

(Cockpit.pilot, $pilot), CanDogfight($pilot)

The setup for this is minimal: the only thing that’s needed is to describe the member with the reflection framework:

world.component<Cockpit>()
.member(flecs::Entity, "pilot");

Flecs Remote API

Flecs v4 has a completely new set of APIs for remotely connecting to Flecs applications! The new Flecs Remote API includes a simpler JSON format, a new REST API with a cleaner design, and a new JavaScript library for the development of web clients that use Flecs data.

The first customer of the Flecs Remote API is the new v4 explorer. Check out the explorer project to see examples of the API in use!

Improved Documentation

It’s not the sexiest topic, but good documents go a long way to ensure a smooth developer experience! Several weeks of the v4 release cycle were spent on improving the documentation and making sure it’s up to date. This has resulted in an entirely new set of manuals that cover features in much more depth than before. Here’s an overview:

All of the manuals have been updated with C, C++, C# and Rust examples. Big thanks to Indradb, Bruce Mitchener and BeanCheeseBurrito for helping out with writing the new example sections and correcting my many, many typos!

What’s next

It’s always difficult to predict the future, but here are a few features you can look forward to in upcoming Flecs releases:

Reactivity. Reactive frameworks such as Vue and React are some of the main drivers behind what makes the web such a productive environment. The core idea is that you transform input data into an entity hierarchy (or DOM). Whenever the input changes, the entities change (hence “reactive”). This saves applications from having to write tedious CRUD code which is especially nice when building complex user interfaces.

With the new script implementation, Flecs is taking its first steps into becoming a full-fledged reactive framework that is deeply integrated with the ECS. Expect many incremental updates in future releases that will bring reactivity to gamedev!

Dense Tree Storage. A challenge with games that have many small subtrees is that child entities get fragmented. This can cause bottlenecks for performance sensitive components such as Transform. To address this problem, future versions of Flecs will introduce a new storage mode that stores a single dense component array per subtree which does not get fragmented by other child components, while keeping all of the ease of use benefits of the ChildOf relationship.

The dense tree storage will also have a number of enhancements that specifically benefit reactivity. Stay tuned for more details!

Dense/Sparse tables. This was a feature that got announced all the way back in the v3.0 blog post! Several attempts were made to implement it, but having three distinct query implementations made it too complex (and is actually what kicked off v4!). Now that there is just a single query implementation, expect this feature to land in a future v4 release.

The feature itself is a technique to prevent component fragmentation by storing tags and components differently. Here is a high-level diagram that shows the idea:

Pluggable Storages. Pluggable storages add an interface to Flecs allows full customization of how components are stored. Similar to dense/sparse tables, this work was blocked by having to support storage plugins across multiple query implementations. With this problem out of the way, pluggable storages are expected to land in a future v4 release.

Node API. The node API is another feature that was announced in v3. It will allow applications to wire up systems (“nodes”) in graphs, which will open the door to visual ECS programming. Nodes will also have a role to play in wiring up reactive assets to game logic, stay tuned for more details!

Big Thanks To

The v4 release would not have been what it is without the many contributions from the Flecs community! A special thanks to everyone that contributed PRs and helped with the development of Flecs v4 features (in no particular order):

Bruce Mitchener, Indradb, BeanCheeseBurrito, Paulo Rafael Feodrippe, Garrett Swan, Javier Peletier, James O’Brien, Matthew Collins, ZeroErrors, Indiana Kernick, Benji, Lennart, Tim Čas, Alex, Elliot, TBlauwe, Garret, David Amador, Charlie-83, Maciej Biedrzycki

Also a big thanks to everyone that sponsored the project ❤️:

Dominik Madarász, Red J, Bjorn, ikrima, Hronet, tcdude,
Maciej Biedrzycki, Vladyslav Boroday, Joel Ong, Megafunk, schipdah, Scaless, Tiansheng Li, Paulo Rafael Feodrippe, Isaac, Andrew Spiering, Justin Walsh, Lauren, Neodon, Alexander Knorre, evolvingfridge, Silent Tower Games, TFlippy, John, Celeste Soueid, Rasmus, Matheus da Silva Garcias, wesleysliao, and all of the private sponsors!

--

--

Sander Mertens

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