Skip to content

Physics

DownDraft provides a pluggable physics abstraction layer with a Rapier3D backend via Rust FFI.

A PhysicsRealm represents an isolated physics world. Multiple concurrent realms are supported.

import { PhysicsRealm, RealmTier } from "@downdraft/engine";
import { createRapierBackend } from "@downdraft/engine/libraries/physics-rapier";
const backend = await createRapierBackend();
const realm = new PhysicsRealm(backend, {
name: "main",
tier: RealmTier.Near,
gravity: [0, -9.81, 0],
tierConfig: {/* per-tier LOD config */},
});
import { startGame } from "@downdraft/engine/app/renderer";
import { PhysicsRapierLib, PhysicsAPITok } from "@downdraft/engine/libraries/physics-rapier";
startGame({
libraries: [PhysicsRapierLib],
// inject the typed token in onReady:
onReady: (ctx) => {
const physics = ctx.inject(PhysicsAPITok);
},
});

Bare class exports (RapierPhysicsBackend, createRapierBackend, UniversalPhysicsAPI) remain available for games that wire physics manually.

Physics-related components include:

  • RigidBody — Static, dynamic, or kinematic bodies
  • Collider — Box, sphere, mesh, or convex shapes
  • Velocity — Linear and angular velocity
  • PhysicsTransform — Synced transform between physics and ECS
import { Collider, RigidBody, Velocity, createBoxCollider } from "@downdraft/engine";

A built-in character controller handles player movement with proper collision response, slope handling, and stepping.

// Ray and shape queries are available through the physics interface
const hit = realm.raycast(origin, direction, maxDistance);

Multiple physics realms can run concurrently, enabling scenarios like:

  • Separate simulation spaces (interior vs exterior)
  • Local physics bubbles around players
  • Preview physics in the editor without affecting the main simulation

The PhysicsBackend interface defines the contract for physics implementations. Alternative backends can be registered via the physics registry.