|
Physics
The physics
engine is the second most complex component of the game engine. It has
to resolve all collisions, every frame, with minimal time overhead.
Because the objects were all dealt with in a BSP tree, the time overhead
was minimized, and collisions with the BSP are polygon accurate. Most
of the Newtonian mechanics are true to life, although some things were
simplified to save time.
Characters
are implemented as a hierarchical models. As such, they’re very time
consuming to work with. Characters are often simplified to deformed
spheres for collision purposes. This simplification can cause some strange
side effects and doesn’t allow bullets to hit specific locations on
the body (this feature should have been added but alas, we ran out of
time). Again, as processor speed increases and more work is offloaded
onto dedicated 3D hardware, better physics simulation will become feasible.
 |
|
SpecOPs
characters
were often simplified to deformed spheres for collision purposes.
|
Viper
has a very impressive servo-based system for simulating vehicles. They
are able to drive and fly over almost any terrain. The truck in the
first level of SpecOps navigates the terrain based only on a
series of vertices, which tells the servo where the road is. The truck
applies a velocity in the direction in which it wants to drive, and
the motion forward causes the wheels to move a corresponding amount.
The friction model will cause the wheels to slip on steep slopes. A
similar system of servos allows the helicopter to navigate over the
trees in the forest and land in the clearings. The best part about working
with servos is that they can deal with all sorts of environments without
any additional work. The worst part is that they can sometimes do unpredictable
things that are hard to reproduce.
Sound
We created
the sound engine with Microsoft’s DirectSound. The initial implementation
was fairly easy, but we spent months twiddling with it to deal with
a variety of problems that popped up. Furthermore, we were using DirectX
3 when we began the project, but we shipped with DirectX 5. While there
were supposedly no changes to the DirectSound API between these releases,
the sound panning stopped working when we updated to version 5. Furthermore,
because of some sort of multithreading issue, the sound never quite
played correctly on Windows NT.
 |
|
Audio
designers actually sampled the sounds of weapons being fired.
|
In response
to these DirectSound problems, we tried briefly to switch to DiamondWare’s
tools, which perform much better under Windows NT and have an easier-to-use
API. Overall, DiamondWare Sound Toolkit was a better solution, but it
also had a threading problem: it was monopolizing the bus and causing
the 3D accelerator to hiccup. The company’s technical support people
said that they were aware of the problem and had no solution. In the
end, we went back to DirectSound and lived with its problems.
With the
spreading popularity of 3D sound hardware (such as Aureal), hopefully
much of the sound mixing and spatial placement will be offloaded from
the CPU. We strongly considered adding support for Aureal’s A3D, either
in a patch or an expansion pack for SpecOps.
AI
Engine
Viper’s
game-specific AI is written entirely in a scripting language. The language’s
syntax looks like a cross between Basic and Lisp. The scripts describe
hierarchical finite state machines and are object-oriented. The object-oriented
implementation of these AI objects mirror the C implementation of the
data structures in Figure 1. The scripts are compiled into a byte-code
binary file that is executed at run time by the game engine. This was
time consuming to implement, but provided us with several advantages
over a comparable C implementation.
Most importantly,
it created a hard boundary between the game-specific AI and the game
engine. If you combined the main executable with different compiled
script files and a separate set of resources, you would have a totally
different game. This forced modularity saved us time and made it possible
to make significant game AI changes late in development. The game’s
AI team was also able to work fairly independently from the game engine
programmers. This was successful to the point that we were able to create
numerous demos and even start production on a totally different title
while the engine was still being built. In fact, I arrived at work one
day to find that one of the game designers and one of the artists had
gotten together and created a 3D monster truck racing demo without involving
a programmer at all.
 |
|
The
AI script language
allowed the AI team to work fairly independently from the game
engine programmers.
|
This points
out another benefit of using a script language: people without programming
skills can modify the AI. Realistically, a programmer has to write 80
to 90 percent of any given script, but at that point the game designers
can sit down and twiddle with it until it’s just right. That said, I
was often impressed at how adept at working with the script language
many of the people at the office became. Our resident sound guy added
nearly all of the sounds to the game with next to no assistance from
the programming staff. I would often play the game on a Monday morning
and be stunned by how much had been added without programmers being
involved. Implementing game logic in C doesn’t offer this.
Another
benefit of using script-based AI was that because we had one compiled
AI file per level, we only had the AI for a single level loaded at any
given time. Not only did this separation make the division of labor
easier, but it also saved a fair amount of memory.
All was
not rosy, of course. There was the obvious time overhead for the extra
level of indirection in the game AI. For the most part, the AI was so
high-level that this overhead had no real impact on the game’s performance.
Still, more than once we had to implement a routine in C or optimize
the run-time AI interpreter. Also, since this was the initial implementation
of a complex system, we made a few design errors that had to be worked
around. For the next title, we’ll go back and address these changes.
The biggest
problem with using a system like this was that the AI scripts were difficult
to debug. Because they were largely just simple logic wrapped around
calls to C functions, this problem was tolerable. Still, more than once
we wished the scripts would just generate C code so that we could use
Visual C++ to debug them. This might be a superior implementation, and
something we will consider in the future.
|