Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Video] Implementation of a component-based entity system in modern C++  (Read 10471 times)

0 Members and 1 Guest are viewing this topic.

SuperV1234

  • SFML Team
  • Full Member
  • *****
  • Posts: 188
    • View Profile
Hello SFML community.

Like last year, I attended the truly excellent CppCon 2015 conference (Bellevue, WA) and presented two talks.

The video of my first talk, which is heavily oriented towards game development, is now available on the conference’s official YouTube channel:

http://www.youtube.com/watch?v=NTWSeQtHZ9M

The talk shows the audience how to write a simple yet powerful C++14 component-based entity system, from scratch.

I use SFML for window/input management and to render simple 2D graphics.

Modern C++ features and idioms are used.
I’ve tried to make the implementation as cache-friendly and data-oriented as possible while maintaining a reasonable level of simplicity.

It is not an AAA framework, but I think I’ve managed to write a small powerful system that shows the benefits and ideas behind a data-oriented ECS.

Choices I’ve made:

  • Components are logic-less. (They are simple structs.)
  • Entities are implicit. (The Entity class is just an ID with some metadata.)
  • Components are stored in separate, contiguous arrays. (Every component type has its own array.)
  • Systems are implicit. (Entities are matched using “signatures”.)
  • Entity metadata is sorted in memory for efficient iteration. Component data is not sorted or “compressed”. (Think about the storage as a relational table, where the columns are the entities and the rows are the component types.)

There are many open-ended questions and possible improvements of this implementation - my goal was showing people how beneficial and convenient a more data-oriented and component-based approach is, and how C++14 makes coding such a system extremely satisfying (thanks to its modern features and cost-free abstractions.)

I’m very open to feedback and would love to hear what you think.
Hope you find the video interesting!

You can find all the material (slides and code) on my GitHub repository:
https://github.com/SuperV1234/cppcon2015

Satus

  • Guest
Re: [Video] Implementation of a component-based entity system in modern C++
« Reply #1 on: October 08, 2015, 12:04:30 am »
Sounds very interesting and I will definitely watch full video later, but the first thing I've noticed while looking at the source code on github is that it is barely readable. 1k+ line of source code in file p7.cpp, not to mention a lot of files in Other folder with nonintuitive structure and contents. It would be much better to have separate file (possibly with header/source separation) for each class and without any other files that just include other files without having any additional code in them.

SuperV1234

  • SFML Team
  • Full Member
  • *****
  • Posts: 188
    • View Profile
Re: [Video] Implementation of a component-based entity system in modern C++
« Reply #2 on: October 08, 2015, 12:53:56 am »
Sounds very interesting and I will definitely watch full video later, but the first thing I've noticed while looking at the source code on github is that it is barely readable. 1k+ line of source code in file p7.cpp, not to mention a lot of files in Other folder with nonintuitive structure and contents. It would be much better to have separate file (possibly with header/source separation) for each class and without any other files that just include other files without having any additional code in them.

All the code segments were written for the talk - they're supposed to be shown one after another, explaining the additions/removals/changes from the previous code segment. They were made with the idea of a "step-by-step" live talk in mind, so I understand that they might not be well suited to reading. Sorry about that!

Regarding the code in the "Other/" folder - that's code that has been included mostly to get utility functions out of it. There's also an outdated ECS library prototypical implementation - my intention was to show some of the ideas present in the library but not in the live code segments if I had enough time during my session... but I actually ran out of time  :-\

So, yeah, the material was created with the live talk in mind.
However, if you'd appreciate me to explain anything regarding the code or the talk, don't hesitate to ask :)

Satus

  • Guest
Re: [Video] Implementation of a component-based entity system in modern C++
« Reply #3 on: October 10, 2015, 01:52:55 am »
Hi again! I finally got time to watch the video and I really like it. It is different from the simpler approach that I use: I have 3 classes (entity, component, system), entity stores an array on components (with methods like add/remove component), and in the update function I call update for each system and pass it a global array of entities, then check for every entity if it has required components and process it with a system. I was thinking of some way to redesign it to remove unnecessary overhead. But I am not quite sure yet that I like the idea to store all entities separated from their components and inside some manager.

Another possible problem that I thought about is that if I have to store entities (more specifically - their references) in some data structure inside systems to optimize that systems work (example - quad tree for collision detection), I will have to manage lifetime of entities for every structure I have in my game. Is there any way to automate the process?

I'm new to ECS and sometimes it's confusing because all of my previous programming experience was based on using OOP to design data model for my program.

Again, thanks for the interesting presentation!

rooger

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: [Video] Implementation of a component-based entity system in modern C++
« Reply #4 on: February 14, 2016, 01:08:05 am »
Great talk. Thank you.

Interestingly I have an ECS implementation which is very close to yours and was developed completely independently [1]. Same emphasis on compile time configuration (C++1y FTW). The bitset with tags at the end, the components meta list and the concept of signature, everything is here. For that latter I don't request the user to declare his signatures prior using them (I use Eric Niebler's tiny meta library). Yet we both pass lambda with expanding auto& arguments matching the components. Awesome.

My tuple of vectors of components data are "compressed". Random access requires an extra level of indirection through a lookup table (handle ID+counter). Initially I thought it was a good idea which allowed me to loop through valid components data without encountering "holes" but it prevents me from looping over more than one vector at the same time because indexes don't necessarily belong to the same entity (compression might reorder slots in one vector but not the others).

Also I should definitely use std::get<T> rather than std::get<size_t> for tuple element access. It simplify things greatly ;)

[1] I'm by no mean a game developer but got interested in ECS after reading stuff about DOD. I don't remember having watched your video but I for sure read lots of articles on the net. The compile-time approach (meta list of components) without some kind of static counters or typeid doesn't seem common at all.

SuperV1234

  • SFML Team
  • Full Member
  • *****
  • Posts: 188
    • View Profile
Re: [Video] Implementation of a component-based entity system in modern C++
« Reply #5 on: February 14, 2016, 05:29:32 pm »
Great talk. Thank you.

Interestingly I have an ECS implementation which is very close to yours and was developed completely independently [1]. Same emphasis on compile time configuration (C++1y FTW). The bitset with tags at the end, the components meta list and the concept of signature, everything is here. For that latter I don't request the user to declare his signatures prior using them (I use Eric Niebler's tiny meta library). Yet we both pass lambda with expanding auto& arguments matching the components. Awesome.

My tuple of vectors of components data are "compressed". Random access requires an extra level of indirection through a lookup table (handle ID+counter). Initially I thought it was a good idea which allowed me to loop through valid components data without encountering "holes" but it prevents me from looping over more than one vector at the same time because indexes don't necessarily belong to the same entity (compression might reorder slots in one vector but not the others).

Also I should definitely use std::get<T> rather than std::get<size_t> for tuple element access. It simplify things greatly ;)

[1] I'm by no mean a game developer but got interested in ECS after reading stuff about DOD. I don't remember having watched your video but I for sure read lots of articles on the net. The compile-time approach (meta list of components) without some kind of static counters or typeid doesn't seem common at all.

Thanks for the feedback, glad you enjoyed the talk!

It's really cool to see that someone else had a similar idea - I think heavily using compile-time computation to define ECS architectures is valuable and I'll continue to explore it further in the future.

There is another C++14 developer who built something interesting as well:
http://maikklein.github.io/2016/01/14/Entity-Component-System/

Is your implementation available online? If not, consider putting it on GitHub - I would be happy to see it and learn from it.

rooger

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: [Video] Implementation of a component-based entity system in modern C++
« Reply #6 on: February 19, 2016, 05:25:06 pm »
Hi. Thanks for the reply.

I took a look at Maik Klein's solution and i find it quite interesting. It pretty much "solves" the problem I encountered previously which prevented me from looping over more than one array of component at a time (because of the reordering and indexes that don't match anymore from one array to the other).
His solution is roughly equivalent to using X number of "entity managers" rather than just one. Each one manages its components arrays.

Anyway I implemented something similar to Maik Klein on top of my previous experiment just from reading his blog post. He's using Hana. I kept using Niebler's Meta. Also from the start I was using the C++17 folding expressions which are awesome.

Something interesting (not sure it's that interesting though lol) is I have to access tuple elements by an index at runtime in some occasion. Basically the component group ID (tuple index) is stored in my handle type as a runtime member rather than a constant template parameter. Weird design choice maybe but I wanted to have the same type for all my handles.

This is just a brain dump of what I have done. It's mostly a pretext to get back to c++14/17 programming rather than a serious project: https://github.com/metagoto/rako


« Last Edit: February 19, 2016, 10:06:22 pm by rooger »

 

anything