Physics · interface

ColliderSurfaceOptions

A ColliderSet answering "where is the ground here?", so a solid holds a body up.

Explained in Your first game, Rigid bodies.

interface ColliderSurfaceOptions
import type { ColliderSurfaceOptions } from '@driftengine/physics';

In depth

Because a collider was solid to walk into and not to stand on. The kinematic sweep resolves a body against a collider set laterally, and CharacterController senses ground through PhysicsWorld bodies and through a GroundSurface — a collider set is neither, so nothing ever asked it what was under your feet. Measured before this existed: a character dropped over a ColliderSet slab whose top face is at 5.5 m falls to −84 m in three seconds, which is exactly what it does with no slab at all.

Reported by a consumer building flyovers, who could express a sloped deck as a hull already and found that standing on one did not hold them up. The alternative available to them was to add every deck to a PhysicsWorld as a static body as well — the same geometry twice, in two structures that can disagree.

It is a GroundSurface and not a new seam, which is what makes it worth having. Everything that stands on ground already takes one: the character controller, the raycast vehicle, the third-person camera boom, the rain field. And because heightSurface takes a list of surfaces, a world can be terrain and slabs without either knowing about the other:

const ground = new CompositeSurface([
  heightSurface((x, z) => terrainAt(x, z)),
  colliderSurface(decks, { minY: -10, maxY: 60 }),
]);

What it is not. It is not a replacement for the sweep: the sweep is what stops a body walking into a collider, and this is what stops it falling through one. A consumer wants both, and they read the same set.

Properties

NameTypeDescription
minYreadonlynumberThe vertical extent to look through, metres.
More

Required, and guessing would be worse than asking. A ground query is a column, and the spatial hash walks every cell in it — an unbounded column over a 4 m grid is half a million cells and a frozen frame. A consumer knows how tall their world is; the engine does not, and a default would be wrong quietly.

maxYreadonlynumber