Chipmunk2D for Platformers.

Physics engines and platformers are apparently a pretty good way to start flame wars on the internet. It’s definitely possible to make really bad physics-based platformers, and there are some pretty common hacks to do it that work quite poorly. Things don’t need to be this way!

Locomotion Commotion

How do you make a character move in a physics based platformer? Do you modify the position of the character directly? That’s almost always a bad idea in a physics engine and will lead to mushy or glitchy collisions. How about setting the velocity of the character? Getting warmer, but this is still likely to produce huge collision forces if the character runs into anything. So how about calculating and applying forces? This is a much better idea except for one problem… How do you calculate the force? To push the player along, you need to overcome the force of friction, deal with inclines, deal with standing on moving platforms, …, etc. This is hard and the end result isn’t that your character is walking around gracefully, it’s more comparable to pushing around a box without any wheels. What if you fiddle with the friction of the character, but only when it’s moving or … (Give up now! Hope is nearly lost!) It’s possible to make a game with hacks like this, but it’s a very frustrating path.

Friction is your Friend

So what’s missing here? For starters, when a person walks around, they aren’t a simple shape like a box or a circle. That’s half of the problem. A person stays in roughly the same shape, and it’s perfectly reasonable to approximate them with something simpler, but this doesn’t let you model how their feet work. Chipmunk2D solves this by providing the concept of surface velocity, or how the surface of a shape is moving even if the shape itself is not. The simplest example is a conveyor belt. The overall shape of the conveyor doesn’t change, but it’s surface moves around. A platformer character stays (reasonably) box shaped, but the bottom surface of the shape (it’s feet) moves.

Using Chipmunk2D surface velocity to move a character is much more similar to the real world. Your character’s feet move backwards, and friction with the ground makes the character move forward. If you are standing on a moving surface, it “just works”. If you are standing on a dynamic object, that also works. If you want your character to accelerate or skid to a stop, that works too! The only real difficulty is setting up friction to get the result you want.

Your Story was a contest game I collaborated on a few years ago. It uses techniques I talk about in this post. Check it out on GitHub

You’re Grounded!

One of the basic things you need to know when making a platformer is if a character is on the ground or not. When using a physics engine, how do you know if a character is grounded? With some physics engines, this can be pretty difficult to track. If the game has it wrong, you might not be able to jump or walk. Animations can be played incorrectly. That sort of thing. Sometimes it’s easier to be able to check this with your own code.

Each time the physics is stepped in Chipmunk, it saves the contact graph. You can ask any body which other bodies (and shapes) it’s colliding with, what the collision normals are, what the collision overlap amount is, which points are touching, etc. Checking if you are grounded becomes pretty simple. Just check if there is a collision with a normal that points upwards.

Welcome to Sloppy Joe’s

One pretty valid complaint against using physics engines in platformers is that they can produce “sloppy” collisions. They are generally imprecise since they prioritize performance over extreme accuracy. Sometimes objects overlap a little and sometimes joints stretch out. The problem in both cases is the same. The physics engine is trying to solve several collisions and joints at once, and sometimes their solutions fight each other.

Chipmunk doesn’t really have an edge here. It has the same problems as any other iterative solver. The secret I discovered is not to care. Let the simulation do what it wants and fix the imperfections when you draw. If the player sank into the ground a little from a hard landing, just use the information from the contact graph to push the character out of the ground. When working with joints, project the objects together as if the joint was working perfectly. The graphics will look perfect, and the difference in the simulation will be very hard to notice.

In other cases, you will simply have to design around deficiencies. Everybody has seen physics glitches in games. Do what you can to avoid them by limiting the interactivity. If there is no crate to wedge into the bunker door, then you can’t make a glitch with it. Obviously that advice isn’t 100% practical, but try to keep things simple.

Don’t Step on a Crack

Physics engines hate sharp corners, and they get their revenge by letting things get stuck on them. Players hate getting stuck on things and get their revenge by giving your game bad reviews. Even cracks between objects can cause problems. I don’t think I’ve seen a physics engine that can gracefully handle two squares placed flush together. You’ll always catch on that crack!

Chipmunk doesn’t have a magical solution to this exactly, but it does give you the option to round the corners on all of it’s collision shape types. If the corners are rounded off, then there is little to catch on. Even better, if you round all the corners, the collisions will react more smoothly and predictably too. Players like that. Rounding the corners actually improves the collision detection performance. When using segment collision shapes, it’s possible to give them information on their neighbors to avoid catching on internal edges. Put together, it may not give you a perfect solution, but it’s a pretty good one.

Fits like a Glove

Old game consoles could do hardware accelerated, pixel perfect collision detection. How much more accurate can you get right? For some people, this is the pinnacle of 2D collision detection and they are disappointed that it’s difficult to replicate on modern systems. On the old 2D consoles, it was a necessity to free up their very slow CPUs from needing to run collision detection. Making it pixel perfect was simply a way to save memory and silicon by combining the rendering and collision detection into a single step. Quite ingenious, although generally with some serious limitations. Sprites were often limited to having two collision types, player or enemy. The collision detection is also limited by the same constraints as the sprites. Collisions only happen onscreen and the number of sprites per row of pixels was limited. Collision information is also limited to a yes/no check if a player sprite is touching an enemy sprite.

Modern GPUs work based on triangles, fancy blending, 32 bit color and high resolution framebuffers. Per pixel collisions really aren’t very practical anymore. That leaves you with other bounding volumes like circles, rectangles and polygons. You’ll never get a per-pixel collision test with that right? *sigh* Well, do you really need one? You’ve probably played a number of games that approximated the player with a simple circle or rectangle and wasn’t even aware of it. In my experience, I’ve found that nice rounded shapes like circles, or well rounded segment or rectangle shapes work great. It’s really just a question of which fits the closest. They key is to keep things simple and make it match just close enough.

What about collision geometry for levels? How do you make physics shapes for a tilemap or image chunks? Tilemaps are fairly easy using something like marching squares, or by storing a polygon for each tile. It’s easiest to do this as a preprocessing step when compiling so you can write easy but wasteful code. Doing it at runtime is harder since it needs to be reasonably efficient.

Collide and Conquer

One benefit of DIY collision detection is that it gives you ultimate control over how and when to check for collisions, what collides with what, and how to handle it. Some physics engines are so physics oriented that they take away too much flexibility in order to simplify everything down to the same simple set of rules. You only get a few, static criteria for filtering, and slow, awkward constructs for being notified of collisions.

For static filtering, Chipmunk2D provides a layers bitmask and a group identifier. It also lets you filter collisions dynamically using callbacks. On that note, Chipmunk2D provides what I call collision handlers. Basically you tag collision shapes with types, say player, monster or bullet, and then register a sets of callbacks for when certain types collide. For instance, say you only want to know when a player collides with a monster or when a monster collides with a bullet. These callbacks are pretty powerful. They can override collision properties like the restitution or friction coefficients, they can calculate a custom relative surface velocity, they can even override collision points. As mentioned before, the callbacks can also filter out collisions entirely. I came up with this system after being frustrated with how inflexible other physics libraries were.

This will be taken a step further in Chipmunk 7. One of the early features I implemented was wildcard collision types. Basically you can find out when a bullet collides with anything else and still have all the power of regular collision handlers. I also replaced collision layers with the slightly more flexible category/bitmask system used by several other physics engines.

Cartoon Physics

There are a number of physics oddities in platformers to make them fun instead of realistic. If Mario was a real person, he would jump 5 meters high in a way that defied gravity. He can also change direction while falling! Platforms float through the air. Surfaces that can only be walked through or jumped through one way. Running on water. Goofy stuff like that. So how do you make it all work with a physics engine? Well I’ve done it all, and nothing was terribly complicated given some insider knowledge on how physics engines work. Most of this is implemented in the Your Story game above, but here’s a quick rundown of what has worked well for me.

Jumping: Most platformers implement this using a simple impulse. Easy enough by doing body.velocity.y += someValue. To control the jump height, gravity is disabled for as long as the jump button is held down up to a certain limit. Chipmunk allows you to override how velocity integration works making this relatively easy too. Integration callbacks are also a pretty good place to implement air control or falling speed. You can skip using forces and modify the velocity directly.

Moving Platforms: There are several ways to implement platforms. You can use rogue (kinematic) bodies, or soft constraints. Kinematic bodies are powered by unstoppable forces while constraints are not. Both have their tradeoffs.

One Way Surfaces: Chipmunk makes this very trivial using a simple collision handler.

Still, Why Physics?

Ok ok. So maybe I’ve convinced you that it’s possible to make a platformer that doesn’t suck using Chipmunk2D, but does that make it better than rolling your own platformer physics? The answer depends on what you are doing, but there are definitely advantages. The biggest reason is that it opens up possibilities. Platformers have been around forever, and in a lot of ways are tired and old. Adding a full rigid body physics engine opens up a lot of possibilities for implementing new ideas. It gives you the opportunity to add a lot more interesting interactions to your games and have things that animate in interesting and natural ways. Implementing vehicles without physics? Sounds hard. It can also save you a lot of work. You get fancy, high-performance collision detection for free. You get queries for free (point queries, raycasts).

Physics engines may not be for every game, but don’t reject the idea too quickly because you’ve had bad experiences with them in the past. Maybe you just haven’t tried the right one yet. 😉