Jump to content
  • Advertisement
Sign in to follow this  
Promit

Aggregation/component based system?

This topic is 5037 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

On his site, Kyle Wilson wrote an article talking about aggregation vs. inheritance, which includes this snippet:
Quote:
So if an inheritance-based game object design is riddled with problems, what is a better approach? In redesigning the Plasma engine used by HeadSpin/Cyan, the software engineering team opted to flatten the game object hierarchy down to a single game object class. This class aggregated some number of components which supported functionality previously supported by derived game objects.
Now, I'm not familiar with this design pattern at all. I'd really appreciate a basic explanation of what's going on.

Share this post


Link to post
Share on other sites
Advertisement
Is aggregation the same as implementation? Because if it is, I may be able to help.

Share this post


Link to post
Share on other sites
is that Aggregation vs inheritance?

then it's




// inheritance
class CObject: public CPhysicsObject, public CRenderObject, public CNetworkObject
{

};

// aggregation
class CObject
{
CPhysicsObject* m_pxPhysicsObject;
CRenderObject* m_pxRenderObject;
CNetworkObject* m_pxNetworkObject;
};



Personnaly, I'd prefer aggregation over inheritance. It's the dilemma 'is-a' (inheritance) with 'has-a' (aggregation), to put it simply.

Share this post


Link to post
Share on other sites
zahlman beat me to it, with a hammer.

obviously, you can see the major benefits of composition straight away against inheritance, and the benefits of inheritance (multiple inheritance might be OTT thought) other composition (aka aggregation).

Share this post


Link to post
Share on other sites
I think the article in question might be talking about a system more like plug-ins, where separate components are aggregated/composed into a functional whole.
Quote:
Component-based game objects are cleaner and more powerful than game objects based on inheritance. Components allow for better encapsulation of functionality. And components are inherently dynamic -- they give you the power to change at runtime state which could only be changed at compile time under an inheritance-based design.

This is quite different from "regular" aggregation. I've implemented a system that builds game objects dynamically at runtime from components, and it sounds very similar to what the article is talking about.

Basically, you create a Component interface class which allows you to create and manage trees of components that work together, usually communicating via some event system. It's really nice to be able to change behavior simply by specifying a different component for a game object--even during the game. For example, if I need a game object to play sounds, I simply add a SoundComponent to the object.

There is some overhead since communications must be through events, as you don't normally want to keep naked pointers to components. This decentralization adds complexity, but it's worth it IMHO, because you are now liberated to create objects by mixing and matching parts at runtime rather than relying on a static inheritance hierarchy.

Share this post


Link to post
Share on other sites
hmm... Sounds also like a lot of code to add another component in the game. Since components never inherit from each other (that's the whole point, isn't it?). It's kind of going back to C, with message passing and parsing, and all that jive. If I understand correctly. However, sounds very cool for scripting and general flexibility. The overhead could be quite costly if you have lots of different components in hierarchies. That's my first impressions.

Share this post


Link to post
Share on other sites
It's definitely a much more "flat" class hierarchy, but the flexibility is tremendous, and it's still very OO. So it's not like C in that respect.

For example, you could build a player object from several components which are "composed/aggregated" at runtime (I use XML to define objects):

- KeyInputComponent (react to user input)
- RenderComponent (sprite, textual, point, mesh, etc)
- PhysicsComponent (position, orientation, motion)
- CollisionComponent (method of detection as well as response can differ)
- SoundComponent

These would be contained by the game object (itself a component) which would receive events from the system, passing events to each child component for handling. So if you get a "damage" event, the render component might spawn a particle effect, the physics component might push the object in the direction of damage, the sound component might play an appropriate damage sound.

The coolest thing is that you can change behaviors at runtime, so that if you get a power-up, say, you add a component for it and remove the component when the power-up is gone. In my "2 player pong" game, the balls change state this way, and it works well.

The overhead is in the event system and in the communications between components because they have to "look up" each other to talk. You can't simply say "set the position of the player to x, y." You have to first ask for the PhysicsComponent, then tell that component to set the position. Optimizing that part of the system is what I'm working on for the next iteration of my engine, but I've found the overhead to be pretty slight and well worth the freedom it gives you.

Share this post


Link to post
Share on other sites
Quote:
Original post by griminventions
I think the article in question might be talking about a system more like plug-ins, where separate components are aggregated/composed into a functional whole.
Not really, at least not specifically. oliii's example nails it perfectly.

Now, nothing is stopping you from making CPhysicsObject/CRenderObject/CNetworkObject inherit from a CComponentObject class, and allowing for all sorts of interesting run-time behavior, but it's not strictly necessary.

Personally, I agree with the philosophy. I prefer only to inherit, when I actually plan to use a class through that interface. Even then, I'll arrange my code to avoid having to use classes through multiple interfaces (ie. instead of separate collections of Physics/Render/Network objects, simply add Visitor-style members to the CObject class).

If I had my way, inheritance wouldn't even be linked to polymorphism. We'd all just define interfaces:

class CObject : CFooObject, CBarObject {
...
}

// Matching names/signatures automatically match
interface CObject to CFooObject {
// Otherwise, matches can be specified w/ conversions
someCFoomember(int x, int y, int z) = someCObjmember(Vector3(x, y, z));

}

...

CObject o;
CFooObject* f;
f = &o;
f->someCFooMember(1, 1, 1);



Share this post


Link to post
Share on other sites
I admit my knowledge is not very wide when it comes to these kind of subject. I learn things everyday.

Anyway, when I design classes, I try to answer to both question: is Thing a AnotherThing? (this question gives me interesting bits about the identity of a class). The second question is more complex: do I think that Thing is AnotherThing because Thing extends AnotherThing or because Thing uses AnotherThing? In the later case, of course, I tend to prefer aggregation over inheritance.

Some concrete - and, admittedly, not so trivial - example: consider a generic graphic device interface. Now, consider the OpenGL specialization of such device: is it an extended device of does the generic device uses the OpenGL one? I know, this kind of question looks really weird :)

Regards,

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!