drunken monkeys

 


 


Demon monkey fighter

craig donner’s struggle for collision detection


game concept

In all truth, our original design for dmf was rather vaporous and vague, but we intended to create a humorous parody on first-person-shooters like quake and doom, with stunningly appealing graphics that would blow away the competition.  The core of the game was to be centered on combat between monkeys using wacky weapons, all while running across a terrain or climbing jungle trees.  Additional (unnecessary but planned) features were tribe (team) play and capture the flag. 

I’d like to interject here with a little note on concept engineering.  The way it works goes a little something like this.  You come up with an incredible idea, such as a fast-paced, first-person, three-dimensional, monkeys swinging through the jungle, on branches and vines, with bombs, banana peels, and tribal team play kind of game.  Then the graphics “expert” (Craig) comes in and tells you that you can’t have trees.  Ooh, they’re so hard to make.  No, we can’t have swinging.  That’s too complex.  We only have ten weeks, man.  Then you concede and your concept follows your pride into that little corner where no one notices you.  Thanks. -- Yoway Buorn

We did not actually name the game until the end of the third week of implementation.  Even then, the game was in Japanese (onizaru, which roughly translates to devil-monkey), to which Yoway appended “fighter,” giving our game the English acronym dmf.  Actually, we started with “drunken monkey bomber,” then moved to “fighter.”  The “d” started as “drunken,” then moved to “devil,” and finally transmogrified to the rolls-off-the-tongue “demon.”  Of course, the whole time we’ve just called it “dmf.”

In the course of implementing dmf, we tried to make as few compromises as we could on our basic design.  We stayed with the first-person-shooter concept, with the simple goal of killing as many of your fellow players as possible.  Providing a unique twist to the game, our demonic monkey models and wacky power-ups clinched the comedic theme that gave the game personality. 

There were, however, inevitable concessions.  Although we provided dmf with a realistic terrain, and even put in some trees at the last minute, without true collision detection, the monkeys couldn’t climb the trees.  We also quickly dropped the idea of shaking the trees when a bomb explodes nearby.  The lack of true collision detection, however, provided the monkeys with another mode of movement, namely flying.  Although we didn’t have time to add the jetpack model, flying monkeys added an entire new dimension to the game, as well as more comedy.   

With regard to implementation, our initial design was to have multiple independent modules, such as graphics, sound, network, physics, and input.  Although sound, physics, and input started and remained separate, distinct modules, the graphics and network quickly became amorphous blobs of unbelievable hacks and messy code.

There remained a few memory management issues between threads that caused random unexpected crashes.  These mostly revolved around the Input menu, which was strategically not shown at the demo.  For the most part, however, each member (or often pairs of members) could work on a certain module without breaking the overall game. 

Initially, we did not decide on how do divide the workload of the game; we finally settled on a client-server model rather than a peer-to-peer model for simplicity’s sake.  The client is essentially a dumb rendering terminal, sending all actions of the user to the server.  The server itself controls the entire game state, taking data from all users, updating the current game state, and then sending it back to the clients.

In implementing our program, there were several pieces that were harder than we expected them to be. Gladly there were a couple things that turned out to be easier than we expected as well:

n         Collision detection: This was the bane of Craig’s existence. For the life of him he couldn’t get collision detection to work correctly. We would always slowly slip through the ground.

n         3-D Sound: This turned out to be a lot trickier than we expected. The DirectAudio library leaves a lot to be desired in terms of automatically allocating sound buffers. But eventually we wrote our own sound buffer management system to take care of this. I was very surprised that there was nothing in the documentation or the sample code about handling multiple 3-D sound buffers.

n         Networking: This was a lot easier than we initially thought. After pouring through all kinds of nasty Microsoft documentation about the API, we finally just used their example code. The main problem with Microsoft code, is that it generally works, but they try to hide why it works under mounds of useless code. Once we had the code running, we just added our custom messages and let it do its thing.

n         Particle Systems: This turned out to be incredibly simple given how great it looks on screen. The entire particle system code is a couple hundred lines of code. Once it was in, adding particles was a breeze.

n         Character Animation: We initially thought we would do animation as it is done in Quake-style games, namely having a separate display list for each frame of animation.  To ease the creation of animation frames and to increase the smoothness of the animation itself, we instead used Milkshape for skeletal animation.  We then loaded the model files directly into the game and rendered interpolated frames off the keyframes created in Milkshape.  Once some of the bugs in Milkshape were worked out, doing the animation was actually easy.  To modify the rendering code to only play specific ranges of keyframes took a bit more work, but was not terribly time consuming.

n         Trees: We spent a lot of time trying to figure out how we were going to do trees. Eventually we settled for some trees that we ripped off from a Nvidia demo, though we don’t collide with them.

n         Terrain creation: The terrain went from a blue square to a valley of multicolored polygons, and finally became a heightmap.  We chose a heightmap because it allowed us to simply create rolling terrains with only a bitmap.  The triangles that the game engine actually rendered were created by using the values of the heightmap as vertices. 

n         The Z-Rotation Hack: One thing we were worried about was how to send player model states such as which animation to play at a given time, and how other players know if the player is visible, invulnerable, fast, etc. It turns out that for each monkey (actually for each entity) we send 6 numbers. The x,y, and z positions, and the x, y and z rotations. The x and y rotations were used to move around the player’s camera, but the Z rotation was left unused. So we finally just put flags into the Z rotation, as they were being ignored anyways. Not quite what it was envisioned initially, but it worked great J.


Schedule:

Weeks 2 & 3

      Even from the very start, we were unable to fully keep up with the schedule we created.  During the first few weeks, the graphics, networks, input, and user interface were always able to keep up with the schedule and at times were able to go beyond the schedule especially in the graphics department.  The graphics, led by Craig, left everyone in the dust since he managed to complete 2 weeks worth of work for each week of the first 2 weeks.   Text messaging was actually done in the 3rd week as opposed to the 5th since it was useful to test how well the network and graphics integrated.  However, physics and art lagged seriously since physics lacked a context in the game for much to be done and everyone was to busy work on the art. 

Week 4

As week 4 came about, Yoway and Sunny were transferred over to the art department to compensate for the lack of work that was being done in that department.  Physics, by then was decided to be a stripped down version than what was anticipated earlier since as the game developed we realized that not much was being done in terms of physics.  The pace the graphics had taken in the earlier weeks had slowed down considerably by the question of how to create the world structure.  In the game specs, the trees were to be an integral part on the gameplay, but the question of how to do the actual collision with the tree became an enigma that elluded the group.  Refusing to be bogged down by this, Craig rushed forward in his usual gusto to include lens glares and a moving sky that cast shadows on the ground, features that weren’t even on the original specs.

Week 5-6

Since art was started only at the beginning of the 4th week, everything for the 5th week that was related with integration between the various departments and art was delayed.  Rotation however, was completed by John by displaying a set of axes for each of the clients.  Player location was also represented by the axes, and players were able to transmit location updates to the server which it would then broadcast it back to everyone else.  (This is the first time we first saw actual interactivity with the players so some of us had the strange idea that we should redo our whole game concept from monkey fighter to axes fighter)  Also, the world management was completed by John and Kuowen, which would then be the basis how the server managed entities and how it would transfer information to the client.  Monkey sense and grappling hooks were however given up on due to the fact that at this point there was no collision with the the entities and the world (nothing to hook onto) and that monkey sense would be too much work for too little gain.

Week 7

      With the discovery of the Milkshape loading files, we were able to start integrating the weapon and monkey models Sunny and Yoway made so painstakingly from that flawed program.  Rockets matured quickly from 2D bricks to 3D bricks to actual bananas.  The first tree models were also generated by dumping the data from Nvidia's tree demo.  Player death was triggered upon collision with a banana rocket and afterwards, the player was subsequently respawned at the origin.  (For those who were wondering why we chose to have "ewarped" as part of the kill message, the reason was that the moment a player was killed, he was "warped" back to the origin.  The "e" that prefixed the word came from a non-sensical Kuowen-esque variable, "eborked", which became our rallying cry as the weeks dragged by.)  Zoom mode, was introduced by John so that he can now snipe at everyone, while safely hidden behind the sun.  Name billboarding was also done to do character differentiation ( and also to make everyone obvious targets for John's trigger-happy monkeys.)  By this time, of course John became the person that was coordinating all the efforts in integration since he was the only one that was familiar with everyone else's code (since he had helped all of us with our code at one point or another).   Craig also began changing the whole world (yet again) and added multitexturing, a new welcome screen, and procedural textures.  The world ended up looking much more detailed since now you are able to actually distinguish one pebble on the ground from another.  We gave up on the ideas on most of week 7's advanced features since we didn't even have a basic game sequence at this point.

Week 8

      Since we had the basic structure of the game up, we now can begin implementing some of the more complex stages of the game sequence.  John added randomized monkey colors, and Sunny allowed for input in the menu to change the colors through that.  Kuowen then adjusted the input so that multiple changes can be registered with one press of the keyboard.  An end-game state was finally introduced so that once a set number of kills has been reached, a message pops up showing the number of kills each person has inflicted.  John added explosions and rocket trails to each of the rockets to make them look more realistic.  (A trio of bananas flying towards you without some type of trail just doesn't manage to strike fear into the hearts of the players)  Railguns and a prelimary coconut bomb were put in to add for more diversity in game play.

Week 9

      The ideas of the "power-up coming down in parachutes" was introduced from the last meeting with Professor Voelker due to the ease of implementing them, so we went right to work with that.   The original idea was for power ups to come from at random points and getting stuck in trees (provided collision detection worked) so that players will be forced to go into the trees to collect powerups and also so that John will have to come down back to the playing arena once in awhile to collect more ammo.  Sunny and Yoway contributed to the art for the powerups and John added the necessary code in the server and client modules for the power ups to exist.  With power ups, you need some type of count for ammo, so an ammo count was displayed on the HUD.  Before this point, the collision Craig introduced was still buggy at some areas so his collision detection was never put into the group workspace (he had his own workspace to experiment on his own).  Instead of having monkeys slip underneath the ground, a height map collision detection was provided by John so that the monkeys will appear to walk on land.  Monkey animations were also integrated so that the monkeys animations will match its actions.  The integration between sounds and player actions began this week since we finally had a computer in the lab with a sound card.   The Blizzard sound raid Craig, Kuowen, and Yoway took proved to be very worthwhile as the sounds were just spetacular in accurately depicting the actions.

 

Week 10

      We did a huge amount of work the night and morning before the game demo.  We added two more powerups, the Voelker portrait, and the Wheaties cereal box, which added a whole new dimension to the game play.  (Of course when this was introduced, "Bob", aka John, began monopolizing these new powerups and prevented anyone from ever killing him again.)  John introduced the "Akira" explosion such that when a rail trail hit a rail ammo canister, an explosion would engulf the whole playing area.  More background music was added and we now had interactivity in the "Audio" menu thanks to Kuowen, John, and Yoway.  Correct weapon animations were also introduced and the weapons now correctly corresponds to the current action from the player.


software methodology

Our approach to designing DMF involved a combination of object oriented programming and package reuse.  Specifically, most modules of DMF were implemented in some sort of class.  This hid most of the DirectX-specific implementation details from the other modules, effectively providing a simplified interface for each module to be accessed by other modules and the entire game engine.  There are exceptions however, such as graphics and world management where global variables become an asset because they simplify access to data and also provide a small performance boost over more structured programming.

We ended up using a whole slew of third-party packages and libraries.  The most significant component of DMF is the graphics engine, which was written entirely in OpenGL.  Using OpenGL proved to be very helpful in abstracting hardware specifics from the programmers, and in making graphics generation easier in general because of all the pre-written functions for performing common graphical actions.

Another reason that we decided to go with OpenGL is that two of our programmers are quite proficient in it, specifically, Craig Donner, who designed the “Kokoro Graphics” engine using a combination of pre-written code and original code.

The lens flare effect was created by Craig form an online tutorial.  The particle system was written from scratch by John.  The textures for the particle system were stolen.  The text library and the 3D text functions were also stolen.  The procedural textures were derived from the Xterminate Terrain Engine.  Height mapping was derived from the OO engine.

Models were created in Milkshape 1.5.5, and were loaded using code provided by tutorials on NeHe.  Targa texture loaders were stolen.  The models for the trees were created by modifying a tree creation program from Nvidia.

All other aspects of the graphics engine were written originally by Craig after hours of poring over papers on the different aspects of graphics engine design, including frustum culling and the ultimately-not-implemented-but-it-would-have-been-cool octree.

The networking module, created by Sunny Chow and John Rapp, involved modifying the DirectPlay sample “simpleclientserver.cpp”.  The DirectPlay API proved to be quite complicated, so this sample code was a lifesaver.

The input module, created by Kuowen Lo, also involved using the DirectInput sample code.

The sound module, however, was not quite as straightforward, because the sample code in the DirectX documentation was extremely limited in that it did not provide any samples of positioning multiple sounds in three-dimensional space.  So, Yoway Buorn had to write a wrapper class entirely from scratch using the absurdly complicated DirectSound API.  The sample code did, however, provide some insight into how the wrapper class should be written.

The sound module also involved implementation of an MP3 player.  The MP3 player class is a wrapper class for DirectShow, provided by some guy who had some program called Step8.  The wrapper class made playing MP3s very simple, and we did not have to modify it at all.  We simply called the functions to initialize the MP3 player, then loaded the MP3s and then exposed the MP3 player interface inside CmonkeyAudio.

Specific to our implementation in C++, templates were very useful in giving us quick access to advanced data structures like stacks and lists.

 

team mechanics

Although very rough at the start, the use of WinCVS proved to be very helpful in maintaining an always functioning code base. 

The majority of team communication took place over e-mail and through the use of our website.  The DMF website features status report forms on each aspect of the game design.  Each week, when a team member completed a certain amount of work, he would enter a status report which would automatically be e-mailed to the rest of the team members.  Anything not related to development status was just sent over e-mail.

For the most part, the team moved quite fluidly.  On the not-so-often occasion that someone slipped up, we would place the team member in question on the stocks, and place him in the middle of Price Center, and humiliate him in front of millions of his fellow students.  This proved quite effective at the most critical times.

John Rapp proved to be very useful at times of total confusion.  His ability to increment numbers in VIM using CTRL-A and CTRL-X also proved a godsend.  One particular occasion stands out.  As Yoway was trying to load syntax highlighting into VIM, he encountered difficulties with carriage returns not converting correctly when transferred.  Luckily, John was there to get Yoway back on his feet.  The game would not have compiled if it was filled with ^M’s.

Overall, the most important factor in the development process was individual participation.  Several times a week, all of us would come together at the OSTL lab, and stay there until the wee hours of the day working on various things.  If at any time, someone was left idle, some task would be found to keep that person busy.  If anybody was unable to make it, someone would be available to take on his tasks.


unforseen difficulties

Milkshape 3.5.5.  This program sucks.

DirectSound.  This interface sucks.

WinCVS.  Sometimes this program sucks.

Craig sued Yoway for two million dollars.

 

Second chance

Given the opportunity to start this project over from scratch, we would have hidden Kuowen’s stash of Red Bull from him, so that he would get some sleep and be able to come into lab with a clean, non-ripped shirt.

We also would have devoted more time to working out the gameplay and game cycle.  It turned our that the last few days, which we spent on creating power-ups, were the most valuable days throughout the ten week period.  The addition of power-ups contributed greatly to gameplay.

Although we were using WinCVS to maintain an always-runnable code base, we still had problems with not keeping logs and with leaving bad code in the repository.

Although the program ran pretty well most of the time, random crashes would occur because of memory allocation problems.  If we could go back, we would have implemented mutual exclusion to take care of this.

On the graphics side, we would have included environmental elements such as rain, falling leaves, wind, a moving sun, and a variable time of day.

On the audio side, we actually had an enormous library of really nice sounds.  However, we ended up using less than half of the available sounds.  This would have involved making the game more event driven so that the exact time a sound needed to be played would have been known.  This also would have involved implementation of certain features that we did not have time to implement such as the shotgun and the environmental elements.

 

course feedback

The Windows API book was helpful.  Writing Solid Code was funny.  Especially the subtitle: “Microsoft’s Secrets to Writing Bug-Free C Code.”  That was really funny.  That book probably would have been useful, but we’re already the best programmers in the world so no problem there.

The order of the day is graphics.  If you do not have a graphics expert, you will suck.  Preferably, you want someone who has taken MAE 293.  You also want everyone in the group to have some sort of graphics background, even if that means concurrent enrollment in CSE 167.

One suggestion that stands out came from Sunny.  He suggested that the class get together and throw a kegger every week, so that students can get to know each other and provide help to each other on various aspects of game development, and maybe even get drunk and talk about flying monkeys.

Teaching Assistants who have taken the advanced graphics course should be available.

All the software provided was very useful.  The MSDN library on CD’s would have also been helpful.  It would also help to provide a database of links and resources available for the class.  All the models and software that we used proved to be extremely helpful.  Especially Milkshape, with which we created most of our models.

We also suggest that professor Voelker start his own warez site.  Specifically, the site should have copies of Lightwave, Photoshop, 3DS Max, Bryce 3D, SoundForge, CoolEdit, and 3D Exploration.  Of course, there is always the option of purchasing licenses.  Maybe the school could provide funding for all of this.  No, wait, then the Dean will want to be in the intro video.