---
title: "Physics colliders rigid bodies triggers and joints"
description: "Anything that blocks movement, detects overlaps, falls under gravity, or is physically constrained to another body. Colliders are passive shapes; rigid bodies are dynamic; joints are constraints."
engineVersion: v1.0.234
date: 2026-09-28
license: "(c) Gessa, proprietary. Cite with attribution to https://gessa.ai/docs/. Terms: https://gessa.ai/terms/."
canonical: https://gessa.ai/docs/knowledge/playbooks/physics-colliders-rigidbodies/
---

# Physics colliders rigid bodies triggers and joints

## When to use

Anything that blocks movement, detects overlaps, falls under gravity, or is
physically constrained to another body. Colliders are passive shapes; rigid
bodies are dynamic; joints are constraints.

## Bodies first, components second

Place the physical entities themselves in bulk with the world build document
(see authoring-with-the-world-build-document): the floor, the walls, the props.
That lands their Transform and Renderable as one transaction. Physics is a
COMPONENT layer attached on top: the document does not emit colliders or rigid
bodies, so attach them as a precision step. To make many entities solid or
dynamic at once, attach the components in ONE atomic `project_apply_transaction`
rather than one entity per call.

## The recipe

1. Solid blocker or ground: attach `ColliderComponent`
   `{ "type":"ColliderComponent", "shape":"box", "collision":"solid",
   "size":{"x":10,"y":1,"z":10}, "layers":["default"], "friction":0.5,
   "restitution":0 }`. `shape` is `box`, `sphere`, `capsule`, `disc`, or `mesh`.
2. Trigger volume (fires overlap events, does not block): same component with
   `"collision":"trigger"`. A script reacts with `addTriggerHandler` (its
   payload is `{firstEntityId, secondEntityId, worldId, distance}`).
   TRIGGER PARTICIPANT RULE (load-bearing, proven on the arena benchmark): the
   moving entity that should FIRE a static trigger must NOT carry a
   RigidBodyComponent. Any RigidBody hands that entity's pairs to Rapier,
   where a kinematic-vs-static-sensor pair is never reported, so the trigger
   silently never fires (16 entities in, 16 out, zero diagnostics). A player
   is CharacterMovementComponent with enableKcc plus a collider - no
   RigidBody, ever. If a trigger seems dead, check the toucher for a stray
   RigidBodyComponent first and remove it with project_remove_component.
3. Dynamic object: add `RigidBodyComponent`
   `{ "type":"RigidBodyComponent", "bodyType":"dynamic", "mass":1,
   "gravityScale":1, "linearDamping":0, "angularDamping":0,
   "lockTranslations":{"x":false,"y":false,"z":false},
   "lockRotations":{"x":false,"y":false,"z":false} }`. `bodyType` is `dynamic`,
   `kinematic`, or `static`. Enable `ccdEnabled` for fast movers.
4. Constrain two bodies: add `JointComponent` on the child body with
   `jointType` `fixed`, `revolute`, `prismatic`, `spherical`, `spring`, or
   `rope`, and set `connectedEntityId` to the other body. Anchors and `axis`
   are in each body's LOCAL space; `motor` and `limits` apply to revolute and
   prismatic joints.
5. Apply an impulse or launch from a script (not from authoring): call
   `ctx.physics.command(entityId, bodyCommand)`; query space with
   `ctx.physics.overlapTest`, `ctx.physics.shapecast`, `ctx.physics.occupancyQuery`.

## Pitfalls

- `friction` and `restitution` are clamped 0..1. A bouncy ball is high
  `restitution`; ice is low `friction`.
- Do NOT author `ForceComponent` or `VelocityComponent` values: both are hidden
  internal runtime lanes. Forces go through `ctx.physics.command`; the movement
  vector is runtime-owned.
- A `RigidBodyComponent` makes the runtime own that entity's Transform each
  tick. Do not also drive it with `CharacterMovementComponent`; pick one motor.
- A collider with `collision:"none"` neither blocks nor triggers; it is only a
  query/placement shape.
- Joint `motor`/`limits` on a `fixed` joint do nothing; they exist only on
  revolute and prismatic.
- The document places the bodies; the per mutation call is the precision tier for
  attaching these components, not a bulk placement tool.

## Verify

- `engine_get_component_schema` on `ColliderComponent` and `RigidBodyComponent`
  for shape/bodyType enums.
- `simulation_run` (`qa.run.start`) to confirm solids block and triggers fire.
- `runtime_proof_run` (`runtime.proof.run`) for a deterministic physics
  transition receipt.
