August 11, 2007
Rethinking the rendering code
Due to the category system in WordPress I’m trying to keep to one topic per post. It’s time for a software design related post.
During the week I have been spending some time doing some preliminary work for Ice Slider. To start with, I have taken the current code base and attempted to emulate some of the features I had running in the now obsolete prototype I had last year.
However I’ve quickly reached a snag with the text rendering. Last month I was experimenting with a scene graph like method for grouping sprites so they could be manipulated in logical groups. However I had failed to fully integrate it into support code such as that used for displaying text. After spending some time away from the code it’s painfully obvious that the graphics system is starting to fall apart with the tacked on upgrades; it’s in clear need for an overhaul.
After putting some thought into how I’m going to implement Ice Slider, I think my current approach for handling graphics is fundamentally flawed. The present system I have is very encapsulated; game modules can register a handle to create and manipulate a sprite, but they don’t interact with the graphics module directly, not even to handle render commands. It’s all handled internally by the graphics system, which keeps its own internal representation for the sprites hidden from other code.
It’s all very nicely protected, but it only makes sense for games which have a lot of persistent sprites. For the majority of 2D games this isn’t the case; tile based games like Ice Slider often only have a portion of the screen showing, and it makes sense to only convert the portion of the tile map shown to sprites. I can bend my current system to cope with this, but it will either break the point of the paradigm or be needlessly inefficient.
As a consequence I’m leaning to moving the graphics pipeline back to the traditional methodology where the game modules contain render functions that are called whenever the screen needs to be redrawn. At the moment I’m still trying to jot down the basic approach I’ll be using. The tricky part is that with a 2D graphics engine you need to ensure that the sprites are drawn from back to front, otherwise the alpha blending will be broken. I’m fairly sure that the best way to do this is to have an interface layer within the graphics module which stores the coordinates of the sprites to render, and performs whatever sorting and operations necessary before passing the information on to the graphics card via OpenGL. For now I don’t particularly care exactly what the graphics module will do with the data - that’s easy to change - but getting the interface sorted out is important.
I’ve also spent too much time reading about scene graphs, as I’m still keen on using them as the basis of 2D objects. It makes a lot of sense to group objects within the system, with each child specifying its coordinates relative to the frame of the parent rather than the universal world coordinates. I have a copy of David Eberly’s game engine design book, which goes into his system in detail, but it seems like overkill for my needs.
I’m hoping soon to have jotted down enough ideas to build together a hypothesis of a decent way of approaching the whole sprite and game object code, so I can prototype it with Ice Slider. The key thing I have to remember is not to get too sidetracked into irrelevant extra features, since chances are I’ll need to revamp the whole thing again for my next game.