intermediate · 28 minute study
Movement is a vector; collision is a query
A model can look solid while its collision leaks. Reason about simple mathematical shapes first, then make the rendered world agree with those rules.
Useful preparation · 1 prerequisite
Use this as a map, not a lock. If these ideas are familiar, continue.
- Actions outlive individual input devices — Supporting keyboard, touch and controllers becomes fragile when every mechanic knows device-specific buttons. More devices should add adapters, not duplicate gameplay rules.
First, build a mental model
A movement vector describes direction and amount. Collision asks whether a proposed shape or the path it travels is allowed. The mesh is a presentation; the collision shape is an explicit approximation chosen for gameplay and cost.
- A vector such as (3, 4) has length 5. Divide by its length to obtain direction (0.6, 0.8), then multiply by speed and time. Handle the zero vector separately; dividing by zero is not a direction.
- An axis-aligned bounding box uses intervals on each axis. Overlap requires overlap on all relevant axes. Rotation can make an AABB a loose approximation; oriented boxes, circles or capsules may fit a particular mechanic better.
- A discrete test inspects the destination. A fast object can move entirely across a thin wall between samples. A swept test considers the segment or swept volume and finds the earliest blocking contact.
- A broad phase cheaply chooses potential nearby colliders. A narrow phase applies a precise test to those candidates. Response then accepts, stops or slides the movement according to the game's rules.
- Define contact conventions: whether touching counts, how much tolerance is used, and what happens when starting overlapped. Geometry without a documented response policy is not a complete movement system.
function unitVector(x, y) {
const length = Math.hypot(x, y);
return length === 0 ? { x: 0, y: 0 } : { x: x / length, y: y / length };
}
// Restricted example: a body moves right toward an infinite vertical wall.
function crossesWall(previousX, nextX, halfWidth, wallX) {
return previousX + halfWidth <= wallX &&
nextX + halfWidth >= wallX;
}
console.log(unitVector(3, 4)); // { x: 0.6, y: 0.8 }
console.log(crossesWall(8, 26, 1, 20)); // true
// A general 2D/3D sweep must also test other axes and candidate contacts.- Before
The body's center is at 8 and its right edge is at 9. A vertical wall begins at x = 20.
- Candidate
The center requests 26, putting the right edge at 27. The right edge crossed 20 even if neither endpoint is inside a thin wall.
- Resolve
For this one-sided example, stopping with the center at 19 places the right edge at 20. A different game might slide along the wall or reflect velocity.
Production thinking
Take this beyond the example.
Regression cases should include reverse motion, thin walls, corner contacts, initial overlap, pause/resume and large deltas. Visualize hitboxes during development. Increasing polygon detail should not silently increase collision cost or change where the player is allowed to move.
Sources and further reading
Your evidence
unseen is a local learning signal, not a credential or proof of production competence.
Explain the mental model, then explicitly acknowledge it. Opening a page is not evidence.
Supported retries can complete this lesson. Independent evidence and delayed review determine the skill stage.
Next lesson · State machines make behavior explainable →