Silverball Studios concludes its two-part guide to the extreme game development methodolgy with some advice on fine tuning the approach.
Click here to read part one.
1. Test Driven Development.
This one takes some getting used to, but pays enormous dividends. Before writing a function in the game we make a little automated test that will check that it’s working. Once we see it failing, which you’d hope it did because we’ve not written the code yet, we write the code and watch the test pass. Hurrah. Or not, because often either the code or the test were wrong, but at least we noticed.
Once written that test keeps being run for the rest of the project. If ever your original code stops working – well, you know about it straight away, not when some unfortunate player tries it in several months time.
Writing good tests takes practice. You don’t want every change to a class to need a change to all the tests. We aim to test all our public functions, but trust the private stuff to do the work. In this way we only have to change the tests when we change the class interface, and it can implement the functionality any way it wants.
It’s important to know that automated tests do not replace QA and playtesting, but they make sure you’re building the system on solid foundations. Reported bugs are tackled the same way, with a test that exposes the bug first, then the fix. This makes sure it doesn’t rear its head again.
2. It Always Works.
Although we have polished versions at the end of every two weeks, we can take a working build at any time. We have a machine dedicated to building every configuration, and running every test all day every day. If your check-in stops it working, you fix it immediately. Build failure is subtly flagged by a booming proclamation from an electronic Brian Blessed we keep in the corner.
Bugs are also fixed as soon as they are found, taking priority over starting new tasks. This constant fixing prevents the large build-up of problems at the end of a project, and keeps our estimates accurate as bug-fixing time gets built into the schedule.
3. Don’t Repeat Yourself.
In code, this is just good practice. You don’t copy and paste code; you refactor into a common function. That way bugs are more likely to be noticed, and when they’re fixed in one place they’re fixed everywhere. It’s always worth taking the time to do something properly.
In wider development terms this means automating any donkey work. We have autocomplete, macros for many common operations, shell scripts for art and build processing and so on. The computer is wrong far less often than a bored developer.
4. Pair Programming.
XGD’s most unusual practice is to have programmers sitting next to each other at the same development station, working on the same task card. One has the keyboard ‘driving’, while the other is ‘navigating’ – a process that involves thinking about the design, fielding questions, spotting mistakes, using the devkit for testing, finding advice on the internet and so on.
Pairs swap roles frequently, with one developer writing a test and the other writing the code to pass it. During the day the member of the pair who isn’t signed up for the current task will swap onto a different task, so developers also move around the room.
Although this may seem like it should reduce productivity, it provides many benefits. Code has to be clear enough to be understood by another person, and many bugs at the design level are caught before the cursor leaves the edit line. It is slower to produce code, but having at least two sets of eyes look over everything means that you rarely have to come back to it later. You also don’t hit a wall; There’s always someone with fresh ideas and a new perspective that can get things moving again.
With each coder on every task, knowledge of the whole system percolates through the group. This stops duplicate code being written, and means that work can always continue through illness or holiday.
Artists also perform pairing, although of a looser kind where they share a desk so that they can see what the other is doing and get advice if needed.
All these techniques reduce our level of wrongness, and so our risk. The game is on time and on budget because you can always stop when the deadline arrives and it’ll be working. It might not have all the features you wanted, but those you do have will be of production quality, not rushed for a deadline.
A subtler, but useful benefit is improved developer confidence and morale. Progress is visible, tangible. You know you’re going to hit your ship date.
You know the change you just made didn’t break the game. It can actually be played almost immediately, getting better story by story. Good ideas can be added at any point in the process. Involvement in the planning process gives a sense of empowered control, rather than detached helplessness. For similar reasons, the publisher is happier. They can see the game make progress and actually play it. Corrections can be easily incorporated. The game will be ready on schedule, and there are no nasty surprises.
Sounds like it’s perfect.
Well, it is good, and it’s the first system I’ve used as a developer that feels like it was made for software, not circuits or bridges. However, there are some drawbacks. Some aspects of games are just very difficult to write tests for. How do you reliably and quickly test that a random element in a feature is working? Brrr. Still, having some tests is better than none, and it’s important to remember that you still need QA, it’s just that they get to find the interesting bugs not the basic stuff.
Also while it’s a highly efficient system for developing software, other important jobs such as coming up with new game ideas, or creative tinkering with better ways of doing things will be missed unless you explicitly schedule time for them.
During ‘dead’ times, like a long re-compilation, you generally talk to your partner, rather than browse newsgroup discussions or the web. While this is admirably sociable, you can also lose awareness of the wider world.
Scale is also a question. There are a dozen of us in our team, and we all work in in the same (admittedly large) room.
It’s very easy for each person to interact with everyone else. Because we swap pairs at least twice a day, it’s easy for everyone to have a good idea what’s going on in their own discipline, and a fair idea what’s happening in the other.
I doubt it would work well if there were two-dozen or more of us, or if we were spread across multiple locations. In such a situation it’d be better to parcel up jobs into chunks, then use the XGD method on the smaller sections.
All told, I love developing with XGD and I’d find it hard going back to the old hack-it-and-hope, or plan-then-ignore techniques.
I’m still wrong a lot – we all are – but at least I know that it can be put right, and at the end of the development cycle I know there’s going to be a good game because I’ve already played it.
Image: DipDip Blog