Physics — the opt-in simulation layer
physicsis the opt-in simulation sibling: momentum, forces, restitution, friction, stacking — real dynamics, kept deterministic by a fixed-step integrator and an ordered solver. It integrates dynamic bodies during Advance, consumes contacts found during Detect, resolves them during Resolve, and presents settled state to React. Reach for it only when you want simulated motion; the arcade case stays on collision + script responses.
Status: design. Not built yet.
What it is, and why it's separate
collision deliberately stops at detecting overlaps, because response — bounce, push-apart, stacking — is where physics engines lose determinism. physics is the layer that does response properly: it takes collision's contacts and resolves them with real dynamics, and it keeps determinism the only way response can — by discipline:
- a fixed timestep (the stage tick, never wall-clock), so the simulation advances in identical increments regardless of display rate;
- an ordered, bounded solver — a fixed number of iterations in a defined pair order — so contact resolution is reproducible, not order-of-arrival.
It is opt-in precisely so the common case doesn't pay for it: an arcade "hit it → do this" game uses collision events and script policy, no integrator. Enable physics only when you want things to fall, bounce, and pile up on their own.
Bodies
A target becomes a body by being given physical properties:
| Body kind | Moves | Forced | Affects others | Example |
|---|---|---|---|---|
| dynamic | yes | yes | yes | a crate, a ball |
| static | no | no | yes | the ground, a wall |
| kinematic | yes (driven) | no | yes | a moving platform |
A body carries mass, velocity, restitution (bounciness), and friction. Dynamic bodies get their position from the integrator (forces → acceleration → velocity → position) instead of from motion / tween — a target is either animation-driven or physics-driven, not both at once.
In the tick — integration, detection, and resolution
physics participates in the phase order across Advance and Resolve:
Input → Advance (
physicsintegrates bodies) → Detect (collision finds contacts) → Resolve (physicssolves those contacts) → React
Advance integrates dynamic bodies at the fixed step and writes predicted positions and velocities. Resolve then reads those body states and collision's contacts, solves contacts (separates penetrating bodies, applies restitution and friction along the contact normal), and writes the settled positions and velocities — which React then sees. Determinism holds because the step is fixed, the solver order defined, and nothing consults real time.
Forces and control
force/impulse— a continuous force, or an instantaneous impulse, on a body (gravity is just a force every dynamic body gets).velocity— read or set a body's velocity directly (a launch, a jump).- kinematic drive — a kinematic body can still be moved by motion; it pushes dynamic bodies but isn't pushed back, so a scripted platform carries physics crates.
Determinism — the whole point
Same bodies, same forces, same start tick → the same simulation, every run and on replay — because: fixed timestep, ordered bounded solver, no randomness, no wall-clock. That is what lets a physics scene run identically on the simulator and the EE, be recorded and replayed, and be stepped with stage.tick. It is the same contract the rest of the family keeps — earned here by discipline rather than by being a pure function, since dynamics are stateful.
Clients
- Luau —
require("physics"): make bodies, apply forces, read velocities. - AntBASIC — a light front door: mark a sprite
PHYSICS, setGRAVITY, and let collisions resolve — enough for a falling-blocks or platformer feel without scripting the solver.
Related
- collision — the detector it consumes · stage — the fixed tick and phase order it needs · motion — drives kinematic bodies
- luau_physics — the Luau API