Sunday, June 11, 2006

More on composite vs. inherited game objects

Hello again,

I will continue the interview form post I started last time soon. But since then I have been asked a few interesting questions about engine development in the JavaGaming.org forum so I will post an answer (at least part of it) here.

Here is the question that was posted (unedited):

The one that particularly got my attention was ww.gamearchitect.net one with the 3 series on scenegraph objects and such. It seems to me that most, if not all, of his concerns stem from bad design. For example "The Diamond of Death. What do you do if trigger objects are derived from game objects, and dynamic objects are derived from game objects, but you want a dynamic trigger object?"

Why would a trigger be in the same group as a mesh or a skinned character? Technically, they are both "game object"(s); your just costing yourself unnecessary overhead...

In the second GameObjects blog/article, he says "Using a directed acyclic graph instead of a tree, you can share objects and animation state across multiple locations in your world" which only begs the question, what is the difference between a directed acyclic graph and a tree? Conventional trees *are* directed acyclic graphs from what I have understood.

"You'll have the same problem animating control points for higher-order primitives. Height fields, lights, volume fog and shadows are similarly likely to end up being awkward special cases.". Those seem to fit quite elegantly in the scheme of things from what ive read and seen...

Apologies if it seems like ive put his blog/article under a microscope, but Im in the middle of making my own game engine and I thought i had the scenegraph element well and truly finished Smiley

PS. the reason I got Java involved in this because he mentions multiple inheritence in a few places

And now my response...

As mentioned in the opening of the forum link I posted, try to get a hold of:

"In the latest GameDeveloper Mag (March 2006), there was an article by Mick West titled "Evolve Your Hierarchy: Refactoring Game Entities With Components"....."

The article was one of the best short pieces on what I am talking about and what can be done.

The component model doesn't really have anything to do with a scene graph (at least not directly) or Java. I use Java3D, which is a scene graph the rendering system, but my game objects are composite "groups"(the whole game object thing kind of gets blurry in the component model which is one reason why developers can be resistant to it). Of course there is some inheritance, you have to have it at least for consistent abstract object handles, but what you think of a "player" is no longer a game object type or even an object and behavior objects. It's a lose collection of components that do small independent parts and often don't even know about each other. Inheritance (and multiple-inheritance are not used and/or needed).

But I think the major different from a programmers perceptive is this; the game object (player, item, whatever) is not a class that is made in code at compile-time, it is a collection of run-time connected components. The compile-time vs. run-time change is felt the most in code since you can no longer go look up your player class and mess with it. You have to think differently about how to make objects and things happen.

The other reason for doing this is not obvious until you have a large enough game with inherited game objects and you start having difficulty deriving new types. With the component model you can "derive" (or in this case combine to form) new types at run-time, or load time, or and here's the real concrete direction for this, with scripts at run-time (or from a GUI tool that makes scripts and/or configuration files). That is the real key because as the inheritance system grows it gets heavier and heavier and slower, like quicksand, to develop with. It's a strange paradox as you have more capabilities in your engine it gets harder to use them (and this is especially true for a game logic programmer working atop this mess).

The component model (when done well) gets back development speed and versatility as well as adding in new run-time capabilities.

How exactly does it get back development speed and versatility? The short answer is it just does. The long answer will have to wait for another day.

3 Comments:

Blogger Len Bullard said...

"...as the inheritance system grows it gets heavier and heavier and slower, like quicksand, to develop with. It's a strange paradox as you have more capabilities in your engine it gets harder to use them (and this is especially true for a game logic programmer working atop this mess)."

Good observation. Capability is like intelligence: it doesn't scale in the sense of applying or reaching to more and more classes. Exactly the reverse. That is why XML is Just a Syntax, HTML is just a bunchaRenderingObjects, and most of what is in a browser's navigation system should have been operating system capabilities (See MAC 86). As more methods are acquired, it begins to resemble an attractor in a dynamic system and as events approach it, they slow down. Weird eh.

Object = Thing. About as meaningful and about as useful.

Dynamic domains or clusters in topical vector models is one way out.

Good luck with DarkStar. Cool stuff.

8:47 AM  
Blogger Mike Nelson said...

I just wanted to say, you've got good observations here, Shawn. I've thought a lot about this problem too, and I agree with you on all your points. The component object model is one thing that I'm using in my new game for all these same reasons (probably will start implementing that part this coming week, the project is just spinning up).

Loosely, I sometimes think of this paradox like this, the more well defined an engine is the more it describes what it's not and it's hard to tell something to do something that it says it can't do.

10:03 AM  
Blogger Mick said...

Old discussion I know, but my object component article is now online at

http://cowboyprogramming.com/?p=30

11:01 PM  

Post a Comment

<< Home