Wednesday, August 05, 2009

Major refactoring

I've just pushed a major refactoring I've been working on the last couple of weeks to the master repo. In the end it turned out really well.
The main part of the refactoring was to totally revamp the whole entity hierarchy in Ember, and how the entities are tied to graphical Ogre representations (meshes, lights, particle systems etc.). As with most refactorization, I had made some assumptions about how things worked a couple of years back which didn't hold anymore, and the code was beginning to creak from workarounds and special cases.
One of the assumptions made was that all entities in the entity hierarchy tree would be represented as an Ogre scene node. Another was that all graphical entities would be shown using the Model class. As one of our GSoC students, Amey, began to implement his task and needed some client extension for this it became apparent that these assumptions do not always hold. It's not always certain that an entity will be arranged in the Ogre scene graph through the use of a scene node. The most common instance is when something is attached to a skeleton (like a person wielding something). In addition, there are many kinds of entities which need graphical representation, but not through the use of a Model. In Amey's case it was the ocean.
Furthermore, when I first made the entity class system I used inheritance, so that each different entity would be of either just a normal EmberEntity class, or a PhysicalEmberEntity class, depending on whether it had a graphical representation in the world. However, as I work more and more with software I've come to realize some of the issues with depending too much on inheritance. Instead I now more often find myself component based design. In such a system the behaviour of instances are mainly determined by the interactions between the components that make up them. This of course leads to more complex systems, where it's a bit harder for a newcomer to get the full picture of how any given part should work. But it also leads to much more powerful systems, without many of the incorrect inheritances one tend to end up with when over using inheritance.

All this lead to me totally redesigning the entity class system. There's now only one entity class (well, except for the world entity, but that is a truly unique instance). The way something is shown is now handled completely separate in a graphical component, owned by the entity. And the way it's arranged in the Ogre scene graph is also handled by another distinct component. The end result is that there's now a much more robust system in place which more correctly maps how things really are arranged. This means that we now have a much more cleaner design, which is also extensible enough to handle more advanced cases than the previous system could. I've already pushed code which will connect an ocean entity to a water representation, something which in the old system would have required all kinds of hacks.