Component Game System - Object Examples

Started by
17 comments, last by Zakwayda 14 years, 4 months ago
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?
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.



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.
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.
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.
Game development blog and portfolio: http://gamexcore.co.uk
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.
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.
I started collecting links to component based systems on my website. Some of these links may be useful to you.

Game Object Components and Entities
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
Game development blog and portfolio: http://gamexcore.co.uk
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
Game development blog and portfolio: http://gamexcore.co.uk

This topic is closed to new replies.

Advertisement