Earlier this year, a small hunting simulation called Deer Hunter shocked the industry by rocketing to the top of the sales charts for three months. Presently, it's still selling well and shows every indication of continued good sales. While most hardcore game players stick up their noses at such value-priced games, the truth is that there's still a huge untapped market of computer users who do little with their PCs but write letters, send e-mail, and play solitaire. Death rays and world conquest hold very little interest for them, and they're still waiting for a game they'll enjoy playing.
Although I'm not inclined to debate the merits of games such as Deer Hunter, let me at least point out a few facts regarding the game that might help to tip the balance of opinion in its favor.
It's this last point that I really want to focus on, because it is one of the more interesting aspects of the game, the remarkable sales notwithstanding. How the game sold after it shipped was a shock to everyone, including us, but the development cycle was something that was controllable. At this point you may be saying to yourself, "So what if a small game such as this was written quickly? The product I'm working on is much more complex, has many more features, yada, yada."
This could very well be true. However, many of the lessons learned in a compact development cycle can be applied to any sort of game development project. I've had the opportunity to analyze and fine-tune our development process through five games in one year. Even if a project is expected to require a year and a half to complete, the same strategies can be applied to individual milestones within the project, or even to project components over a much longer period. The techniques don't necessarily have to be used to speed up development, either. They can just as well be used to get more from your existing timelines.
In this article, I outline some of the salient aspects of our development cycle. Some of the points are undoubtedly common sense, but all too often common sense gets ignored in the face of tradition or other external pressures. Other points, however, fly in the face of conventional design approaches. While it's true that not every project could or should attempt to utilize some of these principles, the fact remains that, using these techniques, Sunstorm rapidly produced hit after hit in quick succession.
Lesson 1: Don't Over-Design
It's better to keep the game plan simple and understandable. You don't necessarily have to code the entire game on paper. I've found that the most important aspect of the initial design lies in clearly delegating responsibilities for the project components. Instead of delving into the inner workings of how individual components are going to work, focus on how the major components are going to work together. Again, these don't necessarily have to be completely set in stone. Rather, let the programmers who are dealing with those components work with each other to figure out how their components should communicate. Because they are the only ones the problem affects, it makes sense that they should facilitate the solution, both in design and in code. As long as their solution is solid and well documented, there's no reason to involve other members of the team in the decision process. Planning by committee in cases such as this is both unnecessary and inefficient.
There's one caveat to this technique. One instance in which it does not pay to skimp on design is interface design. Over the course of three projects, I've learned that time spent carefully mocking up all the game screens helps tremendously as a reference for both the programmers and the artists during all phases of development.
Note that I'm not talking about a complete graphical mock-up. I'm referring to a functional mock-up. I use CorelDraw to roughly position all elements on the various screens. I print each screen on a separate page. I label all buttons and explain their functions. I make no attempt to create an aesthetically pleasing screen. The artist's job is to arrange and beautify the various controls except where noted on the document.
A solid interface design not only helps to solidify the flow of the game, it also frees those responsible for its implementation to begin coding and illustrating while the finer points of game play continue to be debated. As the game evolves, this document is updated to reflect the latest changes.
Lesson 2: Don't Be Afraid to Design Dynamically and in Parallel
The original idea for Deer Hunter was actually simpler than what ended up on store shelves. I joined Sunstorm in May of 1997 with a rough idea of what I'd be working on, but no real knowledge of hunting. My first assignment was to design a deer hunting game. You might imagine how thrilled I was at the prospect of designing a game based on a "sport" that consists mostly of sitting and walking around in the woods for hours on end, waiting for a passive animal to show up so you can shoot it.
The initial game idea wasn't much more than many of the other hunting titles seen previously - that is, blasting a deer when it happened to meander across your path. As development progressed and I became more knowledgeable of the intricacies of hunting and stalking deer, I realized that we could, with a slight change of focus, turn the game from an arcade gallery into a simulation with the addition of an overhead map view and a dynamic scene generator. The biggest reason for Deer Hunter's success was that we were the first company to make a serious attempt at creating a realistic simulation. Our dynamic development process allowed us to shift focus enough in mid-development to capture this market.
Although some projects have failed due to the lack of a strong design, we found that taking a flexible approach to game design worked in our case, and it might be worth considering on your next project. I'm not advocating that you turn your 3D shooter into a real-time strategy game halfway through development. Rather, try prioritizing design elements by their expected completion date and finishing designing these elements first.
For instance, if the user interface is rather straightforward but the game play still needs some work, let a programmer and an artist start moving forward on this aspect of the project while others hammer out the details of game play. This is an example of designing in parallel with the project. Because the components have a logical separation from other aspects of the design, this process makes perfect sense and avoids down time.
Likewise, in-house development tools can often be started long before other portions of a game are completed. It may even be a requirement. (For more on this point, see Game Developer's October 1998 Postmortem of Monolith's SHOGO to see what can happen if custom tools aren't given enough attention early in the development process.) If design issues are still up in the air, make sure the tool programmer makes allowances for additional functionality that might be added. The time wasted in having to change a file format is more than made up for by the fact that the programmer didn't have to wait another month for the design specifications to be finished.
Dynamic design - altering the design during development - might also bear consideration. Again, use some common sense - I'm not talking about changing the entire course of a project. We found that it doesn't pay to try to anticipate every problem that may come up during the course of development. Instead, we set goals to attain and expected both the artists and programmers to be creative enough to reach those goals on their own. Many times during the course of a project, we thought of a better way to achieve the goal that we'd set out to reach. One of the more interesting effects in the game is the zoom lens on the rifle scope and binoculars. Although the design of this effect was originally intended to be a simple pixel doubling, I realized that we could make the effect much more convincing if we could preserve the sprites' highest level of detail by using a technique we hadn't thought of earlier. By focusing on the goal instead of the process or the details, those of us working on the project could enhance the game significantly while still maintaining the original schedule.
Lesson 3: Smart Scheduling
I brought up the issue of scheduling when discussing parallel design, but it warrants more attention. Intelligent scheduling means planning to complete components so that you minimize your reliance upon incomplete code; this was one aspect of our development process that allowed us to get Deer Hunter out the door fairly rapidly.
For instance, Figure 1 shows the task schedule from early in the Deer Hunter project. Mike Root, our project leader and lead programmer, was responsible for creating and maintaining the general framework of the game, as well as other items such as creating the weapons and building the sound libraries. He also built a resource editor that helped us manage all the game artwork. Nate Terpstra, our trusty intern, worked on the DirectDraw graphics libraries and user interface controls. My responsibilities included game design, artificial intelligence and deer behavior, map creation, and scene generation.
You can see in Figure 1 how both my game design and AI research were scheduled for a time when it would have been difficult for me to do much else in the way of high-level coding. Much of the game design was still in flux when Mike and Nate were developing the DirectDraw libraries, resource builder, and basic program framework.
Figure 1. Deer Hunter's task schedule
None of this concerned us, however, as we knew what was required of those components regardless of game design. This freed me to continue tweaking the design and continue research even while other team members were busy coding. Note that when I was finally ready to begin coding the deer AI, the elements for allowing me to visualize the deer on screen were nearly in place.
Lesson 4: Code Around Scheduling Delays
In some instances, scheduling cannot be fudged enough to minimize dependencies and still give enough time for everyone to complete their tasks. Or, there may not be enough alternate work with which to fill up that person's schedule. In this case, the best thing to do is simply to code around the problem. This was somewhat of a problem in Deer Hunter's development.
I was responsible for the deer's AI and behavior. A problem arose when the map view took slightly longer than anticipated to get functional (with as tight a schedule as we had, even a week could make a huge difference). Without a graphical view into the deer's world, it was difficult for me to maintain my schedule.
In future projects, I would learn from this mistake and create a separate application exclusively for creating and testing animal movement and reactions. The next generation of hunting games were expected to have more advanced behavior, so I needed far more time to program the AI in our later projects. I used a third-party graphics library, Fastgraph for Windows, to create this test bed, because it had native support for a flexible floating-point coordinate system. The animals all used floating-point vectors for movement in a realistically scaled world, so this worked well for me.
Your particular choice of libraries and tools doesn't really matter, as long as you maintain a clear separation between the test bed and the game code that you're writing. This distinction also has another positive side effect: it forces programmers to maintain a clean and intuitive programming interface to the code modules that they're writing, because the code must be moved from the test bed to the main project. At some point, the actual project may become incompatible with the test bed due to increasing complexities in the game itself. Don't try to maintain the two separate projects unless you're absolutely forced to do so. Simply move the code to the main project and continue working there. Keep in mind that the test bed is simply a means to an end, and once its usefulness has ceased, it should be discarded. Don't make it too pretty by wasting time on irrelevant features. Quick and dirty is the key.
Lesson 5: Create Meaningful Milestones
It's too easy for those who can't see under the hood of a project to want visual milestones. Oftentimes, however, when a game looks only half done, the work is actually 90 percent complete, or vice versa. It's important for project managers to understand this. The easiest solution is to involve the designers, artists, and programmers in the task of creating milestones. Because they're the ones doing the work, they should have a more instinctive feel for how to balance out the workload among equally separated project milestones. This also helps to clarify every individual's responsibilities right from the beginning.
I've seen examples of both approaches. When management alone tries to dictate the milestones, the results are often a huge, unbalanced mix of goals, which fall mostly into the "too easy" or "nearly impossible to achieve" categories. When someone who appreciates the technical aspects of the design is involved, the balance between milestones tends to be much more realistic.
You'll notice that all of these suggestions relate to design or other similar aspects of the project. Truth be known, that was really the only remarkable aspect of Deer Hunter's development cycle. The other parts were pretty plain: solid object-oriented design principles (or solid structured programming techniques for you C programmers), careful programming, and hard work.
The question of code reusability and robustness might come up, and it is indeed a valid point. Minimizing design time doesn't necessarily mean sacrificing these elements. I would offer proof of this by mentioning that the same basic code set was used to create two derivative products, a big-game hunting simulation and a duck/goose hunting game. The success of Deer Hunter was completely unexpected, yet we were able to use the existing code as an engine with which to create these other games, both of which made substantial improvements to the original game. Deer Hunter has now even been ported to the Macintosh. There's no question that the code was well designed and quite robust. Individual programmers sticking to time-honored object-oriented programming techniques achieved the robustness of the code, not a fancy design document.
Remember that design time is essentially overhead. The faster you can get your team up and working, the more time they'll have to do what's really important: produce the game.