Physics & Animation
Collision detection in two phases, why the timestep must be fixed, and how skeletal animation blends into it.
Convincing, Not Correct
Two problems make up most of it. Detection — what is touching what — is a search problem that must not degrade to comparing every object with every other. Response — what happens next — is an integration problem that has to stay stable when the frame rate moves.
Collision Detection
Comparing every pair of objects is O(n²): a thousand objects means half a million tests per frame. So detection splits in two.
| Phase | Job | Uses |
|---|---|---|
| Broad | Reject pairs that cannot possibly touch | Bounding boxes, spatial grid, BVH |
| Narrow | Exact test on the few surviving pairs | Real shapes, SAT, GJK |
The broad phase is where the algorithmic win is, and it is a spatial data-structure problem — a uniform grid, a quadtree, or a bounding volume hierarchy that lets you discard whole branches at once. The narrow phase can then afford to be precise, because it only ever sees a handful of pairs.
Keep collision shapes simple. A character is a capsule, not the rendered mesh. Colliding against detailed geometry is expensive, unstable and almost never what the design needed.
Integration & the Fixed Timestep
Integration advances velocity and position by one step of time. The naive form works and is stable enough for most games, as long as the step never changes size:
velocity += acceleration * dt;
position += velocity * dt;
A variable dt makes results depend on frame rate. Worse, one long frame produces one enormous step, and a fast object moves from one side of a wall to the other without ever being inside it. That is tunnelling, and it is why a bullet passes through a door.
| Problem | Fix |
|---|---|
| Frame-rate-dependent results | Fixed timestep with an accumulator |
| Fast objects tunnelling | Continuous detection — sweep the shape along its path |
| Jitter at rest | Sleep bodies below a velocity threshold |
| Spiral of death after a hitch | Cap the number of catch-up steps per frame |
Skeletal Animation
A character mesh is bound to a skeleton — a hierarchy of bones. Each vertex is weighted to a few of them, so moving a bone moves the surrounding surface. An animation is a set of keyframed bone transforms; playback interpolates between keys, using slerp for the rotations.
Blending is what makes it look like movement rather than a slideshow. Walk to run is a weighted mix of two clips driven by speed; turning is another blend on top; a wave can play on the upper-body bones while the legs keep walking. A state machine decides which clips are active and how fast the weights move.
Root motion decides who moves the character: the animation itself, or the gameplay code. Animation-driven motion has no foot sliding and reads beautifully; code-driven motion is precise and predictable, which multiplayer and platforming usually need more.
Interview Questions
Why split collision into broad and narrow phases?
Testing every pair is O(n²). The broad phase uses cheap bounds and spatial structures to reject almost everything, so the exact tests only run on a handful of surviving pairs.
What is tunnelling and how do you fix it?
A fast object moves further than its own thickness in one step and is never overlapping at any sampled moment. Continuous collision detection sweeps the shape along its path instead of testing endpoints.
Why must physics use a fixed timestep?
Integration results depend on step size, so a variable step makes the simulation behave differently at different frame rates and destabilises it after a hitch.
What is the spiral of death?
A slow frame queues extra catch-up physics steps, which makes the next frame slower still. Capping the steps per frame breaks the feedback loop.
Why use simple collision shapes?
Capsules and boxes are cheap and numerically stable. Colliding against a full render mesh is expensive, jittery, and rarely matches what the gameplay actually needs.
Root motion or code-driven movement?
Root motion removes foot sliding and looks better; code-driven movement is precise and predictable, which multiplayer prediction and tight platforming depend on.