Game Development Community

dev|Pro Game Development Curriculum

Next we make it look good...

by Paul Dana · 05/09/2008 (7:47 am) · 39 comments

Next we make it look good...

www.plasticgames.com/research/zombie/images/zombie_model_comp.jpg
Plastic Games has been working on a co-op Zombie game prototype.

You can play the prototype. Download the zip here. Get your friends to download and play together!

You can watch a video of game play here.


Keep in mind this is a gray block prototype. It is like a rough draft of one chapter of a book. It shows enough game play to see if people would want more. It does not represent the game play of a complete game. The question it asks is: is it fun to kill zombies like this with your friends?


1. Make it Play Good...

Clearly I have failed at my resolution to blog more often, as a result this blog is somewhat lengthy. As I mentioned in my last blog, Plastic Games has been spending time between contract jobs prototyping a co-op Zombie killing game. We realize this is not an original premise. We find our prototype to be fun and we think you might too. We encourage you to checkout the game play in the video link above and if it looks fun download and play it. It is the most fun in co-op mode and we have a server running. Tell some friends about it and play it together.

When I last blogged I mentioned that we had just "found the fun" in the game and were excited to show it to people. Prior to this we were discouraged because the game wasn't very compelling in single-player or co-op. We had improved the performance a bit and had fixed some bugs and the single-player experience got a bit better and so we decided to try to play it on co-op mode and see how it was. It was fun! Granted there were still issues but the fun had at last been found. Turns out we were pretty close to the fun already but performance issues and bugs were hiding it.

www.plasticgames.com/~kirk/blog/zombie/pg_zombie01.jpg
The problem remained that the performance was still crap. We had improved it enough to see the game better but it was still crap, even in single-player without any networking issues. In co-op it was even worse. The only reason we were having fun playing co-op is we knew how all the effects were *supposed* to look (from single-player) even if more than half of it was not showing up in a co-op game. Animations would be skipped or come late, zombies would just slide or warp at you with no animations, blood particles would not show up, the frame rate was terrible especially with lots of zombies on screen.

The solution was to just focus on performance until the feedback we already had in place could be seen more clearly. Later we could work on improving the feedback as well.

2. Make it Run Good...

The art assets we used for the prototype either came from content packs or were interiors that we already had from previous projects or had developed as part of our own testing. Much of it was not optimized in any way. Similarly much of the code we put together for the prototype was script code that got the job done quickly but wasn't very fast code.

So clearly we had some ideas where to start in improving things but, as always with optimization, the place to start is with measurement. Naturally we need to be able to quantify where the performance was suffering before we would know which parts of the code need improving or even to know if any one code change actually helps.

Gemming

www.plasticgames.com/research/zombie/images/plastic_menu.jpg
We did a series of tests with test maps to determine what affected frame rates the most. At Plastic Games we have a philosophy of "Gemming" problems. This means that when we go to solve a problem we try make some part of the solution reusable; a little "gem" of code or whatever that will help us in the future. In this case this meant making script code for *duplicating* objects in a mission file in a regular grid of 3x3 or 5x5 or 7x7. We used this as a way of constructing our test maps procedurally from simple inputs. It also meant creating some code for hiding or showing certain classes of objects so we could do FPS tests without having to actually laboriously go through and hide or show large number of objects. We also made a handy method of temporarily moving the visibility distance way out. It is reset back to what it was automatically before you either SAVE or LIGHT the scene. This helps in the editor to just see what your editing without accidentally changing your visibility settings.

Debug Render Modes

www.plasticgames.com/research/zombie/images/interior_render_modes.jpg
Now that we had confirmed where performance needing improving we prepared for that work. We knew we would need to create some more custom INTERIOR assets for this prototype with proper LOD and such and we decided to use that as an opportunity to create some proper grey-blocking art assets. As part of the need for measurement we took advantage of the Interior Debug Render modes Torque has always had. There is a resource out there for accessing these modes with a dialog so we merged that resource in.

The Show Detail Level render mode is a great help. It color codes the different Interior LODs as: White, Blue, Green, Red, Yellow...with white being the closest, etc. The colors changing in game as you walk around tell you the LODs are changing.

LOD Profile

Another opportunity for Gemming came up when we considered how much of pain it was to update the values that controlled the LOD. We would have to go back to the .map file and update and create a new .dif file, etc. To ease this pain I created the LODProfile:

datablock PlasticLODProfile(GB_LGTEST_LODPROFILE)
{
   geometryFile = "~/data/interiors/greyblock/gb_lgtest.dif";
   detailValue0 = "400";
   detailValue1 = "128";
   detailValue2 = "60";
   detailValue3 = "12";
};

datablock PlasticLODProfile(TEMP_LRG01_LODPROFILE)
{
   geometryFile = "~/data/interiors/greyblock/temp_lrg01.dif";
   detailValue0 = "400";
   detailValue1 = "150";
   detailValue2 = "60";
   detailValue3 = "12";
};

// etc...

An LODProfile is used to override the LOD values stored in the .dif file. To tweak the values that control LOD changes we only have to update this datablock, not re-create the .dif file.

Tweaker

Speaking of tweaking...previous Gemification here at Plastic Games had already given us the Tweaking system. Explaining the origins of this tool we created would take too long so I will just describe what it does. It is a tool to help in the tweaking of game parameters. It helps the programmer expose whatever parts of the script he wants the game designers and testers to be able to tweak. The game designers and testers can user the Tweaker GUI to make and test changes the result is written back out to the scripts. This is very handy.

The way it works for the programmer is also very simple: it uses commands embedded in scripts to indicate which things should be tweakable. For example the above datablocks actually look like this so they can expose some values to the Tweaker system:

datablock PlasticLODProfile(GB_LGTEST_LODPROFILE)
{
   geometryFile = "~/data/interiors/greyblock/gb_lgtest.dif";
   //P[ GrayblockLODProfiles
   //-----------
   detailValue0 = "400";
   detailValue1 = "128";
   detailValue2 = "60";
   detailValue3 = "12";
   //P]
};

datablock PlasticLODProfile(TEMP_LRG01_LODPROFILE)
{
   geometryFile = "~/data/interiors/greyblock/temp_lrg01.dif";
   //P[ GrayblockLODProfiles
   //-----------
   detailValue0 = "400";
   detailValue1 = "150";
   detailValue2 = "60";
   detailValue3 = "12";
   //P]
};

// etc...

At runtime, when the game designer or game tester calls up the tweak panel the game scripts are parsed and then a panel like this is displayed:

www.plasticgames.com/research/zombie/images/tweaker.jpg
Now I can play around with the LOD numbers to get the result I want. Here is an example that shows the use of the Torque Show Detail Level Interior render mode and the tweak system. Remember that WHITE means the LOD zero the most high detailed, then BLUE, then GREEN. In this example there are only three levels of detail. Notice how the scene changes as we tweak the LOD numbers:

TEMP_LRG01_LODPROFILE.detailValue1 = 150

www.plasticgames.com/research/zombie/images/lodprofile_150.jpg

TEMP_LRG01_LODPROFILE.detailValue1 = 200

www.plasticgames.com/research/zombie/images/lodprofile_200.jpg

TEMP_LRG01_LODPROFILE.detailValue1 = 290

www.plasticgames.com/research/zombie/images/lodprofile_290.jpg

DTS LOD Render Mode

DTS Shape objects (like the player and trees and fences) also have LOD settings.

www.plasticgames.com/research/zombie/images/dts_lod_normal.jpg
They are not such a pain to setup as Interiors are and there is ShowTool Pro to view the settings. However it can still sometimes be hard to relate distances as you see them in ShowTool and in-game so I created a debug render mode for DTS shapes that is similar to the Interior Show Detail Level render mode and using the same color code: White, Blue, Green, Red, Yellow, etc:

www.plasticgames.com/research/zombie/images/dts_lod_colors.jpg
Using these tools and our test maps we were able to determine appropriate budgets for shapes and interiors and appropriate distances for LOD changes.

Networking

www.plasticgames.com/~kirk/blog/zombie/pg_zombie09.jpg
So the improvements to the frame rate helped but were not enough as the networking needed improvements as well. You can see the above image from my last blog post. That screenshot was taken in co-op mode and you can't even see any blood at all from that bat impact. Not good.

The problem is how the blood particles are implemented. We had updated the Projectile class to allow a different explosion when a projectile hits a player. This explosion we setup to be a blood particle explosion. This is how the projectile blood was handled. For the bat and zombie scratch we created a blood explosion and set it going.

Ok you ask...so what's wrong with that implementation? Well the biggest problem is that it ends up sending information from the server to the client that, as such, the client should already know. The projectile or a bat swing hit the player on the server. The server sends a damage update to the client. But then also the projectile explodes (or the bat scripts create a blood explosion) and that info is sent to the client. By the time that info is received enough time has gone by that the explosion is actually over with and you never see it.

We can do better

www.plasticgames.com/research/zombie/images/blood.gif
What I did was extend the damage code to include information needed to have the client create all the damage FX itself when the damage was received. Turns out there is already a "damage vector" showing what direction damage is coming from (that is not hooked up anywhere in the scripts that I could see) I added a damage "position" and a 32 bits to control the "type" of blood. I added a new datablock type, DamageBloodData to control things like how many particles should spawn for how much damage, etc. Here is an example of how that looks:

datablock DamageBloodData(bloodSpray)
{
   // Bit 8 is blood spray in direction of damage...
   bloodType = 8;            // if any of these bits match the incoming damageFXType then this effect applies

   particleEmitter = "bloodSprayEmitter"; // particle emitter to use for this blood effect...
   normalFromDamageDir = 1;  // if true then blood FX normal set from damageDir and following flags apply, otherwise blood FX normal set to (0,0,1)
   normalCrossZ = 0;         // if true then normal is crossed with (0,0,1) before inversion or tilting up (only used if normalFromDamageDir=1)
   normalInverse = 0;        // if true then normal is negated after crossing but before any tilting (only used if normalFromDamageDir=1)

   //P[ bloodSpray
   //-----------------
   normalTiltUp = "1";         // if true then normal is tilted UP by approx 45 degrees from horizontal after any crossing or negating (only used if normalFromDamageDir=1)
   //-----------------
   deathMinDamage = "100.0";  // min damage of a deathly blow for purposes of damage FX
   //-----------------
   minDamage = "1.0";           // damage below this does not cause this effect
   maxDamage = "100.0";           // damage above this causes max particles
   minParticles = "15";          // particles at min damage & above
   maxParticles = "50";          // 0=get count from emitter lifetime, else particles at max damage...
   minParticleVariance = "2";    // random variance at min damage
   maxParticleVariance = "10";   // random variance at max damage
   //-----------------
   posZOffset = "0.0";         // 0 = no change, larger values raise blood emitter UP
   startRadius = "0.01";      // radius for random start position of blood particles...
   //P]
};

You will notice the tweak codes again. Note that any comments that are provided near tweakable parameters are used to implement tool tips for that parameter:

www.plasticgames.com/research/zombie/images/blood_spray_tweaks.jpg
This system allows us to define different particle effects for different parts of damage and then specify in the projectile class (or any damage scripts) what sort of damage each projectile does.

In the game we added five types of blood emitters: Fountain, Rebound, Swipe, Spray and Stream. Each type has its own DamageBloodData datablock. The one above is for Spray. As you can see this datablock references its own ParticleEmitterData (which references its own ParticleData). Spray is the blood that shoots out the back of a zombie when you shoot it. Fountain is the fountain of blood you always see. Swipe is to-the-side splash of blood used only for the bat.

www.plasticgames.com/research/zombie/images/blood08.jpg
This system worked well and now blood particles were showing up every time, even in a co-op game. We were able to get rid of the explosions completely which also reduced network traffic.

www.plasticgames.com/research/zombie/images/blood09.jpg
This helped a lot with the feedback. We also did a similar thing for the HUD elements. They were originally implemented in script and were not very efficient. We implemented C++ code to transmit the information that used to be in scripts such as the type and amount of ammo. This made the HUD more responsive and reduced networking even further.

Where's the Mess?

In fact the blood was working so well it made another problem. The ground looked too clean for such a blood fest! We added blood DECALS to solve this. We were concerned about performance adding ray casts to each particle that were not there before, so we made only some particles actually check for collision and leave a decal behind. We ended with one out of five particles leaving a decal.

www.plasticgames.com/research/zombie/images/blooddecals01.jpg
3. Make it Look Good...

OK so that concludes the story of how we got from there to here. In fact, I have left out an amazing number of things I did not have the patience to get into, from changing game goal to a series of checkpoints, to the optimizations we tried that didn't help, and the subtle features we added to particles to make them show up better at far distances. Those things and a better description of the Tweaker system will have to wait for another blog.

The question for this zombie game, of course, is...what next? Well...next we make it look better!

www.plasticgames.com/research/zombie/images/new_right.jpg
This is, after all, just a proof of concept with stand-in art and animations. None of the experience is as rich or as deep as we would like and the quality of the art is nowhere near where we want it. We have ported this code base to TGEA technology and we are exploring making this thing look better. I will try to blog more often and keep everyone up to date. (Don't hold your breath). In the meanwhile go download the game and play. The link is at the top of this blog.

That's all?

You may ask...wait a second. Where is the back story? What about putting this fighting in a larger context with more long term rewards? All these are good questions but we feel the heart of a good fighting game is good fighting. We have a hundred bajillion back story ideas and some really great ideas for how to build the larger game around the fighting. But who cares about our ideas. We want to hear your ideas. Go play the game and tell us what you want out of a zombie killing game.

Also if we don't make it look good then nobody will bother giving it a second glance.

OK, that's all I have for now. I am starting up a small contract now so I am not sure when I will blog on the zombie prototype again. My next blog will probably be about Gemming and the Plastic Gems we have built.

Now go play the game. Preferably with your friends.
Page «Previous 1 2
#1
05/09/2008 (8:02 am)
Very cool write-up! I love the blood decals and tweakable LOD rendermodes as well.
#2
05/09/2008 (8:27 am)
Very well done. It gets pretty intense at times.
#3
05/09/2008 (8:41 am)
Awesome write up. The LOD datablocks are a really neat idea.
#4
05/09/2008 (8:44 am)
So far its looking good. I also think the blood decals and other effects really add to the game. fps could become an issue, but there are afew things you could do right now to increase it (as Im sure you know). Other than that, nice prototype Paul. Good Luck! ~LK
#5
05/09/2008 (9:09 am)
Thanks for the comments everyone.

@ Andrew: FPS is always a concern. As you can see the FPS meter is always up in the prototype.
#6
05/09/2008 (9:26 am)
Really enjoyed this blog. The gameplay and networking looks very responsive. A lot of us here can learn from your optimization ideas and implementations. Look forward to hearing more.
#7
05/09/2008 (9:54 am)
Looks like fun. My favorite zombie movie that I would die if was made into a game is Shawn of the Dead. I just plain love that movie. Except the part where they eat that guys guts. That was a little too gross. Undead are not very sanitary. Who knows what kind of disease they could get from eating raw intestines. Anyway. Good luck making this fun looking game.
#8
05/09/2008 (10:26 am)
Very cool post Paul. Next thing you know I'll be seeing you at IABPA conferences...
#9
05/09/2008 (10:31 am)
Very cool! Fun prototype too
#10
05/09/2008 (10:38 am)
Very detailed and interesting write-up. And seriously, there is no such thing as too many good zombie games. ^_^
#11
05/09/2008 (10:45 am)
www.zombieshortbus.com/nonzsb/Avatars/Fallout/100x100falloutav-tu.gifFantastic write-up Paul!

Can't wait to try out the demo this weekend.
#12
05/09/2008 (10:46 am)
Great game can't wait to see the TGEA version. Keep up the amazing work.
#13
05/09/2008 (10:53 am)
Thanks for the kind words all.

@Andy - thanks for your IABPA link, that made me smile.
#14
05/09/2008 (10:57 am)
Cool, but it DOES look way too similar to L4D or the zombie mod for CSS, leaving me no reason to test the prototype.

Take that as advice. Make it different, make me want to download it because I have seen pictures or videos of it. Otherwise, no one will want to play it because its already out so theres no reason to play a copy when you can play the original.

Good luck!
#15
05/09/2008 (11:10 am)
An excellent point Neill, and these very thoughts dominate our discussions. Turns out there are quite alot of zombie lovers out there and they have expressed the sort of game they would like to play. We would like to keep this true to the zombie genre as defined by popular movies & books on the subject. We have been researching that and have formed some ideas, but we would really like to hear from the GG community on this. Anyone want to pipe in with some ideas on what you would like to see? I am not trying to be coy I just don't want to color the debate before it has begun.
#16
05/09/2008 (11:37 am)
Quote:@Andy - thanks for your IABPA link, that made me smile.

Funny thing is - I actually do go to those conferences :-)
#17
05/09/2008 (2:23 pm)
I just wanted to note that some of us here at Wideload just lost about an hour of time playing this. It was lots of fun even at this basic level. It's great to see folks really working toward finding the fun in their play. If you guys actually finish this I'd definitely buy it. There's just not enough co-op luvin' fun out their in multiplayer world.

-Allen Turner
#18
05/09/2008 (2:45 pm)
Things I'd like to see.

It seems like the zombies move slowly then speed up when they're in a certain range. It would be neat to have some sort of state animation that lets you know they're about to charge.

A grenade. Not a lot of them but enough to soften up mobs every now and then.

Fire. Maybe a Molotov cocktail that you can throw and set a zombie on fire, then try to keep him near other zombies so the fire could spread like a disease. This could be particularly nasty if you back yourself into a corner with flaming zombies.

More design like the setup at the beginning of the graveyard bit. The experience of someone luring zombies while others snipe is awesome. That bit would be great with multiple defensible positions that let you inch worm your way through a space.

Ablative zombies. One of the more fun bits of Stubbs the Zombie was when we started letting the zombies get broken and crawl about. You get a little of this in the more recent Halflife games. The zombies that are hard to kill should fall and crawl after you. Some zombies could randomly start in this state.

Crawling zombies could be more dangerous if they were able to knock you down. It's pretty scary when the walking zombies grab you. It would be even neater to have crawling ones actually pull you down if you're not careful.

Zombies that feign death. Let us shoot some zombies and seemingly kill them only to hve them get back up.

Transformative zombies that got rougher over time. This is something that you'd have to step away from traditional movie-based Euro-American zombie for (which are more ghuls than zombies) and look at some other cultures for. A good example would be the hopping dead from the movie Fearless Vampire Hunters. Those things basically start out as a zombie and then (after they feed enough) turn into something more bizarre and dangerous.

I'd also like to vote for not another zombies from viruses that wipe out the earth story. Take a look at some of the last couple seasons of the new Dr. Who for examples of great zombie stories that feature no walking dead. the episode "Empty Child" from season one and "Blink" from season 3 stand out. There's one with evil tvs that was pretty disturbing. Bink is the best of the lot because it uses a story/game mechanic that it right out of faeire stories and Mario World.

Those are just my random thoughts right now.

-Allen Turner
#19
05/09/2008 (3:03 pm)
Random idea I had after playing the prototype a while ago:

Instead of respawning at the last checkpoint when you die your partner has to drag you to the next (or previous) checkpoint. So the player that died would still be able to shoot but their movement would be disabled and dependent on the player that's dragging them.

It seems like this could create some neat tradeoffs. While dragging, your party would move slower, but the player being dragged would end up covering the back and getting the zombies that would sneak up from behind... This would also keep the party together..

Could be annoying to get the networking to behave though.. heh
#20
05/09/2008 (6:26 pm)
The demo was good fun. I like the way they grab hold of the player - induces panic as hordes more bear down on you.

A sprint/speed-burst function might be nice, only a second or two long, to help the player try and dodge past the occaisional flailing undead.
Page «Previous 1 2