entt
Gaming meets modern C++ - a fast and reliable entity component system (ECS) and much more
Top Related Projects
Fast C++ logging library.
A modern formatting library
Abseil Common Libraries (C++)
Super-project for modularized Boost
Seamless operability between C++11 and Python
GoogleTest - Google Testing and Mocking Framework
Quick Overview
EnTT is a header-only, cross-platform C++ library that provides a fast and reliable Entity-Component-System (ECS) architecture. It offers a set of tools for game development and general-purpose programming, focusing on performance and modern C++ design.
Pros
- High performance and low memory footprint
- Flexible and easy-to-use API
- Extensive documentation and examples
- Active development and community support
Cons
- Steep learning curve for beginners in ECS
- Requires C++17 or later, which may limit compatibility with older projects
- Some advanced features may be complex to implement for novice users
Code Examples
- Creating and using a basic entity:
#include <entt/entity/registry.hpp>
entt::registry registry;
auto entity = registry.create();
registry.emplace<Position>(entity, 10.0f, 20.0f);
registry.emplace<Velocity>(entity, 1.0f, 1.0f);
- Iterating over entities with specific components:
registry.view<Position, Velocity>().each([](auto entity, Position& pos, Velocity& vel) {
pos.x += vel.x;
pos.y += vel.y;
});
- Using tags and groups:
registry.emplace<Enemy>(entity);
auto view = registry.group<Position>(entt::get<Velocity>, entt::exclude<Enemy>);
view.each([](auto entity, Position& pos, Velocity& vel) {
// Process non-enemy entities with Position and Velocity
});
Getting Started
-
Include EnTT in your project (header-only library):
#include <entt/entt.hpp>
-
Create a registry and entities:
entt::registry registry; auto entity = registry.create();
-
Add components to entities:
registry.emplace<Position>(entity, 0.0f, 0.0f); registry.emplace<Velocity>(entity, 1.0f, 1.0f);
-
Use views or groups to iterate and process entities:
registry.view<Position, Velocity>().each([](auto entity, Position& pos, Velocity& vel) { pos.x += vel.x; pos.y += vel.y; });
Competitor Comparisons
Fast C++ logging library.
Pros of spdlog
- Focused on logging functionality, making it simpler to use for its specific purpose
- Offers high-performance logging with asynchronous mode and custom formatting
- Extensive documentation and examples for easy integration
Cons of spdlog
- Limited to logging functionality, unlike EnTT's broader scope
- May require additional libraries for more complex use cases
- Less flexibility for customization compared to EnTT's modular design
Code Comparison
spdlog:
#include "spdlog/spdlog.h"
int main() {
spdlog::info("Welcome to spdlog!");
spdlog::error("An error message with format: {}", 42);
return 0;
}
EnTT:
#include <entt/entt.hpp>
int main() {
entt::registry registry;
auto entity = registry.create();
registry.emplace<Position>(entity, 0, 0);
return 0;
}
Summary
spdlog is a specialized logging library, offering high-performance and easy-to-use logging capabilities. EnTT, on the other hand, is a more versatile library focused on entity-component systems and metaprogramming. While spdlog excels in its specific domain, EnTT provides a broader range of functionality for game development and other complex applications. The choice between the two depends on the project's requirements and scope.
A modern formatting library
Pros of fmt
- Focused on string formatting and output, providing a more specialized and optimized solution
- Simpler API, easier to learn and use for its specific purpose
- Widely adopted and integrated into many C++ projects
Cons of fmt
- Limited scope compared to EnTT's broader functionality
- May require additional libraries for more complex operations
- Less suitable for game development or entity component systems
Code Comparison
EnTT (Entity Component System):
entt::registry registry;
auto entity = registry.create();
registry.emplace<Position>(entity, 10, 20);
registry.emplace<Velocity>(entity, 1, 1);
fmt (String Formatting):
std::string name = "Alice";
int age = 30;
fmt::print("Name: {}, Age: {}", name, age);
Summary
EnTT is a versatile entity component system library primarily used in game development and simulations. It offers a wide range of features for managing entities and components efficiently.
fmt, on the other hand, is a specialized library for string formatting and output in C++. It provides a simpler, more intuitive API for formatting strings compared to traditional C++ methods.
While both libraries are highly regarded in their respective domains, they serve different purposes. EnTT is better suited for complex game development scenarios, while fmt excels in string manipulation and formatting tasks.
Abseil Common Libraries (C++)
Pros of Abseil
- Broader scope: Abseil is a comprehensive C++ library with a wide range of utilities and components
- Google-backed: Developed and maintained by Google, ensuring high-quality and well-tested code
- Cross-platform: Designed to work seamlessly across various operating systems and compilers
Cons of Abseil
- Larger footprint: Due to its comprehensive nature, Abseil may introduce more dependencies and increase binary size
- Steeper learning curve: The extensive API might require more time to master compared to EnTT's focused approach
Code Comparison
EnTT (Entity Component System):
entt::registry registry;
auto entity = registry.create();
registry.emplace<Position>(entity, 0, 0);
registry.emplace<Velocity>(entity, 1, 1);
Abseil (String manipulation):
#include "absl/strings/str_split.h"
std::vector<std::string> result = absl::StrSplit("a,b,c", ",");
While EnTT focuses on entity-component systems for game development, Abseil provides a broader set of utilities for general C++ programming. EnTT is more specialized and lightweight, while Abseil offers a comprehensive suite of tools backed by Google's expertise.
Super-project for modularized Boost
Pros of Boost
- Comprehensive library collection covering a wide range of C++ functionalities
- Long-standing reputation and extensive community support
- Well-documented and battle-tested in numerous production environments
Cons of Boost
- Large library size can lead to longer compilation times and increased binary size
- Steeper learning curve due to its extensive API and complex template metaprogramming
- Some components may be considered outdated compared to modern C++ standards
Code Comparison
EnTT (Entity Component System):
entt::registry registry;
auto entity = registry.create();
registry.emplace<Position>(entity, 0, 0);
registry.emplace<Velocity>(entity, 1, 1);
Boost (Signals2 for event handling):
boost::signals2::signal<void(int)> sig;
sig.connect(boost::bind(&f, _1));
sig(5);
Summary
EnTT is a modern, header-only library focused on providing a fast and reliable entity component system for game development and simulations. Boost, on the other hand, is a comprehensive collection of libraries that cover a wide range of C++ programming needs. While EnTT excels in its specific domain, Boost offers a broader set of tools but may come with additional complexity and overhead.
Seamless operability between C++11 and Python
Pros of pybind11
- Seamless integration between C++ and Python
- Extensive documentation and large community support
- Supports automatic type conversion and function overloading
Cons of pybind11
- Limited to C++/Python interoperability
- Steeper learning curve for developers unfamiliar with Python C API
- Potential performance overhead due to type conversions
Code Comparison
pybind11:
#include <pybind11/pybind11.h>
PYBIND11_MODULE(example, m) {
m.def("add", [](int i, int j) { return i + j; });
}
EnTT:
#include <entt/entt.hpp>
entt::registry registry;
auto entity = registry.create();
registry.emplace<Position>(entity, 0, 0);
Key Differences
- Purpose: pybind11 focuses on C++/Python bindings, while EnTT is an Entity-Component-System (ECS) library
- Use cases: pybind11 is ideal for extending Python with C++ modules, EnTT is suited for game development and simulations
- Language support: pybind11 is specifically for C++ and Python, EnTT is C++-only
- Performance: EnTT is designed for high-performance scenarios, while pybind11 may have some overhead due to language interop
Conclusion
While both libraries are powerful tools, they serve different purposes. Choose pybind11 for Python/C++ integration, and EnTT for efficient ECS implementations in C++ projects.
GoogleTest - Google Testing and Mocking Framework
Pros of GoogleTest
- Widely adopted and industry-standard testing framework for C++
- Extensive documentation and community support
- Supports a wide range of testing features, including mocking
Cons of GoogleTest
- Larger and more complex codebase compared to EnTT
- May have a steeper learning curve for beginners
- Not designed for entity-component systems or game development
Code Comparison
GoogleTest example:
TEST(FactorialTest, HandlesZeroInput) {
EXPECT_EQ(Factorial(0), 1);
}
EnTT example:
registry.on_construct<position>().connect<&my_function>();
auto entity = registry.create();
registry.emplace<position>(entity, 0, 0);
Key Differences
- GoogleTest is primarily a testing framework, while EnTT is an entity-component system library
- EnTT is more focused on game development and high-performance scenarios
- GoogleTest offers more comprehensive testing capabilities, while EnTT provides efficient entity management
Use Cases
- Choose GoogleTest for general C++ testing needs and comprehensive test suites
- Opt for EnTT when developing games or applications requiring efficient entity-component systems
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
EnTT
has been a dream so far, we haven't found a single bug to date and it's super easy to work with-- Every EnTT User Ever
EnTT
is a header-only, tiny and easy to use library for game programming and
much more written in modern C++.
Among others, it's used
in Minecraft by Mojang, the
ArcGIS Runtime SDKs by Esri
and the amazing Ragdoll.
If you don't see your project in the list, please open an issue, submit a PR or
add the #entt tag to your topics! :+1:
Do you want to keep up with changes or do you have a question that
doesn't require you to open an issue?
Join the gitter channel and the
discord server, meet other users like you. The
more we are, the better for everyone.
Don't forget to check the
FAQs and the
wiki too. Your answers may already be
there.
Do you want to support EnTT
? Consider becoming a
sponsor or making a
donation via PayPal.
Many thanks to these people and
special thanks to:
Table of Contents
Introduction
The entity-component-system (also known as ECS) is an architectural pattern used mostly in game development. For further details:
This project started off as a pure entity-component system. Over time the
codebase has grown as more and more classes and functionalities were added.
Here is a brief, yet incomplete list of what it offers today:
- Built-in RTTI system mostly similar to the standard one.
- A
constexpr
utility for human-readable resource names. - Minimal configuration system built using the monostate pattern.
- Incredibly fast entity-component system with its own pay for what you use policy, unconstrained component types with optional pointer stability and hooks for storage customization.
- Views and groups to iterate entities and components and allow different access patterns, from perfect SoA to fully random.
- A lot of facilities built on top of the entity-component system to help the users and avoid reinventing the wheel.
- General purpose execution graph builder for optimal scheduling.
- The smallest and most basic implementation of a service locator ever seen.
- A built-in, non-intrusive and macro-free runtime reflection system.
- Static polymorphism made simple and within everyone's reach.
- A few homemade containers, like a sparse set based hash map.
- A cooperative scheduler for processes of any type.
- All that is needed for resource management (cache, loaders, handles).
- Delegates, signal handlers and a tiny event dispatcher.
- A general purpose event emitter as a CRTP idiom based class template.
- And much more! Check out the wiki.
Consider this list a work in progress as well as the project. The whole API is
fully documented in-code for those who are brave enough to read it.
Please, do note that all tools are also DLL-friendly now and run smoothly across
boundaries.
One thing known to most is that EnTT
is also used in Minecraft.
Given that the game is available literally everywhere, I can confidently say
that the library has been sufficiently tested on every platform that can come to
mind.
Code Example
#include <entt/entt.hpp>
struct position {
float x;
float y;
};
struct velocity {
float dx;
float dy;
};
void update(entt::registry ®istry) {
auto view = registry.view<const position, velocity>();
// use a callback
view.each([](const auto &pos, auto &vel) { /* ... */ });
// use an extended callback
view.each([](const auto entity, const auto &pos, auto &vel) { /* ... */ });
// use a range-for
for(auto [entity, pos, vel]: view.each()) {
// ...
}
// use forward iterators and get only the components of interest
for(auto entity: view) {
auto &vel = view.get<velocity>(entity);
// ...
}
}
int main() {
entt::registry registry;
for(auto i = 0u; i < 10u; ++i) {
const auto entity = registry.create();
registry.emplace<position>(entity, i * 1.f, i * 1.f);
if(i % 2 == 0) { registry.emplace<velocity>(entity, i * .1f, i * .1f); }
}
update(registry);
}
Motivation
I started developing EnTT
for the wrong reason: my goal was to design an
entity-component system to beat another well known open source library both in
terms of performance and possibly memory usage.
In the end, I did it, but it wasn't very satisfying. Actually it wasn't
satisfying at all. The fastest and nothing more, fairly little indeed. When I
realized it, I tried hard to keep intact the great performance of EnTT
and to
add all the features I wanted to see in my own library at the same time.
Nowadays, EnTT
is finally what I was looking for: still faster than its
competitors, lower memory usage in the average case, a really good API and an
amazing set of features. And even more, of course.
Benchmark
For what it's worth, you'll never see me trying to make other projects look
bad or offer dubious comparisons just to make this library seem cooler.
I leave this activity to others, if they enjoy it (and it seems that some people
actually like it). I prefer to make better use of my time.
If you are interested, you can compile the benchmark
test in release mode (to
enable compiler optimizations, otherwise it would make little sense) by setting
the ENTT_BUILD_BENCHMARK
option of CMake
to ON
, then evaluate yourself
whether you're satisfied with the results or not.
There are also a lot of projects out there that use EnTT
as a basis for
comparison (this should already tell you a lot). Many of these benchmarks are
completely wrong, many others are simply incomplete, good at omitting some
information and using the wrong function to compare a given feature. Certainly
there are also good ones but they age quickly if nobody updates them, especially
when the library they are dealing with is actively developed.
Out of all of them, this seems like
the most up-to-date project and also covers a certain number of libraries. I
can't say exactly whether EnTT
is used correctly or not. However, even if used
poorly, it should still give the reader an idea of where it's going to operate.
Integration
EnTT
is a header-only library. This means that including the entt.hpp
header
is enough to include the library as a whole and use it. For those who are
interested only in the entity-component system, consider to include the sole
entity/registry.hpp
header instead.
It's a matter of adding the following line to the top of a file:
#include <entt/entt.hpp>
Use the line below to include only the entity-component system instead:
#include <entt/entity/registry.hpp>
Then pass the proper -I
argument to the compiler to add the src
directory to
the include paths.
Requirements
To be able to use EnTT
, users must provide a full-featured compiler that
supports at least C++17.
The requirements below are mandatory to compile the tests and to extract the
documentation:
CMake
version 3.7 or later.Doxygen
version 1.8 or later.
Alternatively, Bazel is also supported as a build system
(credits to zaucy who offered to maintain it).
In the documentation below I'll still refer to CMake
, this being the official
build system of the library.
CMake
To use EnTT
from a CMake
project, just link an existing target to the
EnTT::EnTT
alias.
The library offers everything you need for locating (as in find_package
),
embedding (as in add_subdirectory
), fetching (as in FetchContent
) or using
it in many of the ways that you can think of and that involve CMake
.
Covering all possible cases would require a treatise and not a simple README
file, but I'm confident that anyone reading this section also knows what it's
about and can use EnTT
from a CMake
project without problems.
Natvis support
When using CMake
, just enable the option ENTT_INCLUDE_NATVIS
and enjoy
it.
Otherwise, most of the tools are covered via Natvis and all files can be found
in the natvis
directory, divided by module.
If you spot errors or have suggestions, any contribution is welcome!
Packaging Tools
EnTT
is available for some of the most known packaging tools. In particular:
-
Conan
, the C/C++ Package Manager for Developers. -
vcpkg
, Microsoft VC++ Packaging Tool.
You can download and installEnTT
in just a few simple steps:$ git clone https://github.com/Microsoft/vcpkg.git $ cd vcpkg $ ./bootstrap-vcpkg.sh $ ./vcpkg integrate install $ vcpkg install entt
Or you can use the
experimental
feature to test the latest changes:vcpkg install entt[experimental] --head
The
EnTT
port invcpkg
is kept up to date by Microsoft team members and community contributors.
If the version is out of date, please create an issue or pull request on thevcpkg
repository. -
Homebrew
, the missing package manager for macOS.
Available as a homebrew formula. Just type the following to install it:brew install skypjack/entt/entt
-
build2
, build toolchain for developing and packaging C and C++ code.
In order to use theentt
package in abuild2
project, add the following line or a similar one to themanifest
file:depends: entt ^3.0.0
Also check that the configuration refers to a valid repository, so that the package can be found by
build2
:-
cppget.org
, the open-source community central repository, accessible ashttps://pkg.cppget.org/1/stable
. -
Package source repository: accessible as either
https://github.com/build2-packaging/entt.git
orssh://git@github.com/build2-packaging/entt.git
. Feel free to report issues with this package.
Both can be used with
bpkg add-repo
or added in a projectrepositories.manifest
. See the official documentation for more details. -
-
bzlmod
, Bazel's external dependency management system.
To use theentt
module in abazel
project, add the following to yourMODULE.bazel
file:bazel_dep(name = "entt", version = "3.12.2")
EnTT will now be available as
@entt
(short for@entt//:entt
) to be used in yourcc_*
ruledeps
.
Consider this list a work in progress and help me to make it longer if you like.
pkg-config
EnTT
also supports pkg-config
(for some definition of supports at least).
A suitable file called entt.pc
is generated and installed in a proper
directory when running CMake
.
This should also make it easier to use with tools such as Meson
or similar.
Documentation
The documentation is based on doxygen. To build it:
$ cd build
$ cmake .. -DENTT_BUILD_DOCS=ON
$ make
The API reference is created in HTML format in the build/docs/html
directory.
To navigate it with your favorite browser:
$ cd build
$ your_favorite_browser docs/html/index.html
The same version is also available online
for the latest release, that is the last stable tag.
Moreover, there exists a wiki dedicated
to the project where users can find all related documentation pages.
Tests
To compile and run the tests, EnTT
requires googletest.
cmake
downloads and compiles the library before compiling anything else. In
order to build the tests, set the CMake
option ENTT_BUILD_TESTING
to ON
.
To build the most basic set of tests:
$ cd build
$ cmake -DENTT_BUILD_TESTING=ON ..
$ make
$ make test
Note that benchmarks are not part of this set.
EnTT in Action
EnTT
is widely used in private and commercial applications. I cannot even
mention most of them because of some signatures I put on some documents time
ago. Fortunately, there are also people who took the time to implement open
source projects based on EnTT
and did not hold back when it came to
documenting them.
Here you can find an incomplete list of games, applications and articles that can be used as a reference.
If you know of other resources out there that are about EnTT
, feel free to
open an issue or a PR and I'll be glad to add them to the list.
Contributors
Requests for features, PRs, suggestions and feedback are highly appreciated.
If you find you can help and want to contribute to the project with your
experience or you do want to get part of the project for some other reason, feel
free to contact me directly (you can find the mail in the
profile).
I can't promise that each and every contribution will be accepted, but I can
assure that I'll do my best to take them all as soon as possible.
If you decide to participate, please see the guidelines for
contributing
before to create issues or pull requests.
Take also a look at the
contributors list to
know who has participated so far.
License
Code and documentation Copyright (c) 2017-2024 Michele Caini.
Colorful logo Copyright (c) 2018-2021 Richard Caseres.
Code released under
the MIT license.
Documentation released under
CC BY 4.0.
All logos released under
CC BY-SA 4.0.
Top Related Projects
Fast C++ logging library.
A modern formatting library
Abseil Common Libraries (C++)
Super-project for modularized Boost
Seamless operability between C++11 and Python
GoogleTest - Google Testing and Mocking Framework
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot