Thursday, December 13, 2012

Heroes of Rock: Alpha Post Mortem



6 sprints worth of work (or what I did)
This semester we were able to get 6 full sprints in, the sprints started off a little slow while we were familiarizing ourselves with Scott Torgeson’s engine, but we were able to quickly pick up the pace and complete our vertical slice for alpha.  Being a programmer, I worked a smattering here, fixed some bugs there, etc. but the two major systems I developed in our game were: Artificial Intelligence and the Particle System.

Artificial Intelligence
What I did
I created a complete Artificial Intelligence system including:
·         weak enemies that run at the player (stupidly; Christian handled the attacking)
·         ranged enemies (stationary)
o   They raycast to determine if they should shoot missiles at the player.
o   The missiles move forward and explode upon colliding with any non-enemy object (complete with smoke trail and explosion effect)
o   When their missile explodes they will try to shoot another
·         Tied into Scott’s triggering system to allowed triggered spawns of enemies
o   Can define type of object to spawn, number of that object to spawn, a delay between each spawn, if you want them to spawn in waves
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)
·         Enemies expel blood when they die
·         The player can walk through all enemies except for the Heavy Enemy.
What still needs to be done
Several portions of the AI need to be improved, the effects can be polished once I have a better idea of how the enemies will be performing their actions.  The AI could needs to be made a little smarter, and I need to add the code for a heavy enemy.  The heavy enemy will perform similar to the weak enemy, but he will move slower and will take a reduced amount of damaged when attacked from the front.  Another slight improvement can be made to the wave spawning system as funny issues will happen if enemies are partially hand placed, partially spawned.  I also need to add the ability for enemies to chase in the Z plane (we plan on doing levels where the level takes starts on the X plane, but changes to the Z plane partway through.  None of these issues are very difficult to change and I already know how to change them, I just made the decision to not polish them for Alpha and help out with other features that we needed to be done.

Particle System
What I did
I made a particle system from scratch that uses textured planes facing the camera to render the particles.  The system is made up of a Particle Emitter, and the particles themselves.  The Particle Emitter has an update, during which it will spawn new number of particles if conditions are met, and updates all the live particles that it has created.  I had never written a particle system before so I wasn’t sure what variables should exist in the system.  However, when I used Unity previously, my team never ran into issues with their particle systems lake of features, so I decided to copy the elements I thought were useful in their system.  After looking through all the variables in their system I decided that I would define the following properties for my emitter:
·         Min Size(float) – minimum size of the particle
·         Max Size(float) – maximum size of the particle
·         Min Energy(float) – minimum time to stay alive in seconds (lifespan)
·         Max Energy (float) – maximum time to stay alive in seconds (lifespan)
·         Min Emission (int) – minimum number of particles to emit a second
·         Max Emission (int) – maximum number of particles to emit a second
·         Local Velocity (Vector3) – Velocity that all particles should start with.
·         Random Velocity (Vector3) – A Vector3 that defines the randomness that can be applied to the particles velocity (e.g. (1, 1, 0) means the particle will have an additional +/- 1 velocity added to its local velocity in the x and y dimension).
·         Random Position (Vector3) – A Vector3 that defines the randomness of the particles position (e.g. (1, 0, 0) means the particle will have an additional +/- 1 added to its position in the x dimension).
·         One Shot (bool) – if true the emitter emits an entire seconds worth of particles at once, and then stops emitting.
·         Texture (Texture2D) – the texture all particles created by the emitter should have. 
Overall, I am happy with the properties I allow, we the ability to create jets of steam, circular explosions, and anything in between.
Just like any system I want my particle system to be as lightweight and efficient as possible.  Because we are using XNA in C# we don’t directly control memory, meaning when we ‘destroy’ objects, they continue to reside in memory, until Garbage Collection is called.  Garbage Collection, frees memory for us so we don’t have to worry about memory leaks, but it can cause the game to freeze up for a second or two during its operation, which is unacceptable for a game.  Particle Systems create lots of particles that have short life spans, so if written poorly your garbage collection will be called quite frequently.
I made an observation early in the development of the engine that all particles have the same texture, so rather than each particle storing redundant data, we should have the emitter store one copy of the texture.  Since the emitter is performing the draw calls for the particles it is simple enough to slightly rearrange the draw call so that the particle emitter is drawing all the particles rather than all the particles drawing themselves.  The most important memory optimization I made was the choice of my data structures and the system of creating particles.  It was an easy choice to use a linked list for the live particles.  You can iterate through all the particles to update them, and you get linear insertion and deletion, meaning that we do not have to sort particles by lifespan or have expensive removes from the middle of the list.  I mentioned before that particles have a short lifespan, meaning that you will not hold a reference to them long before they need to be removed.  However, due to the nature of an emitter you are creating a new group of particles every time you update the system.  When you put these two items together you can come to the realization that it would be smart to recycle the dead particles rather than just deleting them.  So you create a second linked list that you always draw from before creating new particles.  Instead of creating emission rate number of new particles every second, you instead draw from the pool of existing particles and end up creating a total number of particles that is less than 2*emission rate (assuming lifespan < 1 second).  Because of this we can create emitters with much larger rates without running into garbage collection problems.
What still needs to be done
After looking at some more particle systems I think there a handful of changes that are still needed to complete the system.  A basic feature that we still need is the ability to give the emitter a lifetime, we can say “emit for 10 seconds, and then destroy yourself”.  We would then have a “create and forget” system, you just create a particle emitter and the particle system would handle everything else for us (updating and deletion).  In addition, to improve memory further, I would like to have a global pool of particles, when an emitter is created it estimates how many particles it will use, and grabs that many from the pool.  In the case the pool doesn’t have enough particles, it will take as many as it can, and create the rest of the instances locally.  Upon completion the emitter will return its particles to the pool, helping us keep the number of deleted objects down, so we need to run garbage collection less often. 
Of course, there is a list of non necessary features (at this point) that I feel would make our particle system even better.  I like the idea of our particles shrinking in size and fading out their alpha to make a smoother transition when they are removed.  I don’t find the instant remove to be jarring, but there is some room for improvement, and more features are almost always better.   Another thing I would like to look into is applying color/hues to the textures, meaning we would have to create a smaller number of textures if we need multiple colors.  For instance we talked about the having particle FX for our attacks that are different colors based on how accurately you performed the combo.  This would be a reference to Guitar Hero with green, yellow, and red standing for good, okay, and bad respectively.  The last cool addition I thought of would be the ability to give a starting and ending texture for the particle, they textures are then transitioned between during the lifetime of the particle.  Given the time, I will get all these features in, but there are I need to ring other items up to the necessary level of polish before I get that chance.

What I would have done differently
This semester I learned a lot about how to be a better team leader and member.  I wouldn’t have changed a whole lot that had taken place this semester, but I wished I had been more hands on, checking the other programmer’s code more frequently.  I used to lead in the opposite extreme, when people didn’t get their code working how I desired I would change it myself.  The bottom line is that this benefits no one, I have to put in an insane amount of time, and they don’t have a good learning experience.  This semester there are relatively few implementations that I am not happy with, but rather than redoing them I have talked to the programmer, pointed out what I didn’t like about their implementation and sketched out how I would have implemented it.  I wish I had caught these issues a little earlier, but at least I feel like I handled them in the correct manner.


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.  We could have used time estimates, and bug backlogs, but I don’t think the programming team would have kept them updated (I had to fuss them about not marking their tasks done several times).  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.

Things that went well
Team dynamic
This is an extremely fun team to work on.  We quickly got over the disappointment that our games didn’t get picked and have rapidly bonded as a group.  There are no outcasts, we all get along, joke with each other and have a great time.  Everyone on the team is talented, has great ideas, and is good at what they do.
Early group brainstorming
After Heroes of Rock was picked the new team was formed and we had several early discussions on what direction the game should head in.  The game was originally pitched as a platformer that you play with the guitar, but after several discussions we decided this wasn’t a good idea.  If we were going to use the guitar controller we felt as though the input wasn’t precise enough for a platformer.  Instead we focused on what the guitar controller lends itself well too, pushing multiple buttons at the same time, strumming, and ended up with brawler that makes heavy use of combos played by the guitar.  The game we have now is much better than the original idea and the guitar is now something that makes the game cool rather than making it interesting but clunky.  We have run into several obstacles during our project where we don’t know what direction to head in, but we are always able to have a quick discussion and figure it out.
Allowing Democracy without over-scoping
I mentioned in the previous point that we have great group discussion where we come up with a lot of ideas.  This is a great asset when making a game, but can also be a hindrance if the creativity is not kept in check.  It is easy to keep coming up with ideas, but if you put the foot down eventually or you will never get your game out of the door.  On our team we all come up ideas, but we also know when to let them go.  We just met the other day to re-scope our game based on what we had accomplished this semester, and ended up cutting 2 more worlds and 4 enemy character types.  That was a lot to cut, but I was one of the least painful cutting processes I have ever been through.  We all know at a group what the core game, and were easily able creatively swap around the remaining ideas and make them work without the items that had been cut.
Splitting up programming projects
Being the lead for this project I had a couple of goals in mind.  I had worked on several previous projects where people hadn’t contributed, and as a lead it was my job to make sure it didn’t happen on this project.  From personal experience, I know for a fact people work harder and longer if they are working on something they are passionate about.  My goal when dividing up programming tasks was to give people stuff they wanted to work on leaving the undesirable stuff for myself.  This way rather than chasing down and keeping 3 programmers on task, I would just have to keep myself on task (in theory).  I feel like this worked remarkably well, Scott was able to work on the rendering stuff and his engine, Christian seemed to enjoy working on the level editor so he got to stay on that for most of the sprints, and Shandice likes programming front end items, so she was given the task of implementing the GUI and combo system.  I rarely had to chase down programmers (after a few initial slaps on the wrist for not committing their code on time) and after a few weeks I was able to get an idea of how much they could get done in a sprint and was assigning tasks accordingly.

Things that went poorly
Design ideas/communication
Our biggest problem by far, was our communication breakdown somewhere in the design process.  Between AJ (team lead), Jake (Designer), and myself there was instances of confusion.  We would have programming deadlines of features, and I wouldn’t know what the final verdict on the feature, that is I wasn’t sure how the feature was supposed to work in some cases.  This may just be me remembering things wrong, or the design not being final, but it was an issue we had several times.  The easy fix is to put up a document so that we can see in writing what the feature is going to be so the programmers know how to implement it.  So far we have been lucky and it hasn’t cost us, but it is something that left unchecked could come back to haunt us.
Not getting a playable early enough
One thing that hurt us for our Alpha Presentation was that we had finally gotten all of the components together just 3 days earlier.  I am not going to say it was because x wasn’t done with y which delayed us, because that isn’t true.  We had all the pieces were complete, and we had all the mechanics working on the original prototype level, but yet the game was never played.  This could be several reasons behind this: there was a communication breakdown (people didn’t know it was playable), we only had one laptop that could use the guitar, or maybe the right people never played it.  Regardless, we didn’t have enough time to formulate a concise description of what was happening, what still needed to be done, where we were taking it, etc.
Alpha Presentation
To be blunt our presentation of our alpha was a completely disaster.  Due to the aforementioned late playable and issues with design communication several of the people had different ideas of what the game was and where it would be going.  The presentation was two days before it was scheduled so we didn’t have time to discuss what our presentation would be.  To make matters worse, we had people with these conflicting ideas present together.  Our game wasn’t at a state where items were being visually represented well, so a lot needed to be described.  This is where we ran into problems because people were describing it differently and saying we had features or plans that we didn’t have (I was sick and didn’t have enough of a voice to talk about the features we had done).  Luckily Isaac was able to pull aside some people and explain the points that the others had missed saving our presentation.  What we did learn is that we shouldn’t let certain people present, at least not without a script of what they are supposed to say.
Reviewing Code
This one was a personal shortfall.  I was busy this semester, and the thing I didn’t take the time to do on the project was to review other programmer’s code.  This led to an instance where code wasn’t done as desired, and needs to be redone.  I was able to go through a large portion of the code during the final sprint, so we know what needs to be fixed (and people have been assigned these portions to complete over the break).  I am definitely putting a priority on this for next semester to make sure everything goes smoother.
Hardware problems
Our hardware threw us several curveballs this semester, but we have been able to push through them.  Three people, including myself, had their laptop die at some point during the semester, causing us to lose a half sprint worth of work while we waited for fixes/new laptops to arrive.  Unfortunately, it isn’t looking like our laptops have finished giving us problems, because now Christian’s old laptop doesn’t have enough memory available to compile the project (due to the number of art resources).  Hopefully he can upgrade the amount of RAM he has or remove some software (I have seen his desktop, he has a lot of programs installed).  However, laptops haven’t been the only hardware causing headaches; our game is meant to be played with a guitar controller, yet the ‘plug and play’ for the wired guitars doesn’t work on Windows 7.  We can get them to work on Aj’s new Window 8 computer, and Christian’s old Vista computer (I am pretty sure he is the only CS student who still uses Vista), yet we can only get wireless guitars to work on Windows 7.  Because Activision ran the Guitar Hero franchise into the ground and killed it, guitars are no longer being produced, meaning that they are retailing at prices than none of us are willing to spend.  The laptop problems are something that we can’t prevent, but the guitar is a fixable problem.  As of writing this, won’t be a problem next semester because went ahead and purchased one for the group.  Now instead of being forced to crowd around one computer to see the game we should be able to pass the guitar around and everyone can play it on their own computer.

Conclusion
We made some good progress this semester and worked out a lot of the kinks.  We still have plenty of stuff to do, but I am sure with the talent on this team that we will have no problem making our deadlines.  It has been a blast so far, and I can’t wait for next semester to see the game fully realized.

No comments:

Post a Comment