PhysicsDebugRenderer
physics/physics-debug-renderer.ts:86 Extends AbstractWorldComponent<PhysicsDebugRendererDeps>
A world-scoped debugging overlay that draws the outline of every collider in the PhysicsWorld on top of the scene. It exists to answer the question that comes up constantly when wiring up physics — "where does the engine actually think this body is?" — by making the otherwise-invisible simulation geometry visible, so a collider that's the wrong size, offset from its sprite, or rotated unexpectedly is obvious at a glance instead of something you infer from misbehaviour.
On/off at startup, not toggleable
The renderer is opt-in by registration: add it to a world's component factory and the overlay is on; leave it out and there is zero cost. There is deliberately no runtime toggle — wire it in (or behind your own build flag) when you want it. Like PhysicsWorld, it is never auto-attached.
How it draws
Each frame, in post-update — after PhysicsWorld has stepped the
simulation in pre-update, so every body's transform is settled — the renderer
asks Rapier for a fresh set of debug line segments (its built-in
debugRender, the same data Rapier's own debuggers use) and strokes them
into a single Pixi Graphics overlay. The overlay is a child of the
Scene, so it inherits the camera transform and the outlines stay
locked to the bodies as the camera pans, zooms, and rotates. It is given a
very high zIndex (and turns on the scene container's child sorting) so the
outlines sit above the filled body graphics they trace — including bodies
spawned at runtime after this component was added.
By default the segments are tinted with Rapier's own per-collider colours, which distinguish awake from sleeping bodies and sensors from solid colliders. Pass PhysicsDebugRendererOptions.color to override them with a single flat colour (and take the cheaper single-stroke draw path).
Example
import {
Game, initPhysics, PhysicsWorld, PhysicsDebugRenderer,
} from '@arcade2d/engine';
const game = await Game.bootstrap({ canvas: { fill: 'window' } });
await initPhysics();
const DEBUG_PHYSICS = true; // flip per build/environment
const world = game.createWorld({
components: (world) => ({
physics: () => new PhysicsWorld(world, { gravity: { x: 0, y: 980 } }),
// Registering the component is the on switch; omit it and there's no cost.
...(DEBUG_PHYSICS
? { physicsDebug: () => new PhysicsDebugRenderer(world) }
: {}),
}),
});Constructors
constructor(host: World, options: PhysicsDebugRendererOptions): PhysicsDebugRenderer Parameters
-
hostWorld -
optionsPhysicsDebugRendererOptions
Properties
enabled: boolean Per-component gate on the three update hooks (onPreUpdate,
onUpdate, onPostUpdate). When explicitly false, the engine skips
all three for this component during the host's tick — useful for
temporarily pausing behaviour (e.g. a freeze powerup) without removing
the component and losing its internal state.
Does not gate onAdded or onDestroy; those always fire so a host can
never end up with a half-attached component.
Accessors
game: Game The Game the host world belongs to. Always non-null — the
world's game field is a mandatory construction argument, not an
option.
raw: Graphics Direct access to the underlying Pixi Graphics overlay.
Use with care. raw is an intentional escape hatch — for tuning the
overlay's blend mode, alpha, or filters beyond what this component models.
Code that touches raw is coupled to Pixi's public API; prefer
PhysicsDebugRendererOptions where it covers your need.
world: World The World this component is attached to — identical to
AbstractComponent.host at this tier, exposed under the
world name so subclass code reads the same on every tier.
Methods
onAdded(__namedParameters: PhysicsDebugRendererDeps): void Mounts the overlay into the scene and enables child sorting on the scene
container so the high-zIndex overlay reliably draws above the bodies it
traces.
Parameters
-
__namedParametersPhysicsDebugRendererDeps
Returns
void onDestroy(): void Detaches and frees the overlay. Safe to call even if onAdded never ran.
Returns
void onPostUpdate(_update: WorldUpdate, __namedParameters: PhysicsDebugRendererDeps): void Redraws every collider outline for the current, settled simulation state. Runs in post-update so PhysicsWorld's pre-update step has already advanced the bodies this frame.
Parameters
-
_updateWorldUpdate -
__namedParametersPhysicsDebugRendererDeps
Returns
void onUpdate(_update: WorldUpdate, _deps: PhysicsDebugRendererDeps): void Lifecycle hook for the main update phase. Called once per world
tick, after every component's onPreUpdate and before any
onPostUpdate.
Parameters
-
_updateWorldUpdate -
_depsPhysicsDebugRendererDeps
Returns
void resolveDependencies(resolver: WorldDependencyResolver): PhysicsDebugRendererDeps Declares the world-tier dependencies on the Scene and the PhysicsWorld.
Parameters
-
resolverWorldDependencyResolver
Returns
PhysicsDebugRendererDeps Throws
EngineError with code ErrorCode.WORLD_COMPONENT_DEPENDENCY_MISSING when the world has no PhysicsWorld to read colliders from. (The Scene is auto-attached, so only the physics dependency is realistically absent.)