By Kyle Wilson
Wednesday, May 29, 2002
I'm all about data-driven design. How much about data-driven design am I? I don't think a game engine should contain a single line of game-specific code. Not one. No hardcoded weapon types. No hardcoded HUD layout. No hardcoded unit AI. Nada. Zip. Zilch. I'm pretty inflexible in this regard.
There are two reasons why I'm such a hardass about keeping things data-driven.
The first and more sweeping reason is that once a game has shipped, its code tends to be reused for subsequent titles. Unfortunately, it takes a lot of understanding on the part of management and a lot of restraint on the part of developers to scrub the game engine of all its assumptions related to the old title; most teams would rather just launch wholesale into new development immediately. That's why the player input system was named PlayerF22Control for most of the development on I-Magic's F-18 game and why I suspect that Neversoft's Tony Hawk 3 still has a character class named CBruce.
Class names are, of course, simultaneously the most obvious and least important aspect of old code pollution. They'll confuse new hires, but they won't break anything. More troubling is all the functional code that's left lying around never to be executed. It bloats the executable, it makes it harder to find the function you're looking for, and it leaves everyone unsure when to invest effort in making sure something still works and when to just let it lie. Eventually, code will become so bloated and unwieldy that it's impossible to maintain, and everyone on the team will start talking about how much things need to be rewritten from scratch.
It's easier just to not let all that crap in your engine in the first place. Try to abstract out game functionality. Put it in data files. Put it in script. If you absolutely have to for performance reasons, then add hooks to your engine and put it in DLLs, but for heaven's sake don't let game code get tangled up with the core engine code that's going to take your company from one project to the next for years to come.
The second reason to prefer data-driven design is comparative advantage. A group of people will produce the most, for the least cost, when each member of the group performs the task for which he is, relatively, best suited. Heinlein was wrong. Specialization isn't just for ants. It's for anyone who wants to get things done and doesn't have ten lifetimes in which to do it.
In practice, we don't run into many multi-classed characters in game development, so usually you don't need to worry about relative skill. Advantage is usually absolute. For example, I am the world's worst artist. I am a dark, dreadful sinkhole of artistic un-talent. But I'm a pretty decent programmer. If my company hires another guy who's also decent at art, it doesn't make sense for him to ever write code. It wouldn't even if he were as good a programmer as me, but in the real world, he's almost certainly not. The best use of the other guy's time is to produce as much quality art as possible, and the best use of my time is to code.
When important game features are hardcoded instead of being stored in editable data, one of two things happens.
- One, the coder finds himself acting as artist/designer, choosing parameters and tweaking effects in the code. This gets you a guy performing a task other than the one he's best at, which in turn gets you poor features implemented slowly.
- Second, the programmer finds himself acting as a tool, making changes, fetching an artist or designer to observe, getting feedback, and iterating for the desired effect. This will get you decent features implemented even more slowly. Everyone does his job, but the increased overhead adds so much friction to the whole process that the programmer is bogged down and can't implement as many features, and the artist/designer gets fed up and lets the feature go before its the way he really wants it. The whole game slowly subsides toward mediocrity in a thousand cuts.
Ideally, everyone should do the job for which he's best suited. Programmers should write code, artists should make art, and designers should create compelling gameplay. When anyone is doing someone else's job, or is slowed down by poor tools, or is waiting for someone else to be free to evaluate a feature, time and money are being wasted and the game suffers as a result.
Comparative advantage is a less compelling argument than re-use for data-driven design because it calls for evaluating, for any feature, the cost of hardcoding it versus the cost of exposing an abstraction with editable parameters to the designers and artists. These costs are hard to measure precisely and harder to predict, but are affected by
- The complexity of the tools with which parameters are edited. (Do you read a text file or offer a whole UI?)
- How parameters will be adjusted in tweaking look or gameplay. (Almost certainly more often than people expect, in my experience.)
- The extent to which a feature requires a programmer to act as an artist or designer.
The re-use argument, on the other hand, merely requires you to measure the cost of exposing a data-driven implementation of a feature against the cost of scrubbing the feature from the engine later. From what I've seen, though, code scrubbing becomes extraordinarily difficult very quickly as programmers constantly add new code building on any and all existing code, even that which is flagged for later removal. It might be easier to keep later code from depending on game code in a well-levelized engine, but that kind of structure should make it even easier to strip game code out into DLLs completely, too.
I'm Kyle Wilson. I've worked in the game industry since I got out of grad school in 1997. Any opinions expressed herein are in no way representative of those of my employers.