Gibs!

Published on 21/09/2011

A good friend of mine recently tweeted that graphic artists often think that the only thing that needs to go into a game is good art. As someone who writes code for a living, it’s always interesting to see the disconnect between aesthetic and application. What people see versus what people fail to consider.

I’m in the process of writing a hobby game for the iPad that’s fairly far along in terms of development, but still an infant where aesthetics are concerned. It’s full of programmer art and debugging messages and generally things people don’t attribute to a polished product. So today I thought it would be interesting to document just how much work goes into a seemingly simple detail: handling player death and giving visual feedback.

In video games when players meet a grisly end their bodies are often gibbed. A gib, in this case, can be thought of as a chunk of meat or an appendage. In other words: generally stuff you want to keep about your person. Duke Nukem 3D was famous for its elaborate gib sprites (including everything from eyeballs to ribcages and, of course, the ultra-rare testicles).

Fortunately, the game I’m putting together isn’t 3D (or even faux-3D). In fact, it borrows more from the older generation of side-scrollers and platformers. So when it came to adding gibs to our game, I looked to more recent examples, such as the gore-heavy Super Meat Boy.

Jetpack Janitor (as I’ve affectionately nicknamed it) sees players navigating a variety of levels as a jetpack-clad janitor. You’ll move through various levels in a bid to return power to the ship you watch over, avoiding obstacles and hazards as well as solving various physics-based puzzles. Here’s a rough snapshot of a test level featuring a few keys, a closed airlock, and a wall of buzzsaws. You’ll have to excuse the programmer art.

When Stan (that’s our janitor) hits a buzzsaw, he is killed immediately. What we want to do today is not only kill Stan, but also have his body cut into ten or so meaty chunks and distributed about the level.

The Jetpack Janitor engine has been built from the ground up to integrate with the box2d physics engine. This means that every entity (object on screen) is represented by a physics-enabled object. The graphics you’re seeing, from the tilemap that makes up the level, to the player sprite and particle effects, are simple graphical representations that are updated by the physics simulation at regular intervals.

To get the ball rolling, I went ahead and created a Gib class. Because we wanted our gibs to roll around the ground after landing on a surface, I modelled each Gib instance as a circular dynamic body. By turning on debug rendering, you can see that now, when Stan explodes, his body is replaced by three Gib instances (shown here above the buzzsaws):

Unfortunately, while the Gib instances behaved as expected, something felt a little off. I spent a while tweaking their restitution and friction before reaching a point where things felt ‘right’. Finally, I increased the number of Gib instances spawned on death and made the radius of each Gib randomly decided upon instantiation.

With the Gib instances behaving nicely within the physics simulator it was time to up the gore level slightly by allowing each instance to create a finite number of decals. A decal is created each time a Gib collides with a static physical body (such as a wall). In this case, each decal represents a bloody stain that gets painted onto the level geometry.

The plan here was to use a single decal sprite which would then be rotated programatically to fit against the surface it had collided with. As you can see from my initial tests, the method I had hoped to use as a means of calculating decal rotation didn’t quite make the grade. You’ll notice some blood smears towards bottom of the screen are incorrectly rotated.

There are, of course, far more bullet-proof means of calculating the angle and position of such decals. But for our purposes, a simple check against the point of collision versus the relative position of our body seemed to suffice.

With decals working nicely, it was time to work on the actual Gib rendering code. This was a fairly simple case of scaling the meatwad graphic based on the randomly chosen Gib radius. Below I’ve included three screenshots of Stan meeting an untimely end:

So what’s next? Before this code can be considered final, it’s now time to hand it over to Glynn for an art and sound pass. As a result, the code I’ve written is likely to change to encompass the following requirements:

  • A random variety of splatter decals and gib sprites
  • Particle effects during the players initial ‘explosion’
  • Particle emitters tied to each Gib instance
  • And finally, the ability for Gib instances to generate squishy sound effects upon collision with other entities

Hopefully this post has given an interesting insight into the amount of work that goes into even a simple game element.