Game physics & collision
Make bodies collide, move, and stay stable across Godot, Unity, and Unreal. This skill owns the
mental model (body types, colliders, layers/masks, character controllers, joints, queries,
determinism) and maps every concept onto each engine's real API. When physics "feels broken" —
jitter, tunneling, sinking, ghost collisions — the cause is almost always one of: wrong body type,
a layer/mask mismatch, or moving/integrating outside the fixed physics tick. Check those first.
Version contract — read first (never emit these)
| Engine |
Target |
Banned / deprecated |
Use instead |
| Godot |
4.x |
move_and_slide(velocity, up, ...) with arguments (that is Godot 3) |
Godot 4 move_and_slide() takes no args; set the velocity property first |
| Godot |
4.x |
KinematicBody2D/3D, RayShape, WorldMarginShape, linear_velocity *= delta before move_and_slide() |
CharacterBody2D/3D, SeparationRayShape2D/3D, WorldBoundaryShape2D/3D; move_and_slide() is already delta-scaled |
| Unity |
Unity 6 (6000.x) |
Rigidbody.velocity / Rigidbody2D.velocity, rb.drag, rb.angularDrag |
linearVelocity (+ linearVelocityX/Y), linearDamping, angularDamping; new AddForceX/Y |
| Unity |
Unity 6 |
moving a dynamic Rigidbody from Update; transform.position = on a physics body |
move in FixedUpdate; use MovePosition/AddForce, never write transform on a simulated body |
| Unreal |
UE5 (Chaos) |
any PhysX/APEX API, bUseAsyncScene, NvCloth |
Chaos is the only physics backend in UE5; use UPrimitiveComponent physics + PhysicsConstraintComponent |
If you are unsure a symbol exists in the user's exact version, say so instead of inventing it.
When to use / When NOT to use
Use when: designing which body type a thing should be; something falls through, sinks into, or
passes through geometry; a rigid body jitters, drifts, or launches; setting up collision
layers/masks/channels; building or fixing a character/player controller; adding joints; casting
rays/shapes or overlap tests; or physics behaves differently at different frame rates.
When NOT to use (delegate):
- Visual-only wobble, shader/vertex animation, material or lighting issues → gamedev-shaders.
- AI moving along a path, navmesh, A*, steering, avoidance → gamedev-pathing (physics only
executes the move; pathing decides where).
- Deep, engine-specific project setup / editor / build questions → godot, unity, unreal.
- Netcode, lockstep sync, server-authoritative movement → gamedev-multiplayer (this skill gives
you the deterministic fixed-tick foundation multiplayer builds on).
1. Body types — pick before you touch anything
Three categories exist in every engine; choosing wrong is the root of most bugs.
- Static — never moves, infinite mass, cheap. Level geometry, walls, floors. Do not move a
static body every frame; the broadphase caches it. If it must move, it is not static.
- Kinematic / character — moved by you (code/animation), pushes dynamics but is not pushed by
them, ignores forces and gravity unless you add them. Players, moving platforms, doors, elevators.
- Dynamic (rigid) — fully simulated: gravity, forces, impulses, collision response. Crates,
ragdolls, debris, vehicles. You influence it with forces/impulses, never by writing its transform.
Move each the right way:
|
Static |
Kinematic / character |
Dynamic |
| Godot |
StaticBody2D/3D (leave still) |
CharacterBody2D/3D + move_and_slide(); AnimatableBody2D/3D for platforms (set sync_to_physics) |
RigidBody2D/3D (apply_impulse, apply_force) |
| Unity |
Collider, no Rigidbody (or Rigidbody2D bodyType Static) |
CharacterController.Move(), or Rigidbody.isKinematic=true + MovePosition in FixedUpdate |
Rigidbody (AddForce) |
| Unreal |
Static/Movable mobility, Simulate Physics off |
Character + CharacterMovementComponent; movable component moved by code |
Simulate Physics on (SetSimulatePhysics(true)) |
A Godot RigidBody can be temporarily frozen: set freeze = true with freeze_mode = FREEZE_MODE_KINEMATIC to move it by transform without waking the solver wrongly. Prefer
AnimatableBody for a permanent kinematic mover.
2. Colliders / shapes
Collider ≠ visual mesh. Give every body a separate, simpler collision shape.
- Primitives (box, sphere/circle, capsule) — cheapest and most stable. Prefer a capsule for
characters (rounded ends slide over steps and seams). Use these whenever possible.
- Convex hull — dynamic bodies can use a convex approximation; a concave prop needs multiple
convex pieces (a compound), not one concave hull.
- Concave / trimesh — exact triangle mesh, but static-only in every engine. A moving
concave-mesh collider is a top cause of tunneling and solver blowups. Never put a trimesh on a
dynamic body.
- Compound — several child shapes on one body. Godot: multiple
CollisionShape children. Unity:
multiple Collider components. Unreal: multiple primitives / a body setup.
- Triggers / areas — detect overlap, no physical response. Godot
Area2D/3D (signals
body_entered / area_entered); Unity collider Is Trigger (OnTriggerEnter/Stay/Exit); Unreal
set response to Overlap + Generate Overlap Events (OnComponentBeginOverlap). Use for
pickups, damage zones, checkpoints, sensors.
3. Collision layers & masks — the #1 confusion
Layer = "what I am." Mask = "what I scan for." They are separate bit sets.
- Godot: two bodies interact when one's
collision_mask includes the other's
collision_layer — it is an OR, so detection can be asymmetric (A sees B without B seeing
A). Keep them symmetric unless you deliberately want one-way detection. An Area's mask decides
what it detects; its layer decides what detects it.
- Unity: GameObject Layers + the Layer Collision Matrix (Project Settings → Physics)
decide which layer pairs collide. Raycasts/overlaps take a
LayerMask argument. Toggle a pair at
runtime with Physics.IgnoreLayerCollision.
- Unreal: Object Type (channel) = what I am; per-channel Response = Block / Overlap /
Ignore. Package as a reusable Collision Preset. Trace channels (Visibility, Camera) are for
queries; object channels are for physical collision.
Full worked examples (player/enemy/pickup/wall, bit math, one-way platforms) →
references/layers-and-masks.md.
4. Character controllers
Two philosophies — decide up front, don't mix:
- Kinematic character (recommended for most players): you compute velocity and move via a
sweeping helper that resolves collisions and slides. Precise, snappy, no solver fighting. Godot
CharacterBody, Unity CharacterController, Unreal CharacterMovementComponent.
- Dynamic (rigidbody) character: physical pushing/being-pushed for free, but needs high friction
or a physics material, angular constraints (freeze rotation), and tuning to stop tipping/sliding.
Godot 4 (2D — the 3D version is identical with Vector3 and get_gravity()):
extends CharacterBody2D
const SPEED := 300.0
const JUMP_VELOCITY := -400.0
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta # accumulate accel: scale by delta
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
var dir := Input.get_axis("move_left", "move_right")
velocity.x = dir * SPEED if dir else move_toward(velocity.x, 0.0, SPEED)
move_and_slide() # Godot 4: NO args, uses `velocity`, already delta-scaled
is_on_floor() / is_on_wall(), floor_max_angle (slope limit), floor_snap_length (stick to
ground on ramps/stairs), and up_direction handle ground/slope/step behavior. get_gravity() is
Godot 4.3+; on older 4.x read ProjectSettings gravity. Full per-engine controllers (Unity
CharacterController + custom gravity, Unreal movement modes, ground detection, slopes, steps,
moving platforms) → references/character-controllers.md.
5. Joints/constraints & how to apply motion
Joints connect two bodies with a constraint. Godot: PinJoint, HingeJoint3D, SliderJoint3D,
Generic6DOFJoint3D, DampedSpringJoint2D. Unity: HingeJoint, FixedJoint, SpringJoint,
ConfigurableJoint, CharacterJoint. Unreal: PhysicsConstraintComponent (one 6-DOF constraint
covers hinge/slider/ball). Keep connected bodies' mass ratios close — a heavy body chained to a
light one is the classic joint-explosion.
Force vs impulse vs direct velocity (apply all in the fixed tick):
| Want |
Use |
Godot |
Unity |
Unreal |
| Continuous push (thrust, wind), mass-scaled |
Force |
apply_central_force |
AddForce(f, Force) |
AddForce |
| Instant kick (jump, explosion, hit), mass-scaled |
Impulse |
apply_central_impulse |
AddForce(f, Impulse) |
AddImpulse |
| Instant velocity change, ignoring mass |
mass-independent impulse |
set linear_velocity |
AddForce(f, VelocityChange) |
SetPhysicsLinearVelocity |
Setting velocity directly on a dynamic body teleports its momentum and can fight the solver — fine
for character/kinematic bodies, use sparingly on dynamics (prefer forces/impulses).
6. Queries — raycasts, shapecasts, overlaps
Run queries from the fixed physics tick so results match the simulated state.
- Godot: get
get_world_2d().direct_space_state (or 3d), build
PhysicsRayQueryParameters2D/3D / PhysicsShapeQueryParameters2D/3D, call intersect_ray,
intersect_shape, cast_motion. Node helpers: RayCast2D/3D, ShapeCast2D/3D. Queries respect
collision_mask.
- Unity:
Physics.Raycast, SphereCast/CapsuleCast, OverlapSphere, CheckSphere (2D:
Physics2D.*). Always pass a LayerMask; prefer non-allocating RaycastNonAlloc/RaycastAll.
- Unreal:
LineTraceSingleByChannel, SweepSingleByChannel, OverlapMultiByChannel (and
...ByObjectType). Use a trace channel, set the query params (bTraceComplex).
Details, snippets, and the tunneling-safe shapecast pattern → references/determinism-and-queries.md.
7. Determinism & stability
The rules that keep physics from jittering, drifting, or tunneling:
- Physics lives in the fixed tick. Godot
_physics_process(delta), Unity FixedUpdate(),
Unreal substepping / async physics tick. Read input in the frame update, apply it in the fixed
tick. Never simulate in the render frame.
- Scale by delta. Multiply forces/accelerations/manual position changes by the tick's
delta /
fixedDeltaTime — but not the output of a helper that already integrates time (Godot
move_and_slide(), Unity CharacterController.Move when you pass a per-second velocity).
- CCD for fast/thin things. Small fast projectiles + thin walls tunnel. Enable Continuous
Collision Detection: Godot
continuous_cd, Unity collisionDetectionMode = Continuous*, Unreal
Use CCD. Enable only on the fast bodies (it costs). Or use a shapecast/raycast-then-move.
- Keep mass ratios sane. Stacks and joints between wildly different masses (100:1+) blow up.
- Never scale a collider at runtime, and never write
transform/position on a dynamic body —
both corrupt the broadphase and cause explosions or ghost collisions. Move via the API.
- Interpolate for smooth visuals at high frame rates: Godot physics interpolation, Unity
Rigidbody.interpolation = Interpolate. This is visual only — it never changes the simulation.
Deeper: fixed-timestep math, substepping, sleeping, why transform writes break things →
references/determinism-and-queries.md.
Guardrails / gotchas
- Falling through a thin floor at speed → CCD off, or moving in the render frame. Fix both.
- A moving platform doesn't carry the player → use a kinematic mover (Godot
AnimatableBody with
sync_to_physics, Unity kinematic Rigidbody MovePosition), not a static body.
- "Ghost" collisions / catching on seams between tiles → merge colliders or use a capsule character.
- Trigger never fires → in Unity a trigger pair needs at least one Rigidbody; in Godot the
Area's
mask must include the body's layer; in Unreal enable Generate Overlap Events on both.
- Rigidbody vibrates against the ground → mass ratio, too-soft solver iterations, or you're also
writing its transform. Stop writing the transform.
- Character launches off ramps → enable floor snapping (
floor_snap_length / stop-on-slope).
Related skills
- godot / unity / unreal — engine setup, editor, language, and build specifics.
- gamedev-pathing — decides where to move; this skill executes the move and collisions.
- gamedev-multiplayer — builds on the deterministic fixed-tick foundation here.
- gamedev-shaders — for visual/material issues that only look like physics.
Checklist
1---2name: gamedev-physics3description: Use when working with a game engine's physics — rigid bodies, colliders, collision layers and masks, character controllers, joints, forces versus impulses, raycasts and shapecasts, or when a simulation is unstable (tunnelling, jitter, missed overlaps). Covers the Godot, Unity and Unreal equivalents. NOT rendering or shader-driven visual jitter (that is `gamedev-shaders`), NOT navigation, pathfinding or navmesh (that is `gamedev-pathing`).4---56# Game physics & collision78Make bodies collide, move, and stay stable across Godot, Unity, and Unreal. This skill owns the9mental model (body types, colliders, layers/masks, character controllers, joints, queries,10determinism) and maps every concept onto each engine's real API. When physics "feels broken" —11jitter, tunneling, sinking, ghost collisions — the cause is almost always one of: wrong body type,12a layer/mask mismatch, or moving/integrating outside the fixed physics tick. Check those first.1314## Version contract — read first (never emit these)1516| Engine | Target | Banned / deprecated | Use instead |17| --- | --- | --- | --- |18| **Godot** | 4.x | `move_and_slide(velocity, up, ...)` with arguments (that is Godot 3) | Godot 4 `move_and_slide()` takes **no args**; set the `velocity` property first |19| Godot | 4.x | `KinematicBody2D/3D`, `RayShape`, `WorldMarginShape`, `linear_velocity *= delta` before `move_and_slide()` | `CharacterBody2D/3D`, `SeparationRayShape2D/3D`, `WorldBoundaryShape2D/3D`; `move_and_slide()` is already delta-scaled |20| **Unity** | Unity 6 (6000.x) | `Rigidbody.velocity` / `Rigidbody2D.velocity`, `rb.drag`, `rb.angularDrag` | `linearVelocity` (+ `linearVelocityX/Y`), `linearDamping`, `angularDamping`; new `AddForceX/Y` |21| Unity | Unity 6 | moving a dynamic `Rigidbody` from `Update`; `transform.position =` on a physics body | move in `FixedUpdate`; use `MovePosition`/`AddForce`, never write `transform` on a simulated body |22| **Unreal** | UE5 (Chaos) | any PhysX/APEX API, `bUseAsyncScene`, `NvCloth` | Chaos is the only physics backend in UE5; use `UPrimitiveComponent` physics + `PhysicsConstraintComponent` |2324If you are unsure a symbol exists in the user's exact version, say so instead of inventing it.2526## When to use / When NOT to use2728**Use when:** designing which body type a thing should be; something falls through, sinks into, or29passes through geometry; a rigid body jitters, drifts, or launches; setting up collision30layers/masks/channels; building or fixing a character/player controller; adding joints; casting31rays/shapes or overlap tests; or physics behaves differently at different frame rates.3233**When NOT to use (delegate):**34- Visual-only wobble, shader/vertex animation, material or lighting issues → **gamedev-shaders**.35- AI moving along a path, navmesh, A*, steering, avoidance → **gamedev-pathing** (physics only36 *executes* the move; pathing decides *where*).37- Deep, engine-specific project setup / editor / build questions → **godot**, **unity**, **unreal**.38- Netcode, lockstep sync, server-authoritative movement → **gamedev-multiplayer** (this skill gives39 you the *deterministic fixed-tick* foundation multiplayer builds on).4041## 1. Body types — pick before you touch anything4243Three categories exist in every engine; choosing wrong is the root of most bugs.4445- **Static** — never moves, infinite mass, cheap. Level geometry, walls, floors. Do **not** move a46 static body every frame; the broadphase caches it. If it must move, it is not static.47- **Kinematic / character** — moved *by you* (code/animation), pushes dynamics but is not pushed by48 them, ignores forces and gravity unless you add them. Players, moving platforms, doors, elevators.49- **Dynamic (rigid)** — fully simulated: gravity, forces, impulses, collision response. Crates,50 ragdolls, debris, vehicles. You influence it with forces/impulses, never by writing its transform.5152**Move each the right way:**5354| | Static | Kinematic / character | Dynamic |55| --- | --- | --- | --- |56| Godot | `StaticBody2D/3D` (leave still) | `CharacterBody2D/3D` + `move_and_slide()`; `AnimatableBody2D/3D` for platforms (set `sync_to_physics`) | `RigidBody2D/3D` (`apply_impulse`, `apply_force`) |57| Unity | Collider, no Rigidbody (or `Rigidbody2D` bodyType Static) | `CharacterController.Move()`, or `Rigidbody.isKinematic=true` + `MovePosition` in `FixedUpdate` | `Rigidbody` (`AddForce`) |58| Unreal | `Static`/`Movable` mobility, Simulate Physics off | `Character` + `CharacterMovementComponent`; movable component moved by code | Simulate Physics on (`SetSimulatePhysics(true)`) |5960A Godot `RigidBody` can be temporarily frozen: set `freeze = true` with `freeze_mode =61FREEZE_MODE_KINEMATIC` to move it by transform without waking the solver wrongly. Prefer62`AnimatableBody` for a permanent kinematic mover.6364## 2. Colliders / shapes6566Collider ≠ visual mesh. Give every body a **separate, simpler** collision shape.6768- **Primitives** (box, sphere/circle, capsule) — cheapest and most stable. Prefer a **capsule** for69 characters (rounded ends slide over steps and seams). Use these whenever possible.70- **Convex hull** — dynamic bodies can use a convex approximation; a concave prop needs **multiple71 convex pieces** (a compound), not one concave hull.72- **Concave / trimesh** — exact triangle mesh, but **static-only** in every engine. A moving73 concave-mesh collider is a top cause of tunneling and solver blowups. Never put a trimesh on a74 dynamic body.75- **Compound** — several child shapes on one body. Godot: multiple `CollisionShape` children. Unity:76 multiple `Collider` components. Unreal: multiple primitives / a body setup.77- **Triggers / areas** — detect overlap, **no physical response**. Godot `Area2D/3D` (signals78 `body_entered` / `area_entered`); Unity collider `Is Trigger` (`OnTriggerEnter/Stay/Exit`); Unreal79 set response to **Overlap** + `Generate Overlap Events` (`OnComponentBeginOverlap`). Use for80 pickups, damage zones, checkpoints, sensors.8182## 3. Collision layers & masks — the #1 confusion8384**Layer = "what I am." Mask = "what I scan for."** They are separate bit sets.8586- **Godot:** two bodies interact when **one's `collision_mask` includes the other's87 `collision_layer`** — it is an **OR**, so detection can be asymmetric (A sees B without B seeing88 A). Keep them symmetric unless you deliberately want one-way detection. An `Area`'s `mask` decides89 what it detects; its `layer` decides what detects *it*.90- **Unity:** GameObject **Layers** + the **Layer Collision Matrix** (Project Settings → Physics)91 decide which layer pairs collide. Raycasts/overlaps take a `LayerMask` argument. Toggle a pair at92 runtime with `Physics.IgnoreLayerCollision`.93- **Unreal:** **Object Type** (channel) = what I am; per-channel **Response** = Block / Overlap /94 Ignore. Package as a reusable **Collision Preset**. Trace channels (Visibility, Camera) are for95 queries; object channels are for physical collision.9697Full worked examples (player/enemy/pickup/wall, bit math, one-way platforms) →98`references/layers-and-masks.md`.99100## 4. Character controllers101102Two philosophies — decide up front, don't mix:103104- **Kinematic character** (recommended for most players): you compute velocity and move via a105 sweeping helper that resolves collisions and slides. Precise, snappy, no solver fighting. Godot106 `CharacterBody`, Unity `CharacterController`, Unreal `CharacterMovementComponent`.107- **Dynamic (rigidbody) character**: physical pushing/being-pushed for free, but needs high friction108 or a physics material, angular constraints (freeze rotation), and tuning to stop tipping/sliding.109110Godot 4 (2D — the 3D version is identical with `Vector3` and `get_gravity()`):111112```gdscript113extends CharacterBody2D114115const SPEED := 300.0116const JUMP_VELOCITY := -400.0117118func _physics_process(delta: float) -> void:119 if not is_on_floor():120 velocity += get_gravity() * delta # accumulate accel: scale by delta121 if Input.is_action_just_pressed("jump") and is_on_floor():122 velocity.y = JUMP_VELOCITY123 var dir := Input.get_axis("move_left", "move_right")124 velocity.x = dir * SPEED if dir else move_toward(velocity.x, 0.0, SPEED)125 move_and_slide() # Godot 4: NO args, uses `velocity`, already delta-scaled126```127128`is_on_floor()` / `is_on_wall()`, `floor_max_angle` (slope limit), `floor_snap_length` (stick to129ground on ramps/stairs), and `up_direction` handle ground/slope/step behavior. `get_gravity()` is130Godot 4.3+; on older 4.x read `ProjectSettings` gravity. Full per-engine controllers (Unity131`CharacterController` + custom gravity, Unreal movement modes, ground detection, slopes, steps,132moving platforms) → `references/character-controllers.md`.133134## 5. Joints/constraints & how to apply motion135136**Joints** connect two bodies with a constraint. Godot: `PinJoint`, `HingeJoint3D`, `SliderJoint3D`,137`Generic6DOFJoint3D`, `DampedSpringJoint2D`. Unity: `HingeJoint`, `FixedJoint`, `SpringJoint`,138`ConfigurableJoint`, `CharacterJoint`. Unreal: `PhysicsConstraintComponent` (one 6-DOF constraint139covers hinge/slider/ball). Keep connected bodies' **mass ratios close** — a heavy body chained to a140light one is the classic joint-explosion.141142**Force vs impulse vs direct velocity** (apply all in the fixed tick):143144| Want | Use | Godot | Unity | Unreal |145| --- | --- | --- | --- | --- |146| Continuous push (thrust, wind), mass-scaled | **Force** | `apply_central_force` | `AddForce(f, Force)` | `AddForce` |147| Instant kick (jump, explosion, hit), mass-scaled | **Impulse** | `apply_central_impulse` | `AddForce(f, Impulse)` | `AddImpulse` |148| Instant velocity change, **ignoring mass** | mass-independent impulse | set `linear_velocity` | `AddForce(f, VelocityChange)` | `SetPhysicsLinearVelocity` |149150Setting velocity directly on a *dynamic* body teleports its momentum and can fight the solver — fine151for character/kinematic bodies, use sparingly on dynamics (prefer forces/impulses).152153## 6. Queries — raycasts, shapecasts, overlaps154155Run queries from the **fixed physics tick** so results match the simulated state.156157- **Godot:** get `get_world_2d().direct_space_state` (or 3d), build158 `PhysicsRayQueryParameters2D/3D` / `PhysicsShapeQueryParameters2D/3D`, call `intersect_ray`,159 `intersect_shape`, `cast_motion`. Node helpers: `RayCast2D/3D`, `ShapeCast2D/3D`. Queries respect160 `collision_mask`.161- **Unity:** `Physics.Raycast`, `SphereCast`/`CapsuleCast`, `OverlapSphere`, `CheckSphere` (2D:162 `Physics2D.*`). Always pass a `LayerMask`; prefer non-allocating `RaycastNonAlloc`/`RaycastAll`.163- **Unreal:** `LineTraceSingleByChannel`, `SweepSingleByChannel`, `OverlapMultiByChannel` (and164 `...ByObjectType`). Use a **trace channel**, set the query params (`bTraceComplex`).165166Details, snippets, and the tunneling-safe shapecast pattern → `references/determinism-and-queries.md`.167168## 7. Determinism & stability169170The rules that keep physics from jittering, drifting, or tunneling:1711721. **Physics lives in the fixed tick.** Godot `_physics_process(delta)`, Unity `FixedUpdate()`,173 Unreal substepping / async physics tick. Read input in the frame update, *apply* it in the fixed174 tick. Never simulate in the render frame.1752. **Scale by delta.** Multiply forces/accelerations/manual position changes by the tick's `delta` /176 `fixedDeltaTime` — but **not** the output of a helper that already integrates time (Godot177 `move_and_slide()`, Unity `CharacterController.Move` when you pass a per-second velocity).1783. **CCD for fast/thin things.** Small fast projectiles + thin walls tunnel. Enable Continuous179 Collision Detection: Godot `continuous_cd`, Unity `collisionDetectionMode = Continuous*`, Unreal180 `Use CCD`. Enable only on the fast bodies (it costs). Or use a shapecast/raycast-then-move.1814. **Keep mass ratios sane.** Stacks and joints between wildly different masses (100:1+) blow up.1825. **Never scale a collider at runtime**, and never write `transform`/`position` on a dynamic body —183 both corrupt the broadphase and cause explosions or ghost collisions. Move via the API.1846. **Interpolate for smooth visuals** at high frame rates: Godot physics interpolation, Unity185 `Rigidbody.interpolation = Interpolate`. This is visual only — it never changes the simulation.186187Deeper: fixed-timestep math, substepping, sleeping, why `transform` writes break things →188`references/determinism-and-queries.md`.189190## Guardrails / gotchas191192- Falling through a thin floor at speed → CCD off, or moving in the render frame. Fix both.193- A moving platform doesn't carry the player → use a kinematic mover (Godot `AnimatableBody` with194 `sync_to_physics`, Unity kinematic Rigidbody `MovePosition`), not a static body.195- "Ghost" collisions / catching on seams between tiles → merge colliders or use a capsule character.196- Trigger never fires → in Unity a trigger pair needs at least one **Rigidbody**; in Godot the197 Area's `mask` must include the body's `layer`; in Unreal enable Generate Overlap Events on **both**.198- Rigidbody vibrates against the ground → mass ratio, too-soft solver iterations, or you're also199 writing its transform. Stop writing the transform.200- Character launches off ramps → enable floor snapping (`floor_snap_length` / stop-on-slope).201202## Related skills203204- **godot** / **unity** / **unreal** — engine setup, editor, language, and build specifics.205- **gamedev-pathing** — decides *where* to move; this skill *executes* the move and collisions.206- **gamedev-multiplayer** — builds on the deterministic fixed-tick foundation here.207- **gamedev-shaders** — for visual/material issues that only look like physics.208209## Checklist210211- [ ] Every moving thing has the right **body type** (static / kinematic / dynamic).212- [ ] Colliders are **primitives/capsules**; no trimesh on a dynamic body; compound = many convex.213- [ ] Layers/masks (or channels/presets) set so exactly the intended pairs collide; triggers use214 overlap/Area, not solid response.215- [ ] All physics motion and queries run in the **fixed tick**; deltas scaled correctly (helper216 output not double-scaled).217- [ ] Forces/impulses/velocity chosen deliberately; no `transform`/`position` writes on dynamics; no218 runtime collider scaling.219- [ ] Fast/thin bodies have **CCD**; character has floor/slope/step handling; mass ratios are sane.220- [ ] Correct API for the stated engine **version** (Godot 4 `move_and_slide()` no args; Unity 6221 `linearVelocity`; UE5 Chaos — no PhysX).