Talos docs

Joint

Since 0.6

Present on ctx.joint while the entity's joint component is in force: a hinge, a slide or a weld from this entity's body to another's or to the world.

Plain text

Null without a joint component, and from the moment the joint is gone — its connected entity despawned, which is how a game breaks a joint on purpose. The coordinate. position is radians about the axis (revolute) or metres along it (prismatic), 0 in the pose the joint was built in — the scene's pose, for a scene's joint — and positive for a right-handed turn about the axis or a slide along it. limits and a position motor's target are in the same coordinate. A fixed joint reads 0. Motors are acceleration-based: stiffness and damping are scaled by the bodies' inertia, so one tuning moves a light door and a heavy gate alike; maxForce is the physical cap. Defaults: velocity mode damping 50, position mode stiffness 100 and damping 20. A motor or limits change is in force from the next physics step (the top of the next tick). Refusals. A NaN or infinite number, a negative maxForce/stiffness/damping, limits with min above max, an unknown mode, or a first motor with no maxForce, throw a RangeError. setMotor, stopMotor and setLimits on a fixed joint, or through a handle kept after its joint went, change nothing, do not throw, and are counted on GET /perf → unwired.joint_ignored. ts // A door that swings to 90° when the player is near and closes when they leave. update(ctx) { const near = ctx.entity.distanceTo(ctx.world.find("player")!) < 2 ctx.joint?.setMotor(near ? Math.PI / 2 : 0, { mode: "position", maxForce: 200 }) }

Signature

export interface Joint {
  /**
   * Drive the free axis: to a speed (`mode: "velocity"`) or to a place (`mode: "position"`). The mode defaults
   * to the current motor's, else velocity; a mode change takes that mode's default stiffness and damping.
   */
  setMotor(target: number, options?: JointMotorOptions): void
  /** Switch the motor off: the axis is free again, within any limits. */
  stopMotor(): void
  /** Replace the limits: `[min, max]` in radians or metres from the rest pose, or null for none. */
  setLimits(limits: Vec2 | null): void
  /** What the joint leaves free; null once the joint is gone. */
  readonly kind: JointKind | null
  /** The connected entity, or null for a joint to the world (and once the joint is gone). */
  readonly connectedTo: EntityHandle | null
  /** Radians (revolute) or metres (prismatic) from the pose the joint was built in. */
  readonly position: number
  /** rad/s or m/s along the free axis. */
  readonly velocity: number
  /** `[min, max]`, or null for none. */
  readonly limits: Vec2 | null
  /** The motor, or null for none. */
  readonly motor: JointMotorState | null
}

Import: import type { Joint } from "@argus/api"

Members

MemberSignatureDescription
setMotorsetMotor(target: number, options?: JointMotorOptions): voidDrive the free axis: to a speed (mode: "velocity") or to a place (mode: "position"). The mode defaults to the current motor's, else velocity; a mode change takes that mode's default stiffness and damping.
stopMotorstopMotor(): voidSwitch the motor off: the axis is free again, within any limits.
setLimitssetLimits(limits: Vec2 | null): voidReplace the limits: [min, max] in radians or metres from the rest pose, or null for none.
kindreadonly kind: JointKind | nullWhat the joint leaves free; null once the joint is gone.
connectedToreadonly connectedTo: EntityHandle | nullThe connected entity, or null for a joint to the world (and once the joint is gone).
positionreadonly position: numberRadians (revolute) or metres (prismatic) from the pose the joint was built in.
velocityreadonly velocity: numberrad/s or m/s along the free axis.
limitsreadonly limits: Vec2 | null[min, max], or null for none.
motorreadonly motor: JointMotorState | nullThe motor, or null for none.

Example

The tested fixture fixtures/host/door.ts.

import type { Behavior } from "@argus/api"
// docs/API.md, "Joints": a door on a hinge that swings open while the player is near and closes
// behind them. Typechecked by packages/api's tests.
export default {
  update(ctx) {
    const player = ctx.world.find("player")
    const near = player !== null && ctx.entity.distanceTo(player) < 2
    ctx.joint?.setMotor(near ? Math.PI / 2 : 0, { mode: "position", maxForce: 200 })
  },
} satisfies Behavior