Saturday 29 August 2009

Scene graphs? Yuch!

So one of my friends has been nagging me for some time to start on the graphics library I have been planing on writing for a few months now. Always had other work I needed to do first. But now I'm all done with that, and I can finally start on it.

I was thinking about how the scene system would work, and how different behaver would be added to different entities (ok, that's more an overall engine design point, rather than graphics, but meh), and I can't for the life of me figure out why so many people try to do this through inheritance. It's like the idea of inheritance has been so ingrained in people as A Good Thing, that it's heresy to do anything else.

But it makes things so hard. Imagine, say, you have a DrawableEntity class. From this you inherit a NpcUnit class. Now you want to add some AI. As you probably want all NPCs to have some AI, you could stick that in between Drawable and Npc. Alright so far.

Now lets say you have a door, which you make inherit off DrawableEntity.
One of the characters in your game is a talking door. It has the characteristics of a door, and it has AI. What do you do now? You could have Door inherit from AIUnit instead, but now all doors have AI..

The solution is to use composition. Have an Entity class, which contains a collection of EntityComponents, each of which represents a piece of functionality which you want to add to the entity.

As I was searching the net for what other people had done with this, I stumbled upon a post from Nick Gravelyn, in which he talks about such a system. Except that in his implementation, any components which have properties which return another EntityComponent type, his entity will automatically hook it up with an instance of that type if it has one available in its components collection.

I loved his implementation, and decided that I would use that, but with one addition.

As I was thinking about how my graphics library would handle the scene graph at the time, and how so much of a bad idea scene graphs are, I thought I would modify Nicks entity system so that it could fully operate as a scene graph replacement.

All that needed adding was the idea of each EntiyComponent type defining a manager to manage its instances. For example, when a PositionComponent is added to an Entity, the entity will stick the component into a manager dedicated to managing PositionComponents. This manager could implement a tree to show parent/child spacial relationships (like a swords' position being relative to the players' hand). On the other hand, a StaticDrawableComponent would register itself with a manager which places it into an octree, for efficient visibility determination.

And there you go, we are no longer trying to stuff many entirely different relationships into the same, messed up convoluted, tree.

1 comment: