flecs

Join the chat at https://gitter.im/flecsdev/community Discord Chat Build Status Build status codecov

Flecs is a fast and lightweight Entity Component System for C89 / C99 / C++11 that packs a lot of punch in a small footprint:

  • Blazing fast iteration speeds with direct access to raw C arrays across multiple components
  • Built-in support for entity hierarchies, prefabs, nested prefabs and prefab variants
  • An efficient lock-free staging architecture allows for modifying entities across multiple threads
  • Expressive entity queries with support for and, or, not and optional operators
  • Systems that are time triggered, rate triggered, run every frame or run only when needed
  • Modules allow for creation of large scale applications by organizing systems & components in reusable plug & play units
  • A fully customizable core that makes it easy to integrate Flecs into other frameworks / game engines

Make sure to check the flecs dashboard:

dashboard

What is an Entity Component System?

ECS (Entity Component System) is a way to organize code that is mostly used in gaming and simulation projects. ECS code generally performs better than traditional OOP, and is typically easier to reuse. The main differences between ECS and OOP are composition is a first class citizen in ECS, and that data is represented as plain data types rather than encapsulated classes. A framework is an Entity Component System if it:

  • Has entities that are unique identifiers (integers)
  • Has components that are plain data types which can be added to entities
  • Has systems that are functions which are matched against entities with a set of components

Documentation

Example

This is a simple flecs example in the C99 and C++11 APIs:

typedef struct Position {
    float x;
    float y;
} Position;

typedef float Speed;

void Move(ecs_iter_t *it) {
    Position *p = ecs_column(it, Position, 1);
    Speed *s = ecs_column(it, Speed, 2);

    for (int i = 0; i < it->count; i ++) {
        p[i].x += s[i] * it->delta_time;
        p[i].y += s[i] * it->delta_time;
    }
}

int main(int argc, char *argv[]) {
    ecs_world_t *world = ecs_init();

    ECS_COMPONENT(world, Position);
    ECS_COMPONENT(world, Speed);
    ECS_SYSTEM(world, Move, EcsOnUpdate, Position, Speed);

    ecs_entity_t e = ecs_new(world, 0);    
    ecs_set(world, e, Position, {0, 0});
    ecs_set(world, e, Speed, {1});

    while (ecs_progress(world, 0));

    return ecs_fini(world);
}
struct Position {
    float x;
    float y;
};

struct Speed {
    float value;
};

int main(int argc, char *argv[]) {
    flecs::world world();

    flecs::component<Position>(world, "Position");
    flecs::component<Speed>(world, "Speed");

    flecs::system<Position, Speed>(world)
        .each([](flecs::entity e, Position& p, Speed& s) {
            p.x += s.value * e.delta_time();
            p.y += s.value * e.delta_time();
        });

    flecs::entity(world, "MyEntity")
        .set<Position>({0, 0})
        .set<Speed>({1});

    while (world.progress()) { }
}

Building

You can build flecs with either CMake, Meson, Bake or embed the sources into your own project.

Embedding:

Flecs can be easily embedded into projects, as it does not require complex build instructions. The following build instructions are enough to build a functioning Flecs library with gcc:

gcc src/*.c -Iinclude --shared -o libflecs.so

CMake

git clone https://github.com/SanderMertens/flecs
cd flecs
mkdir build
cd build
cmake ..
make

Meson

git clone https://github.com/SanderMertens/flecs
cd flecs
meson build --default-library=both
cd build
ninja

Bake

Install bake first:

git clone https://github.com/SanderMertens/bake
make -C bake/build-$(uname)
bake/bake setup

To then install Flecs, do:

bake clone https://github.com/SanderMertens/flecs