Guide
Game physics explained
Game physics is the simulation layer that makes objects fall, bounce, slide, and stack believably. It sits downstream of collision detection — once you know two bodies overlap, physics decides what happens next: velocities change, objects separate, friction slows a crate across ice. Whether you roll your own integrator for a platformer or drop in Box2D for a physics puzzle, the same concepts recur: rigid bodies with mass and velocity, forces accumulated each step, numerical integration advancing time, and impulse resolution when shapes touch. This guide explains how that pipeline works, which integration methods survive large timesteps, why fixed physics steps matter for feel and netcode, and how to pick between 2D libraries, 3D engines, and kinematic shortcuts when performance is tight.
Simulation vs detection — two halves of one system
Collision detection answers a boolean question: do shape A and shape B overlap right now? Collision response (part of physics) answers a dynamics question: given that overlap, how do their velocities and positions change so they separate and behave according to material properties?
Many arcade games cheat physics entirely — they teleport the player out of walls and zero vertical velocity on landing. That is valid design. Full rigid-body simulation shines when emergent motion is the gameplay: stacking crates, ragdolls, vehicle suspension, or a dice chip tumbling across a felt table. The cost is complexity: unstable integrators explode, tunneling still happens at high speed, and networked games need deterministic or server-authoritative solvers.
A useful mental model: detection is geometry; physics is calculus approximated on a budget. Your game loop may render at variable 144 Hz while physics ticks at a fixed 60 Hz — decoupling simulation from display is one of the first architectural choices you make.
Rigid bodies — the state you integrate each step
Translational state
A rigid body treats an object as indeformable. Its state at time t typically includes:
- Position
p— center of mass in world space - Linear velocity
v— meters (or pixels) per second - Mass
m— or inverse mass1/mfor static immovable bodies
Forces change velocity; velocity changes position. Static geometry (floors, walls) sets inverse mass to zero so impulses do not shove the world.
Rotational state
Rotating bodies add orientation (angle in 2D, quaternion in 3D), angular velocity, and moment of inertia — rotational equivalent of mass. A long plank is harder to spin around its center than a compact disc of the same mass. Torques integrate like forces: torque changes angular velocity; angular velocity changes angle.
Kinematic vs dynamic bodies
Kinematic bodies move because you set their position each frame (moving platforms, scripted doors). They push dynamic objects but are not pushed back. Dynamic bodies are fully simulated. Mixing the two is standard — only simulate what gameplay needs.
Forces, gravity, and constraints
Each physics step begins by clearing force accumulators, then applying:
- Gravity — constant acceleration (often
F = m * gdownward). Tunegfor feel; Earth-accurate 9.8 m/s² often feels sluggish in 2D platformers. - Damping — velocity multiplied by a factor slightly below 1 each step to simulate air resistance without expensive fluid math.
- Springs and joints — constraints that pull bodies toward rest length (ropes, suspension). Implemented as corrective forces or as direct constraint solvers.
- Player input — often applied as impulses or direct velocity changes rather than literal Newtonian forces for snappy control.
Constraints restrict degrees of freedom: a hinge allows rotation but not translation off the pivot; a slider keeps motion on one axis. Physics engines solve constraints iteratively (sequential impulses or position-based dynamics) because exact analytic solutions for stacked contacts are intractable in real time.
Numerical integration — advancing time without blowing up
Euler integration and its problems
Explicit Euler is the textbook first step:
v += a * dt, then p += v * dt. It is easy but
unstable — energy drifts upward in oscillating systems (springs
explode) and large dt makes fast objects tunnel through thin colliders.
Semi-implicit (symplectic) Euler
Update velocity first, then position with the new velocity:
v += a * dt, p += v * dt. Still simple, but far more
stable for games. Many indie platformers use this with hand-tuned collision
resolution. It is the default integrator inside several 2D libraries.
Verlet and position-based dynamics
Verlet integration stores previous position and derives velocity
implicitly: p_new = 2*p - p_old + a*dt². It conserves energy
better in many setups and underpins cloth and rope simulation. Modern engines
often use position-based dynamics (PBD) — directly nudging
positions to satisfy constraints, then deriving velocity from position delta.
PBD trades physical accuracy for stability and artist-controllable results
(ragdolls that never fold inside themselves).
Fixed timestep and the accumulator pattern
Variable frame times make physics non-deterministic and feel inconsistent. The standard fix: simulate at a fixed dt (e.g. 1/60 s) inside an accumulator loop that consumes real elapsed time. Leftover fractional time carries over; render interpolates between previous and current physics state for smooth visuals. This pattern is non-negotiable for reproducible multiplayer netcode and replay systems.
Collision response — separating overlaps and exchanging momentum
When detection reports penetration, response runs in roughly this order:
- Positional correction — push bodies apart along the collision normal by a fraction of penetration depth (Baumgarte stabilization) so they do not sink into each other next frame.
- Impulse application — instant velocity change along the normal based on relative velocity and coefficient of restitution (bounciness: 0 = inelastic thud, 1 = perfect bounce).
- Friction — tangential impulse capped by Coulomb friction (
μ * normal_impulse) so boxes slide to a stop on ramps.
The impulse magnitude derives from conservation of momentum using both bodies' masses and inertia tensors. In code you rarely derive this from scratch — engines expose restitution and friction material properties per collider. Tuning those sliders changes game feel more than swapping integrators.
Continuous collision detection (CCD) sweeps fast thin objects (bullets, dice) from last position to current position to catch tunneling that discrete step tests miss. Enable CCD only for objects that need it; sweeps are expensive.
Engine and library choices
2D — browser and indie
- Box2D — industry-standard 2D rigid bodies (C++ core, ports to JS via WASM). Stable, well-documented, used in Angry Birds-era mobile games.
- Matter.js — pure JavaScript 2D engine, easy Canvas integration, good for prototypes and medium-complexity web games.
- Chipmunk2D — fast C library with JS bindings; strong for mobile.
3D — consoles and PC
- NVIDIA PhysX, Havok, Bullet — full-featured solvers integrated into Unity, Unreal, or standalone.
- cannon-es, Rapier — WASM-friendly 3D options for WebGL and Three.js stacks; Rapier emphasizes speed and determinism.
Roll your own?
Custom physics makes sense for tile-grid platformers (AABB sweep and snap), top-down games with circle colliders only, or deterministic lockstep fighters with a handful of states. Once you need rotation, stacking, or joints, use a library. Compile hot loops to WebAssembly if profiling shows JS integration is the bottleneck — not before.
Architecture with ECS and gameplay code
In an
entity component system,
physics bodies are components (position, velocity, collider shape, material).
A physics system reads input forces, steps the solver, writes back transforms for
the render system. Gameplay systems subscribe to collision events: onEnter
when a hurtbox touches an enemy, onStay for ground contact to enable
jumping, onExit to start coyote-time timers.
Keep gameplay logic out of the solver callbacks when possible — queue events and process them after the step to avoid re-entrancy bugs (destroying an entity mid-solve). Use layer masks so bullets hit enemies but not other bullets, mirroring the filtering described in the collision detection guide.
Determinism, networking, and replays
Lockstep multiplayer requires identical physics on every peer given the same inputs and seed. That means fixed dt, no floating-point order surprises across platforms, and no threading races inside the solver. Most modern action games instead run physics only on the server (or host) and replicate positions — simpler, but clients need prediction and reconciliation as covered in the netcode guide.
Record inputs plus initial state, not rendered frames, for replays. If physics is deterministic, replay is free; if not, store keyframe snapshots every N steps.
Performance on web and mobile
- Reduce active bodies — sleep objects at rest; wake on impulse or proximity.
- Simplify colliders — convex hulls or circles instead of mesh triangles; compound shapes beat high-poly concave meshes.
- Lower solver iterations — joints may wobble slightly but frames recover.
- Substep only when needed — extra physics substeps for stability cost linear time; prefer CCD on fast actors over global 4x substeps.
- Profile on target hardware — desktop Chrome is not a budget Android browser; thermal throttling changes the frame budget mid-session.
Common mistakes
- Using render delta directly for physics — tab backgrounding spikes
dtand launches objects through floors. Clamp or accumulate into fixed steps. - Scaling mass or gravity independently without retuning jumps — doubling gravity without adjusting jump impulse breaks level design.
- Ignoring tunneling — raycasts or CCD for projectiles; thicker colliders for thin platforms.
- Applying forces in the wrong space — world vs local axis confusion makes vehicles steer sideways.
- Mixing transform parenting with physics transforms — parent scale skews child colliders; let the engine sync graphics from physics bodies, not vice versa.
- Trusting default material friction on ice levels — explicit low-friction materials per surface type.
Key takeaways
- Game physics simulates motion; collision detection only finds overlaps — response applies impulses and corrections.
- Semi-implicit Euler or engine solvers beat naive Euler for stability; fixed timesteps keep feel consistent and enable determinism.
- Tune restitution, friction, and gravity for game feel before optimizing integrator math.
- Use kinematic bodies, sleeping, and simple colliders to stay inside the frame budget.
- Pick Box2D, Matter.js, Rapier, or engine builtins instead of writing a full solver unless scope is deliberately narrow.
Related reading
- Collision detection in games — broad/narrow phase, AABB, SAT, spatial hashing
- Game loop and frame timing — fixed vs variable timestep, interpolation
- Entity component system (ECS) — wiring physics components into game architecture
- Multiplayer netcode — server authority, prediction, and physics replication