|
Graphic Goodness
Like the designers, the artists were also under significant time pressure. Neverwinter Nights had the dubious privilege of not only being a full role-playing game but a role-playing construction kit too. Since creation of 3D artwork would be beyond the skills of practically the entire user base, Neverwinter Nights needed to include an art set that was as complete as possible. Of course while there was no way of even scratching the surface of the full set of monsters, characters and environments the twenty-five years of Dungeons & Dragons fans have created, we still wanted to provide a representative sample. As a result the art team needed a full three years to produce the required art elements. The only problem was that the graphics engine itself took nearly two years to create. To get the artists working early, we defined the art constraints as best as we could and accepted the eventual passes over the artwork required when the graphic engine was finally completed. Once again, we were sacrificing efficiency for gains in the actual completion date.
You've Got A Bad Reputation Around Here
We asked a few designers about what they thought about working on our next project versus Neverwinter, and we got a unanimous opinion - "it's way easier! We don't have to deal with the NWN reputation system!" This struck us as odd: how could a reputation system become a universally despised system?
The NWN reputation system is described in greater detail elsewhere [Brockington03], but a short description will be required to explain why it was a mess. Every person in the world belongs to a faction, and this faction has a standard reaction to every other faction in the world. These factions are allowed to change through standard mechanics (such as assisting or attacking a member of another faction). Each player character (PC) belongs to its own faction, so that every non-player character (NPC) faction could have its own set of reactions to the player. We intended on having four different factions to start with: Commoners, Merchants, Guards and Monsters, and the designers could add any number of additional factions that they wanted.
Well, let's start with each two-hour mission. The designers did not want all monsters to behave the same way. They wanted some monsters to look friendly to the player, and only attack once the dialog was over. Thus, they had to be in their own faction. Each set of animals had to react independently of one another, so the deer would be put in a different faction from the cows (for example). Plus, if there were important plot creatures, they invariably got factions of their own, too. So, each two-hour mission had approximately 20 factions to keep track of and assign values to. That's 380 "reactions", or 190 if you could assume symmetry between them. That didn't seem too bad.
Then all of the two-hour missions were stapled together into chapters. Most of these factions could not be integrated with one another so four two-hour missions became 80 factions. So, instead of entering 190 reactions, the designer responsible for the module had on the order of 3160 reactions to enter and keep track of. In fact, Chapter 2 (our largest chapter) had over 180 factions near the end of development. (For those of you that are keeping track, it worked out to 42000 reaction values, but only 21000 if you could include symmetry.) This, by itself, required 3 seconds to load and parse in the initial generic file format code, and took 2 megabytes to store. So, we had to revise the file format to make it faster, but the conversion didn't go as smoothly as planned; some data was lost. Designer task: Confirm 21000 reaction values.
So, we have 180 different factions that could be hostile to the player at some time. However, any one of those 180 factions could be hostile to another one of the 180 factions. This led to one of our favorite bugs concerning the reputation system: the disappearing orcs. The orcs were placed in the Aurora Toolset, the module designer then starts the chapter, and plays through the chapter, testing for balance. By the time the designer reaches the area containing the orcs, there is only treasure lying on the ground; the orcs are long gone. The AI was accused of forcing the creatures to drop their treasure and run away. Upon further investigation, the orcs had been told to "wander" near the area that they were standing in. Nearby, there was a large encounter area that spawned deer. However, orcs are hostile to deer. So, the orc would "wander" into the area, and a deer would appear. The orc then proceeds to make short work of the deer. All is fine in the world, but the deer don't like orcs any more. The encounter area resets, and says "there's a hostile creature nearby", and the deer runs headlong at the orc. The orc says "Fine! Deer Stew #2 coming up!". Repeat ad nauseum. Unfortunately, the orc doesn't have an unlimited capacity to heal himself. After about 25 deer are spawned in, they finally get enough lucky attacks on the orc to kill the orc outright. To tie things off, the encounter area would reacquire and destroy the deer, since keeping extra encounter creatures that weren't actively fighting or watched by a PC was just a waste of CPU time. Hence, the orc's treasure would be left on the ground, and no sign of the victorious deer was to be found!
Another fun bug occurs when faction members span over multiple areas. Let us say there are orcs and deer living in peaceful co-existence in many areas of the game. However, orcs hate player characters, and one of them casts an area of effect spell that attacks both a PC, but kills a deer. All bets are off at this point, the deer and orcs are at war. Off on the other side of the world, in a completely different area, the deer rears its head and goes headlong after the orc. The poor orc doesn't understand what is happening … and suddenly all of the ambience of an idyllic setting is destroyed with deer and orc carcasses everywhere. Thus, most factions that spanned multiple areas were subdivided into each area to prevent bizarre behavior. Which means even more values to test and verify!
Each and every time the reputation system changed, it had global ramifications on game play. One wouldn't think that a change to how the game engine handled henchman AI could cause deer and orcs to hate one another … but it did.
Every time the designer thought about the system, they thought about verifying 21000 numbers, retesting all of their areas every time there was a reputation system change, and trying to keep all of the various factions far enough apart so they wouldn't cause a suicidal rampage (at least the Montagues and Capulets had a wall) … and it's not hard to wonder why the reputation system became despised.
Let's Add Another OS!
At the start of the project, we stated that we were going to implement the game on four different platforms: the PC, Macintosh, Linux and BeOS. This was theoretically possible because we managed to isolate the machine-independent libraries from the machine-dependent ones. Everything seemed fine. One of the programmers was responsible for keeping up with the latest build of the game, telling us how we were breaking the build on the other operating systems. Similarly, getting your code base up and running on three different compilers (CodeWarrior, Visual C 6 and gcc) stopped us from making some horrible mistakes that were not caught by default with the settings we had set up.
However, as the project progressed, we encountered numerous issues. The programmer who worked on the porting to other operating systems was the only programmer on the project who was comfortable looking at code anywhere in the code base, and rapidly became the go-to guy when you needed a "little something" done in the code, and we needed a lot of unscheduled "little somethings" in a game as feature-rich as Neverwinter Nights. We also had a horrible time getting driver support for some of the other operating systems. This tended to stall development until the graphics team could help by working around the driver problem, or we waited until the driver support was finally ready.
Last, but not least, we had problems with the toolset component of the project. The Aurora Toolset was built in Borland C++ Builder, based on the fact that we heard all sorts of rumors of a Linux and Macintosh version of Builder. However, this turned into a monstrous headache for development. C++ Builder would throw floating-point exceptions during the middle of the graphics engine, which would not show in the middle of the same library run through Visual C. We couldn't link the graphics library with Builder without going to a DLL, so we had to make the graphics library source tree work on C++ Builder as well. The Macintosh version of Builder vanished into the land of vaporware, and we were left holding the bag.
The server code initially tried to isolate some of the rules into classes that Builder could use, but the tendrils of game code reached in. A decision was made early on that the Aurora Toolset wouldn't attempt to enforce the D&D rule set, that was the domain of the game. After that decision was made, the game code invaded the rules components like shoppers descend on Wal-Mart on the day after Thanksgiving. When it became clear that the decision on rules enforcement was ill-advised, there was little we could do except include the entire server into the Aurora Toolset. So, we are trying to duplicate the rules code in both C++ Builder and Visual C for the most important components. We are investigating alternatives to C++ Builder for future projects.
When the pressure finally hit to get the game shipped, the priorities of getting the Windows client and server done won out over getting the ports finished. Although we managed to salvage enough resources to have a Linux standalone server ready for download when the game hit store shelves, it still took us nearly six months to ship the Mac and Linux clients, and these are now in the final stages (at time of writing).
Conclusions
In June 2002, we received word from our publisher that the Windows version of Neverwinter Nights (translated into English, German and Korean) was done; it was a hairy 3 and a half year ride. Not only did we manage to get the game done in a time frame that was not going to bankrupt the company, but we feel that we achieved all of the marketing hype. We had a single-player game that we were proud to release, but we also had a relatively stable multiplayer framework for playing through the same story, with or without a dungeon master. We also had a toolset that has been used to create over 2000 modules within the first six months.
Our fan community has been giving us wonderful feedback. Their suggestions are improving the game and making it better suited to their needs in the months and years ahead. BioWare has announced two expansions to Neverwinter Nights, which should benefit both the custom content creators and those people who are looking for another dose of the game.
We hope that you've learned quite a lot about some of the trials and tribulations that Neverwinter Nights went through. If you have any other questions, please feel free to ask.
References
[Brockington03] Brockington, Mark, "Building A Reputation System: Hatred, Forgiveness and Surrender in Neverwinter Nights", Massively Multiplayer Game Development, March 2003.
[Frohnmayer00] Frohnmayer, Mark and Gift, Tim, "The TRIBES Engine Networking Model", Game Developers Conference 2000, pp. 191 - 207.
______________________________________________________
|