
EnTT: Gaming meets Modern C++ - skypjack
https://github.com/skypjack/entt
======
mottosso
I've been using EnTT for the past 6 months or so for real-time content-
creation development, coupled with a graphics framework called Magnum, and am
really enjoying it. It's very intuitive and the author is very friendly and
responsive too which is a massive plus for to get going and bounce ideas
around - [https://gitter.im/skypjack/entt](https://gitter.im/skypjack/entt)

~~~
narak
This sounds interesting, could you share any more of your project? I want to
get back into c/c++ dev, the modern libraries look great!

------
mtsr
Skypjacks blog posts about all the design choices in making an ECS is great
for understanding why EnTT works the way it does:
[https://skypjack.github.io/2019-02-14-ecs-baf-
part-1/](https://skypjack.github.io/2019-02-14-ecs-baf-part-1/)

------
nybblesio
I've used EnTT in both compiler and graphics projects over the past few years.
Nice API, good documentation, and continuous updates from skypjack. If you're
looking for a C++ ECS, give EnTT a try.

~~~
mattgreenrocks
I’m curious how you use it for compiler projects. Can you expand on that?
Normally I see the typical stage-based design employed there.

~~~
lenkite
Read the post and realised it might be a great idea. Perhaps each node in the
AST is an entity and you can add/remove components to a node during
compilation ? Need to really try it out to be sure this works.

~~~
nybblesio
Yes, this is the basic idea. Tokens from the lexer, AST nodes, basic blocks,
control and data-flow graph nodes + edges can all be entities and/or
components of entities, depending on how you wish to structure your data.
Since a 32-bit entity ID provides a sufficiently large "address space", you
get the added benefit of only needing to store 4-byte handles instead of
8-byte pointers.

EnTT has an eventing system as well. These can be triggered in various ways
(entity created, entity deleted, component assigned/removed, etc). I've used
eventing to control fine-grained compilation pipelines. For example a recent
scheme compiler I wrote used events to simplify inlining (both define-
macro/define-syntax and straight procedure inlining) and quote/quasi-
quote/unquote/unquote-splicing translation.

If you spend a lot of time writing compilers, I find an ECS like EnTT can give
you extra flexibility during the design/prototype phase. Try it out on a
simple prototype and see if you like it.

~~~
skypjack
Wow. Is this a public project or something you can mention? It sounds very
interesting!

~~~
nybblesio
My recent work involving EnTT is still under NDA, though at least one of the
projects should have a public announcement sometime next year.

With that said, if there is interest, I'd enjoy building a clean room compiler
for an existing language using EnTT and other techniques I've developed over
the years. Thoughts? While I absolutely adore TinyCC, it might be worthwhile
giving that space another go?

~~~
skypjack
Well, I don't think I've enough skills on this and I'd follow the project
eagerly to learn something new, so I'd go with what you feel confident and/or
you like! My thoughts are that such a project would be of interest for tons of
people though, I'd willingly share it as much as possible. :)

------
s9w
It's a fantastic piece of c++. I've been using it for a year or so and it's
still impressive and an immense time saver. The only thing I could think of as
an improvement is the documentation. There is a lot of it but it's in many
different places and not easy to find. There's an article series on his blog,
there is some in the readme but most is in different pages on the GitHub wiki.

~~~
skypjack
This is a good feedback. Reach me out if you have any suggestion on how to
improve and organize the doc. Help is always appreciated! :)

~~~
s9w
Oh it's the master himself - maybe I will! Thanks for your work.

------
avolcano
I was looking at EnTT's API when building a little toy ECS of my own in
JavaScript. Since I'm working in JS, I haven't really tried to copy its
internal architecture since it doesn't quite make sense for a higher-level
GC'd runtime, but I think the public API was a really handy reference for the
kinds of things a practical ECS needs to have. It's a really impressive and
robust project, and the documentation is super thorough and worth a peek if
you have any interest in game architecture.

 _(slightly off-topic, but I 'm excited to have a venue to ramble a bit about
this:)_ ECS is really cool, and I'm excited about using it more for my games.
The "cheap" (de)serialization by moving all state into pure, data-only
components is really fascinating - I've been playing around with building
networked multiplayer games for a while now, and I'm currently experimenting
with rollback netcode.

A key part of rollback is saving your state every frame so you can load it if
you need to roll back, and ECS makes saving/loading easier to reason about,
since you can "just" grab the components and their associated entity IDs and
load if needed (EnTT, for the record, has an API for this[1], though they
leave the actual (de)serialization up to you). Of course, JS's lack of a
memcpy equivalent makes this much harder than what you could do in C++, which
has lead me to experiment with immer[2] in my ECS, which uses structural
sharing to avoid mutation, so you can get a "copy" of your state by just
keeping a reference to it, as future updates will make new objects. This, of
course, theoretically could make a ton of garbage (e.g. updating your position
every frame would create a new Position object every frame), which is not
great for high performance games. I'm not sure how bad this will be in
practice - JS GC is _relatively_ smart and fast these days, but I haven't
tried doing much beyond little pong or platformer demos yet. I'd also imagine
that, like, doing a deep clone of my state tree every frame (or doing the
whole JSON.stringify/parse dance if I stick to primitive values) probably
generates just as much garbage. Maybe if I could integrate immer with some
kind of object pool it'd avoid these issues, but I have no idea how useful
object pooling is in practice in JS...

[1] [https://github.com/skypjack/entt/wiki/Crash-
Course:-entity-c...](https://github.com/skypjack/entt/wiki/Crash-
Course:-entity-component-system#snapshot-complete-vs-continuous) [2]
[https://github.com/immerjs/immer](https://github.com/immerjs/immer)

~~~
nicoburns
> but I have no idea how useful object pooling is in practice in JS...

I'm pretty sure most JavaScript games use object pooling extensively. GC is
definitely an issue if you want to hit 60fps. Even for non-games actually.

~~~
gameswithgo
and 60fps is not even the gold standard anymore, 140+ is, the pickiest people
for competitive shooters will want ~200+

You don't have a lot of ms

~~~
avolcano
I'm not actually sure requestAnimationFrame() in a browser ever gets you >60
fps. At that point, honestly, you'd probably need an independent render thread
(doing some degree of interpolation) and stick to a 60fps logic tick. Which
you can theoretically do in JS using web workers, though I know message-
passing incurs some serious overhead in that case.

~~~
modeless
requestAnimationFrame absolutely supports higher than 60 FPS. You can also do
all rendering off the main thread with OffscreenCanvas, though you can
certainly hit 144 Hz or higher without doing that.

~~~
pjmlp
Currently OffscreenCanvas is only supported on Chrome. :\

~~~
BuckRogers
And the new Edge? Of browsers from major vendors at least, I thought Edge was
worth mentioning since it recently overtook Firefox in desktop market share.

~~~
pjmlp
Nope, only Chrome based engines.

------
Lawrencemm
You can achieve a lot of things with this library, a whole new world of
architectural patterns opened up for me when I got into it.

~~~
sali0
I am very unfamiliar with ECS but I am learning. Could you expand on what
you're speaking of? Very interested.

------
macgyverismo
Having read through the README, I'm not quite sure what makes this perform
better than other systems. I can see that it will perform excellent when
iterating over a single type as all entries for this type are next to each
other. However, for each meaningfull operation you are likely to combine at
least two different types, which means data will have to be read from
different locations, defeating the purpose. You could put more data in a
single type (for the example from README, you would put velocity and position
in a single type) but than you are back to hand-tuning your data types as you
would in any other system. It still looks like an interesting library, but if
there are any inherent performance benefits I am failing to see, I would love
to hear about them.

~~~
skypjack
The design is such that you pay for what you need. To do what you're looking
for, that is, a linear access on multiple components without jumps nor
anything else, there exist groups. They are the fastest thing you can imagine
because you iterate literally N arrays for N components in order with no jumps
nor branches. They affect performance on creation/destruction though, in order
to speed up quite a lot linear accesses. Also, views are such that it doesn't
worth it creating a group when one of the components involved in a query is
assigned to few entities, since the view internally uses the shortest pool.
And so on, there are tons of details and use cases. The documentation (the
wiki, not the README) contains all the details but it's pretty big and takes a
while to go through all them. The fact is that a real world software isn't
made only of linear accesses, so the whole library is meant to allow
optimizing the given access pattern when needed.

Feel free to ask if I triggered you and you want more details. ;) Reach me out
here, on gitter, discord, by mail, whatever...

------
danbolt
I really enjoy the storage strategy for EnTT. Other ECS games I had known the
architecture for were a lot more rigid in terms of space, and it's nice to see
more flexibility in that aspect.

------
ur-whale
It's header only, good start and makes it worth a second look.

