• 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
Alex B.

Entity Component System and Parent Relations

11 posts in this topic

Hi there,

 

our team is trying to build an data oriented entity component system for our game.

 

We understood in most cases the benefits of the system. But we are struggeling with the parent relationships a scene graph qould give us. For example you got a transformation change of a matrix. So all childs related to this matrix get updated in relation to the parent.

 

How can such relations be built in an ECS? Or do we have to run a scenegraph together wit h the ECS?

 

Thank you!

0

Share this post


Link to post
Share on other sites

I was thinking about this myself. The most straight forward way might be to make the transform component be a some kind of scene node. Still I am not sure how you attach e.g. a weapon entity to the bone of a skeleton in this case.   

0

Share this post


Link to post
Share on other sites
You can sort the objects stored in the scene graph by parent->child relationships. If you have a parent A with two children C and D and then another root node B, you'd want it sorted ACDB. Resorting every frame (possibly in parallel) is just fine. Now you can just iterate through the list of scene nodes and update matrices with back-references. Locality of reference will be high, cache coherency will be strong. This contiguous array of scene nodes can be veyr useful for certian rendering architecture,s too.

Note that a scene node is not an entity, nor is it necessary a component all its own. One entity might have multiple scene nodes representing a complex dynamic object. You should end up with separate object modules: your game object module, your scene node module, your physics module, etc. The components are just there to associate game objects with the other modules. You're mostly forced to work this way in bigger scale games where you are usually using a third-party physics library or graphics middleware (Umbra, FaceGen, Granny, etc.).
0

Share this post


Link to post
Share on other sites

There are several possible solutions. I'm fine with the following one:

 

A Placement component defines a position and orientation for the entity in the world. This component is a storage, e.g. it does not update itself. Updaters for Placement may be an animation or a behavior component (or a script if you like). One possible behavior component is Parenting which implements forward kinematics (other behaviors are Aiming, Aligning, Tracking, Interposing, Billboarding, Grabbing (a special kind of "parenting" that reflects holding or equipping), ... ). Such behavior components can have their own variables. E.g. the local placement of a child entity is stored within its Parenting component. WIthout any write access to a Placement, the entity is in fact static w.r.t. its position and orientation. I've chosen this way because forward kinematic is just one way of controlling a Placement, and it is not special compared to others.

 

Other relations between entities could be expressed similarly. Again other relations that may be expressed by uber scene graphs are only reflected partly in components themselves. E.g. while a collision volume may be an own component or part of a component, the structure of managing colliders and detecting / resolving collision is a task placed over components, and hence should always be done in a sub-system (its the way I prefer handling components anyway). 

 

 

EDIT: I recommend not to use scene graphs at all. Notice that a scene graph is a sole hierarchy which is used to express, well, everything. One should instead use structures that are well suited to solve the problems one by one. That said, also ECS can be "misused" similarly to how a scene graph can be. Hence I prefer to look at ECS as a structure to compose the scene, perhaps like a flattened graph where all relations are made explicit. From this some more specialized structures are extracted / derived and handled at runtime inside the belonging sub-systems. The transformation graph and the collision resolution are examples of this. 

Edited by haegarr
0

Share this post


Link to post
Share on other sites
Hi, thanks for the information!

Okay so everything seams to be doable with an ECS :o

But the relation thing I still don't understand.

For example: i got a car with 4 wheels.
Car body gets turned by 90°. So the wheels would have to geht turned relative to the car body.

Can you explain how that could be done with the ECS approach?
Maybe with a code snippet.

Thank you very much guys!
0

Share this post


Link to post
Share on other sites

Well, question is whether a wheel as part of a car should be its own entity at all… But nevertheless, let's use it as an example. Of course, I describe it the way I'm doing things. Other solutions are possible as well, you know. A description in code snippets is meaningless until the API is known, but the API is engine specific; so I stick with a verbose description.

 

Create and entity for the car body. Create another entity for a wheel. Create a Placement component for the 1st and another for the 2nd entity. Because of the existence of the Placement components in their initial state (i.e. identity transform) both entities are located at the world's origin and are facing along, say, the z axis. Notice that both entities exist side by side and not hierarchically. I allow nesting entities in the editor not for the sake of dependency but just for a logical grouping, allowing the designer to straighten up things to its wish.

 

Because there is nothing set-up that alters the both Placements, both entities are static. Now create a Parenting component and assign it to the wheel entity. The Parenting component is assigned to the entity whose Placement component is to be controlled, i.e. the "child" entity. In order to complete this step you obviously need to tell which entity the "parent" role plays. So attach the car body's entity to the Parenting controller's parent slot.

 

Now we have a mechanism installed to the wheel that computes the value of the entity's Placement as usual for parenting, i.e. when using column vectors:

     my_entity_Placement_value := parent_Placement_value * local_placement

 

Nothing has changed on screen because both right hand side transforms are still identity transforms. So translate the wheel to where it should be located relative to the car body's placement. In fact you do not alter the wheel's Placement directly but the wheel's Parenting local placement value.

 

When you compare this with a scene graph solution, then the parenting is not expressed by a wheel node below a transform node below a car node, but (when still using the term "node") a transform node below a wheel node besides a car node.

 

The sense of this set-up will become probably more clear when thinking of other mechanisms (I'm supporting 12 different mechanisms at the moment). Let us have a look at targeting. Let's say you have a Tracking component installed to a weapon, and it tracks the Placement of an enemy. For sure weapon and enemy are 2 real distinct entities, and putting the one as node of a scene graph into the other makes no sense. Instead, both live side by side in the CES and the one is explicitly expressed to target the other by the current existence of a Tracking component.

 

Besides the mechanisms mentioned above, there is another kind of controller that fits into this set-up: Animation. Let's say the animation sub-system currently runs a track that changes the local rotation of the wheel's Parenting component. Voila, the wheel rotates in place, and it moves with the car body.

Edited by haegarr
0

Share this post


Link to post
Share on other sites
I'm interested in this as well. I have a couple questions about the system you described Haegarr:

1) How does your system know what position component to update? In your example, you have a placement component that stores a local position, which is the position relative to the parent's position. Now suppose someone kicks the wheel. How does the physics system know to update the Parenting component's local_placement rather than the Position component's position?

2) How does the rendering system resolve the "final" position of the entity?

3) And lastly, what happens if there are several different types of these parenting-type components (you mention having 12 different ones) on one entity? Or is that just considered a no-no?
0

Share this post


Link to post
Share on other sites


Say we have a weapon entity and we want to attach it to the right hand of of the skeleton in another entity. How do we solve this?

I solve this using what I call the Grabbing mechanism. It is a kind of extended parenting and works as follows:

 

An entity that can be grabbed gets a Grip component. An entity that is able to grab something gets a Grab component. Both of these components have a set of key values. One of the key values of a Grip needs to be identical to one of the key values of Grab, then the Grab is allowed to be paired with the Grip. This is used to control what entities can be held by which entities and how.

 

A Grip has a local placement which defines an anchor point and orientation. A Grab also has such a placement. The anchor of a Grab is usually linked to a bone of a skeleton. The anchor of a Grip is usually static.

 

When a Grabbing is established then the Grab is paired with a Grip. This is marked in the Grab by referring to the Grip and vice-versa. The task is then to make the two anchors coincident. When the local placement of the Grab is updated e.g. due to skeletal animation, its world position can be computed as

    grab_global := entity_with_Grab__Placement * grab_local

The corresponding formula for the Grip is

    grip_global := entity_with_Grip__Placement * grip_local

and both should be identical, hence
     entity_with_Grab__Placement * grab_local = entity_with_Grip__Placement * grip_local
so that
    entity_with_Grip__Placement = entity_with_Grab__Placement * grab_local * inv_grip_local

 

In other words, Grabbing sets the grabbed entity's Placement to the value as computed above. (Remember that Placement components ever store a world position.)

0

Share this post


Link to post
Share on other sites


1) How does your system know what position component to update? In your example, you have a placement component that stores a local position, which is the position relative to the parent's position. Now suppose someone kicks the wheel. How does the physics system know to update the Parenting component's local_placement rather than the Position component's position?

Nope. A Placement component ever stores a global placement (I use the term placement for a combination of position and orientation). When an entity has a Placement component it is placed in the world. Notice that a global placement makes sense by itself but a local placement does not because the latter requires a reference frame. The local placement e.g. within the Parenting component is not a component but a member value. I used a uppercase "Placement" for component (like written as a classname) and a lowercase "placement" otherwise.

 

So the question is how does the physics system know whether to update the local placement or the global Placement of the wheel. So read on ...

 


2) How does the rendering system resolve the "final" position of the entity?

It doesn't, because it need not. Notice that the rendering sub-system is the last executed during an iteration of the game loop. When it comes into play all of animation, physics, collision resolution and so on is already done. Hence all Placement components are up-to-date and, because those components ever store the global placement, ready-to-use.

 

Nevertheless the Placement instances which are controlled in some way need to be updated. Notice that this problem is unrelated to CES. Animation controlled placements are driven when the animation system is updating, of course. Placements that are controlled by what I call mechanisms are updated when the belonging sub-system (named SpatialServices) is updated. You can solve this problem using a dependency graph with or without dirty state propagation, as usual, where the edges of the graph are defined by the components implementing the mechanisms. Physics and collision resolution can work as usual.

 


3) And lastly, what happens if there are several different types of these parenting-type components (you mention having 12 different ones) on one entity? Or is that just considered a no-no?

It makes no sense to run competing controllers on the same value. Well, this brings up the question what the controlled value is. A placement can be seen as one compound value, as a position and an orientation, or as 3 position scalar channels and 3 orientation scalar channels. The latter one is nowadays typical for 3D content creation packages but probably too fine grained for games. The former one is perhaps too coarse. I used to use the separate position and orientation channels. Hence a controller may control both or one of both channels. For example, the Tracking component naturally controls the orientation only, while an Orbiting controls both channels. If meaningful then the control by a component can be switched on or off. With respect to physics, the controlled channels are constrained.

 

Additionally, it is valid to have several controlling components if they don't compete because all but one is disabled. For example it is okay to have several Grip components on an entity as long as at most one of them is paired with a Grab.

1

Share this post


Link to post
Share on other sites

Thank you very much guys, that helped us a lot!

 

Otherwise we would have ended developing a ECS and a Scenegraph! :P

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