OptionaladapterThe 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).
OptionaldeterminismThe 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).
"2d" or "3d" (§21). Required — there is no defensible default.
OptionalgravityWorld 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.
Optionallocal§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.
OptionalonCalled 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.
OptionalposesThe 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.
Optionalsleeping§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.
Optionalsolver§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.
OptionalsolverConstraint-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).
OptionalsolverThe 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.
Optionalunits§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.
How a PhysicsWorld is constructed: §20's world options plus the adapter instance (plan P5-5) and the optional §43 pose store.
Named
…Initrather than…OptionsbecausePhysicsWorldOptionsis already §37's own record — the one handed toadapter.initialize— and this type is that record plus the engine-side wiring, which is not part of what a solver is configured with.