2D Physics Setup: 8 Common Mistakes That Break Your Game
Most 2D physics problems are not bugs in the engine — they are setup mistakes. The eight that cause almost every case: feeding the engine pixel units instead of meters, running physics on a variable timestep, picking the wrong body type, leaving continuous collision off, steering the player with a rigidbody, setting solver iterations too low, writing directly to the transform, and ignoring sleeping bodies. Fix these at setup and most 'jitter', 'tunneling' and 'floaty jump' issues disappear.
Most 2D physics problems are not engine bugs — they are setup mistakes. The eight mistakes below cause almost every case of jitter, tunneling, floaty jumps and unreliable collision that new developers blame on their engine. None of them require a different engine; they require setting the engine up the way it was designed to be used.
If your game uses a 2D physics engine — and most do, because Unity, Godot and GameMaker all run their 2D physics on Box2D or a close relative — the defaults are sane, but the defaults assume you followed a few rules that are easy to break the first time. This article is those rules, as a checklist.
1. Feeding the engine pixel units instead of meters
This is the single most common mistake, and it produces a whole family of symptoms: objects fall too slowly or too fast, stacks collapse, friction feels wrong, the whole simulation looks "off."
Box2D is tuned for meters, kilograms and seconds (MKS). Its documentation states plainly that moving objects should be between 0.1 and 10 meters, with about 1 meter being the sweet spot. Erin Catto, Box2D's author, has a dedicated post on why you should not use pixels as units. The engine's gravity, solver and sleep thresholds are all calibrated for that scale.
When you feed it a 64-pixel player and a 128-pixel wall, you are telling the engine the player is roughly the size of a building. Gravity, mass ratios and contact behaviour were never meant to work there.
Fix: pick a scale (commonly 32 or 100 pixels per meter), keep one constant for it, and convert at the boundary. The physics world thinks in meters; your renderer thinks in pixels. Never mix them.
2. Running physics on a variable timestep
If your physics step equals the frame delta, the simulation runs at a different speed every frame. On a 30 fps hitch it takes a huge step; on a 240 fps monitor it takes a tiny one. Large steps make objects tunnel and stacks explode; tiny steps change how friction and restitution resolve. The result is physics that behaves differently per machine and even per moment.
Fix: a fixed timestep with an accumulator. Advance the simulation in constant increments (1/60 s is typical), accumulate leftover real time, and cap the accumulator so a stall cannot produce a spiral of death. Optionally interpolate the rendered position between physics steps for smoothness. Glenn Fiedler's Fix Your Timestep! is the canonical write-up of this pattern, and most engines already implement it internally — but you must make sure your own movement code respects the fixed step, not the frame delta.
3. Picking the wrong body type
Physics engines offer three body types, and using the wrong one breaks behaviour immediately:
| Type | Reacts to forces/gravity | Moved by collisions | Use for |
|---|---|---|---|
| Static | No | No | Walls, floors, immovable level geometry |
| Kinematic | No | No (but can move itself) | Moving platforms, doors, triggers |
| Dynamic | Yes | Yes | Crates, enemies, anything that should fall and be pushed |
A common error is making the floor dynamic by accident, so the whole level falls. Another is making the player kinematic and then wondering why crates don't react when the player walks into them — kinematic bodies push dynamics, but only if the engine is told to detect the contact. Match the type to the role before anything else.
4. Leaving continuous collision detection off for fast objects
Discrete collision detection checks "is this object overlapping anything right now," once per step. If a bullet moves further in one step than the wall is thick, the check at the start and the check at the end both miss, and the bullet is through the wall before the engine knew they were near each other. That is tunneling.
Fix: turn on continuous collision detection (CCD) — called "bullet" mode in Box2D terminology — for fast-moving dynamic bodies. CCD sweeps the shape from its old position to its new position and checks the whole swept volume for contact. It costs more CPU, so enable it per body, not globally. Pair it with a reasonable simulation rate and, for very fast thin objects, an explicit raycast.
5. Steering the player character with a physics rigidbody
A dynamic rigidbody is a simulation: forces accumulate, momentum carries, restitution bounces. That is wonderful for a crate. It is miserable for a platformer character, where you want exact, snappy control — run here, stop now, jump exactly this high.
Players who drive their character by setting velocity or applying forces to a rigidbody get the classic "floaty jump," air control that feels like ice, and characters that slide past where you stopped. The engine is doing exactly what it was asked to do.
Fix: use a character controller. The established pattern is a kinematic body (or no physics body at all) moved deliberately by your code, with a raycast or shape-cast downward to decide whether the character is grounded. Let the physics engine simulate the crates the player throws; do not let it simulate the player.
6. Setting solver iterations too low
When bodies overlap, the engine's solver pushes them apart over a number of iterations. Too few iterations and the resolution is sloppy: stacked boxes jitter and slowly sink into each other, joints feel rubbery, hinges wobble. Box2D defaults to 8 velocity iterations and 3 position iterations, which is fine for most scenes. Dense stacks or complex joint systems need more.
Fix: raise the iteration counts (velocity first, then position) and watch the stack stabilise. There is a CPU cost, so raise only what you need and only where the scene demands it. Also make sure restitution is zero for objects that should rest — non-zero restitution on resting contacts is a major source of perpetual micro-bounce.
7. Writing directly to the transform of a physics body
If a body is dynamic and you set its position directly every frame (to follow a path, snap to a grid, or correct an error), you fight the solver. The engine has momentum and contact resolution planned for the body's natural position; you teleport it somewhere else; next step the engine yanks it back or applies huge corrective impulses to neighbours. The symptom is violent shaking or objects launched across the room.
Fix: for a body the physics owns, never write its transform directly. Move it through the physics API — set velocity, apply a force or impulse, or make it kinematic for the period you want to drive it manually. If you must teleport it, do it through the engine's intended method and reset its velocity.
8. Ignoring sleeping bodies and the broad phase
Two performance mistakes that show up as the game grows. First, the engine can put resting bodies to sleep and skip them entirely — but only if you let it. A tiny script that pokes every body's velocity every frame keeps them all awake. Second, collision detection is accelerated by a broad phase (an AABB tree) that cheaply rules out distant pairs before the expensive narrow phase; if your colliders are enormous or you have thousands of tiny overlapping ones, the broad phase cannot prune and the frame stalls.
Fix: let bodies sleep; don't poll them when they are at rest. Keep colliders close to the visual shape (no giant invisible boxes "just to be safe"), and prefer a few composite colliders over dozens of tiny ones for complex shapes.
Symptom → setup mistake → fix
| Symptom | Likely setup mistake | Fix |
|---|---|---|
| Objects fall at the wrong speed, stacks collapse | Pixels used as physics units | Convert to meters (0.1–10 m range) |
| Physics differs per machine, jitter on hitches | Variable timestep | Fixed timestep with accumulator |
| Fast projectile passes through a wall | CCD off for the fast body | Enable bullet/CCD, raise rate, raycast |
| Player feels floaty, slides past stops | Player is a dynamic rigidbody | Use a raycast/kinematic character controller |
| Stacked boxes jitter and sink | Solver iterations too low, restitution non-zero | Raise iterations, zero restitution at rest |
| Objects violently shake or launch | Transform written directly | Move through physics API, don't teleport |
| Frame drops as scene grows | No sleeping, bloated colliders | Let bodies sleep, keep colliders tight |
How Egmatic fits
Every mistake on this list is a setup mistake, which means the difference between good and bad 2D physics is fast iteration: change a setting, see the result, decide. Egmatic is built around a live preview that keeps the scene running while you adjust properties and logic, so tuning gravity, solver iterations or a body's type is something you watch happen, not something you rebuild to check. The physics lives on top of a cross-platform engine, and physics events — collisions, contacts, triggers — are exposed as nodes you can wire into gameplay without leaving the visual editor. If you want the deeper explainer on what a 2D physics engine actually does internally, see 2D Physics Engine: Everything You Need to Know; for tuning parameters while the game runs, see Real-Time Physics Editor: See Results As You Build.
The bottom line
A 2D physics engine is a simulator, and a simulator only behaves well when you respect its contract: feed it the units it was tuned for, step it at a fixed rate, give each body the right type, turn on continuous detection for fast things, keep the player out of the simulation, give the solver enough iterations, never fight it with direct transform writes, and let resting bodies sleep. Get the setup right and most "physics bugs" simply do not occur — and the few that remain are narrow, diagnosable problems you can fix in minutes, which is the subject of How to Fix Game Physics Bugs Fast.
Related Posts
Is Godot Too Hard? What Beginners Should Actually Know in 2026
Godot is not too hard for beginners — but it is different. This guide explains what actually makes Godot feel difficult (the node-and-scene mental model, GDScript, and the version-3-vs-4 tutorial trap), gives a realistic 2–6 month learning timeline, and compares Godot honestly against Unity and Unreal for a first engine.
How to Fix Game Physics Bugs Fast: A Diagnostic Method
Fixing a physics bug starts with a method, not a guess: turn on debug draw, reproduce the bug in isolation, then read the symptom. Tunneling means the simulation step is larger than the collider; jitter means overlapping bodies the solver cannot settle; glued objects mean friction or a stuck contact; floaty jumps mean the player is a rigidbody. This article maps each symptom to its cause and the exact fix, with a diagnostic checklist you can run in minutes.
How to Test Game Ideas Fast: A Rapid Prototyping Playbook
The fastest way to test a game idea is to isolate the one mechanic that has to be fun, build the cheapest version of just that, and put it in front of real players within days. This playbook covers paper prototyping, greyboxing the core loop, playtest discipline, and kill criteria — so you find out whether an idea works before you invest months in it.