L3DEdit
allowed us to use two approaches in controlling enemy units in our levels.
The first was a spline-based method which, as the name implies, centered
on placing splines and moving units along them. This approach was exclusively
used in the original Rogue Squadron and Battle for Naboo.
The second approach was the introduction of more sophisticated flocking
AI behavior. Again, as the name suggests, we had our units flock to other
objects. This approach was new and proved to be a very useful approach.
However, there were pros and cons in both approaches and in the end, we
realized using a combination of both was the best, most efficient way
to design our levels.
The main
benefit of using splines to control AI was predictability. When an object
traveled on a spline, we knew where it started and where it was going
to be at any given time during the level. It would not stray from its
defined course unless the level designer willed it. Therefore, pacing
of gameplay and scripted events could be controlled, reducing the number
of potential bugs. There were however, several problems with using splines.
One of the biggest problems was that it did take some time to create and
adjust the splines and/or objects traveling on them to look and act the
way we intended. The more objects moving in a level, the more time was
required to adjust and modify the splines that drove them. More splines
also increased the likelihood of more problems later because moving one
spline accidentally or intentionally would most likely affect another.
That was not a good thing when trying to create elaborate epic space battles.
Attempting to create such a battle using splines would quickly lead to
a nightmare of spaghetti that would take time to unravel.
Another
problem with the spline approach was that it was more difficult to present
a dynamic experience for the player. No matter how many loops or elaborate
spline networks were built into a level, eventually the player would be
able to recognize that the objects around him were just traveling on rails.
Patterns would emerge over time and the player would no longer be fooled
into thinking that he was engaging a "smart" foe. What then
would be the solution? At this point we started to look more seriously
into using AI with flocking behavior.
There were
two benefits to using AI with flocking behavior. First, it saved a tremendous
amount of time. For example, to get a simple dogfight engagement implemented,
the level designer had to assign an AI-driven Tie Fighter to attack the
player. Place the Tie Fighter at its start position, script its initial
start conditions and run the level. This leads us to the second benefit
that behavioral AI gave us flexibility. We could assign several Tie Fighter
groups, each consisting of two or more individual fighters and have them
all engage the player. If we didn't want all the Tie Fighters to converge
on the player, we could easily script one group to attack a Rebel transport
instead and when it was done with that, its orders could be set to attack
the player again. This could be done in a couple of seconds instead of
laborious minutes or hours required by the spline approach.
Of course
there were cons to relying purely on AI behavior. The biggest risk was
the reliance on programming and technology. It did take time for AI to
be programmed, tested and tuned which left the level designer hanging
until these things were done. In fact, because of time constraints, some
AI would have to be tested by the level designer as he tried to implement
it. This invariably caused problems and generated bugs or worse, put a
stop to developing gameplay in the level. Also, during the tight schedule,
programming man-hours were stretched to the limits. Therefore, waiting
for AI features to be implemented or fixed was even riskier because programming
might not have been available when a level designer needed it.
Another
problem with the AI behavior driven approach was its unpredictability.
It was not surprising to see that with its enormous flexibility came a
price. Controlling where a certain unit was and what it was doing became
more complicated and the level designer had to pay special attention to
this problem. Not doing so early in implementation would have caused problems
and bugs later down the line.
Now that
we've seen the pros and cons of both methods, we can come to some interesting
observations. First of all, it was obvious that no one approach was perfect
for all situations. Clearly, a combination of both was the best way to
provide the level designer with the right amount of control and flexibility.
Almost every level in the game used a combination of both approaches in
some fashion. What was the optimum amount? It was really up to the level
designer and his preference. Some level designers enjoyed the flexibility
and was able to deal with the complexities of managing the problems that
the AI behavior driven approach generated. Using AI driven units allowed
for larger dynamic engagements where spline networks proved too cumbersome
and time consuming. Other level designers felt more comfortable with the
control and reliability of the spline approach and when used for smaller
scale level or specific situations, it provided very good results.
A Modular
Approach
Considering
the time constraints we were under, and the sheer vastness and complexity
of the material we wanted to present (Death Star surfaces, Star Destroyers,
other huge capital ships), we knew we would need to find smarter ways
of working. We knew our deadline was inflexible, and we certainly weren't
prepared to cut content, and so we needed to invent ways of creating the
most spectacular Star Wars environments possible in the least amount of
time. In many cases, we adopted a modular approach to creating levels.
In our first
attempts to recreate the Death Star 2 surface, the broken-up, half constructed
surface seen in Return of the Jedi was anemic at best. Originally,
we took what we thought was a time-tested, "safe" approach,
which was creating single poly-surface representations of the most memorable
shapes based on film reference and arranging them on a flat surface in
our design tool. It was a somewhat traditional approach, hearkening back
to our N64 experiences.
Regrettably,
once we saw the results on the development station, we were nonplussed.
Basically, we were left staring at exactly what we made: disassociated
shapes arranged loosely on a flat surface. We couldn't arrange the shapes
densely because the polygon count would have exceeded hardware limitations.
So we went back to the drawing board and decided to scrap our Death Star
environment, and begin anew. This time we scrutinized the film more carefully
and allowed Nintendo's new hardware to help us get the look and feel we
wanted.
On examining
the film, we noticed the Death Star 2 surface was constructed of many
layers of interlocking geometry with many levels of elevation arranged
in a haphazard manner. These randomly arranged elevations helped underscore
the immensity and complexity of the Death Star 2 surface, while creating
an intense feeling of speed whenever the camera flew by. To create the
same effect in the game, we arranged a variety of simple cube shapes on
a limited number of tiles. We allowed most of the cube shapes to intersect
at random, one layered on top of another, thus creating the illusion of
more polygons than actually existed. Basically, we "stuck all the
cubes together," and relied heavily on the Gamecube's 24-bit z buffer
to handle all the sorting.
Once our
tiles were created, we arranged them into mosaics, rotating them, changing
their order of appearance. We allowed the randomness of our tile layout
to create the illusion of a vast, highly detailed, seemingly random landscape.
In the end, we made the entire Death Star 2 surface out of only sixteen
tiles - all copied, pasted, rotated and arranged.
We used
our tile approach wherever possible. We used it on the first Death Star
surface, on Bespin (the city itself was a mosaic of randomly arranged
tiles), and, to some degree, in the Death Star 2 tunnel sequence, which
utilized only eight modules. In taking a modular approach, we were able
to focus on infusing large amounts of detail into a smaller set of generic
component parts which saved us a great amount of time.
Like the
Death Star 2, the first Death Star surface was created using a tile-based
modular solution. The entire play area was essentially made up of approximately
ten distinct tiles. By simply randomizing and rotating the tiles that
we created, we were able to form the initial play surface in a couple
of hours instead of days or weeks. To enhance the feeling of vastness,
border tiles were programmatically added to the outer edge of the original
playfield. This saved time that was better spent on designing and implementing
gameplay. This programmatic extention of the Death Star surface was further
utilized in the recreation of the trench run. The trench itself was made
up of only six unique "U" shaped tiles. Again, simply rotating
and randomizing them reduced any repetition to a minimum. Since the player
was going to spend most of his time in the trench, the surface that extended
from either side of the trench tiles were programmatically placed and
randomized. This saved hours of tedious hand placing of surface tiles
and allowed the level designer more time to tune the obstacle section
and the Tie Fighter encounters. The key to the Death Star's successful
and timely completion was that programming was brought in to automate
a potentially time consuming tasks, allowing the level designer to focus
on making the level fun and authentic to its big screen counterpart.
Use of
Displacement Maps
To generate convincing, photo-real terrain, we decided to utilize and
enhance the approach we had used on both Rogue Squadron and Battle
For Naboo. Beginning in Photoshop, our level designers created very
rough grayscale topographical images, with white representing our highest
terrain elevation and black representing our lowest. The level designers'
job was simply to rough out areas where gameplay was to occur. At that
point, our grayscale images were turned over to Paul Topolos, our lead
artist, who enhanced the images, mainly by incorporating terrain features
from USGS satellite scans.
By utilizing and enhancing a reliable, time-tested approach, we
were able to avoid many of the pitfalls of creating convincing terrain.
We then
loaded our finished grayscale images into L3DEdit, which converted the
images into displacement maps. Our artists created textures for the displacement
maps, applied texture layers using an alpha-blending technique, and created
bump maps, far-detail maps, and cloud shadow maps specific to each terrain
type. Lighting on the landscape was applied by the game's rendering engine
using a real-time light source.
By utilizing
and enhancing a reliable, time-tested approach, we were able to avoid
many of the pitfalls other developers have been trapped in when attempting
to create convincing terrain. We didn't need to model highly detailed
landscape tiles, nor did we need to create unique textures for those tiles.
In addition, whenever we wanted to change aspects of our displacement
maps, we were able to make those changes quickly, simply by altering our
grayscale images or by changing the scale of the displacement map inside
L3DEdit. There was no need to waste precious time hand tweaking or waiting
for another artist to do the work. This allowed level designers great
flexibility and direct control over the terrain and most importantly,
no wait time.