Sign in to follow this  
samgzman

Component based game object system implementation

Recommended Posts

A long while back, a Game Developer magazine article discussed a game object system that was component based. It has been mentioned a few times in the past on these forums, but not much has ever come out of those posts in my opinion. Basically, the main idea of the component based approach is to place the responsibilities of a game object into discrete component classes. A game object then consists of a collection of these components. Its really just the preference of composition as opposed to inheritance This strategy avoids many pitfalls that occur with deep inheritance hierarchies, such as the so called "blob anti-pattern" where too much data and functionality exist at the near-root levels of the inheritance tree. It also can help avid the "diamond of death" inheritance trap if used in a clever fashion. Also, its very powerful to be able to define entirely new game object types by unique combinations of components. It seems the general opinion is that such components should be as independent as possible, but this is only reasonable to a certain point. If the components are totally independent, then how can they collectively contribute the overall game object in a useful way? Obviously, some sort of inter-component communication scheme is needed Sometimes a component might only need to simple notifications to other objects, sometimes it might need to make requests, and sometimes a significant amount of data needs to be moved/copied. I wanted to get a good idea how other people have implemented such inter-component communications, or how they might go about solving the problem if they were to implement such a system. My current approach is to maintain a mapping of interface identifier to component object in the game object container. Component interdependencies are handled by allowing an object to request the appropriate interface from the game object container and directly interact with objects. This strategy is pretty lame though. It doesn’t allow multiple component objects to handle generic events such as when a game object moves. But this event might only be meaningful if the Position_Component is a part of the game object. In short, how can components communicate when the recipients of messages are unknown to the sender? One idea i had recently might be to have a mapping of message type identifiers to a list of functors (objects that serve as high level function pointers to object methods) in the game object container. Objects would be responsible for registering a functor for each of their event handlers with the parent game object container. On their destruction, they would need to unregister themselves. Each component object would be tedious to write in such a system unfortunately. Anyone have any thoughts or ideas?

Share this post


Link to post
Share on other sites
The way I've got mine working is that there is one central data manager. As each component gets initialized, it registers whatever data-types it uses with the manager. (For example, the graphics component might register a geometry data type, an image (texture) type, and a drawing surface type)

What happens is that the component passes an example of the data type to the manager. If another component has already registered that type, the manager returns a pointer to the existing type, otherwise it will create a new one.

This way the individual compontents don't actually have to communicate, they just each access and deal with whatever data types they need to, completely blind to what other components might be doing with that same data.

If the compents have to communicate between themselves, they do so via a datatype called message (which at this point is just a string and an int to idendify where the message originated)

Share this post


Link to post
Share on other sites
Quote:
Original post by methinks
This way the individual compontents don't actually have to communicate, they just each access and deal with whatever data types they need to, completely blind to what other components might be doing with that same data.


That sounds like the antithesis of encapsulation.

Having fairly shallow inheritance trees for the components that share data would probably be a better approach.

Share this post


Link to post
Share on other sites
Samgzman: Your proposal sounds pretty much equivalent to a message based system in which components can decide which messages they are able to recieve, is this the case or is that not the whole of the idea?

Personally, I think inter-component communication should be a combination of messaging (/events) and requesting/using interfaces to specific components. The former allows general communication in an extensible and flexible manner, and the latter allows more complex things to go on, though I'm undecided as to whether or not this is proper encapsulation or not - it seems unlikely. For an implementation that uses these two methods, see GPG5, there's a rather excellent article on component systems in the first section.

Edit: also, does anybody know how I can get a hold of the Game Developer article? I don't fancy having to shell out for the whole magazine, I'm on a very tight budget being a student!

Share this post


Link to post
Share on other sites
Quote:
Original post by hymerman
Samgzman: Your proposal sounds pretty much equivalent to a message based system in which components can decide which messages they are able to recieve, is this the case or is that not the whole of the idea?

Personally, I think inter-component communication should be a combination of messaging (/events) and requesting/using interfaces to specific components. The former allows general communication in an extensible and flexible manner, and the latter allows more complex things to go on, though I'm undecided as to whether or not this is proper encapsulation or not - it seems unlikely. For an implementation that uses these two methods, see GPG5, there's a rather excellent article on component systems in the first section.

I'm sort of thinking of this too, after reading a couple of master's theses on game engine design.

Here's the idea I've got in my head:


Any inter-process communication is done by "dropping off" messages for a certain task, which is later picked up at any time. That way there's no stress to always have to respond to messages, which could potentially be beneficial.

It works sort of like enginuity, in which there's a spoke of tasks that the game engine iterates through and runs, and then each task manages it themselves. One of the big benefits here is that you could probably implement a scripting language that just "forges" messages coming from different modules, and thus have some sort of flexibility.

One of the big problems is the overhead of message passing (e.g. picking up only the ones that Audio Player cares about). But it seems like it could be very scalable, and potentially multithreaded provided access to the data object is mutexed properly.

The biggest benefit for me is separating code from data finally; this'll make it easy as hell to just serialize the huge-ass "game state" data object at once.

Share this post


Link to post
Share on other sites
Quote:
From Samgzman: "how can components communicate when the recipients of messages are unknown to the sender?"

Quote:
From Hymerman: "pretty much equivalent to a message based system in which components can decide which messages they are able to recieve"

Quote:
From Ravuya: "One of the big problems is the overhead of message passing (e.g. picking up only the ones that Audio Player cares about)"

Sorry if I haven't understood the whole thing, but aren't you talking about the almighty "Observer" design pattern? I use it, but I've changed it a bit so that the observers/subjects unregister themselves (dangling references no more), and it could be templated.

Bye!

Share this post


Link to post
Share on other sites
I've gone with the event messaging approach. Each game object component is given a chance to register which events it cares about with the game object container. This works by giving the game object container a collection of event ID and functor-to-component- event-handler-method pairs. The game object maintains a dictionary of Event IDs which maps to lists of registered functors. Firing an event is then simply a matter of iterating through and called each functor.

Right now, messages are simply forwarded straight through on-the-spot instead of added to a queue of events for later processing. Since these event system are fairly small and isolated to each game object, I don’t think marinating a queue per game object is worth the trouble.

Quote:
From MajinMusashi: "Sorry if I haven't understood the whole thing, but aren't you talking about the almighty "Observer" design pattern?"

Yes, its definitely the observer pattern, but with a bit more abstraction than the traditional approach. The functors are used to allow runtime binding of events. I can now even bind the same event handler to multiple different event types. Its pretty flexible. I guess I’ll see how far this takes me.

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