Sunday, September 10, 2006

Subversion Broke my Code!

Well, that’s not entirely true! The introduction of Subversion highlighted a problem with my code! In the last week I’ve been going through all of my existing source code and getting it into the Subversion repository. At the same time, I have migrated from Visual 2003 to Visual 2005 so I had to carefully ensure that everything still built properly. Nothing did; I had to change all of my projects.

The largest and most important project I have is called Morde and was my 3rd year project for University. It is a system for creating, hosting and playing online multiplayer RPG games. I was originally intending to continue work on that as my ‘pet project’ but decided against it for a few years. Still, there are a lot of similarities between Morde and Mod Wars so I certainly want to make sure that Morde is building and running properly.

I had to do quite a lot of work to get it working, mainly because the Gui library that I used for it no longer worked under VC8. The good news is that they had released a VC8 version, the bad news is that they had also updated the library (it’s a good thing really, just inconvenient for me at the time) and the changes broke all of my Gui code so I had to fix all that in the process.

However, I’ve still not mentioned how Subversion broke my code too! When a game session is running in Morde, the server application persists the state of the game world to disk on a regular basis. This data is reloaded to continue a session at a later date when the server is restarted. Subversion operates by putting a directory ‘.svn’ in every subdirectory under source control. In my code, I naively thought that because it was my code that created this particular directory structure, that I could make assumptions about what should be in it. I had a loop that loaded all files in the player directory and just to create players out them. The .svn file did not make a valid player and an exception was thrown! Bad, bad code!

Lessons Learned...

I learned two important things during this exercise:

1) Shield your code against changes to third party libraries

When you have to rely on third part code that you are not in control of (such as a third party library), try to minimise the impact on your code from potential changes to that library. This is the design principle “find what varies and encapsulate it” in action. In future projects I will highlight every third party library in use and in Mod Wars there will be several – graphics library, GUI library, XML library, Networking library and probably more. For each library, I will do my best to ensure that the code that calls into these libraries will be as encapsulated as possible, ideally in just one class.

That’s trickier to do on a Gui library that typically impacts a large part of the application but then the solution is to use another abstraction mechanism that at least treats the Gui as a separate layer of its own. In fact, I had such problems finding a suitable Gui for Morde that I have already tinkered with some designs for enabling the Gui to be completely switched out to an alternative one. Another reason for this is to allow me to create a fake Gui that isn’t even graphical but allows me to make a scripted Gui to help with testing, but that’s another story.

2) Don’t make assumptions about things beyond your control

The Subversion issue was purely the result of lazy coding and it was a very silly mistake. Who am I as a programmer, to make assumptions about files in the operating system? It’s not only possible that the directory structure will get changed but the possibility is really quite high! There are all sorts of programs that add files to a directory, and don’t forget the operating system itself! So when coding Mod Wars, I’ll always be thinking to myself, “What assumptions am I making here? Can I be sure that my assumptions are correct?”

No comments: