Another Component Entity System Question

Started by
5 comments, last by McGrane 10 years, 2 months ago

Hi All,

After reading the abundance of message's recently about the subject, it got me interested in researching into it. Al tough I feel that I understand the theory behind it, there are a few conflicting ideas in articles and question I have, and am hoping someone can help me with.

In relation to the article I read on GameDev http://www.gamedev.net/page/resources/_/technical/game-programming/implementing-component-entity-systems-r3382 I have implemented a small demo using this, but am unsure if i'm going in the right direction.

In the article things are defined as Position[Entity_MAX], Velocity[Entity_MAX], Appearance[Entity_MAX].

When an entity is created, it returns an unsigned int, which I take to go across all arrays - for example the first entity that is created has a position and a velocity which is Position[0], Velocity[0], if a static item was then added it would be Position[1] and Appearance[1].

My real confusion is of the empty space ( if my understanding of how it all ties together is correct ) If I have many components created in this way - for example 50, and the majority of my entity's only use one or two of these components at a time - will that not just waste a wide range of space? - or is this acceptable because of the cache speed increase?

Alternately, am I just creating the Components in the wrong way? While using the technique he shows for the mask, I run into a problem.

My code at the minute, when being used to move and render is as below


World    = new s_World;
	
CreateDynamicObject( World, 0.0f, 0.0f, 0.0001f, 0.0001f ); // xPos, yPos, xVel, yVel

Graphics = new cGraphics();
Physics  = new cPhysics();

void cGame::Render() {

        glClearColor( 0.1f, 0.1f, 0.1f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT );

	Physics->Update( World );

	Graphics->Render( World );
}

void cGraphics::Render( s_World *World ) {

     for( int entity = 0; entity < ENTITY_MAX; entity++ ) {

          if( (World->mask[entity] & STATIC_MASK) == STATIC_MASK) {
               // Render Code
          }
      }
}
Using this method, if the mask is a STATIC_MASK, it will render it - but if I also want it to render dynamic, do i just add another if statment, and another mask, and so on and so on until I have every scenario that needs to be rendered / Anything else i want to do
Im sure some of these questions about masks and things are going over peoples heads that have not actually read the article. But im hoping that someone with experience using a similar system can help me out.
Please let me know if I need to clarify this post more ;)
Any information / insight would be appreciated
David
Advertisement

Na, the point of the masks is so that you don't have to care what type of object it is. Don't render based on if your object is static of dynamic, but rather, render if it fits the requirements of being rendered.

something like this:


unsigned STATIC_MASK = POSITION | IMAGE;
unsigned DYNAMIC_MASK = VELOCITY | POSITION | IMAGE;
void cGraphics::Render( s_World *World ) {
 
for( int entity = 0; entity < ENTITY_MAX; entity++ ) {
unsigned mask = World->mask[entity];
if( (mask & POSITION) && (mask & IMAGE)) {
// Render Code
// this should render both static and dynamic objects
}
}
}

Ok i see where i was confused now, need to look up on my bit wise anding :) When i broke down your code, and thought about it it made a lot more sense, Thanks ultramailman ;)
With that said, am i right in thinking that your if statement is slightly incorrect. By anding any statement with any component, they would be true.

So the if statment would be if( true && true ) render all

Im guessing it should be if( ( mask & position ) == position )

As for my other question, am I correct in thinking that if i had 100 components, and a particular entity - like Static above - uses only 3, that all 97 other components are just left blank?

Thanks for the Help !


With that said, am i right in thinking that your if statement is slightly incorrect. By anding any statement with any component, they would be true.
So the if statment would be if( true && true ) render all
Im guessing it should be if( ( mask & position ) == position )

Assuming POSITON and IMAGE are just single bits, if an entity were missing POSITION, then (mask & POSITION) should be 0, and so his if statement would evaluate to:

if (false && true)

and would not be executed.

A better way to write it though (one less comparison), is like this:

if ((mask & (POSITION | IMAGE)) == (POSITION | IMAGE))

Thanks for the reply phil. In fact, going in line with the article (which i probably should have cleared up a little)

Position is 0001

Velocity is 0010

Appearance is 0100

Static_Mask is ( Position | Appearance ) or 0101

Dynamic_Mask is ( Position | Velocity | Appearance ) or 0111

if( (mask & POSITION) && (mask & IMAGE)) - would be (assuming static mask ) - if( (0001) && (0100))

Thanks for the suggestion on "if ((mask & (POSITION | IMAGE)) == (POSITION | IMAGE))" but i think now with the clarity of how the masks are defined (if i understand it correctly ) the statement i wrote for " if( ( mask & position ) == position ) " Would work properly, if using either a StaticMask( 0101 ) or Dynamic Mask (0111) and anding it with position (0001), would prove true for both cases. I think your method runs on the same idea, but with the image added in, which i was no including as i was using it elsewhere on another system that handles rendering.

Thanks,

David

Ok i see where i was confused now, need to look up on my bit wise anding :) When i broke down your code, and thought about it it made a lot more sense, Thanks ultramailman ;)
With that said, am i right in thinking that your if statement is slightly incorrect. By anding any statement with any component, they would be true.
So the if statment would be if( true && true ) render all
Im guessing it should be if( ( mask & position ) == position )

As for my other question, am I correct in thinking that if i had 100 components, and a particular entity - like Static above - uses only 3, that all 97 other components are just left blank?

Thanks for the Help !

You are right, it wouldnt work if position and image have more than one bit set. But they ate probabably single bit masks, unless you want to have x and y component separate for position, for example.
And yes, the other 97 component arrays would be left undefined. So far, I have 15 components in a game I'm working on, so I dont know what impact will 100 components have.

Ok great, thanks !

I'm sure the impact would be minimal, i mostly only wanted to verify that i was doing it correctly, it seems a little wasteful, but like im sure the cache speedup will outweigh this. I've been in work all day - so have not been able to try any of this out, so looking forward to getting back at it :)

Also i just realised that when speaking above about the seperation of image and position, that in fact in the example i have given was about rendering, so what i meant in the above comment is that my position is handled elsewhere ;)

Thanks for the help guys..

This topic is closed to new replies.

Advertisement