• Advertisement
Sign in to follow this  

Component Game System - Object Examples

This topic is 2993 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

I've read all I can find on component game systems, and have the general idea of the various implementations, but I feel like some of the more complicated, specific cases are not addressed. I know there is no exact way of combining components, but I would like to see some others' successful implementations. I would also like input on my own ideas to make sure I understand how the components communicate. Example: Object: Chase_Camera Components: Movement::Follow_Target (Contains an offset value for the min separation from target, a max separation value, and a speed at which it is capable of moving toward the target. This allows it to appear as a more dynamic entity.) Position Orientation Simple_Collision::Sphere (Simple collisions would generally be used for collisions with the world and other large objects. But it is left to the script to determine the response in each case.) Complex_Collision::Frustum (Complex collisions would be used for more specific tasks, such as bullet collision in a FPS or line of sight collision in this case.) Script (In charge of dealing with collision response for each case) In this case, if someone wanted to switch from third to first person, the only change would be to the Follow_Target component. It would require setting the min and max offset to <0,0,0>. Mostly what I am unsure about in this case, is the collision response. Do you believe the added functionality of a Script to handle how an object interacts is a good idea? Or should I add a 'Collision_Response' component for all the different cases. I can see it getting annoying having to write the collision response in the script for every object, but I can also see it allowing for a lot more diversity. For example, if I have a bomb object, and on_Collide I would like it to explode. I could script it to create an explosion object that is scripted to hurt anything it collides with. But then again, I could write separate collision responses for each--one that would Spawn_Object(...) and one that would Hurt_Objects(...). But for me, scripting makes the entire problem of object interaction seem so much simpler. What are some of your thoughts on the matter? Should there simply be a ton of pre-programmed components for every case, or should it be left up to the script to decide?

Share this post


Link to post
Share on other sites
Advertisement
Components systems are not fun to try and find documenation thats for sure, in fact if you could put up the links you have id be very interested, i had a very similar problem the only web links i can provide are all on here:


my lectures site->Game Architectures

and they arnt fantastic the first one clears up the differences between component and entity systems and i found that quite interesting...but ulmitatley useless.

im relativley new to component programming myself, ive tried and failed in the past but the current one is working =]!

First of all how do you're components communicate with each other (if at all) as i found this to be a big issue, for me the life saving thing came from messaging systems. if you unsure of what i mean by messaging systems it would be usefull for you to look at the sorce code in this book:

,chapter2->westworldwithmessaging

but essentially all components would be given the ability to listen out for messages so for your collision example you could simply make sure the collision component would send out a "collided" message to all other components owned by that agent.

then a component like "explode" could recieve that message and explode. The beauty being neither rely on each other as the collided message is simply sent out it doesnt care if its processed and similaly if a collided message is never sent out it wont effect the explode component.

but you may want to set up a trigger system which is explained in the raven chapter of matt bucklands book (to be honest i would higly recommend the book in general).

There are tons of differnt ways of doing it though, personally i prefer the pre-progammed component approach (but i wouldnt say a ton as they dont need to be derived from collision response-like components) as its easier to add and remove components at will if i wanted a case where my agent touched nuclear waste and became himself a nuclear bomb ready to explode when touched, then i could remove the component that currently lets him move around and add the explode component so that he will explode when collided with.

However i do like your scriptable approach it will solve problems when the preprogrammed components won't.

Its a nice idea and personally i would like to see a combination of both, i would say in general if you can make it generic make it into a component, if not, if its a bit more complex then make it into a scipt =]. and i would say you would have a very good re-usable system on your hands.

i think the only possible draw back of the scriptable sysem is you may start using it when generic components could have solved the same problem.You may also start using it in a way that breaks the original flexibility of the idea.

i find running crazy off the top of my head ideas helps me keep on track, could i make it so that i could attatch the explode component, collision compent and Follow_Target component all onto the camera so that the player has to run away from the camera...if my answer to all of these is yes then i generally think its a good system =]

p.s. my lecturer recomended a nice component idea to me the other day which for some reason i hadnt thought of, attatchAgentComponent, a glue for another agent to be attatched relative to another agent, this made turrets so much nicer to code =] thought id throw it up there.



Share this post


Link to post
Share on other sites
For the collision, i would have the rigid body object of your physics system capable of calling a callback, maybe a boost function or some other cutely wrapped function pointer.

You could have a collision response component that when added to an entity looks for the rigid body component and registers its callback with the rigidbody. In that call back you could choose to call a script.

So you may have a ScriptCollisionCallback component, which calls a script on collision. Every object does not need to have one of these. Other objects like vehicles may redirect that call somewhere else rather than a script.

As far as your camera. I'm not sure that your camera needs to be an entity nor needs to be involved in this whole entity/component party. When a script is called it could operate on different game settings, where the camera control lies, rather than attached to the player entity itself.

There's a million and one ways to do these things and they're very unclear to myself. But i plan to start working on the same issues when i get home.

I've never been a fan of messaging systems. It seems lazy but maybe it works great. I prefer to have things happen immediately though. To inform the correct system immediately that something has happened. If internally that system wants to queue a process to do later that's fine. But it should have the ability to respond at the time of the event.

I would suggest instead that your components go through an initialization phase where they find all their dependencies and store smart pointers to them for quick access in the future.

Share this post


Link to post
Share on other sites
Quote:
Original post by bzroom
I've never been a fan of messaging systems. It seems lazy but maybe it works great. I prefer to have things happen immediately though. To inform the correct system immediately that something has happened. If internally that system wants to queue a process to do later that's fine. But it should have the ability to respond at the time of the event.


You have to be careful when dealing with order of operations in this case though. Generally in your game loop you go through and update all game objects in the world. However, it's possible that the first object in the list can affect the 2nd object in the list before the 2nd object has a chance to do its update. In a worst case scenario, the second object now behaves differently, and decides to do something on the 3rd object that wouldn't have happened otherwise. This could in theory repeat indefinitely, affecting every single object in the world causing strange results.

It's workable, you just have to be careful.

Share this post


Link to post
Share on other sites
Quote:

I've never been a fan of messaging systems. It seems lazy but maybe it works great. I prefer to have things happen immediately though. To inform the correct system immediately that something has happened. If internally that system wants to queue a process to do later that's fine. But it should have the ability to respond at the time of the event.


It seems there as if your thinking of a messaging system working the same way as the royal mail does, you send a letter and it arrives who knows when, thats not really the case (well unless you want it to be ofc).

In our messaging system (both me and ChrisPepper1989 are working ont his project) messages are delivered to an agent immediatly before anything happens, just through a middle man instead of a calling a method. In the end you get the exact same workings, with a slight bit of overhead, but a whole load of redundancy for things going wrong.

Here's a little example:

Were making an RTS, I want to click on an object and him become selected, so I click, work out which object it is and tell him hes selected, ok, so a conventional way would be to get the object from the spatial partitioning system, and call obj->Selected(), now all objects need this Selected() function, but is this really he way it should be? Afterall I dont want to be able to select a mountain.

In the components and messaging system, I work out which object is under the cursor and PostMessage(obj->ID(), CLICKED) to send a message through the system (or since I have a pointer to the object instead of just an integer UID for it, I could call the post message function directly and ignore the system). Now the agents hands this message to all its components, if it has the ClickableObject component attached, this component will respond to the CLICKED message.

I use this example for a good reason, I'ts the one that clicked this system into my head, even after the components and messaging system was programmed.

Share this post


Link to post
Share on other sites
Quote:
Original post by ChrisPepper1989
Components systems are not fun to try and find documenation thats for sure, in fact if you could put up the links you have id be very interested


All can be googled or reached through this forum, I'd repost but I didn't save the URLs and I'm too occupied to dig them up again. Sorry.

I know this was my starting point: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
As it offers a _very_ general description of a component system and some object implementations.

Quote:
Original post by ChrisPepper1989
First of all how do you're components communicate with each other ... For me the life saving thing came from messaging systems.

I use a queued message system. I felt like forcing the component to deal with the message immediately removed some of the modularity of the system.

Quote:
Original post by ChrisPepper1989
but you may want to set up a trigger system which is explained in the raven chapter of matt bucklands book


Assuming you mean http://books.google.com/books?id=gDLpyWtFacYC
it looked very similar to a message system but a with some added intelligence. I just glanced at it though so feel free to say I'm wrong.

Quote:
Original post by ChrisPepper1989
i find running crazy off the top of my head ideas helps me keep on track, could i make it so that i could attatch the explode component, collision compent and Follow_Target component all onto the camera so that the player has to run away from the camera...if my answer to all of these is yes then i generally think its a good system =]

Yes, I actually didn't think of that when I described it, but that could be one (very creative) application of my described follow_target component

Quote:
Original post by ChrisPepper1989
p.s. my lecturer recommended a nice component idea to me the other day which for some reason i hadnt thought of, attachAgentComponent, a glue for another agent to be attached relative to another agent....

Oh, I forgot to specify the Target component in my camera example. Follow_Target would then query for Target. But I like your attachedAgentComponent name better :D. This could be useful in many situations. You would have to be careful when adding multiple targets though, in making sure that each system knows what target is desired (if not all of them). It would take some more planning to be perfect.

Quote:
Original post by bzroom
For the collision, i would have the rigid body object of your physics system capable of calling a callback, maybe a boost function or some other cutely wrapped function pointer.

You could have a collision response component that when added to an entity looks for the rigid body component and registers its callback with the rigidbody.

I would be a fan of this approach, as it is efficient, but I don't like the dependencies. I know this is strange, and some may consider it poor programming, but I'd rather just send a message off somewhere and never worry about it again.

Quote:
Original post by bzroom
As far as your camera. I'm not sure that your camera needs to be an entity nor needs to be involved in this whole entity/component party. When a script is called it could operate on different game settings, where the camera control lies, rather than attached to the player entity itself.

I was thinking along the lines of a racing game or any third person game really where the camera depends on the players movements mostly, instead of being independent of the moving object. But either way, I don't see a harm in letting it be party of the "entity/component party", especially if the components it uses can be reused elsewhere.

Share this post


Link to post
Share on other sites
I'm sort of migrating my game to a component system. Basically that means that I add functionality by adding sub-objects instead of subclassing. Right now I have a single Entity class. It contains a graphics object, which it manipulates to change its graphical representation. It also contains a controller object, on which it calls an Update() method which in turn calls methods on the Entity. But there's no overriding component-based architecture.

All this to say, don't worry about a pure architectural paradigm. Just do what works and makes sense.

You can check out my system on its Sourceforge.net project site here: Somnopatru. If you don't have SVN, you can look through the files here. Viewsys is the graphical system, inspired by MVC and Sneftel's outboard component system. The classes to look at are IViewComp, IViewSystem, SDLViewComp, and SDLViewSystem. In the somnopatru folder, look at IController, IControllable, TileEntity, InputComponent and InputSystem to get you started.

If you search this forum, you'll find a number of threads about component systems and how to make the components communicate. I can think of three major systems for communication. 1) Components go through the entity to get pointers to each other and call methods on them. 2) Components modify shared data attached to the entity but not to any specific component (Trefall's property-based system is a variant of this). 3) The message queue thing. I've personally taken a liking to the last one, and will probably use it the next time I start from scratch.

Share this post


Link to post
Share on other sites
Those links have been very useful in the development of my system, when I'm finished implementing (and writing it up) I'll leave a post here for the rest of you to look at.

Scott

Share this post


Link to post
Share on other sites
An update on my work, I have finished implementing my components system, and have pretty much come across the same roadblock the original poster was talking about, I have a components system set up like this:

GameAgent derives from PropertyContainer, Messenger, and ComponentContainer, this class acts at the "hub".

Messenger provides the functionality to send / receive messages from all other Messengers in the game world (a messenger is not just an agent, for example the GraphicsSubsystemGameComponent also derives from messenger and is listening for messages on the GRAPHICS_SUBSYSTEM channel).

PropertyContainer provides the functionality for the handling of propertys - variables of any supported type that are assignable by a named value.

ComponentContainer handles all the components the agent has.

Components also derive from PropertyContainer so that they can have their own propertys, I did this instead of explicit variables (or as-well as explicit variables) to allow components to have variables set up in script, eg the script to load an agent with a "Renderable" component looks like this:

component renderable
string MeshFile HumanBattleship.mesh

Using these systems together has solved inter-agent and inter component communication, however I now have this situation:

A "planet" in my game is defined as this:

"A body in space which can be controlled by a team, when a team controls the planet, the planet will give it resources and allow the team to build space stations in its orbit"

I have no idea how to go about implementing this functionality now, my first thought would be to give the planet a property called "OwningTeam" which is a GameAgent*, and a component called "GiveResources" which will send an "INCREASE_RESOURCES" message to the team if the pointer isn't NULL. However the next problem I face is how do I give a team the functionality to own this planet.

And here is my main gripe im finding with trying to implement this component system... every solution raises 10 more questions.

Scott

Share this post


Link to post
Share on other sites
Personaly, I find it easier to seperate logic and data into components and properties, and make the choice that both are owned by the entity. You're not forced to do it this way, the way you've set it all up works perfectly as well, it just makes it all work more logically in my brain that way.

So, how I'd think when solving your problem would be something like:
- Planet has a logic module that allows only one team to own it.
- When a team owns a planet, the team can extract resources.
- When a team owns a planet, the team can build space stations in it's orbit.

Planet thus needs to hold a component that allows a team to own it. For this, the logic require that the planet has a property on who owns it. Let's say it's the ID of the team.

Planet would also need a resource component, that holds the logic that defines the planet as an extractable resources. If nothing else, to initialize such properties as resource type, and extraction-rate modifiers.

A team needs a resource extractor component, that holds the logic to deal with extracting resources from a resource. It doesn't "have" to be a planet. Let's say that the planet resource component holds a special logic that checks for the ownerId property, and if the resource extractor is not of this id, then it won't allow resources to be extracted. This component could also check item stats and whatnot, to check the capabilities of the team to extract resources.

A team also needs a space station builder component, which would allow a team to build space stations. Let's say that building one in the orbit of a planet makes the component logic check that the planet's ownerID is equal to the team's id. If it isn't, they won't be able to build there.

I think it's a good idea to use messaging between entities. Myself, I found that doing messaging within entities too, between components and all that, got a little messy for me. I, instead, let components share common properties instead, and react with logic on properties changing. Also, I'd suggest that you consider extactly what you benefit from your component system. Do the rendering, physics and sound really need to be a component? Is there a point of making something a component if most every single entity will share that logic and capability? This might be a way to simplify your component domain, and make designing and seperating your components easier.

Myself, I've made the decision that my components were only to be used for gameplay logic. Every entity in my engine has rendering, physics and sound capabilities hardcoded in there.

Share this post


Link to post
Share on other sites
I think it is interesting just how many people are advocating using an Object wrapper for components and applying properties to it. It tends to make the concept easier to deal with in your mind, but I think overall it is less efficient (haven't tested or analyzed, I just have a hunch) as it adds another layer of complexity to the organization.

But I wanted to talk more about the implementation of component objects and less about how they communicate.

Share this post


Link to post
Share on other sites
The thing is, the implementation is totally dependent on how the components communicate with each other. Once the interface between components is defined, the internal workings are totally up to the component. The tricky part of component-based design has always been, IMO, getting the components to work together.

Share this post


Link to post
Share on other sites
Quote:

I think it is interesting just how many people are advocating using an Object wrapper for components and applying properties to it. It tends to make the concept easier to deal with in your mind, but I think overall it is less efficient (haven't tested or analyzed, I just have a hunch) as it adds another layer of complexity to the organization.


I have this hunch as well, and its a fair point after all, when you consider how much more work happens in my system when I was to do basic tasks such as get the position of an object, in the classic inheritance model it comes down to an inlined function call:

object->Position();

In my system I have to first lockup a map for a string to see if it exists, I then have to retrieve the property, and dynamic_cast it to the correct type, and then return it.

Another example: Renderable component creating a mesh inside Ogre:

Using the inheritance model we would simply say something along the lines of:

object->AddToRenderer(mRenderer);

In my model, here are the steps that are taken:
- Renderable component sends a message to GRAPHICS_SUBSYSTEM asking for the renderer.
- PostOffice receives message and forwards it to all Messengers that are listning in on GRAPHICS_SUBSYSTEM.
- The renderer receives this message and posts a message back to the agent that has the Renderable component with a pointer to itself.
- The Agent forwards the message to the Renderable component.
- The Renderable component receives this void pointer, casts it to a Renderer and creates the correct mesh (after using the above property system to get the mesh name ofc).

So yes, this is going to be very slow, and can only be optimized so far, without tightly coupling the components and property's. However it does allow maximum flexibility and the ability to combine any components and properties without things breaking (as in crashing).

So what am I going to do about it? I've dubbed it the "Lego and glue philosophy", I build my masterpiece out of Lego bricks (components and property's), this way I can switch bricks in and out as I please until the structure is perfect. Afterward I will glue the bricks together (start tightly coupling components and creating dependency for the sake of efficiency) to make sure the structure doesn't fall apart over time.

Share this post


Link to post
Share on other sites
In my component system, I don't lookup every time I use a property. Since the components know which properties they need in order to perform their logic, each component store a reference to that property instance at construction. Since, in my system, the properties are shared among components inside their respective entities, and since all logic lies in the components, I hardly ever have to do a lookup in the map.

Also, what I've concluded with and have spoken of in the past for how I feel about approaching components, is that overusing components can have more bad than good with it. Do you really need the flexibility of having a rendering component, or physics component? Won't every game object in your world need both anyway? So, why overly complicate this core functionality of the game object? Myself, I focus components on the gameplay logic. Keep the core optimized and hardcoded, but keep the gameplay logic flexible, that's the part of a game object's code that your designers will care about and want to "lego" brick for brick anyway. Complicating the requirements of your core engine pipeline because you want to use components... just makes the whole component approach that much more complex and difficult to integrate in your game engine imo.

Also, since my "Components and how they communicate" post over a year back, I had the personal realization that using events as the means of communication between components inter-entity made the actual flow of logic more complicated than necessary. Yes, it solved coupling, but I found myself in situations where ping-ponging between components would some times occure, or where logic would jump between different components, to make each component cover their responsibility domain during the execution of some gameplay logic.

In the end, what I realized, was that in most situations, if not all, the communication between components inter-entity was based on changing properties. Thus, making properties the "glue" between components inter-entity simplified everything. When a component can listen to a property that change, and perform some kind of logic when it do, you achieve much the same as you'd get with inter-entity component communication via events, but with a lot more independent and seperate relationship between the execution in components.

I still use events to communicate between entities however. So if there's a component who performs some kind of logic towards another entity, like a "target", it would send an event to that target, not start accessing it's properties directly.

Of course, this is a solution I find to be working really well in my own project, it might not fit as well in yours, or might not ring as clear in your mind as in my mind. A different approach might be better for you. There's a win/lose for every decision though. Optimalization and flexibility are kind of "opposites" like that...

Share this post


Link to post
Share on other sites
Quote:
Also, what I've concluded with and have spoken of in the past for how I feel about approaching components, is that overusing components can have more bad than good with it. Do you really need the flexibility of having a rendering component, or physics component? Won't every game object in your world need both anyway?
I don't think that's a given - it really depends on the game.

I use a component system in my game, and there are many game entities that don't have physics and/or rendering components. Many entities (static obstacles, stationary powerups, UI elements, menu items, some background design elements) are non-mobile and therefore don't require a physics component. Other entities (triggers, sound sources) don't have a visual component. In fact, although I agree with you that you can take it too far, I've felt at times that even having a transform component built in to each entity was less flexible than I wanted. (There are some entities in the game that don't have a spatial configuration of any sort.)

My ideal component system would make no assumptions about what components an entity should or should not have. However, the more abstract the component system gets, the harder it becomes to design (IMO), and of course there can be performance implications as well.

There's certainly no 'one size fits all' solution, and sometimes it's best to favor practicality over elegance and flexibility. However, I think the question of whether one needs the flexibility of an entity not having this component or that component really depends on the programmer and on the project.

Share this post


Link to post
Share on other sites
Most certainly, which is why I've been very careful to point out that the way I'm speaking of may certainly not be the best way for someone else.

I do think, however, that many who start adapting their engine/game to the component-based approach, don't focus enough on the problems they try to solve, or the flexibility that their game requires. The question of "optimal" solution or is this approach "efficient" is too commonly asked imo, because it all depends on the requirements of your project and the problem-domain your components are there to solve.

Share this post


Link to post
Share on other sites
Yeah, we had that same design decision to make, "well all entitys are gonna need a position, so why dont we just put that in the base class" but in the end this project is one very big experiment (uni project, and are the first "team" to be doing it, its always been done seperatly as well as trying to get people from other courses (art, sound eng etc) to work with us) so we figured why not tackle another experiment at the same time, "Can we make everything out of interchangable components and have it work".

So far were going strong, but were very early on, the only thing that isn't a component at the moment is the Team that the entity belongs to, but afterall, asteroids in the background and the sun dont belong to anyone, so maybe this should go aswell.

As for the events when a property changes, this was one of the thins that clicked in my head as well, so I implemented an OnChange event so that components will be notified when the property changes.

Share this post


Link to post
Share on other sites
Quote:
I do think, however, that many who start adapting their engine/game to the component-based approach, don't focus enough on the problems they try to solve, or the flexibility that their game requires. The question of "optimal" solution or is this approach "efficient" is too commonly asked imo, because it all depends on the requirements of your project and the problem-domain your components are there to solve.
Agreed :)

Share this post


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

  • Advertisement