Documentation
    Preparing search index...

    Interface PhysicsWorldInit

    How a PhysicsWorld is constructed: §20's world options plus the adapter instance (plan P5-5) and the optional §43 pose store.

    Named …Init rather than …Options because PhysicsWorldOptions is already §37's own record — the one handed to adapter.initialize — and this type is that record plus the engine-side wiring, which is not part of what a solver is configured with.

    interface PhysicsWorldInit {
        adapter?: PhysicsWorldAdapter;
        determinism?: DeterminismLevel;
        dimension: PhysicsDimension;
        gravity?: Vector3Input;
        localPlane?: LocalPlane;
        onSolverReject?: (report: SolverRejectionReport) => void;
        poses?: PoseBuffer;
        sleeping?: Partial<SleepingConfig>;
        solver?: SolverSelection;
        solverIterations?: number;
        solverRegistry?: SolverRegistry;
        units?: PhysicsWorldUnits;
    }

    Hierarchy (View Summary)

    Index

    The solver this world drives, as an instance the application constructed (plan P5-5).

    Its capabilities are checked against dimension and determinism at construction, so a world that cannot be simulated fails immediately rather than degrading quietly (§37).

    Exactly one of adapter and PhysicsWorldInit.solver is required; giving both is refused rather than silently preferring one (§85).

    determinism?: DeterminismLevel

    The reproducibility tier the world asks for (§33). Defaults to "same-runtime" (Appendix A). A world may not ask for more than its adapter declares in PhysicsCapabilities.determinism; the world checks that at construction (WP-5.3).

    dimension: PhysicsDimension

    "2d" or "3d" (§21). Required — there is no defensible default.

    gravity?: Vector3Input

    World gravity in m/s². Defaults to (0, -9.81, 0) (Appendix A); a Vector2 widens to z = 0, and a "2d" world rejects a non-zero z.

    localPlane?: LocalPlane

    §21 simulation plane in world space. Bodies with RigidBody.space === "local-plane" author a 2D pose in this plane's frame; feed/publish maps through the plane basis.

    Omitted means origin 0, normal +Z, xAxis +X (the world XY plane — the 2D default). addBody accepts "local-plane" against that default. Screen / viewport / camera / billboard stay refused (§8).

    Engine-side: not forwarded to adapter.initialize.

    onSolverReject?: (report: SolverRejectionReport) => void

    Called for each solver solver: "auto" passes over, with the §37 reason ("unsupported", "dimension", "determinism").

    The solver-side twin of §62's fallback diagnostics event, delivered as a callback for the same reason: the frozen §3.1 matrix gives @fourjs/physics no @fourjs/diagnostics edge, so the report is handed to the application to route. Unread for an instance or a named solver.

    poses?: PoseBuffer

    The engine's previous/current pose store (§43). When given, the node of every dynamic body — and of every "blended" node, whatever its §22 type — is tracked on registration and untracked on removal; see the module header for why the world never captures into it.

    sleeping?: Partial<SleepingConfig>

    §32 sleeping thresholds. A partial record is merged over DEFAULT_SLEEPING_CONFIG by resolveSleepingConfig, so { timeThreshold: 2 } changes one field and keeps Appendix A's rest.

    §20's solver: "auto" — or one §102 solver by name — resolved through @fourjs/physics's solver registry (PH-19, 2026-08-07).

    The alternative to PhysicsWorldInit.adapter, and the reason it took this long: resolving a name means something has to map it to a class, and that something must not be this package, which would then have to import every §102 solver package — wasm images included — into every program that ever named PhysicsWorld. (That is the cost this design avoids; it says nothing about which solvers exist. Only @fourjs/physics-rapier ships an implementation today — physics-box2d and physics-soft are reserved stubs, as docs/COMPATIBILITY.md records.) So a solver package opts in explicitly and this option resolves against whatever the application actually imported:

    import { registerRapierSolver } from "@fourjs/physics-rapier";

    registerRapierSolver();
    const world = new PhysicsWorld({ dimension: "3d", solver: "auto" });

    "auto" takes the first registered solver whose §37 capabilities cover this world's dimension and determinism (§20, §37); a name is handed back unfiltered, so an unsatisfiable one fails with this constructor's own §21/§33 message. Either way the adapter arrives uninitialized and PhysicsWorld.initialize awaits it exactly as it awaits one you constructed yourself.

    solverIterations?: number

    Constraint-solver iterations per step (§28 "solver iterations") — a world-level accuracy/cost dial, closing the gap recorded at the Phase 6 exit ("§28 solver-iterations feature not exposed anywhere", 2026-08-02; closed 2026-08-04).

    World-level and not per-joint because that is what solvers actually offer: Rapier 0.19.3 exposes exactly World.numSolverIterations (default 4 — more iterations, stiffer joints and stacks, linearly more cost). Omitted means the solver's own default, so existing worlds — and every recorded §33/§34 checksum and replay — are untouched. Setting it is checksum-affecting, exactly like changing gravity: two runs must use the same value to reproduce.

    A positive integer; validated at construction (§85).

    solverRegistry?: SolverRegistry

    The registry PhysicsWorldInit.solver resolves against; the shared one by default (§37).

    Pass one to keep a selection scope to itself — the discipline the tests use so that one world's registrations are invisible to the next.

    §40 scale factors for authored numbers (§40, §101).

    Structurally the scale half of @fourjs/core's unit-system record (lengthToMeters, massToKilograms); pass that record through. When set, authored gravity / poses / masses are converted into SI for the solver and converted back on publish. Internal solver state is SI. Omitted means today's identity path — existing tests stay bit-identical.

    This field is engine-side: adapter.initialize is handed the resolved SI gravity and never sees the scale record.