Improve your build process in 5 days

5 days ago our build system was rather traditional, not to say old school. We had a one-click full build, but it was executed manually. Usually about 1 build per day, sometimes more often, sometimes more seldom, it depended on the number/importance of changes. I’ve been thinking about improving it for long time, but never really could force myself to actually try it. Finally, about one week ago I decided it’s really high time to give it a go.

One of the reasons we couldnt be arsed to try it for so long is that we work with this huge legacy codebase (*cough*check our site for details*cough*). Test coverage of our source code is, let’s say, minimal. I wanted to try Continuous Integration, but it doesnt really have many advantages without at least some kind of automatic tests. After some research it turned out that it’s not that hard to create simple functional tests driven by scripts. I only had to add NSS function for terminating application with error code, basically. This gave me some hope and made me download basic CI software. Bear in mind that most of this work has been done in “free” moments, because at the same time I’ve been working on economy/shops system for The Witcher.

Day 1: I download CruiseControl.NET, Automated CI server and NANT (.NET based build tool). As far as I can tell, those are the most common applications, but frankly, I had no time to do a proper research. I install both systems and after some time manage to force CC.NET to get source from VSS. CC.NET is only responsible for getting source, launching NANT and generating final report. Sadly, I couldnt make NANT to work with MSVC 2005 solutions directly, so I made it to execute devenv.com. First important note here: it’s funny, but if you use devenv.com, NANT can intercept its output, if you use devenv.exe - it doesnt work.

Day 2: I create first functional test. It’s based on a bug I was fixing at this time. There was an error in our quest system, upon quest completion, player always received only 1 item, even if designer specified more in the quest editor. The test launches dialog-based quest (it completes after dialog is done) and after that checks if player has valid number of items, then exits (reporting error if needed). Seems to work nice.

Day 3: I add the possibility to start game with arguments. One of the possibilities is to launch game, then automatically load and run specified level (for example our quest test). I also finally manage to fix our record/playback system. I’ve been working on it some months ago in my spare time, but never really finished it. Now it turned out it only lacked some finishing touches. I wouldnt trust it when it comes to recording demos or even reproducing subtle bugs, but it should work fine for setting up simple scenarios. First test is player opening door and moving to another module. Works! I had 90% of code ready, otherwise it would take longer than 3 hours.

Day 4: Another exe switch - you can tell the game to load & run specified file with recorded input. We also have system for reporting errors. So, every time game crashes for any reason, it fails a test automatically. I also make a NANT task, which mails errorlog to us (normally it can be triggered by the user from error window, but I wanted to make it automatic).

Day 5: I put it all together. CC.NET gets code from VSS and runs NANT. NANT rebuilds the source, grabs latest data from SVN, runs tests and sends error logs (if needed). So far we only have very basic tests: quest test I mentioned before, module reload test (it tries to reload module several times, we used to have often crashes here) and simple record/playback test. It may not seem very impressive, but it’s a base, from here we can move on, add new tests. Whole system is not ready yet, so far it runs on my work machine, so builds are done 2 times per day, before I go to lunch and just before I leave the office. I’ll set it up on some free build server soon. I’ll also make the other guys to install CCTray application (status of the latest build in your tray, so that you dont check-in when build is broken). For companies working with new source, with funky build systems and 99% tests coverage it’s probably nothing earthshaking, but I’m really satisfied with the results. I already feel more comfortable with check-ins and I hope it’ll improve our build stability. In fact, this article is aimed at developers who are in situation similar to ours. I hope it shows that it’s perfectly possible to bring your build process to a whole new level with relatively little amount of work. However, I’d recommend trying it even if it would take much more time. I must admit I havent been so happy with non-game related code since I coded that error-reporting system I mentioned above. It doesnt have direct impact on game, but it improves work comfort of the whole team.

Articles/resources