|
Education

Postmortem:
Beam Runner Hyper Cross
What
Went Right
1.Realistic
Goals. At the start of many game development projects, it's easy for
designers to become overzealous when setting their goals for the game.
As five graduate students working on our first independent game, we initially
had grand ideas of creating an incredible game full of state-of-the-art
graphics algorithms and rendering techniques. When we finished laughing,
we scaled back our goals for BHX and came up with a realistic plan
that could be accomplished in a few short months of work.
To determine
what features BHX needed, we put together a list of key components
for an action game. We considered the following high-level features necessary
for BHX:
- Graphics
- Sound
- Artificial
Intelligence
- Game
play
- Win/Lose
Functionality
- Fun
As soon
as we had these main categories, we began to fill in details and divide
up the work. Our initial goal was to get the engine running as quickly
as possible. This meant no heavy algorithms in the engine. For example,
the objects in the scene were stored in a list, rather than a spatial
partitioning data structure.
It was challenging
to restrict ourselves to use only simple implementations for the first
pass of the required components. If we had taken the time to build components
that are more complex, we would never have finished the entire engine.
We used
object-oriented design to abstract these components, so that we could
return and replace them as needed without breaking the engine. After we
had laid the groundwork and had a prototype game running, we were able
to add more features to the engine, such as environment mapping, sound
effects, dynamic lighting, improved artwork, enhanced A.I., and an improved
control model.
Setting
realistic goals from the start motivated us because we knew we could accomplish
the tasks at hand. We've seen too many over-ambitious projects with unrealistic
goals, and we found that a mixture of realistic goals and a love of games
pushed us to exceed our expectations.
2.The
Code Nazi. Five
programmers working together part time can easily lead to difficult situations.
Add to the mix different work schedules, and it's bound to be rough at
times. For example, it is often a problem to find people to answer questions
about their code especially when you need to modify or decipher it. Perhaps
you're sure that there is a bug in the code somewhere. When that time
comes, and the other programmer is AWOL, you're sure glad you have a Code
Nazi on the team.
The Code
Nazi has a zero tolerance rule for poorly written or designed code. He
looks over the new code submitted to the project, and ensures that the
class definitions are well formed; member variables and functions are
following naming conventions, etc.
Now, everyone
knows that it is best not to check in code without testing it first. Checking
in broken code will cause your team to quickly team up against you for
a good pounding. However, even "working" code isn't always good
enough. It may contain problems that will not be noticed for a while.
Small performance hits can build up, and memory problems are especially
tricky. Cleaner code will assist in working those out. Most of all, the
code must be easy to understand and reworkable by others.
We didn't
officially select our Code Nazi; he just assumed the position (no pun
intended). However, no matter how painful it is to have someone there
to rip your work to shreds, it's much better in the long run.
3.Flexible
Programmers. Before each milestone, the team would meet to decide
exactly, which parts of the game and engine we planned to complete before
the next milestone. Once we had a clear list of tasks, we assigned individuals
or pairs of programmers to complete them. This assignment process could
easily have been a major problem if group members felt that they
were stuck doing grunt work on uninteresting parts of the game, the whole
project would quickly have lost all of its fun and become just another
class assignment.
We prevented
this by being flexible and giving every person a chance to work on the
parts of the system that interested him. If more than one person wanted
to work on a task, we would resolve the problem in several ways. If the
task was large, spanning more than one milestone, different people would
take over the task for different stages of the project. If a task was
small, pairs of programmers could work together on it. The goal was to
give as many people as possible the chance to work on parts of the game
engine that they wanted to learn about, and make the entire process a
worthwhile learning experience for everyone.
There were
instances when it was impossible to give everyone the task they wanted.
In these situations, team members had to be flexible, perhaps settling
for their second choice, and then getting their first choice of task after
the next milestone. Even in these situations, since the group would often
meet to discuss approaches to the problems we encountered, any member
could make suggestions or raise issues in order to lend a hand on a problem
he wasn't directly working on. At the end of the project, we all felt
that we had the opportunity to tackle interesting problems and learn about
aspects of game programming that we had never encountered before.
4. DirectX
8. We
decided right away to use DirectX 8 rather than the OpenGL API with which
we were more familiar. We made this choice for two reasons. First, DirectX
looked to be more than a low-level API for graphics and sound it
was rife with utility functionality that might prove valuable under our
constrained schedule. Second, we saw the value of learning an important
tool of our prospective trade.
DirectX
8 proved to be everything we had hoped, allowing us to make BHX
and the HyperX engine into more than we had expected to build in a single
semester. On the graphics front, D3D and the D3DX toolkit were highly
useful. D3DX provides extensive X-file model loading and rendering support.
Coupled with the sample X-file exporter for 3DS MAX, this allowed us to
build a basic model rendering engine within a week or so. On top of our
rendering engine we built our own powerful shading framework ("HyperFX")
around the D3DX "Effects and Techniques" infrastructure. Using
HyperFX, we could modify the shading of objects in the scene without changing
code. D3DX allowed us to easily incorporate features such as multi-texture,
texture compression, and cube environment maps. Content creation and testing
was made easier through built-in support for multiple image formats, which
allowed us to immediately get textured models into our fledgling engine.
There is
more to a game than graphics, though, and DirectX seemed to do it all.
Besides Direct3D and D3DX, we used DirectInput to automatically detect
input devices and to allow the user to easily reconfigure the game controls.
Also, we were able to quickly add sound effects to our game during the
end-of-semester crunch using DirectSound and DirectMusic.
It is worth
noting that while DirectX 8 is an extremely powerful API, it is more than
enough rope to hang oneself. Fortunately, we decided early on to design
a useful and flexible set of classes around DirectX, and we stuck hard
to that decision. By carefully creating a design for the HyperX engine
that abstracts DirectX, we avoided being overwhelmed with complexity that
wasn't needed for our game.
5. Dedication
and Communication. One
of the strongest qualities of our team was the common hunger to succeed.
The game course did not provide hard deadlines and a blueprint to follow;
we all came together as a team and set weekly deadlines for ourselves,
deadlines that we consistently kept. It was very important that we not
simply plan together as a group, but also set goals together as a group.
Working on the game had to be a consistent and pervasive priority to each
one of us for the entire semester.
BHX
had little to nothing by the way of design documentation. The class was
offered on short notice, and did not provide us with the luxury of casual
meetings to refine documentation that would clearly map out the direction
the game would take. Without documentation, a crucial step in the game
design, it becomes incredibly difficult to align the gun sights of each
programmer to aim at the same abstract target. Because the game was not
simply a goal but a priority, the five of us regularly scheduled time
for group meetings outside of class whenever we could. We discussed each
and every step of progress that was made, to ensure each programmer was
clear on the current state of the game, and to decide where, as a group,
we needed to go from there. These meetings took a lot of time, but helped
with both our bond as a group, and our focus and direction as individual
programmers. Setting up a private newsgroup solved our daily communication
needs. We used a free nntp server to host our technical discussions and
code check in log. Some technical topics will span an entire project,
and being able to refer back to a discussion thread is very useful. Further,
each code check in was accompanied by a post to server describing what
had been done and any outstanding issues.
______________________________________________________
|