Refactoring

Since I’ve spent so much time on exciting new tech recently, I decided that it was time to buckle down and do some of the less fun work that’s been needed for a while, improving the code which I’ve inherited from MMORPG Tycoon 1.1, and which it in turn inherited from version 1.0.

It’s important to note that version 1.0 was written for a game writing competition, which had only a month to complete the game.  And while I had already created several games in far shorter periods of time than that, MMORPG Tycoon 1.0 was a massive game, and so I was taking any shortcuts I could make, in order to implement it as quickly as possible.  Often (or usually), this meant trading away clean, maintainable code, in favour of simple approaches that I could churn out in a short period of time.  Much of that old code is still in the project, only getting worse as time passes.

So from time to time, I go and try to rip out the bad code, and re-implement it in a nicer way.  Programmers call this process “refactoring”;  it’s not a fun process or an easy process, and when you’re working for a company, management usually doesn’t see the benefit of doing it at all.  It takes a lot of time and brainpower, and there’s no externally visible benefit from having done it.  But if you don’t do it, then the codebase slowly rots from the inside, becoming more and more unpredictable, fragile, and inconsistent over time.  As unpleasant a task as it is, it’s a big time saver over the long term.

The last few days, I’ve been refactoring how many of the player’s game design settings are stored.  In MMORPG Tycoon 1.0 (and later in 1.1), these settings were stored together with the code which drew their UI screens.  For example, when the game’s combat engine needed to figure out the chance that a particular character would be able to hit a particular monster, it had to talk to the UI screen for the character’s class, and the UI screen for the monster’s class, and also the “General Design” UI screen in order to retrieve the necessary values.  This was convenient for rapid development, but isn’t very flexible at all, so I’ve been working to decouple the data storage from the UI code.  It’s slow going, but worthwhile to have done.

The other nice thing about this type of “clean-up” task is that it gives me time to reflect about the next set of game design choices that I’m going to be confronting.  At this point, I have most of the design for MMORPG Tycoon 2.0 worked out;  there are only a few little niggling details that I’m still kicking around.  The one I’m thinking about at the moment is how (and whether) to allow the user to perform within-a-region terrain editing.  There are a few options.  I could let the player draw directly onto the terrain height map, which would give a lot of freedom to build terrain precisely how you like it, but would completely rule out the possibility of ever being able to share your maps with your friends over the internet (save files would be far too huge), or otherwise let others see what you’ve been doing.  I’m not planning either of these features to be in MMORPG Tycoon 2.0, but they’re at the very top of the list of features that I’d want to have present for a future version 3.0 release, and I really don’t want to have to remove a 2.0 feature in order to allow people to share levels in 3.0.

Alternate options include “no within-region terrain editing allowed” (which I don’t like).  Another option would be “placement-based terrain editing”, which would have the user placing “terrain” objects on the map in the same way that he places buildings, to create terrain features.  Imagine placing a “Mountain” object or a “Forest” object, and having a mountain range or a vast collection of trees spring up around it.  Another option would be to subdivide each region into many smaller districts, in the same way that the world map is currently subdivided into regions, and then allow the user to choose features for each of these regions, in the same way that he now selects a level range for each region.

I’m not really convinced yet;  I’m still weighing up the options.  But I’m currently leaning toward subdividing into districts.  Those districts would also be useful for improving AI pathfinding and a few other little tasks.  Anyone have other thoughts/preferences?