Skip to main content

Clipping vs Substepping

· 4 min read
raysplaceinspace
Creator of Easel

Like many game engines, Easel simulates physics in discrete time steps, or "ticks". There are 60 ticks per second.

Sometimes, if you have a fast-moving object, it can move so far in 1/60th of a second that it can have already passed through to the other side of a wall before the physics engine has a chance to notice it. This can cause problems like:

  • Tunneling: A bullet moving fast could pass right through a thin wall and hit someone on the other side. Ouch.
  • Penetration: For a hero jumping and landing on the ground, you want the hero to land level on the ground, and not partially sink into it before the physics engine catches the collision and pushes them back up.

Continuous Collision Detection

The way to fix this is to use continuous collision detection, but there are multiple ways to go about it, each with different trade-offs:

  1. Substepping: The physics engine runs multiple times per tick, for example not just at t=0 but also maybe at t=0.123 if that is when the collision would have happened. This produces the most accurate results.
  2. Clipping: The physics engine only runs once per tick. The path of fast-moving objects are "clipped" to their first collision, stopping them from penetrating other objects. This can make them stutter a little, but is much faster to compute because it only runs once per tick.

When to Clip vs Substep

Substepping is more accurate, but clipping is faster. The key is knowing when to choose one over the other. Here are some cases when you must substep:

  • Knockback: If your hero swings a hammer to knock back their enemy, first the hammer must close the gap between the hero and the enemy, and second it must transfer the force to the enemy. Clipping is not enough here because it only ever completes the first step and by the time it gets the second step, it's already the next tick and the force behind the hammer no longer exists.
  • Sensors: If you have a hoop that detects when the Quaffle passes through it, clipping would be incorrect because the hoop should only sense the Quaffle, not collide with it. It should not stop the Quaffle or affect its motion in any way. Substepping is the only correct solution here.
  • Bouncing: If you are making a game that relies on bouncing, like Pool or Mini Golf, you will want to substep so that the ball bounces in a physically accurate way. Clipping would make the ball travel a shorter distance than it should, and so it would not come to rest at the correct location.

The example of a hero landing on the ground is a case where clipping is okay, because there is no knockback, sensors or bouncing involved. There will be a slight error where the clipping stops the hero from sliding along the ground a little bit after landing, but it is not normally noticeable and is a good trade-off for performance.

How Easel does it

Easel chooses between clipping or substepping automatically. Essentially, if an object is travels further than its body length in a single tick, it will switch to substepping, as any errors are likely to be noticeable. This gives you more accurate results while remaining performant. All you need to do is enable continuous collision detection (intercept=true on your PolygonCollider) and Easel takes care of the rest.

An Example

The new Jumping example shows you how to make a character run and jump in a platformer game. It makes use of continuous collision detection to make sure the hero lands perfectly level on the ground, without sinking into it, every time. Additionally, it teaches you all the tricks to make your platformer feel good, like coyote time and variable jump height. Go try it!

Jumping example