Postmortem: Beam Runner Hyper Cross
The fact that Beam Runner Hyper Cross was created by five programmers, working in their spare time, on a zero budget, and all within four months time is nothing next to amazing. BHX is a graduate student project created by Team Whoopass of UNC Chapel Hill under the guidance of David Eberly. This graduate student postmortem discusses the teams success' and frustrations they faced in creating BHX and the Hyper X game engine as an end of year project.
Beam Runner Hyper Cross (BHX) is a fast-paced futuristic racing game for the PC. The guys will hate me for spilling this, but the idea for the game came from Tron. Tons of games have already been made from the movie Tron, so this may seem a little cliché. However, we've never seen a game based on the ships that cruised on the energy beams.
We took this great concept and changed it around a bit: the beams are high in the upper atmosphere of a planet, curving in great arcs, and running along each other for a great distance. It's the perfect setup for a race where you blast the enemy opponents!
From a third person perspective, you control the speed and rotation of your ship on the beam while aiming with your mouse. Shooting other players will slow them down, but keep an eye out for slow moving traffic in your way and those gun turrets placed to block your path. Do forget to lean the ship into those curves; you'll go faster that way.
"Too simple", you say? Well, give us a break — we worked on this part time over only 4 months. This was a class project for a Game Engine Design Course at the University of North Carolina at Chapel Hill. Team Whoopass consists of five computer science graduate students.
We're happy to say that members of our team are responsible for the course's existence. Two of us worked hard to petition for the course. We approached the faculty with a specific syllabus covering topics in advanced computer graphics which apply to game graphics engine design. A team project was also included to give students valuable experience implementing components in a complete and working engine. We expected that there would be much to learn about implementing algorithms that work in co-operation with a system, vs. small isolated implementations.
The faculty wasn't too excited about offering a so-called game course. However, they perked up when David Eberly, a PhD alumnus of UNC's CS department and author of "3D Game Engine Design", came back as a visiting professor to teach the course.
The graphics topics alone can be found in many computer graphics courses at universities everywhere, but the project experience is something not so easy to find.
The Engine: HyperX. BHX uses our HyperX 3D graphics engine, as well as some auxiliary components. HyperX uses DirectX 8.0 for rendering, input, and sound. Both BHX and HyperX were designed and implemented during the Spring 2001 semester by Team Whoopass.
HyperX provides interfaces for scene management and display, audio, basic AI, input, resource management, and more. The user can define custom effects and materials with no recompilation, and can load models exported from 3D Studio MAX. Primitives in HyperX include mesh models, billboards, particles, and beams.
It is worth noting that we used WinCVS for our source control. This free version control client was crucial in allowing the team to work on and merge code. Source control is critical (even for solo developers). Other groups in this class had serious setbacks, which could have been avoided by using source control properly.
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.
What Went Wrong
1. Tight Schedule, Zero Budget. Since we knew that a tight schedule and zero budget were factors from the start, it might not be fair to consider them as "what went wrong". Nevertheless, they certainly are non-ideal game production constraints, and they made our work difficult. We're graduate students. Everyone on the team had a full class load of project-laden computer science courses, a twenty-hour-a-week teaching or research assistantship, and other activities such as dissertation research and paper publications. But we're not whining — we love what we do. The bottom line is that stress ran high, and tempers wore thin. Without the teamwork, communication, and organization that we had from the beginning, everything would have collapsed.
Team Whoopass could have also been called Team Lowcash. We had zero cash with which to work. We all have a small income from our assistantships, but that pays for rent, meals, and if we're lucky, beer. Fortunately, we had access to university resources: PCs, C++ compilers, and a copy of 3DS MAX. The biggest thing that suffered was our content creation. We had five programmers, and while one of us is also a great artist, he had limited 3D modeling experience. We didn't have the resources (money- or time-wise) to hire artists, so we settled for "programmer art". Our sound effects were heavily edited sounds that someone from our team created with his mouth. (Explosions, for example, are just heavily modulated versions of him saying "Kaboom Kaboom!"). We like to think that partially because of these limitations, BHX is a unique and entertaining game.
2. Conflicting Goals. We already talked about how important realistic goals were to our project, but didn't mention that conflicting goals can easily turn excitement into frustration. Unfortunately, we did not have a mix of programmers, with specialists in sound, A.I., artwork, game play, and 3D graphics like most companies do. All five members of Team Whoopass are graduate students studying computer graphics, and therefore we all wanted to work on graphics programming.
The first conflict came early in the design process: we did not agree on what type of game to make. Each team member envisioned a different type of game, and initially there was very little compromise. We finally settled on BHX after much deliberation and design tweaking to match people's interests.
Each member wanted to gain experience in computer graphics, and we butted heads trying to decide who would work on what portion of BHX and HyperX. Multiple people wanted to work on the core rendering engine and the scene graph. This was not entirely possible because we were already stretched thin on programmers. In the end, each person had to sacrifice some desires and work together as a team to accomplish the project. We sometimes used extreme programming to allow multiple people to work on portions of the project, with excellent results. A little sacrifice and a lot of collaboration made everyone happy in the end.
3.Content Creation Time/Skills. A well-designed game does not necessarily equate to a fun or visually appealing game. With the time constraints placed on our group and our ambitious goals for five individuals to create a working, well structured game in four months, visual appeal was forced to take a far lower priority. The infrastructure for the game was clean and well thought through. The code and its organization were also developed cleanly. However, much of the final art content for the game became a last minute shotgun run.
Of the five members of Team Whoopass, we had five strong programmers, only one of whom had any notable art skill. This was clearly a problem. One of the team members has substantial 2D art talent, especially in comic-style illustration and graphic design. Two others have a little 2D artistic experience, but we had little time or understanding on how to adapt these simple artistic experiences to the expansive demands of a truly rich 3D game.
Each of us had some familiarity with many of the common modeling programs available, such as Maya and 3D studio Max, but aside from squashing and deforming spheres into abstract spaceship-style shapes, our modeling experience was minimal. To our credit, we exhausted the paltry artistic resources the five of us brought to the table in the final product of BHX, but the game clearly could have used the touch of a professional modeler, artist, and content creator.
4. On The Fly Game Design. Before we began working on the project, the group met and worked out a general design of the game. After this was nailed down, and we knew that we would have beams, ships, shooting, racing, etc, there was still a lot of detail that was left unspecified. Without a complete vision for the game, decisions about game design were made months into the project by the individuals programming those parts of the game, or by the whole group whenever we had a chance to meet. This was especially apparent in the game play, which continued to evolve right up to the last 24 hours before the project was submitted.
Some aspects of game play, such as ammunition power ups, were added to the game late in the project. Other elements that we had planned to include from the beginning, such as jumping between beams, were scrapped because of lack of time.
In terms of the educational goals of the project, this ad hock game design did not pose much of a problem. But, in terms of producing the best possible game in the time available, a clear set of guidelines early in the development process would have allowed us to use our time only on the features that mattered.
5. Last minute hacking. Humans procrastinate. If you run into someone who doesn't, be afraid, because they're likely a robot or an alien. The electronic game industry is well known for Crunch Time. We planned from the very beginning to beat the system. The academic semester workload always skyrockets at the end, and we decided to front load this project to avoid that condition.
We failed…or did we?
We did have the bare bones of our project up and running 1/3rd of the way through the project. However, the last few weeks were significantly busier. Audio was plugged in at the last moment (at the expense of a game-play feature of jumping from beam to beam). The very last night we were a long way from having a good demo. Memory problems had crept into the system, causing floating bugs. Each time we tracked down one bug's location, we would find it to be only a phantom bug, being caused by memory leaks from somewhere else.
We locked the code and data (because changing those can cause a memory leak symptom to move as well), and worked on it all night, and managed to fix the final problems only minutes before the class presentation. Somehow, we did manage to sneak in a few final features that night.
To help avoid the problems we had we should have been a little more careful earlier on. Specifically, more code checking should have been included to reduce the time spent debugging. Assertion statements, redundant pointer validity checking, bounds checking, reasonable data range checking, and not assuming that a function will return the right value are all encouraged. Trust no one, as it were.
We failed in avoiding a last minute crunch, even though we worked hard to do most of the work early in the project. However, the crunch time was small with respect to other teams, and of course real world teams. If we had not prepared, things could have likely been much worse. In the end, many agreed that ours was the best demo in the class.
______________________________________________________
Read more about:
FeaturesAbout the Author
You May Also Like