Physics · interface

ControllerInput

Explained in Your first game, Rigid bodies.

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

Properties

NameTypeDescription
moveXnumberDesired direction, in world units per second. Length above maxSpeed is clamped.
moveZnumber
moveYoptionalnumberThe third component, for a body whose up is not world Y. Absent means zero, which is what every caller with a level floor means and is arithmetically what they got before this existed.
More

Two components span the tangent plane only while up is world Y, and setUp made up a parameter without making the input one. On a wall whose normal is +Z, up the wall is +Y and no pair of moveX and moveZ describes it: the input plane collapses onto a line, so a body that could stand on the wall could not be steered along it. Reported from outside by a consumer that gave up on the acceleration curves, the air control and the speed clamp entirely — writing velX/velY/velZ directly each tick with acceleration: 0, deceleration: 0 so that applyFeel would leave the velocity alone — which is the whole of the feel this class exists to provide, bypassed to get one axis back.

Read as a world direction and flattened onto the surface, exactly as the other two are. A caller supplying all three describes "forward" in whatever frame it is standing in.

projectMoveoptionalbooleanWhether to flatten the move vector onto the plane the body is standing on. Absent means yes, which is what every caller before this got and what a body moving on one surface wants.
More

False is for a body between two surfaces, which is the one case the projection cannot serve. Steering normally holds the along-up component out, steers the rest and puts it back, because that component is gravity and the jump rather than the stick. A body crossing a convex edge has a third thing there: while its frame rotates from the old face to the new, the correct direction of travel is neither face's tangent but a blend of them, held by the contacts already on the far side. Flattened onto the frame's current plane that command is turned aside — by 8.5 degrees early in a 90-degree crossing and more later — and the body crawls the transfer instead of crossing it. Measured from outside on a sprint across a 90-degree convex edge: contacts decaying from four to none by tick 46, slipping at 46, falling by 51, 21 ticks of 90 with nothing under it against none when the velocity was written directly.

It is the projection and not the acceleration, which the reporter separated before asking: the same crossing at acceleration times 15, 60, 240 and 2000 of maxSpeed gave 21 ticks every time. A lag would have improved.

With this false the move vector is the velocity the body is steered toward whole — the along-up component included, because a caller that has taken responsibility for the direction has taken responsibility for all of it. Everything else still applies: the speed clamp, the acceleration and deceleration curves, airControl when off the ground, and gravity afterwards. That is the difference between this and the direct velocity write it exists to retire, which bypasses all four.

jumpbooleanHeld, not edge-triggered: the controller does its own edge detection and buffering.