• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
matrisking

Question about the Entity Component System architecture

7 posts in this topic

Hey everyone,

I've been reading up on the Entity Component System paradigm ( http://www.gamedev.net/topic/643095-good-articles-on-entity-components-systems/ has been very helpful) and I think I understand everything I need to implement it except for one thing:

Where do the components "live"? Getting into implementation specifics, I'll be writing this in C++. So, for the sake of example, let's say I have a position component, a velocity/movement component, and a motion system which acts on both components.

Would it make sense for each entity to have a data member container consisting of pointers to components? If so, how would the motion system keep track of which entities have position and velocity/movement components? Or maybe a better way of phrasing the question is: How does the motion system keep track of which components it needs to iterate over when it runs?

When I look at diagrams and read articles about ECS, everything seems to make sense to me. But when I sit down with a pen and paper and try to map out the class relationships, my level of understanding starts to break down.

Thanks!

Edit: I've thought about this a little bit more, and maybe the a good approach would be to have each system contain a container of pointers to entities that contain a matching set of components. This would mean that every time an entity adds or removes a component, it would have to be examined by each system to determine if it contains the right components to be used by that system. However, this also means that each system doesn't have to go through and check EVERY entity to see if it has the right components in every iteration of the game loop. Thoughts? Am I heading down the wrong path? Edited by matrisking
2

Share this post


Link to post
Share on other sites

There are hundreds of previous posts on matters like this. Have you used the search function? (The short answer is - different people do it different ways, and they all work.)

0

Share this post


Link to post
Share on other sites

The short answer is - different people do it different ways, and they all work

^this. 
"ECS" is not as specific as other design patterns. It's a very vague description for hundreds of different designs, with the only common pattern being "components are some kind of structure, entities are groupings of components". That detail alone can be implemented in dozens of ways, and there's dozens of other details that may or may not even exist depending on the overall design, and whether the designer has come from a relational, OO, procedural or functional background, etc...
 
Different "ECS" systems are also designed around different requirements.
Sometimes the whole point is so that different components can automatically find each other, and send messages to each other without the programmer having to manually bind them (the "entity" is basically a message router and service provider).
Other times the whole point is just to allow entity "templates" to be defined in data (the component connections might be specified in the data files or magic like above), with the ECS basically being a fancy serialization and inversion-of-control library.
Other times the whole point is to decouple different parts of entities so that data can be rearranged into cache-friendly structures and processing can easily be multi-threaded (i.e. a design stemming from performance considerations, to avoid the pitfalls of OOP).
 
Given this huge range of designs falling under the "ECS" banner, you really have to be able to define what it is that you want your ECS library to achieve and what it's requirements are, before you can evaluate the merits of different design choices.
 
With that out of the way...

Where do the components "live"? Getting into implementation specifics, I'll be writing this in C++. So, for the sake of example, let's say I have a position component, a velocity/movement component, and a motion system which acts on both components.

Would it make sense for each entity to have a data member container consisting of pointers to components? If so, how would the motion system keep track of which entities have position and velocity/movement components? Or maybe a better way of phrasing the question is: How does the motion system keep track of which components it needs to iterate over when it runs?

I'm not a fan of the automatic binding (entity as message router and service provider) style of ECS, and I personally prefer a style where entity is a component, rather than some first class concept of the pattern. So, I'd KISS and just implement this in 7 lines of code, with the supporting library only being a compacting-pool class (a pool that moves items to always be contiguous, whenever a 'hole' is created through erasing an item) that supports handles (because pointers won't work due to the compaction):

struct Position { Vec3 pos; };
struct Movement { Handle<Position> who; Vec3 velocity; };
void MovementSystemUpdate( const Pool<Movement>& movements, Pool<Position>& positions, float dt )
{
  for( const Movement* m=movements.begin(), *end=movements.end(); m != end; ++m )
    positions[m->who].pos += m->velocity * dt;
}

Bam! "ECS" without the bloat cool.png

Edited by Hodgman
2

Share this post


Link to post
Share on other sites

FWIW, here what i think are the 2 most used options for where the components live, and how they are coupled with entities:

#1, Components simply have an "int EntityOwner" that stores which entity owns them, and entities are simply an unique number.

#2, Entities contain a list of pointers to Component it owns. (something like a std::vector<TComponents> Components member).

 

How they are accessed is a much larger answer that has been covered.

1

Share this post


Link to post
Share on other sites

In my ECS, which is somewhat based off the artemis framework, the components are stored in arrays in the "entity manager". The entity manager also maintains a mapping from entity to indices into these arrays (so that's how we determine which components are associated with a particular entity).

 

Each system declaratively states which types of components its interested in (e.g. "I require the Aspect and Position components"). Whenever an entity aquires Aspect and Position, the entity's index is automatically added to a list in that system. So each system is always guaranteed to have an up-to-date list of the entities (or rather, indices to the entities) in which it is interested.

1

Share this post


Link to post
Share on other sites

In my ECS, which is somewhat based off the artemis framework, the components are stored in arrays in the "entity manager". The entity manager also maintains a mapping from entity to indices into these arrays (so that's how we determine which components are associated with a particular entity).

 

yes, relational database type thing. this seems the way to go. 

 

i was thinking an array for each component type, and its associated methods, and a list (array) of entities, of course with indices pointing to the other databases.

 

your method is exactly the way i'd do it myself.

0

Share this post


Link to post
Share on other sites

Thanks for all the help/feedback.  You guys have given me a lot to think about and consider when designing this.

 

As far as Hodgman's point that there are different reasons to pursue ECS, I'd have to admit that my reason seems more basic than any of the ones he listed.  It simply seems like a nice, clean alternative to rigid inheritiance heirarchies or potentially problematic multiple inheritance situations.  Does this seem like a strong enough justification for the system in and of itself?

 

Also, in light of this fairly general goal, what are the pros and cons of storing the components within entities as opposed to in containers or structures that exist outside of the entities?

 

I'll keep hackin away and update this thread if more questions surface.

0

Share this post


Link to post
Share on other sites

It's a common requirement in software to be able to have an object that can vary its behaviour in several different ways, so that different instances of the same object can behave differently. Much of the book 'Design Patterns' talks about ways you can achieve this, eg. with the State pattern, the Strategy pattern, Composite pattern, Decorator pattern, etc. It's a false assumption to believe that the only practical way to get similar-but-different objects in an OOP application is to employ large inheritance structures or multiple inheritance approaches. As such there is nothing new about this particular problem and no intrinsic reason why anybody should feel that a formal component-based-entity approach is the one true way forward.

 

I like to have a single Entity class and then I vary the behaviour within the entity by swapping out subcomponents as necessary. But I don't make everything into components, only the bits that I think need to be interchangeable, and which don't lend themselves to any simpler approach. (eg. Sometimes a simple if (npc) check will do, meaning there's no need to create separate PlayerCharacter and NonPlayerCharacter components.)

 

If you don't have a reason to factor out components into a separate structure, don't do so. You'll only waste a lot of time and energy finding ways to communicate between the components effectively. Probably the best reasons to have an 'outboard' architecture like that are for increased parallelism and to benefit from cache coherence, neither of which should be a concern to you at this point. My opinion would be to just store the components within the entity and allow them to access each other if necessary.

1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0