Flecs v4.0
A fast entity component system (ECS) for C & C++
|
See the ECS FAQ
There are a lot of reasons, but the main ones are:
You can! Even though the C++ API is C++11, you can use it with any revision at or above 11.
You can! Components can contain almost any C++ type.
Archetype-based refers to the way the ECS stores components. It means that all entities with the same components are stored together in an archetype. This provides efficient CPU cache utilization and allows for things like vectorization and fast querying.
Other examples of archetype implementations are Unity DOTS, Unreal Mass and Bevy ECS.
For more information, see this blog: https://ajmmertens.medium.com/building-an-ecs-2-archetypes-and-vectorization-fe21690805f9
Flecs and EnTT both are ECS libraries, but other than that they are different in almost every way, which can make comparing the two frameworks tricky. When you are comparing Flecs and EnTT, you can generally expect to see the following:
When doing a benchmark comparison don't rely on someone else's numbers, always test for your own use case!
Yes, Flecs is used commercially (see the README).
This is likely because queries (flecs::query
) are created repeatedly in a loop or system. Queries are the fastest way to iterate over entities, but are expensive to create, so make sure to create them in advance:
Likely because of the same reason as above. Queries are registered with the world, and unless they are deleted explicitly they will take up space. To delete a query, do:
System functions are called for each matching archetype (see above for "What is an archetype"). In short, the reason for this is that it provides systems with direct access to component arrays.
If you have code that needs to run only once per frame or you want to take control over the entire iteration, take a look the custom_runner
examples, which show how to use the run
callback.
Yes it can! See the quickstart manual for more information.
This happens in C if the variable that holds the component id can't be found. This example shows how to fix it: https://github.com/SanderMertens/flecs/tree/master/examples/c/entities/fwd_declare_component
When you inspect the integer value of an entity you may see that this value is very large, usually around 4 billion. This is not a bug, and instead means that the entity id has been recycled. This example shows when recycling happens:
An add
just adds a component without assigning a value to it. A set
assigns a value to the component. Both operations ensure that the entity will have the component afterwards.
An add
is used mostly for adding things that don't have a value, like empty types/tags and most relationships. If add
is used with a component that has a constructor, adding the component will invoke its constructor.
Additionally you can use emplace
to construct a component in place in the storage (similar to std::vector::emplace
).
Yes it can! See the reflection examples:
If you look at the size of the distr/flecs.c and distr/flecs.h files you might wonder why they are so large. There are a few reasons:
Not all addons are useful in any project. You can customize a Flecs build to only build the things you need, which reduces executable size and improves build speed. See the quickstart on how to customize a build.
Make sure that:
ecs_progress
/world::progress
in your main loopIf that doesn't work, see the README of the explorer for potential issues with browser security settings and how to run a local instance of the explorer.
No! The https://flecs.dev/explorer page is a 100% client side application that does not talk to a backend. When you navigate to the page it will attempt to connect to http://localhost:27750 to find a running Flecs application. The data that the explorer fetches never leaves your machine.
The explorer can only display component values if the reflection data has been registered for the component. See the C reflection examples and C++ reflection examples for more information.
Flecs has builtin change detection. Additionally, you can use an OnSet
observer to get notified of changes to component values. See the query change detection and observer examples for more information.
No, relationships are a deeply integrated feature that is faster in many ways than a component with an entity handle. See the relationship manual for more information.
You can! Systems can be created from any function, except other systems.
You can! The flecs scheduler (implemented in the pipeline addon) is fully optional and is built on top of Flecs. You can create a custom pipeline, or a custom schedule implementation that does something else entirely than what Flecs provides.
You can! Systems are an optional addon that can be disabled. You can build applications that just use Flecs queries.
This is likely because the entity has a parent. A lookup by name requires you to provide the full path to an entity, like:
or in C++:
You can! By default ECS operations are deferred when called from inside a system, which means that they are added to a queue and processed later when it's safe to do so. Flecs does not have a dedicated command API, if you call an operation from a system it will be automatically added to the command queue!
A LOCKED_STORAGE error means that you're trying to add or remove an entity to an archetype that is currently being accessed, usually during query iteration. An example:
Most LOCKED_STORAGE errors can be resolved by putting defer_begin
and defer_end
around the iteration, which postpones the table-changing operations until after the iteration: