What it is
EnTT is a fast and flexible C++ Entity-Component-System (ECS) library used in game development and simulation. It provides efficient memory management, entity lifecycle handling, component storage, and iteration utilities for building scalable and data-driven applications.
EnTT allows developers to create entities, assign components, and iterate over them efficiently. It leverages modern C++ templates and compile-time features to minimize overhead while maximizing flexibility.
Installation
find_package(EnTT CONFIG REQUIRED)Getting started
The smallest useful thing you can do with it, and what each part means.
#include <entt/entt.hpp>
#include <iostream>
struct Position { float x, y; };
struct Velocity { float dx, dy; };
int main() {
entt::registry registry;
auto entity = registry.create();
registry.emplace<Position>(entity, 0.f, 0.f);
registry.emplace<Velocity>(entity, 1.f, 1.f);
std::cout << "Entity created with Position and Velocity." << std::endl;
return 0;
}registry.view<Position, Velocity>().each([](auto entity, auto& pos, auto& vel) {
pos.x += vel.dx;
pos.y += vel.dy;
});Advanced usage
Where the library earns its place over a simpler alternative.
auto view = registry.view<Position, Velocity>();
for (auto entity : view) {
auto &pos = view.get<Position>(entity);
auto &vel = view.get<Velocity>(entity);
pos.x += vel.dx;
pos.y += vel.dy;
}struct CollisionEvent { entt::entity a, b; };
entt::dispatcher dispatcher;
dispatcher.sink<CollisionEvent>().connect([](const CollisionEvent& e){
std::cout << "Collision detected!" << std::endl;
});
dispatcher.trigger(CollisionEvent{entity1, entity2});auto group = registry.group<Position, Velocity>();
for (auto entity : group) {
auto &[pos, vel] = group.get<Position, Velocity>(entity);
pos.x += vel.dx;
pos.y += vel.dy;
}Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Accessing non-existent component
- Check with `registry.all_of<T>(entity)` before accessing components.
- Performance issues with sparse components
- Use groups or compact storage to improve memory locality.
- Entity lifecycle mismanagement
- Always destroy unused entities with `registry.destroy(entity)`.
Best practices
- Favor composition (components + systems) over inheritance for scalability.
- Use groups or views for performance-sensitive iteration.
- Keep components lightweight and focused on data only.
- Leverage EnTT’s signals and dispatcher for decoupled event handling.
- Profile your ECS usage to avoid creating too many small entities unnecessarily.
Background
Why it exists, and what it was reacting to.
EnTT was created by Michele Caini to provide a modern, high-performance ECS framework for C++. Unlike traditional object-oriented game engines, ECS focuses on separating data (components) from behavior (systems), enabling better performance and scalability. EnTT has gained popularity in both indie and professional game development as well as simulations and modeling.
