A C++14 Entity Component System



This project is currently in the progress of being rewritten for C++17. Check out this issue if you have any suggestions/know a good way to transition!


EntityPlus is an Entity Component System library written in C++14, offering fast compilation and runtime speeds. The library is header only, saving you the trouble of fidgeting with build systems and there are no external dependencies.

The ECS framework is an attempt to decouple data from mechanics. In doing so, it lets you create objects out of building blocks that mesh together to create a whole. It models a has-a relationship, letting you expand without worrying about dependency trees and inheritance. The three main aspects of an ECS framework are of course Entities, Components, and Systems.


EntityPlus requires C++14 conformance, and was mainly developed on MSVC. It has been tested to work on

  • MSVC 2015 update 3
  • Clang 3.5.0
  • GCC 5.3.0


Since EntityPlus is header only, there is no need to build the library to use it. Just #include <entityplus/entity.h>! However, there are tests and examples you can build with cmake.

To build the tests, you need to specify the catch directory. An in tree build could look like this:

cmake -D Catch_dir=dir/to/catch ..
make test


Components contain information. This can be anything, such as health, a piece of armor, or a status effect. An example component could be the identity of a person, which could be modeled like this:

struct identity {
    std::string name_;
    int age_;
    identity(std::string name, int age) : name_(name), age_(age) {}

Components don't have to be aggregate types, they can be as complicated as they need to be. For example, if we wanted a health component that would only let you heal to a maximum health, we could do it like this:

class health {
    int health_, maxHealth_;
    health(int health, int maxHealth) :
        health_(health), maxHealth_(maxHealth){}
    int addHealth(int health) {
        return health_ = std::max(health+health_, maxHealth);

As you may have noticed, these are just free classes. Usually, to use them with other ECSs you'd have to make them inherit from some common base, probably along with CRTP. However, EntityPlus takes advantage of the type system to eliminate these needs. To use these classes we have to simply specify them later.

Components must have a constructor, so aggregates are not allowed. This restriction is the same as all emplace() methods in the standard library. There are no other requirements.


Entities model something. You can think of them as containers for components. If you want to model a player character, you might want a name, a measurement of their health, and an inventory. To use an entity, we must first create it. However, you can't just create a standalone entity, it needs context on where it exists. We use an entity_manager to manage all our entitys for us.

using CompList = component_list<identity, health>;
using TagList = tag_list<struct TA, struct TB>;
entity_manager<CompList, TagList> entityManager;
using entity_t = typename entity_manager<CompList, TagList>::entity_t;

Don't be scared by the syntax. Since we don't rely on inheritance or CRTP, we must give the entity_manager the list of components we will use with it, as well as a list of tags. To create a list of components, we simply use a component_list. component_lists and tag_lists have to be unique, and the component_list and tag_list can't have overlapping types. If you mess up, you'll be told via compiler error.

error C2338: component_list must be unique

Not so bad, right? EntityPlus is designed with the end user in mind, attempting to achieve as little template error bloat as possible. Almost all template errors will be reported in a simple and concise manner, with minimal errors as the end goal. With C++17 most code will switch over to using constexpr if for errors, which will reduce the error call stack even further.

Now that we have a manager, we can create an actual entity.

entity_t entity = entityManager.create_entity();

You probably want to add those components to the entity.

auto retId = entity.add_component<identity>("John", 25);
retId.first.name_ = "Smith";
entity.add_component(health{100, 100});

If we supply a component that wasn't part of the original component list, we will be told this at compile time. In fact, any sort of type mismatch will be presented as a user friendly error when you compile. Adding a component is quite similar to using map::emplace(), because the function forwards its args to the constructor and has a similar return semantic. A pair<component&, bool> is returned, indicating error or success and the component. The function can fail if a component of that type already exists, in which case the returned component& is a reference to the already existing component. Otherwise, the function succeeded and the new component is returned.

Sometimes you know all the tags and components you want from the get go. You can create an entity with all these parts just as easily:

entity_t ent = entityManager.create_entity<TA>(A{3}, health{100, 200});

The arguments are fully formed components you wish to add to the entity and the template arguments are the tags the entity should have once it's created.

What happens if we create a copy of an entity? Well, since entities are just handles, this copy doesn't represent a new entity but instead refers to the same underlying data that you copied.

auto entityCopy = entity;
assert(entityCopy.get_component<health>() == entity.get_component<health>();

What happens if we modify one copy of the entity? Well, the modified entity is the freshest, and so it is fine, but the old entity is stale. Using a stale entity will give you an error at best, but it can go unnoticed under certain circumstances (if using a release build). You can query the state of an entity with get_status(). The 4 statuses are OK, stale, deleted, and uninitialized. To make sure you have the newest version of an entity, you can use sync(), which will update your entity to the latest version. If the entity has been deleted, sync() will return false.


The last thing we want to do is manipulate our entities. Unlike some ECS frameworks, EntityPlus doesn't have a system manager or similar device. You can work with the entities in one of two ways. The first is querying for a list of them by type

auto ents = entityManager.get_entities<identity>();
for (const auto &ent : ents) {
    std::cout << ent.get_component<identity>().name_ << "\n";

get_entities() will return a vector of all the entities that contain the given components and tags.

The second, and faster way, of manipulating entities is by using lambdas (or any Callable really).

entityManager.for_each<identity>([](auto ent, auto &id) {
    std::cout << id.name_ << "\n";

You can supply as many tags/components as you want to both methods, so if you need all entities with tag1 and tag2 you can simply do get_entities<tag1, tag2>() or for_each<tag1, tag2>(...). In addition, for_each has an optional control parameter, which you can modify to break out of the for loop early.

entity_t secretAgent;
entityManager.for_each<tag1, identity>([&](auto ent, auto &id, control_block_t &control) {
	if (id.name_ == "Secret Agent") {
		secretAgent = ent;
		control.breakout = true;

That's about it! You can obviously wrap these methods in your own system classes, but having specific support for systems felt artificial and didn't add any impactful or useful changes to the flow of usage.


Tags are like components that have no data. They are simply a typename (and don't even have to be complete types) that is attached to an entity. An example could be a player tag for the entity that is controlled by a player. Tags can be used in any way a component is, but since there is no value associated with it except if it exists or not, it can only be toggled.

assert(ent.get_tag<player_tag>() == true);


Events are orthogonal to ECS, but when used in conjunction they create better decoupled code. Because of this, events are fully integrated into the entity manager. The first two template arguments of the event_manager must be the same component_list and tag_list as the ones used for the entity_manager. Additional events can be used by supplying their type after the components/tags.

struct MyCustomEvent {
	std::string msg;

event_manager<CompList, TagList, MyCustomEvent> eventManager;
subscriber_handle<entity_created> handle;
handle = eventManager.subscribe<MyCustomEvent>([](const auto &ev) {
    std::cout << ev.msg;

Subscriber handles are ways of keeping track of a subscribers. They do not rely on the type of event manager, unlike entities, and can be stored just like any other object. They do not get invalidated either.

There are also special events that are generated by the entity manager, which is why we need the components/tags to be the same. To use an event manager with an entity manager, you must set it.


By doing this, you can now be notified to a wide variety of state changes. For example, if you want to know whenever a component of type health is added to an entity, you can simply subscribe to that event.

eventManager.subscribe<component_added<entity_t, health>>([](const auto &event) {
	event.ent.get_component<health>() == event.component;

Here is a full list of predefined events.

component_added<entity_t, Component>
component_removed<entity_t, Component>
tag_added<entity_t, Tag>
tag_remved<entity_t, Tag>

Note that a destructive event is issued at the earliest possible point while a constructive event is issued at the latest. This is so that you can use as much information inside the event handler as possible. It is rarely useful to know if an entity was destroyed if you can't access any of its components, and it is likewise useless to know that a component was added to an entity before the component exists. Component/tag removal events are also issued when an entity is being destroyed, however they are issued after an entity destroyed event for the aforementioned reason.

Exceptions and Error Codes

EntityPlus can be configured to use either exceptions or error codes. The two types of exceptions are invalid_component and bad_entity, with corresponding error codes. The former is thrown when get_component() is called for an entity that does not own a component of that type. The latter is thrown when an entity is stale, belongs to another entity manager, or when the entity has already been deleted. These states can be queried by get_status() which returns a corresponding entity_status.

To enable error codes, you must #define ENTITYPLUS_NO_EXCEPTIONS and set_error_callback(), which takes a std::function<void(error_code_t code, const char *msg)> as an argument.


EntityPlus was designed with performance in mind. Almost all information is stored contiguously (through flat_maps and flat_sets) and the code has been optimized for iteration (over insertion/deletion) as that is the most common operation when using ECS.

There is currently little tuning available, but additional enhancements are planned. Entity manager provides a set_max_linear_dist option. When iterating using for_each, the relative occurrence of a component is calculated against the maximum possible amounts of iterated entities. If this number is small, then a linear search is used to find consecutive entities. Otherwise, a binary search is used instead.

For example, say there are 1000 entities. 500 of these entities have component A, but only 10 have component B. We call for_each<A,B>. Since we know the maximum amount of entities we will iterate is 10, we calculate the relative occurrence of these entities in A. 500/10 = 50, which means we are likely to iterate over 50 entities in a linear search before we find an entity that has both A and B. If we had set_max_linear_dist(55) then we would do a linear search through the entities that contain A. If instead we had set_max_linear_dist(25), we would do a binary search. The default value is 64, and can be queried with get_max_linear_dist().


If you know you will be querying some set of components/tags often, you can register an entity group. This means that under the hood, the entity manager will keep all entities with the components/tags together in a container so that when you need to iterate over the grouping it won't have to generate it on the fly. For example, if you know you will use components A and B together in a system, you can do this:

entity_grouping groupAB = entityManager.create_grouping<A, B>();


// later

Now whenever you do a for_each<A,B>() or a get_entities<A,B>() the iterated entities will not have to be built dynamically but are already cached. Additionally, whenever you do a query like for_each<A,B,C>() the manager will only iterate through the smallest subset of tags/components it can find, which in this case would be the group AB, so you will get performance gains through that as well.

There are already pre-generated groupings for each component and tag, so you cannot create a grouping with an 0 or 1 items (since 0 is just every entity and 1 is just a single component/tag).


I've benchmarked EntityPlus against EntityX, another ECS library for C++11 on my Lenovo Y-40 which has an i7-4510U @ 2.00 GHz. Compiled using MSVC 2015 update 3 with hotfix on x64. The source for the benchmarks can be viewed here. The time to add the components was very negligible and unlikely to impact performance much in the long run unless you're adding/removing components more than you are iterating over them.

Entity Count | Iterations | Probability | EntityPlus | EntityX
    1 000    | 1 000 000  |    1 in 3   |   1706 ms  |  20959 ms
   10 000    | 1 000 000  |    1 in 3   |  16541 ms  | 208156 ms
   30 000    |   100 000  |    1 in 3   |   5308 ms  |  63012 ms
  100 000    |   100 000  |    1 in 5   |  14780 ms  | 133365 ms
   10 000    | 1 000 000  |  1 in 1000  |    396 ms  |  16883 ms
  100 000    | 1 000 000  |  1 in 1000  |   4610 ms  | 170271 ms

Big O Analysis

n = amount of entities

has_(component/tag) = O(1)
(add/remove)_component = O(n)
set_tag = O(n)
get_component = O(log n)
get_status = O(log n)
sync = O(log n)
destroy = O(n)

Entity Manager:
create_entity = O(n)
get_entities = O(n)
for_each = O(n)
create_grouping = O(n)



entity_status get_status() const 

Returns: Status of entity, one of OK, UNINITIALIZED, DELETED, or STALE.

template <typename Component>
bool has_component() const 

Returns: bool indicating whether the entity has the Component.

Prerequisites: entity is OK.

template <typename Component, typename... Args>
std::pair<Component&, bool> add_component(Args&&... args)

template <typename Component>
std::pair<std::decay_t<Component>&, bool> add_component(Component&& comp)

Returns: bool indicating if the Component was added. If it was, a reference to the new Component. Otherwise, the old Component. Does not overwrite old Component.

Prerequisites: entity is OK.

Throws: bad_entity if the entity is not OK.

Can invalidate references to all components of type Component, as well as a for_each involving Component.

Can turn entity copies STALE.

template <typename Component>
bool remove_component()

Returns: bool indicating if the Component was removed.

Prerequisites: entity is OK.

Can invalidate references to all components of type Component, as well as a for_each involving Component.

Can turn entity copies STALE.

template <typename Component>
(const) Component& get_component() (const) 

Returns: The Component requested.

Prerequisites: entity is OK.

Throws: bad_entity if the entity is not OK. invalid_component if the entity does not own a Component.

template <typename Tag>
bool has_tag() const 

Returns: bool indicating if the entity has Tag.

Prerequisites: entity is OK.

template <typename Tag>
bool set_tag(bool set) 

Returns: bool indicating if the entity had Tag before the call. The old value of has_tag().

Prerequisites: entity is OK.

Throws: bad_entity if the entity is not OK.

Can invalidate a for_each involving Tag, only if set != set_tag<Tag>(set).

Can turn entity copies STALE.

bool sync()

Returns: true if the entity is still alive, false otherwise.

Prerequisites: entity is not UNINITIALIZED.

void destroy()

Prerequisites: entity is OK.

Throws: bad_entity if the entity is not OK.

Can invalidate a for_each.

Turns entity copies 'DELETED'.

entity vs entity_t

entity is the template class while entity_t is the template class with the same template arguments as the entity_manager. That is, entity_t = entity<component_list, tag_list>.

Entity Manager

template <typename... Tags, typename... Components>
entity_t create_entity(Components&&... comps)

Returns: entity_t that was created with the given Tags and Components.

Can invalidate references to all components of types Components, as well as a for_each involving Tags or Components.

template <typename... Ts>
return_container get_entities() 

Returns: return_container of all the entities that have all the components/tags in Ts....

template <typename... Ts, typename Func>
void for_each(Func && func)

Calls func for each entity that has all the components/tags in Ts.... The arguments supplied to func are the entity, as well as all the components in Ts....

std::size_t get_max_linear_dist() const
void set_max_linear_dist(std::size_t)
void set_event_manager(const event_manager &)
void clear_event_manager()
template <typename... Ts>
entity_grouping create_grouping()

Returns: entity_grouping of the grouping created.

Entity Grouping

bool is_valid()

Returns: true if the entity grouping exists, false otherwise.

bool destroy()

Returns: true if the grouping was destroyed, false if the grouping doesn't exist.

Event Manager

template <typename Event, typename Func>
subscriber_handle<Event> subscribe(Func && func);

Returns: A subscriber_handle for the func.

template <typename Event>
void broadcast(const Event &event) const

Subscriber Handle

bool isValid() const

Returns: true if the handle holds onto a subscribed function, false otherwise.

bool unsubscribe()

Returns: true if the subscribed function was unsubscribed, false if there is no subscribed function.

  • The Future, C++17

    The Future, C++17

    This project is currently in a bit of a limbo state. The version for all intents and purposes should be at 2.0, however I am afraid there are certain features/changes that are not backwards compatible that I want to make before I release, but have not had the time to sit down and examine the code thoroughly to make the change. I am currently very busy with school work, and I don't see it slowing down for at least a month or two.

    With all this being said, I want to wait until GCC/Clang/MSVC support C++17, or at least most of the nice features that are coming with that standard version. I think that when that happens, I will rewrite a lot of the code to use these features and support C++17 only. This would mean nicer error codes and a more simplifications in the code. However, this may reduce the userbase of the library.

    To combat this standard version bump, I will rewrite the code alongside a 2.0 release. That way, any features (or breaking changes) that occur as a natural result of the rewrite can be also ported into the 2.0 release. The rewrite will force me into the state of mind that I need to be in to further extend and enhance the library, as I have not touched the code for some time now. In effect, there will be a 2.0 and 3.0 release simultaneously, with the only difference between the two being compiler/standard version.

    I don't know if a standard version increase is a deal breaker for any users (or potential users), so I would like to hear your input too.

    opened by Yelnats321 3
  • Storeable entities

    Storeable entities

    Currently you are prohibited from storing entities. Rather, altering an entity will invalidate any previous reference to it. This restriction is made so that you can have caching on the entity side for has_(tag/component). Although the case can be made that the restriction is not worth it for anO(1) has_component, the main feature of tags is their low overhead and so removing O(1) has_tag is detrimental to that, making them obsolete in terms of performance.

    It seems useful for some applications to be able to store entities rather than having to query them each time. Without event integration this is not very useful, but with it the want for storeable entities is increased.

    There are two options that I see for this feature. Either modify entity so that it has an sync() function, which will sync it up to its actual values inside entity_manager. The issue here is that I am not sure how to deal with the case where a sync reveals that the entity has been deleted. I can add a bool indicating this state but it just adds more complications for state checking and the like. However this can be alleviated by sync() returning an indication of if the entity is valid post sync.

    The other option is to have another type that we would call an entity_handle. This would be a barebones storeable type that underneath only holds a pointer to its manager and an ID. You can get an entity_handle from an entity via get_handle() and also convert an entity_handle to an entity via get_entity(). The same problem exists as with the syncing if the entity was deleted in the meantime. This would probably mean that get_entity() will have to return a pointer or an optional, but without library support I am very hesitant with the latter option.

    On the one hand the second option conveys more information because we know that entity is temporary, entity_handle is not. On the other hand having additional types is annoying and complicates code needlessly. I am leaning more towards the first option, especially because the interface can be much nicer.

    opened by Yelnats321 3
  • Grouping entities

    Grouping entities

    As it stands for_each will iterate over the smallest component/tag provided, however this means that if the intersection of the provided components/tags is very small compared to the smallest component/tags, we are doing a lot of unnecessary work. It may be helpful for the user to provide groups of entities they plan on iterating over in the future to reduce the cost of this iteration.

    As an example, say there are 50 entities, 20 of which have only tag A, 25 which have only tag B, and 5 which have both A and B. If we did for_each<A, B>() we would iterate over 20 entities (the ones with tag A) and then compare the bit signatures of the entities to match AB. Instead the user may tell us that they will use a grouping of AB regularly and so now we have a separate list of all entities with AB that we update with changes, and now we only have to iterate over the 5 AB entities.

    opened by Yelnats321 3
  • Error C2737: 'entityplus::meta::delay_v': 'constexpr' object must be initialized

    Error C2737: 'entityplus::meta::delay_v': 'constexpr' object must be initialized


    I'm trying to use your library:

    cmake . -- Building for: Visual Studio 14 2015 -- The C compiler identification is MSVC 19.0.23026.0 -- The CXX compiler identification is MSVC 19.0.23026.0 [...]

    When building the solution from Visual Studio 2015, I get the following error message:

    \entityplus\metafunctions.h(26): error C2737: 'entityplus::meta::delay_v': 'constexpr' object must be initialized


    opened by arnaud-jamin 2
  • Template improvements

    Template improvements

    Benchmark current template metaprogramming implementation and try to reduce compilation times if possible. Saw some things on this blog that may be useful: http://odinthenerd.blogspot.com/2017/03/start-simple-with-conditional-why.html. Will test out templight and metabench, research other tools.

    opened by Yelnats321 2
  • Integrate events into entity_manager

    Integrate events into entity_manager

    Add events for adding/removing components/tags and creating/deleting an entity. This feature should be optional (by providing an event_manager to the entity_manager ctor or by specifying one via a function).

    opened by Yelnats321 2
  • Exposing entity to the user

    Exposing entity to the user

    Currently there is no pretty way to take an entity as a parameter for the library user, since the fully qualified type is in detail. Either expose entity_t from entity_manager so the user can typedef it, or somehow inherit from a base class that the user can use it in parameters.

    The issue with the first approach is that the user will need to expose typedef to any function that wants to take an entity, but this is no large burden as they can just write their own header #includeing the library and defining the typedef.

    The second approach requires a whole new set (or an exposure) of the functions that operate on an entity inside entity_manager (the ones that take entity as a param) and will need to be kind of tricky about making sure the type information will match up. It will also introduce a new way to operate on entitys, which is something I'd like to avoid.

    First approach easiest to implement for now, but may be changed later.

    opened by Yelnats321 2
  • Deletion in for_each

    Deletion in for_each

    Currently for_each is much faster than get_entities for traversing some set of components because it uses iterators under the hood. However, this means that removing components or creating or deleting entities will break it. It may be possible to modify the control_block_t to pass this information to the manager.

    Destroying an entity or deleting its components make the most sense to add support for. Additionally, adding components to the current entity should already be supported, because it won't invalidate any iterators being used.

    Adding support for creating entities withing for_each in my opinion has little usage and adding support for it would be hard and possibly limiting (how many entities should be created?)

    opened by Yelnats321 1
  • No exception support

    No exception support

    Although the library was designed with a no exception mode in mind, all the exceptions are non recoverable for the most part. Have to figure out how to support a no exception environment and also write tests for such an environment (as currently all the tests are based on an exception environment).

    opened by Yelnats321 1
  • Fix non-dependent lambda triggering errors before eval_if

    Fix non-dependent lambda triggering errors before eval_if

    In add_component due to an MSVC bug the lambda is not generic and therefore all the types can be deduced when the function is called, before the lambda is invoked. This means that the pretty eval_if errors are swamped by other errors. One way to fix it is to change the entity manager's add_component to take a tuple of perfectly forwarded args instead, so that the generic lambda does not rely on the parameter pack and can once again be generic.

    opened by Yelnats321 0
  • Relationships between entities (inventory as an example)

    Relationships between entities (inventory as an example)

    Curious if you have any recommendations on a good way to handle references between entities, and how to store and access those relationships. In particular, we're looking at this in context of entity inventories.

    Originally what we kind of hoped was going to work was a component along the lines of this:

    struct Inventory {
        int capacity;
        std::vector<entity_t> items;

    and then use a system and events to manage adding/removing items to a particular entity. This fell flat on its face because entity_t is defined after the components are.

    One easy little change we found out we could make was to expose entityplus::detail::entity_id_t; and then using that in place of entity_t above in the vector. We kept going to see how it plays out, and what we ended up with was this helper function to convert the entityplus::detail::entity_id_t; into entity_t:

    template <typename ...CompsAndTags>
    inline std::unique_ptr<entity_t> find_entity_by_id(entity_manager_t* manager, entityplus::detail::entity_id_t id)
        for (entity_t entity : manager->get_entities<CompsAndTags...>())
            if (entity.id == id)
                return std::make_unique<entity_t>(entity);
        return NULL;

    and it made for fairly enjoyable access anywhere you wanted to use the entities items

    auto inventory = player.get_component<Components::Inventory>();
    for (auto iter : inventory.items)
        auto item = find_entity_by_id(this->entity_manager, iter.second);
        // now we have a pointer to work with
        // off we go using the entity

    We actually ran with that for a little bit and it's been alright, but it feels dirty given that we have to modify entityplus to expose that ID. We're lookin to switch this up, but the best next alternative we can think of is having the Inventory component know nothing about the items and go through our InventorySystem which could maintain a mapping of entities with inventories to the list of item entities, then have a function like std::vector<entity_t> InventorySystem::get_items_for_entity(entity_t) for accessing the items.

    The reason we don't like that approach as much is because we lose the ability to fully describe our entity by simply looking at its components. With that approach our component tells us how many items might be in the inventory, but we need to communicate with a system to know what items those actually are.

    So I guess what I'm asking is if you have any ideas that might allow for referencing entities from within a component. Or perhaps you know of an entirely different approach that maybe we didn't think of. I did notice you mentioned in #19 kind of this scenario we're talking about, but we're failing to understand how the tag approach would work when we have N entities that could have inventories (N tags?).

    Appreciate any thoughts.

    opened by jddeal 1
  • Transitioning to 2.0

    Transitioning to 2.0

    I am currently in the process of rewriting EntityPlus! One of the issues is how to transition this repository to the new version. As this is a ground-up rewrite, I am not sure what the correct approach is. I also want to push to the repo when I have a working, mostly stable interface, and it will probably be a single commit that entirely changes the code. It may not be as fast as intended, but featureful enough to use and additional optimization will be added without altering the interface (ideally).

    I am not sure if this is the best way to do this. If you have any suggestions on how to transition to this new rewritten version, please let me know!

    If you have any features you are interested in, check out the other issues, especially #22 and see if they are covered there. If not, please let me know.

    enhancement help wanted 
    opened by Yelnats321 3
  • Future Plans

    Future Plans

    So I am currently in the process of a pretty large rewrite, meaning a lot of old code will be removed and replaced with (hopefully) better code.

    The main key points I am trying to hit are:

    • const correctness
    • Customization
    • Efficiency
    • Faster speeds
    • C++17
    • Stronger versioning

    I will also be maintaining the current feature set, just possibly in a slightly more cohesive way. Some functions may be renamed and the status quo may change a bit, but I aim to not reduce the feature set (and hopefully add to it in a meaningful way).

    opened by Yelnats321 4
  • Const correctness

    Const correctness

    Currently entities employ reference semantics rather than value semantics, which is the less intuitive of the two. This means that passing in a const entity to a function does not guarantee that the entity won't be modified (since you can just copy it into a non const entity and modify it there).

    There are other problems like sync() not being able to be called from a const entity and other little things that just feel off.

    The options going forward are either to keep things as is or to split entity into two classes, a const entity and a non-const one, where the manager will return one or the other based on context. Probably the best approach to this but might feel unintuitive and hard to follow.

    opened by Yelnats321 0
  • Examples


    Add more examples! In the code so people can just expand on those and see what works and what doesn't, as well as lead by example with idiomatic code.

    Will mesh well with cmake I think.

    opened by Yelnats321 0
  • Versioning


    Versioning has been a little lacking. There is only one release (v1.0) even though in reality there have been other releases (minor and patches, and also a couple breaking ones). Adding entity grouping will be technically a release of v.2.0.0 and then afterwards I will try to follow semantic versioning as best as I can. The git will still have commits that don't necessarily correlate to a version, but when I feel satisfied with a feature I will bump up the minor version, for bug fixes the patch version, and also for breaking changes the major. I don't foresee many breaking changes with the current feature set, but that may of course change.

    opened by Yelnats321 0
Elnar Dakeshov
Elnar Dakeshov
Simple tower defense game using C++ with Entity Component System (ECS)

CubbyTower CubbyTower is a simple tower defense game using C++ with Entity Component System (ECS). The code is built on C++17 and can be compiled with

Chris Ohk 39 Dec 20, 2022
A C++14 Entity Component System

NOTICE: This project is currently in the progress of being rewritten for C++17. Check out this issue if you have any suggestions/know a good way to tr

Elnar Dakeshov 187 Nov 9, 2022
Gaming meets modern C++ - a fast and reliable entity-component system (ECS) and much more

EnTT is a header-only, tiny and easy to use entity-component system (and much more) written in modern C++. Among others, it's also used in Minecraft by Mojang and The Forge by Confetti.

Sean Middleditch 8 Feb 16, 2021
An open source C++ entity system.

anax ARCHIVED: as I haven't maintained this library for at least a couple of years. I don't have the time or interest to work on this. Please use anot

Miguel Martin 457 Nov 16, 2022
Yet another component system

Yet another component system Header-only c++11 entity component system Depends on Parallel hashmap for fast pointer container Compile time type name a

Devil Devilson 11 Jul 30, 2022
Replace Minecraft entity with MMD model.

KAIMyEntity Replace Minecraft entity with MMD model. KAIMyEntitySaba 将Github项目 benikabocha/saba (https://github.com/benikabocha/saba) 魔改成一个以JNI形式Expor

null 30 Oct 16, 2022
A foobar2000 component which allows you to load and play ncm files directly.

Play NCM files directly with our favourite How to setup and build project Download foobar2000 SDK and extract into vendor/sdk Download WTL from source

null 37 Nov 25, 2022
Simple CSV localization system for Unreal Engine 4

BYG Localization We wanted to support fan localization for Industries of Titan and found that Unreal's built-in localization system was not exactly wh

Brace Yourself Games 56 Dec 8, 2022
GammaGo is an interactive go game system that integrates image recognition with robot arm control.

Introduction GammaGo is an interactive go game system that integrates image recognition with robot arm control. This repository contains all the neces

Jin Zihang 5 Jul 31, 2022
Part copy from the Google Code repository by Shiru, part fork of SNES Game Sound System by Shiru

Part copy from the Google Code repository by Shiru, part fork of SNES Game Sound System by Shiru

null 5 Sep 6, 2022
A cross-platform, top-down 2D space shooter written in C using only system libraries.

A cross-platform, top-down 2D space shooter written in C using only system libraries.

Tarek Sherif 1.3k Jan 2, 2023
VTK is an open-source software system for image processing, 3D graphics, volume rendering and visualization

Introduction VTK is an open-source software system for image processing, 3D graphics, volume rendering and visualization. VTK includes many advanced a

Kitware, Inc. 2k Dec 30, 2022
A fast entity component system (ECS) for C & C++

Flecs is a fast and lightweight Entity Component System with a focus on high performance game development (join the Discord!). Highlights of the frame

Sander Mertens 3.5k Jan 8, 2023
A fast entity component system (ECS) for C & C++

Flecs is a fast and lightweight Entity Component System with a focus on high performance game development (join the Discord!). Highlights of the frame

Sander Mertens 3.4k Dec 31, 2022
Gaming meets modern C++ - a fast and reliable entity component system (ECS) and much more

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

Michele Caini 7.6k Dec 30, 2022
apecs: A Petite Entity Component System

apecs: A Petite Entity Component System A header-only, very small entity component system with no external dependencies.

Matt Cummins 17 Jun 1, 2022
Simple tower defense game using C++ with Entity Component System (ECS)

CubbyTower CubbyTower is a simple tower defense game using C++ with Entity Component System (ECS). The code is built on C++17 and can be compiled with

Chris Ohk 39 Dec 20, 2022
Small implementation of c++ entity component system inspired by Unity

EntityComponentSystem About This is small implementation of entity component system with C++. The API is heavily inspired by Unity ECS framework, but

Lukas Chodosevičius 2 Oct 13, 2021
EntityX - A fast, type-safe C++ Entity-Component system

EntityX - A fast, type-safe C++ Entity Component System NOTE: The current stable release 1.0.0 breaks backward compatibility with < 1.0.0. See the cha

Alec Thomas 2k Dec 29, 2022
A C++14 Entity Component System

NOTICE: This project is currently in the progress of being rewritten for C++17. Check out this issue if you have any suggestions/know a good way to tr

Elnar Dakeshov 187 Nov 9, 2022