• 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
vinnyvicious

Entity component system: efficient component retrieval?

14 posts in this topic

So, my ECS right now is pretty simple. I have a GameObject class, which represents my entity, that contains a few helper methods. It also contains a hash set with all the components that specific game objects has. I have a few methods, like GetComponent, GetComponents, etc. I also have a Scene, which has all GameObject instances (stored in a hash set as well, with the gameobject name and instance) and other scene data (transition in, out, etc.). My AbstractScene contains a method for getting all components of a specific name, from all game objects in that scene. Something like this:

 

scene.getComponents('position'); // returns a list of all components with the name "position", from all GameObject in the scene.

 

This method is called from the Behaviors. PositionBehavior is responsible for processing all the "position" components. It's the system.

 

My question is: how do i optimize this? Having to iterate on all GameObjects and find all components, creating a new list and returning seems pretty cumbersome and inefficient. And i'm doing this on every update. My architecture is something like this:

  • Start first scene
  • Game loop
    • Call the render() method on the Scene object
    • Call all Behaviors that are Renderable
    • Call the update() method on the Scene object
    • Call all Behaviors that are Updateable
    • Call PhysicsBehavior
0

Share this post


Link to post
Share on other sites

Does your PositionBehavior have a list of all Positions components? if so then it can update them without getting them from the object itself.

 

This is how I do my component updates.

1

Share this post


Link to post
Share on other sites

Is your PositionBehavior a singleton, then? In my case, i add components to my entities via addComponent method, which is a method of the GameObject class. How do you link your components to the entities?

0

Share this post


Link to post
Share on other sites

Why would it have to be a singleton?

When adding a component to a GameObject, add it to both the object, and the system responsible for updating it, keeping only a reference/pointer to the component in the system. If a GameObject gets deleted, make an event to each system telling it about the deletion so it can remove that objects' component from the list/vector/hashmap/whatever.

1

Share this post


Link to post
Share on other sites

I do all of my component updating through the systems themselves. This makes sure that only those entities that have said component get updated and the order of updating. If there are messages to be handled, it's all done during that system's update. 

 

My systems each contain a Dictionary<ulong, Component> (I'm using C#, so substitute whatever method you use) which holds the entity id (the ulong) and the component with the data associated with that system. This way, you shouldn't have to iterate over all of your entities because you already have a list of each component and the entity to which it belongs. I don't think, other than adding/removing a component, that I ever actually use the Entity objects themselves (I use the EntityManager class to handle messages, because each message type may have to be sent to multiple systems, so I just use it as a hub to send the messages to all applicable systems, though this may not be the most efficient way of handling this business). 

0

Share this post


Link to post
Share on other sites

How are your entities aware of the systems, then? Where do you add a component to a game object? I have an "addComponent" method on my Entity class, but that requires all systems to be singletons, in your case, or have some kind of complex DIC setup. Also, how do you track from which entity is which component? 

 

In my case, there's this relationship hierarchy:

 

  • Behavior (System)
  • Scene
    • Game Objects
      • Components
Edited by vinnyvicious
0

Share this post


Link to post
Share on other sites

In general (because I don't know how NoAdmiral does things in particular):

 


How are your entities aware of the systems, then?

Entities are not aware of sub-systems, perhaps besides one that generates entity IDs and store entities. In your case those sub-system is part of the Scene.

 


Where do you add a component to a game object? I have an "addComponent" method on my Entity class, ...

With the sub-system approach an entity need not be anything more than an ID. You can, of course, still have an explicit entity, e.g. to store a collection of all of its components, if you wish. But in fact the components are added to the belonging sub-systems with the entity's ID as reference.

 


... but that requires all systems to be singletons, in your case, or have some kind of complex DIC setup.

Singletons? No! They usually need to be unique in a context, yes, but that does not mean they they need to be implement as singletons. E.g. in your case it would be possible that the Scene holds all the sub-systems' instances.

 


Also, how do you track from which entity is which component?

At the moment you have a map of all components of a particular entity with the component type as key. No problem to make a map of a particular component type with the entity ID (may even be the address of the entity instance) and store that in the belonging sub-system.

2

Share this post


Link to post
Share on other sites

Check out the articles in my signature for how I do my components.  They're basically just arrays of components (one per type) and another array of component masks.  An entity is the aggregation of all the elements at a given index in the arrays, where the component mask describes which components "exist" (are turned on).

 

It's cache friendly and requires no memory allocation past the initial allocation of the arrays.

0

Share this post


Link to post
Share on other sites

Just for the record I haven't read post above (Boreal Games) when I wrote mine - now I did and it seems to be similar in approach to what I wrote in 2). 

 

I can think of at least 3 approaches to this:

 

1) Registering components in corresponding systems so you don't have to query scene for objects that have component "Position" - system already has list of these components and its updated when object is added/removed from the scene. This is probably good approach if you plan to have hundreds of thousands of objects. Here you need to decide how component knows which system may be interested in having it - this may work on a listener basis where systems "listen" for certain components being either added/removed from object, or objects with components being added/removed from scene. 

 

This approach requires that removing/adding is properly handled so you don't end up with systems keeping components that were removed, or their owners no longer exist.

 

2) Querying objects that meet component criteria, based on some "key". In my system I'm using a uint64 bit mask - when component is added to object, this objects sets a mask for component's family (family is a group of same-type components, for example Renderable is family sharing common interface that can be derived from to create TerrainRenderable etc.). When component is removed, it clears the mask. This allows me to know exactly what component types belong to a given game object - I don't have to retrieve exact component when I just need to gather objects that have for example Renderable and Spatial component.

 

When adding component to object:

 

m_CompMask |= static_cast<uint64_t>(family);

When checking if object has certain components, for example Comp::RENDERABLE and Comp::SPATIAL:

 

bool HasComponents(uint64_t mask)
{
      return (m_CompMask & mask) == mask;
}

if (obj->HasComponents(Comp::RENDERABLE | Comp::SPATIAL))
{
}

This way you can iterate over scene objects quite efficiently checking only bitmask. This still won't scale too well if you plan on having really A LOT of objects.

 

I use the second approach for scene on client-side where I don't really plan to have more than maybe few hundreds to a couple of thousands objects at any time. But for something like managing all game objects on some online game server side, this can easily go up to hundreds of thousands of objects and may be too slow - this is where I'd look into first method and register components in systems that require them.

 

3) System-ownership where systems are owners of components - if they own them, they already know about them so no need to query smile.png This may be best considering cache friendliness and speed, but gets complicated if there is system that works on more than 1 component - who owns such component then? Because of this I haven't tried this approach. In my case, object owns its components, and scene queries its objects for certain criteria. If I have render system that requires both - SPATIAL and RENDERABLE components on object, it can ask scene for them easily.

Edited by noizex
0

Share this post


Link to post
Share on other sites

Although i find the bitmask approach very elegant and efficient, it's limitations appear too quickly, specially since i'm trying to create a generic engine for my games. After writing so much tight and not very reusable code, i'm trying to abandon those vices. I read in many articles that the system can have an std::vector with the component instance and the entity ID, and to optimize removal, use move.

 

Do you guys agree with that? 

0

Share this post


Link to post
Share on other sites

There is an example of an ECS implementation, which is very efficient. I think it is based on a similar idea as noizex #2, but without a hard 64-bit limitation?

 

Look at the tutorial on the front page, it is quite easy to follow. It takes away most of the implementation details from the user.

0

Share this post


Link to post
Share on other sites

Check out the articles in my signature for how I do my components.  They're basically just arrays of components (one per type) and another array of component masks.  An entity is the aggregation of all the elements at a given index in the arrays, where the component mask describes which components "exist" (are turned on). It's cache friendly and requires no memory allocation past the initial allocation of the arrays.


I'm not sure I agree that components must be data-only and you also specified that systems operate only on groups of components when they all exist. Not sure what you meant by that but doesn't that negate the plug-and-play nature of ECS?
0

Share this post


Link to post
Share on other sites

 

Check out the articles in my signature for how I do my components.  They're basically just arrays of components (one per type) and another array of component masks.  An entity is the aggregation of all the elements at a given index in the arrays, where the component mask describes which components "exist" (are turned on). It's cache friendly and requires no memory allocation past the initial allocation of the arrays.


I'm not sure I agree that components must be data-only and you also specified that systems operate only on groups of components when they all exist. Not sure what you meant by that but doesn't that negate the plug-and-play nature of ECS?

 

 

Nope, my system is perfectly plug-and-play.  The systems read the component mask to determine if they should act upon the component data for that entity.  If you're "adding" or "removing" a component, you're just modifying the component mask to change the visibility of the component to the systems.

0

Share this post


Link to post
Share on other sites

Check out the articles in my signature for how I do my components.  They're basically just arrays of components (one per type) and another array of component masks.  An entity is the aggregation of all the elements at a given index in the arrays, where the component mask describes which components "exist" (are turned on). It's cache friendly and requires no memory allocation past the initial allocation of the arrays.


I'm not sure I agree that components must be data-only and you also specified that systems operate only on groups of components when they all exist. Not sure what you meant by that but doesn't that negate the plug-and-play nature of ECS?
 
Nope, my system is perfectly plug-and-play.  The systems read the component mask to determine if they should act upon the component data for that entity.  If you're "adding" or "removing" a component, you're just modifying the component mask to change the visibility of the component to the systems.
I see that makes sense now
0

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