Possibility and Probability

A Python programmer with a personality thinking about space exploration

1 January 2006

A refactoring success story

by Nick

Today I decided to do something about a project that has been nagging me. I started write a game last year (or was it 2004? It was started a while ago at any rate…), but then I just stopped working on it for a variety of reasons. One of the biggest reason was that my design, while it sounded good in theory, wasn’t working out too well in practice. My idea was to make a Wasteland style RPG type of game that used a state machine to control the game. The idea worked pretty well in the beginning. I found a project that was similar to what I wanted to do, then adapted the code and put a state engine in there to drive everything. It worked well enough until I wanted to add in more features like events, changing maps, etc. Then the code revealed how convoluted it was. A lot if it is my fault, I’m still not in the “Python frame of mind” for everything I do, and that has made things more difficult. I checked around on the internet to see if anyone else was tackling a project like this and lo-and-behold there was. This site has a great little tutorial that pretty much covers everything I wanted to do, but done without an (explicit) state machine. Instead it uses a different pattern, the mediator. The mediator looks a lot like the observer pattern, at this point I’m not sure what the major difference between them is. At any rate, I had some time today so I set out to refactor my little game and see if I could drop in the mediator/observer pattern in the place of the state machine. Much to my surprise and delight, it was fairly easy to do. After about 3 hours or so of work I’m now almost at the same point (functionality-wise) that the original code was. At first glance it looks like I’ve streamlined my code base a lot and can eliminate a lot of extra code that was introduced to the system. The only downside I can see so far is it looks like the mediator/observer based code is inefficient in that every game object gets called every game tick. At this point I’ve got a pretty small number of objects, but the moment I get NPC’s and inventory items working I’m going to have to do something because that will introduce a ton of objects to the game world. Truthfully I don’t think it will be too terribly hard, but it is something to think about (the web page mentions this problem and has a few suggestions). The biggest and nicest advantage of this refactoring has to be the separation that has been gained. Before I was using global objects to try and keep everything in touch with everything else. Now each game object is its own little island, knowing about only those objects it needs to know about. This is really exciting for me, before I was dreading adding new things to the game world because of the work that was involved in attaching them to everything. Well, back to the salt mines, let me see if I can make some more progress!