In
October 1997, two employees at Angel Studios posted a message to themselves
on a wall: “We will release a game on September 1, 1999, that people
love. We will know they love it because by January 1, 2000, it will
have sold two million copies.”
Shortly
after, Capcom chose Angel Studios to port Resident Evil 2 to
the Nintendo 64. Project director Chris Fodor and lead programmer Jamie
Briant were charged with this task, and began laying the groundwork
and assembling the team. While they both had previous experience with
the Nintendo 64, this ambitious and challenging project quickly illustrated
that they didn’t really know how the N64 worked. Sure, its got a CPU
and a geometry processor, and a graphics chip, and fire exits here,
here, and there, but at exactly what altitude do the oxygen masks drop
down, or do they have to be triggered manually by the pilot? In the
next few months the OS was rebuilt, vector units (yes, the N64 has a
vector unit) emancipated, and the N64 charmed into revealing her secrets.
The original
Resident Evil 2 for the Playstation spanned two CDs. We had to
get it on a single cartridge. But it’s just a port, right? In our hands
we had a classic game with excellent design, all the art done, and the
AI tuned and in place. However, it was going to require some pretty
clever programming to get it running on the N64. It was a task that
the newsgroups, gaming web sites, and perhaps even the publisher had
doubts could be done.
What Went Right
1. The Work Environment and Team
Given that this was going to be a very technical project, it was critical
that we had a strong and cohesive programming team. The project quickly
ramped up as Alex Ehrath came on board and then me shortly after in
December 1998. Alex brought a wealth of experience, dedication, and
hard work. Fresh out of college, I was handed the task of doing the
full-motion video. (For details on how this feat was accomplished, check
out my article “Mission: Compressible — Achieving Full-Motion
Video on the Nintendo 64” in the upcoming September 2000 issue
of Game Developer.) Chris Fodor and Jamie Briant shared a joint
leadership of sorts. Sometimes this led to “too many cooks in the
kitchen,” but more often than not they complemented each other
and provided effective leadership through the project’s duration. Ken
Kamdar came on towards the end of the project, bringing a sense of serenity
and calm (as well as his programming skills) at just the right time.
By this stage we had Australia, Germany, England, Iran, and the U.S.
represented. You wouldn’t have picked it, but this unusual mix had a
level of synergy rarely found on many programming teams.
![]() |
![]() |
|
We programmers
had our desks arranged in a semicircle, facing outward, but it hadn’t
started out that way. Initially, Chris had his own office, and Alex
and Jamie sat quite a ways apart, staking out their own territory. However,
a month into the project we were way behind schedule. We needed to be
on top of things, and to communicate a lot more.
We decided
to sit together. When I, and later Ken, arrived they just enlarged the
semicircle. A lot has been written about brain states and the zone,
and as Jamie recalls, “Alex would sometimes interrupt me with all
my balls in the air to tell me some really stupid joke, but I guarantee
that the time lost was nothing compared to the gain in efficiency of
having everyone right there”. At the beginning of the project there
are lots of questions that come up and decisions to be made. Everyone
could listen in, even if they weren’t initially part of the discussion,
and often someone would turn around and offer a pearl of wisdom or a
new insight that led to a better solution. By the middle of the project,
we’d got better at not interrupting anyone deep in thought. In the end,
I think we saved months: “It crashed” [points]. [Turns
head] “Oh yeah, that’s the licker bug — don’t press the B
button when it’s doing that [points] — and I’ll be checking
in a fix in ten minutes.”
The long,
hard hours forged a strong mutual trust among the group. It wasn’t long
before we were all working away on our own tasks without supervision.
This allowed for flexible hours without jeopardizing work throughput.
2.
Nailing the First Milestone
If your company doesn’t publish its own titles, then you have an external
producer at your publisher. When the producers go out for a beer, they
talk about how late their developers are and bitch about how to get
them in line. Many producers think developers haven’t got a clue about
marketing deadlines, budgets, and all the other things that we really
don’t have a clue about. We speak a different language. But if you hit
your first milestone, you’re different.
First,
your producer has a different story to tell to his boss and his peers.
Second, you’ve established a basis for communication — you’ve demonstrated
that you understand what the word “deadline” means. Having
learned the first word in a producer’s vocabulary, you’ll find that
they are then open to discussing more complicated ideas, even being
flexible on future deadlines. Finally, you have credibility with the
producer and your publisher. If you miss your first milestone without
a care, your producer will permanently put you in the “baby sit/baby
talk” bin.
3.
No Religious Attachment
It’s never a good idea to become too attached to something you’ve done,
whether it’s a business process, an algorithm, or just an implementation.
If something doesn’t work, don’t do it. If something did work, and it
doesn’t anymore, drop it and find something new.
We applied
this principle to our group communications. We began by using Microsoft
Team Manager 97. That didn’t even last a month. Then we moved our desks
into the semicircle, with everyone close at hand and in the same room.
That worked very well, and we kept it.
Next,
Jamie decided to see what would happen if everyone was forced to use
the same editor, with the same keyboard choices. The result was that
you learn the new editor in a day, you’re fluent in a week, and everyone
can sit down at your machine and use it like it was their own.
We used
Outlook’s tasks system. Outlook’s seemingly simple task list can use
e-mail to keep everyone’s tasks in sync. This worked very well for several
months, but after a while we used it less. This was because at the end
of the project, there was simply a whole list of very well known things
that needed to be done. We tried a very visual display, by making pieces
of paper for every task item and pinning them on the wall under everyone’s
name. And there they stayed, pretty much untouched, until the day we
published the game. They were replaced with Excel spreadsheets.
When it
came to programming, this attitude worked wonders for the development
of our FMV system. Relentlessly trying everything, often multiple times
(as an improvement in quality or speed made a previously rejected approach
viable again), brought us a great result and an industry first — high-quality
video on a cartridge-based console.
We also
learned the value of writing code for the task at hand, not what the
task might be in the future. I hope most programmers find this obvious,
but many of us (including me at one time) have been lost in C++ land.
There are many benefits to C++, but a lot of them just aren’t viable
for performance and size reasons on an aging console. It’s very easy
when writing object-oriented code to fall into the trap of trying to
design even a reasonable system. Don’t bother. Be prepared to rewrite
everything. You might be able to rewrite some section of code three
times faster than it would take you to design a perfect class hierarchy.
The bottom line is that you shouldn’t be attached to what you have.
Be prepared to throw it away and try something else.
4.
Using a Detailed Schedule and Plan
From the outset, RE2 had a clear and detailed plan of exactly
what would be required, broken down into very fine detail. With this
information our capable producer, Stewart Spilkin, was able to schedule
the project’s tasks and resource allocations accurately (Stewart was
instrumental in dealing with external difficulties, which allowed us
to concentrate on development, always pushing the project closer to
completion). I can’t overstate the importance of a detailed plan. It
forces you to examine and often discover what really needs to be done
and allows you to plan for it. You can’t have too much detail. It was
an ambitious schedule to be sure, but one that was attainable — which
made it both hard and rewarding.
We prioritized
features. As a deadline rolled up, we ruthlessly worked on essential,
strategic features only. Occasionally there would be arguments over
what features were and weren’t necessary, but this attitude ensured
that we stuck to the plan and got the project done. We wanted our game
to be perfect, but it had to ship. Do what’s needed to get it out the
door, then make all the touch-ups you have time for.
We dealt
with the publisher’s requests to add new features, especially towards
the end of the project, with aplomb. Rather than an internal attack
of “feature creep,” these came from the outside. Each time
a new feature was proposed, we examined what it would take to implement
it and presented an honest account of what it would take, in terms of
resources, to implement it. For example, we estimated that with an additional
full-time programmer we could definitely achieve task A, probably task
B (80 percent) and maybe task C (20 percent). The client then had all
the information they needed to make a choice and most times they chose
“no.”
Dealing
with these added pressures can be stressful, and each time it takes
you away from your work. However, you can save your project’s schedule
and budget by rationally examining what needs to be done and what implementing
that new feature will require.
5. Maximizing Reuse
With the vast amount of assets provided by the PSX version, it made
much more sense to analyze each type of data (2D sprites, collision
data, and so on) and implement a pipeline that would then convert the
PSX-specific assets into something we could read in and use on the N64.
Since this was a port, we could be sure that we would end up with all
the pieces we needed if we simply batch-converted them in their entirety,
rather than individually touching up each and every one of them by hand,
and save enormous amounts of time this way. It took a few days to write
code that converted all of the 2D sprites into a format we needed, but
it would have taken an artist a very long time to touch up thousands
of sprites by hand.
Whenever
possible, we emulated PSX-specific routines and hardware functions to
achieve similar results on the N64, maximizing our reuse of the existing
source code.