Documentation
    Preparing search index...

    Class SweptCharacterController

    §12's character controller resolved against the collision world — a capsule swept through PhysicsWorld.shapeCast (§30), sliding along walls, stepping over risers up to SweptCharacterController.stepHeight and standing only on ground within SweptCharacterController.slopeLimit.

    Written under §42's "kinematic" authority by SweptCharacterSystem at §39 step 4. See the module note for the holds-not-extends decision, the §39 placement argument, and everything this tier stages.

    The capsule, the skin, the slide budget, the step height and the slope limit are readonly: a retuned character is a new character (OrbitRig's rule). Every one of them changes what a query means, so a mid-run change would silently make this step's casts incomparable with the last's — and it keeps every §85 refusal in one place, the constructor, refusing rather than clamping. The locomotion parameters that do not touch a query — moveSpeed, gravity, jumpSpeed, yaw — stay writable, and their refusals are the held CharacterController's.

    Implements

    Index
    budgetExhaustedSteps: number = 0

    Steps on which the slide budget ran out with motion still unspent — the evidence that SweptCharacterController.maxSlides bit. Non-zero is not an error; it is a character in a corner.

    collisionGroups: number

    §30 bit set this controller's casts belong to.

    collisionMask: number

    §30 bit set this controller's casts may hit.

    groundSnapDistance: number

    How far a grounded character looks down for its ground, in metres.

    halfHeight: number

    Half the capsule's cylindrical length, in metres (§24).

    host: ComponentHost | null = null

    The node this component is attached to, or null. Written by the ComponentRegistry alone (§6a); never assign it.

    maxSlides: number

    Collide-and-slide iteration budget for one fixed step.

    pushDynamics: boolean

    Whether a horizontal slide against a "dynamic" body imparts an impulse. false preserves the pre-PH-11c no-push behaviour.

    pushImpulseScale: number

    Dimensionless gain on the PH-11c push impulse.

    pushMass: number

    Mass, in kilograms, used only for the PH-11c reduced-mass push. The controller is kinematic and is not a solver body.

    radius: number

    Radius of the swept capsule, in metres (§24).

    skinWidth: number

    Gap kept between the capsule and every surface, in metres.

    skippedSteps: number = 0

    Steps on which the controller declined to write because the pose it computed was not finite — CharacterController.skippedSteps' contract, for the same reason: §85's refusals govern authoring, and a value that goes bad mid-step is a transient a fixed step must survive rather than throw in.

    slideCount: number = 0

    Collide-and-slide iterations that ended in an impact, over the run.

    slopeLimit: number

    Steepest walkable ground, in radians from horizontal (§7a).

    stepHeight: number

    Largest rise climbed without jumping, in metres; 0 disables step-up.

    stepUpCount: number = 0

    Step-up attempts that were accepted, over the run.

    world: PhysicsWorld | undefined

    The collision world every sweep is cast against, or undefined.

    Writable so a controller restored from a §79 document can be bound to the world the application builds — the same "reloading a scene is not restoring a simulation" step registerPhysicsSerializers documents for bodies. A controller with no world is skipped, once-warned, by the system.

    typeName: "swept-character-controller"

    Component key (plan D2) and §79 serialization name.

    • get active(): boolean

      Whether the next step would write anything — the gate SweptCharacterSystem applies before the §42 authority check, so a grounded, still, unturned character neither bumps Transform.version, nor casts a single query, nor reports a conflict on a node it does not own.

      CharacterController.active's rule and its recorded corollary: with gravity: 0 a character that has never touched ground stays ungrounded and therefore stays active — it is falling at zero speed, and pretending otherwise would let SweptCharacterController.jump succeed in mid-air.

      Returns boolean

    • get grounded(): boolean

      Whether the last resolved step ended standing on ground within SweptCharacterController.slopeLimit.

      A geometric claim, unlike CharacterController.grounded's claim about a plane: it means the downward probe found a collider whose contact normal is no steeper than the limit. A character on a 60° face with a 45° limit is not grounded — it slides — which is the whole point of the parameter.

      Returns boolean

    • Sets the planar move intent, clamped to the unit disc.

      Parameters

      • forward: number
      • right: number

      Returns void

      CharacterController.setMoveIntent — this forwards to it, so the clamp, its Math.sqrt and its §85 refusals are that class's, executed once.

    • Advances the character by deltaSeconds and writes the resolved pose onto node's transform.

      Called by SweptCharacterSystem once per fixed step, after the §42 authority check. It takes the Node rather than the Transform CharacterController.step takes, and needs to: a swept controller must exclude its own body from every cast (§30 "ignored bodies"), and only the node identifies it to PhysicsWorld.getBodyHandle.

      Both writes commit or neither does: the whole pose is computed into locals and checked for finiteness before position.set, so a NaN arriving from anywhere leaves the transform and the vertical state untouched and counts one SweptCharacterController.skippedSteps.

      Parameters

      • node: Node
      • deltaSeconds: number

      Returns boolean

      whether the pose was written.

    • Moves the character by (x, y, z) metres without sweeping, and marks it as needing a write.

      The escape hatch for motion this controller does not model — the named seam for moving-platform carry above being the motivating one. It is deliberately not resolved against geometry: the caller is asserting that the displacement is legitimate (the floor moved under the character), and sweeping it would be resolving the platform's motion as if it were the character's.

      Parameters

      • x: number
      • y: number
      • z: number

      Returns void

      RangeError if any component is not finite (§85).