Craft·5 min read

How a Game Knows You Hit the Ground

Two rectangles overlapping is the easy part. Deciding what to do about it is where platformers go wrong.

The treetop level of the B Bear platformer, with branches and painted platforms at several heights.

Two rectangles are overlapping when each one starts before the other one ends, on both axes. Four comparisons. That is the entire detection half of collision detection, and it is not where platformers go wrong.

They go wrong in the resolution: having found an overlap that should not exist, deciding what to do about it. That decision is where a character gets stuck on a seam in the floor, slides down a wall it should be standing on, or drops through a platform at speed.

Do one axis at a time

The instinct is to add the horizontal and vertical speed to the position, then look for overlaps and push the character out of anything it is inside. It does not work, and the reason is that once both moves have happened the game can no longer tell which one caused the problem.

A character running into a wall while falling ends up overlapping a block from a direction the code has to guess at. Guess wrong and running into a wall also cancels the fall, so the character sticks to the wall like a magnet.

The fix is to do it twice.

Move horizontally. Check for overlaps. Anything found is a wall, so push back to the edge of it and set the horizontal speed to zero. Now move vertically. Check again. Anything found now is a floor or a ceiling, and which one it is follows from the direction of travel: moving down means the feet landed, so sit the character on top and mark it grounded; moving up means the head hit, so put it under and stop the rise.

Nothing is being guessed. Each check only has one possible interpretation because only one axis moved since the last one. That is the whole trick, and it is a handful of lines.

Falling through the floor

The famous bug, and the one worth understanding because it cannot be fixed by checking more carefully.

A platform is, say, twenty units thick. The character is falling at forty units per frame. On one frame it is comfortably above the platform. On the next it is comfortably below. At no point was it ever inside, so no overlap test, however good, will find one. The character has tunnelled straight through a solid object without touching it.

There are two defences and our builds use both.

Cap the falling speed. Gravity is added every frame but the downward speed is clamped to a maximum, so nothing ever moves further in a frame than the thinnest platform is thick. This is why terminal velocity exists in almost every platformer, and it is a collision fix long before it is a realism one.

Remember where the feet were. The vertical check compares the character's previous foot position against the platform as well as its current one. The question becomes "were the feet above this and are they now at or below it", which catches the frame where it passed through even though it is not overlapping at either end.

The treetop level of the B Bear platformer, with painted branches acting as platforms at several heights.
Every branch here is a rectangle the artwork happens to sit on top of. The painting and the collision shape are separate things.

Platforms you can jump up through

Most platformers let you jump up through a platform and land on it from above. It looks like a special kind of object. It is really just two conditions on the ordinary check.

Only collide when the character is moving downwards, and only when its feet were above the platform's surface a frame ago. Rising into one satisfies neither condition, so the character passes straight through as if it were not there. Falling onto the same platform satisfies both and lands.

Ours adds a small tolerance on each side of the horizontal test, so the very corner of a platform does not catch you as you pass, and a matching tolerance on the vertical so a landing at a slightly awkward speed still registers rather than clipping through.

Those tolerances are the difference between a level that feels solid and one that feels like it is snagging on things. They are also, unavoidably, tuned by playing it.

The shape is not the picture

A thing worth saying plainly, because it surprises people who have not built a game.

The character in our platformer is a rectangle. So is every platform. The painted bear, the branches, the shelves and the cassettes are drawn over the top of that geometry and have no part in the physics at all. Nothing in the collision code has any idea what the game looks like.

This is not laziness, it is what makes the game predictable. Collision against the true outline of a painted bear would mean an ear catching on a ledge, and the player would have no way to understand why. A rectangle behaves the way a player expects a body to behave, which matters more than accuracy.

It also means the artwork can change without touching the physics, which is exactly what you want when the art arrives late and the level was laid out first. That relationship is the subject of why game artwork gets drawn twice.

What this means for a commission

It is the most bug-prone part of a platformer. Not the hardest to write, the hardest to be sure about, because the failures are rare, positional and hard to reproduce by hand.

Which is why we drive it rather than look at it. The acceptance test for a platformer runs the character through the level with simulated input and asserts that it can actually reach the end. That approach is described in proving a game is actually finished.

And it is inseparable from feel. The tolerances above are the same dial as the ones in what makes a jump feel right; tightening collision and tightening the jump are the same afternoon's work.

The platformer this comes from is playable in the arcade. Try landing on the very edge of a shelf.

◆ Questions

Common questions

How does collision detection work in a 2D game?+

At the simplest level, each thing is a rectangle, and two rectangles overlap when each one starts before the other one ends on both axes. That test is four comparisons. The difficult part is not detecting the overlap, it is deciding how to undo it in a way that feels correct.

Why do characters fall through the floor in games?+

Usually tunnelling. If the character is moving fast enough that one frame puts them above a platform and the next puts them below it, they were never overlapping when the check ran. The usual fixes are a terminal velocity so nothing moves further than a platform is thick, and testing where the character was as well as where it is now.

Why is collision resolved one axis at a time?+

Because moving on both axes at once and then resolving leaves the game unable to tell whether you hit a wall or a floor. Moving horizontally, resolving, then moving vertically and resolving again removes the ambiguity, and it is what makes running into a wall stop you without also cancelling your fall.

How do platforms you can jump up through work?+

They only collide when the character is moving downwards, and only when the character's feet were above the platform on the previous frame. Rising through one therefore passes cleanly, and falling onto it lands.

Is collision a big part of a commission?+

Only for platformers, and then it is the part most likely to produce a bug someone finds later. It is why acceptance tests for our platformers drive the character through the level rather than checking that it renders.

  • craft
  • code
  • platformer
  • physics
◆ Keep reading

Related from the journal.

The bedroom level of the Tape Loader birthday game, with platforms, shelves of cassettes and the player mid-run.
Craft·6 min read

What Makes a Jump Feel Right

Every good platformer cheats in your favour. Here are the four places ours does it, and what each one is worth.

Read