What did I even
do?
That is the
question I had to ask myself when I sat down to write this postmortem. Now that may make me sound lazy, but that
isn’t the case, I accomplished a lot this semester. It’s due to the fact that I was working on so
many different things it was hard to remember all the specifics. So here is the list, I decided to cover the 4
systems I was most proud of: AI, Particle FX, the Rock Meter, and the
experimental Beat system.
Artificial
Intelligence
This semester I upgraded the AI system as follows:
·
Pogo enemies
o
A version of the ranged enemies that
jump around the screen using their rocket launcher (rocket jumping).
o
These jumps are chained together making
a pogo effect until the enemy becomes unbalanced and face plants on the ground
at the end of the jump.
o
After face planting he will shoot a few
missiles at the player and then return to pogoing.
·
Shielded enemies
o
A version of the weak enemy that takes
less damage due to their briefcase that they use as a shield.
o
After the player performs their uppercut
move the enemy is disarmed and their behavior changes so that they now run away
from the player and cower on the side of the screen.
o
Unfortunately the shielded enemy was cut
from the final game because we were unable to get working animations for them.
·
Model Caching
o
At the beginning of the semester the AI
system’s performance was awful. This
wasn’t because the code was processor heavy, but because the game would hitch
when we would load all the models and animations when spawning a new enemy.
o
To fix this I could have simply
pre-cached all of the available models, but I took it a step farther and added
pooling for enemies.
§ We
have 3 distinct enemy groups, and each group had two types of enemies.
§ I
was able to create 3 pools of enemies that we could reuse. When spawning we would draw from the pool,
convert to the correct enemy type (if necessary) and then spawn the revived
enemy.
§ This
was more difficult with the weak enemy group because we needed to be able to swap
between 3 models (weak, shielded, and disarmed shielded) as necessary.
§ Assuming
the pool sizes were set up correctly by the level designer, no creation of new
objects would occur in the AI code during the entire level.
·
Enemy Spawning
o
After receiving some feedback from Jake,
our Level Designer, I made a couple of improvements to the Spawning system to
simplify level creation.
o
Wave spawning correctly handles itself
such that when all enemies spawned by triggers die, they will all span another
enemy (assuming they haven’t met the limit)
Particle System
My programming for the particle system this semester
was very similar to the AI system. As we
got closer to finished, artists and designers asked for a few more features in
the system. This including the ability
for particles to have variable size in both the x and y dimension, particles
fading out for a certain amount of time at the end of their life, and growing
or shrinking particles during their lifetime.
I addition to adding new features, the Particle System
also needed to be optimized. Similar to
the AI system, particles are created frequently throughout the game and we want
to avoid as many new/dispose operations as possible to obtain better
performance. So similar to my AI system,
I created a pooling for both the particles and the particle emitters. When a new particle emitter is created we
will grab one from the pool, reinitialize it with the correct texture and
parameters and start emitting. Once a
particle emitter has been started it will grab a certain number of particles
from the global pool, it will then recycle these particles locally, only asking
for more particles when necessary. When
finished the particle emitter will relinquish the particles it used back into
the global pool and place itself back into the particle emitter pool.
These optimizations don’t sound like the most
exciting thing to add the game but they are extremely important. The enemy and particle systems, usually the
most ‘new’ heavy systems in the game during runtime are now completely self
contained and will not be creating new objects while the level is playing.
Rock Meter
Another big feature I added this semester was what I
affectionately call the Rock Meter. The
Rock Meter is the dial is the dial seen in the top left corner of the HUD, and
while each piece of this system wasn’t technically difficult, it interacted
with so many other systems that it needed to be designed correctly to
accommodate this. This included:
·
Health System
o
The Rock Meter served as the player’s
health bar, if it goes below 1 the player would die. So the meter needed to be able to decrement
when the player took damage.
·
Attack System
o
To keep the game fast paced we came up
with an attack system that rewards the player.
As they perform attacks their Rock Meter goes up; however, if they don’t
perform attacks for a certain amount of time the Rock Meter goes down. Because of this we needed to be able to
efficiently modify the Rock Meter when these events happened.
·
Score System
o
The Rock Meter also serves as the
player’s multiplier so it needed to help keep track of what the players score
would be. At the end of the level this
score needed to be reported so that it can be saved. We also want to know what the specific
portions of their score was (how much was due to the number of enemies they
killed, or their highest multiplier, etc.) so that we can make a cooler looking
end screen.
·
Sound System
o
If the player is doing well we raise the
volume and have a crowd cheering. On the
other end if the player is about to die, we lower the music volume and
fluctuate the pitch of the song. Once
again, not something that was difficult to program to the game, but it is my
favorite feature in the entire game.
·
State
o
Because the player could die during any
combat zone the Rock Meter needed to be able to save its state so that it could
restore important values (score, number of kills) in case the player died.
Beat System
Midway through the semester the topic came up about
a complete redesign of our game play and whenever you redesign your game extra
programming will be required. In this
case we wanted to explore a beat based system based on some feedback we had
received during play tests. It was a
hectic weekend, but I built an underlying system that would handle beats and
tied most of our major systems (AI, attacking, etc.) into this so that
everything would happen on a beat from player attacks to enemies spawning. We ended up not going with the beat idea so
some of the code was thrown away, but I was able to save certain pieces such as
a reworking of the AI system that defined how many enemies could attack at a
time.
What I would
have done differently
I can say that looking back on this semester I
wouldn’t have done much differently. I
analysis what I felt I did poorly last semester (not enough upfront oversight
of the systems others are working on) and improved upon it. I knew which teammates struggled with what,
and was able to set up basic guidelines when I was concerned. If I could have changed one thing I would have
preferred to have our crunch for release night a week before we did, but team
members where so busy with other life situations that we had to cut it
close. We got it done it time, but we
came closer to missing the deadline than I would have liked.
Low Fat Scrum
Process
If I had to describe the process we used this
semester I would describe it as the “Low Fat Scrum Process.” We had standup meetings, weekly sprints, and
tasks, but we didn’t go into the full fledged Scrum Software. We used a color coded Google spreadsheet to
keep track of each weeks sprints as well as storing a list of features that
still needed to be tackled, but we didn’t delve too deeply into user stories, bug
backlog, or time estimates. The one
thing I did do as lead programmer differently near the end of the semester is
that I would play through the game every week and generate a bug list. I would fix bugs that were in my code and
inform others of bugs they needed to fix (both programmatically and in level
design). After smashing bugs for the
entire week the process would be repeated with the newest version of the game.
Overall, I would say we were effectively able to use
the agile process to adapt resources to where they were needed to accomplish
our deadlines. Scrum is still the best
process for game development, as it gives you enough structure to stay on task
while also allowing you to quickly switch tasks. This could especially be seen in the two week
stretch in February/March where we decided to prototype a bunch of different
features to make the game more fun.
Things that
went well
Team dynamic
After working with this team for a semester I can
say it is most fun I have had working on a game project. I loved working with everyone on the team
they are extremely talented and are fun to spend time with when not working on
the project (as I learned when 4 of us went to San Francisco for GDC). We had a couple tense weeks as people’s ideas
were being cut, but because everyone was so awesome we were able to pull
through without any resentment.
Crunch meetings
At the end of the day,
the game needs to get finished. I would have
loved to do group meetings outside of class throughout the project that didn’t quite
work out due to everyone’s busy schedules. I was able to set up a couple of key meetings in
the weeks leading up to our deadline that was integral to us getting done on time.
Ultimately this lead to one final “stay in
the lab until its done meeting” that saw us finishing up at 4:30 AM. Not necessarily the most fun way to spend a Monday
night, but getting a few programmers together to find those last few bugs is what
made the difference between us making our deadline.
Artist and Programmer
Pairings
I think something we did very well throughout the project
is having Artists and Programmers work together. By that I mean that Artists would create some art
assets and then the next time we met they would sit with the programmer working
on that section, see how they look in game, and then tweak them accordingly. Once tweaked they would be placed back in the game
so they could be seen again, this process would repeat until we were happy with
the results. Because we did this in person
we were able to save a lot of time that would normally be wasted by taking a screenshot,
emailing the artist, getting a new asset, taking another screenshot, etc. Because of this process and our great Artists we
were able to make some amazing menus, which in my opinion are one of the prettiest
parts of the game.
Things that
went poorly
No early
prototyping
I actually talked about this in my alpha postmortem,
where at the end of the semester I didn’t feel like we had spent enough time
prototyping the game and finding the fun.
Well this semester it can back to bite us, after having two play tests
we had received a lot of negative feedback and had to change the game at a
point where you don’t have time to be prototyping and throwing away code. This goes hand in hand with another item that
went poorly, making design decisions.
Making Design
Decisions
While I felt that in the fall this was something
that went extremely well it ended up being a weakness for us in the
spring. We still were able to generate
plenty of ideas, we just argued way too much about what the correct direction
to go in was. In February a large
portion of the game play was reprogrammed over 2 weeks just for it to be thrown
away after it was decided that nobody actually liked that idea in the first
place. Part of that is my fault, I heard
the feedback and came up with an idea to solve some of these issues, and
assigned people to start working on it because it was approved by the team
lead. I just wish the team had come to a
consensus about not liking that idea before 2 weeks of work was thrown into it.
Animations
While I still don’t know what the issue was with our
animations I can say that they were definitely an issue for us. Whether it was the exporting or the code
(both of which we had working before) we weren’t able to get our shielded enemy
to work. In fact I have more than a
dozen test animations on my computer for our shielded enemy that don’t
work. The really confusing part for me
is that if I had one fbx file with all the animations I could get those to
play, but if each animation was exported individually everything went to
hell. For our animation system we needed
a separate file for each animation, so we were never able to get the shielded
enemy to work which was unfortunate.
Conclusion
Every time you make a game you are never ready to
let it out it to the wild, but with this project I can say I am happy with the
final state. I do feel like we had some
shortcomings in terms of design, but I am extremely happy with all the programming
our small team was able to accomplish to get our game onto the Xbox Live Indie
Games marketplace.