melonJS
    Preparing search index...

    Interface PhysicsAdapter

    Swappable physics engine integration. BuiltinAdapter ships with melonjs and wraps the engine's native SAT-based physics; third-party adapters (e.g. @melonjs/matter-adapter) implement this interface to plug a different engine in.

    Lifecycle contract: one adapter per World, instantiated and passed to Application at construction, never swapped at runtime. Adapter state (bodies, constraints, sleeping flags, etc.) does not migrate between adapters.

    Body handle convention: PhysicsAdapter.addBody returns an opaque handle that becomes renderable.body. Each adapter chooses its own concrete body type — BuiltinAdapter returns the legacy Body class so existing property-based code (body.vel.x = 5, body.isStatic = true) keeps working unchanged. Third-party adapters return their engine's native body type. For adapter-agnostic code, use the portable methods on the adapter itself (setVelocity, applyForce, etc.) instead of mutating the handle directly.

    interface PhysicsAdapter {
        capabilities: AdapterCapabilities;
        gravity: Vector2d;
        name?: string;
        physicLabel?: string;
        url?: string;
        version?: string;
        addBody(renderable: Renderable, def: BodyDefinition): PhysicsBody;
        applyForce(renderable: Renderable, force: Vector2d, point?: Vector2d): void;
        applyImpulse(
            renderable: Renderable,
            impulse: Vector2d,
            point?: Vector2d,
        ): void;
        applyTorque?(renderable: Renderable, torque: number): void;
        destroy?(): void;
        getAngle?(renderable: Renderable): number;
        getAngularVelocity?(renderable: Renderable): number;
        getBodyAABB(renderable: Renderable, out: Bounds): Bounds | undefined;
        getBodyShapes(renderable: Renderable): readonly BodyShape[];
        getMaxVelocity?(renderable: Renderable): { x: number; y: number };
        getVelocity(renderable: Renderable, out?: Vector2d): Vector2d;
        init?(world: World): void;
        isGrounded?(renderable: Renderable): boolean;
        queryAABB(rect: Rect): Renderable[];
        raycast?(from: Vector2d, to: Vector2d): RaycastHit | null;
        removeBody(renderable: Renderable): void;
        setAngle?(renderable: Renderable, angle: number): void;
        setAngularVelocity?(renderable: Renderable, omega: number): void;
        setCollisionMask(renderable: Renderable, mask: number): void;
        setCollisionType(renderable: Renderable, type: number): void;
        setFrictionAir(
            renderable: Renderable,
            friction: number | { x: number; y: number },
        ): void;
        setGravityScale(renderable: Renderable, scale: number): void;
        setMaxVelocity(
            renderable: Renderable,
            limit: { x: number; y: number },
        ): void;
        setPosition(renderable: Renderable, p: Vector2d): void;
        setSensor?(renderable: Renderable, isSensor: boolean): void;
        setStatic(renderable: Renderable, isStatic: boolean): void;
        setVelocity(renderable: Renderable, v: Vector2d): void;
        step(dt: number): void;
        syncFromPhysics(): void;
        syncToPhysics?(renderable: Renderable): void;
        updateShape?(renderable: Renderable, shapes: BodyShape[]): void;
    }

    Implemented by

    Index

    Properties

    capabilities: AdapterCapabilities

    advertised capabilities; user code may branch on these

    gravity: Vector2d

    world gravity. Mutate to change at runtime.

    name?: string

    Optional display name reported on the startup banner. Defaults to the adapter class name. Third-party packages typically set this to their npm package id (e.g. "@melonjs/matter-adapter").

    physicLabel?: string

    Short adapter identifier exposed as world.physic. User code uses it to branch on which physics implementation is active without importing the adapter class — e.g.

    if (app.world.physic === "matter") {
    // matter-only setup (constraints, etc.)
    }

    Convention: a single lowercase token. The first-party labels are "builtin" (default — BuiltinAdapter) and "matter" (@melonjs/matter-adapter). Third-party adapters should pick a concise identifier that won't collide with future official ones.

    The reserved value "none" is set on world.physic only when the user passes physic: "none" to Application to disable physics entirely; adapters should not use it.

    Defaults to "builtin" if an adapter doesn't declare its own — keeps legacy adapters wired in before this field was added still working.

    url?: string

    Optional URL (npm / homepage / repo) reported on the startup banner. Convention matches the debug-plugin's startup line.

    version?: string

    Optional package version reported on the startup banner. Set this when shipping the adapter as a separate npm package so users can tell which version is wired in at a glance.

    Methods

    • Register a body with the simulation. Returns an opaque handle that becomes renderable.body. Each adapter chooses its own concrete body type — see the class doc for the convention.

      Prefer the declarative path. Set renderable.bodyDef and call Container.addChild(renderable) — the container auto-invokes addBody AND inserts the renderable into the world's broadphase (QuadTree) in one atomic step. Direct calls to addBody only register the body with this adapter; they do NOT add the renderable to the world's container hierarchy, so the broadphase won't return it as a collision candidate. A body registered via direct addBody without a matching addChild will integrate (velocity, forces) but never collide.

      Parameters

      Returns PhysicsBody

    • Return the body's axis-aligned bounding box in renderable-local coordinates (relative to renderable.pos). Writes into the supplied out Bounds so callers can poll allocation-free each frame. Returns undefined if the renderable has no registered body.

      Used by ecosystem tooling — most notably @melonjs/debug-plugin — to visualize the body's effective collision extent. The adapter owns coordinate-system conversion: builtin Body already stores bounds in local space, matter stores them in world space and the adapter subtracts renderable.pos before writing.

      Required by the adapter contract: any adapter that registers bodies MUST implement this. The output is the canonical, local- space representation tools rely on regardless of which engine the adapter wraps.

      Parameters

      Returns Bounds | undefined

    • Return a snapshot of the body's collision shapes in renderable-local coordinates. The returned array is intended for read-only inspection (debug drawing, hit-region queries) — adapters may return a live reference for performance, so callers MUST NOT mutate it. Returns an empty array if no body.

      Pairs with getBodyAABB as the adapter-side debug surface; lets each adapter own its coordinate convention without polluting the underlying physics-engine body objects. Required by the adapter contract.

      Parameters

      Returns readonly BodyShape[]

    • Read the body's current velocity cap (mirror of setMaxVelocity). Returns plain {x, y} so callers don't need to import a vector type. Optional — adapters that don't implement velocity caps omit this method.

      Parameters

      Returns { x: number; y: number }

    • Unregister a body. Called automatically when Container.removeChild detaches the renderable; direct calls are the inverse of a direct addBody (rare — use removeChild for the normal lifecycle).

      Parameters

      Returns void

    • Toggle a body between solid and sensor mode. A sensor still fires collision events (onCollisionStart / onCollisionActive / onCollisionEnd) but the engine does not push the bodies apart on contact — useful for one-way platforms, trigger zones, ground-snap ground assists, etc.

      Adapters without a native sensor flag emulate by toggling the collision mask between its previous value and NO_OBJECT.

      Parameters

      Returns void

    • Runtime body-property mutators. Each maps to the corresponding BodyDefinition field and lets game code change a body's physical properties without re-creating it. Adapter implementations route to their native engine (BuiltinAdapter writes to the Body handle; MatterAdapter calls Matter's Body.set* helpers).

      Parameters

      Returns void

    • Copy physics-engine body positions back to renderable.pos and rotations to the renderable's transform. Called after step each frame. Adapters that mutate the renderable directly during step (e.g. BuiltinAdapter) may leave this a no-op.

      Returns void