Guide31 min read21 sections

Owned physics — first runnable backend

Physics ownership, room integration, replay, capacity, and measured limits.

docs/OWNED_PHYSICS.mdSource updated 2026-10-27
Markdown
On this page 21 sections

#October 27 integrated capacity baseline

The actual room runtime now admits the plan's 128 authored-body state and sixteen contact participants. npm run physics:room drives one authoritative body room and sixteen trusted motors on both backends. Capacity admission and restoration checks pass; the CPU timing fails the full-load budget on both backends. ROOM_CAPACITY contains the focused record, timing breakdown and exclusions. Direct component comparison and indexed body lookup now reduce the short local owned simulation p95 from 680.131 to 594.267 ms while retaining prior state hashes; the reference falls from 217.601 to 132.287 ms. Both still fail. The next work is the remaining per-traveler frame/body overhead and owned contact/controller cost. Prepared component readers further reduce that short sample to 565.255 ms owned / 106.976 ms reference, with identical final traveler poses and prior replay hashes. Further small optimizations are deferred at the user's direction; the capacity gate remains open. The default host stays at eight players and Rapier; this does not qualify replacement or alter solver profile 8.

#October 27 collision cost reduction

Bounds and support queries now construct only the vertices they need. Contact clipping reuses the geometry prepared for separating-axis checks. Quaternion vector rotation avoids five temporary arrays, and normalization reuses its already-computed length. Arithmetic grouping is preserved; no solver iteration, collision tolerance or sleeping policy was reduced.

npm run physics:compare -- --warm now warms each backend for 240 steps, starts an identical fresh scene, and reports p50/p95/p99 over 240 measured steps plus machine metadata. On Intel Core Ultra X7 358H / Linux x64 / Node 22.23.4, the unprofiled before/after observations are:

Study Owned p95 before, ms Owned p95 after, ms Rapier p95 after, ms
Continuous impacts 3.818 3.104 0.069
Stacks 9.904 4.950 0.059
Pendulums 1.206 0.600 0.018
Thin-wall impact 1.457 0.985 0.015
Walking terrain 2.731 1.967 0.042
Compounds 3.808 2.064 0.036
Hinged bridge 4.072 2.105 0.043

These short local samples show less work in these scenes, not general capacity or the plan's 16-player/128-active-body simulation gate. The reference remains substantially faster. That integrated load and wider quality/device measurements remain required before replacement.

Acceptance: all 240 prior state hashes remain unchanged in ten fixed-identity replay scenarios. All seven comparison scenes retain their prior final body positions and zero restoration error. The full affected native suite passes 52 checks (five database cases skipped); all eleven Node/Chromium replay and checkpoint-exchange cases pass, including the independently generated vehicle world. Two physical-GPU atelier journeys pass settled support and moving/angular impact save/restore. The settled scene was visually reviewed. Type/boundary/wire and client/engine/server builds pass. Snapshot profile stays darkwind-owned-rigid.8 because the optimization preserves state, rather than introducing a revised solver trajectory.

#October 27 exact Node/Chromium replay

The owned backend now reproduces exact state across Node 22.23.4 and Chromium 155 main-thread/Worker execution on Linux x86-64 for eleven recorded scenarios. The first comparison exposed six failures: continuous impacts, thin-wall impact, walking terrain, the hinged bridge, production platforms and player ragdolls. Their first differences were one floating-point rounding step; they were not waived with a positional tolerance.

The owned solver now uses fixed-order scalar arithmetic for sine, cosine, atan2, angular damping and Euler rotations. The implementation reduces bounded angles before polynomial evaluation and avoids runtime transcendental functions. The lab's authored moving targets use the same scalar path in both backends. The admitted angle range is ±1,048,576 radians; this is bounded physics math, not a general-purpose large-angle library. Native checks compare accuracy across quadrants, tiny/large direction ratios and the physics timestep range.

Acceptance: all eleven scenarios pass exact per-step canonical hashes for 240 steps in Node and both browser placements: stacks, pendulums, impacts, walking, a motorized hinge, compounds, continuous collision, production doors, authored platforms/riders, character collapse/recovery and the actual Alder cart. Each also exchanges the step-120 checkpoint in both directions and matches every remaining step. No rounded comparisons replace state equality. The vehicle world is generated once per test and supplied unchanged to all runtimes. Run on Node 22:

Terminal
PLAYWRIGHT_EXECUTABLE_PATH=/usr/bin/chromium npm run test:physics:replay

The full affected native suite passes 52 checks, with five database-dependent cases skipped, including scalar accuracy, stacks, controllers, contacts, vehicles, ragdolls, compounds, checkpoint continuation and shared rooms. Type/boundary/wire checks and client/engine/server builds pass. Two physical-GPU atelier journeys pass settled-stack save/nudge/restore (7.5 s) and moving/angular impact save/restore plus reference switching (5.2 s). The impact study was visually reviewed. This image shows the running solver; the exact replay proof comes from the state comparisons.

Solver snapshot profile is now darkwind-owned-rigid.8 and the atelier uses darkwind.physics-lab.8 storage. Previous scratch saves are retained separately. Old exact snapshots and recordings need their original pinned engine; the new runtime rejects the old solver profile instead of promising identical old motion. Rapier remains the default production backend.

Remaining replacement gates: additional supported browser/OS/CPU targets, longer mixed workloads and failure histories, the skipped database cases, controller/reference quality and measured performance/capacity. This closes the recorded Node/Chromium replay defect for the exercised matrix, not all milestone 16 requirements. Final character choice is approved; recorded animation and presentation refinements remain in TRAVELER_ART.

#October 27 stacking correction

The observed off-center sphere drift is fixed in the existing Balance & weight study. Previously its support retained a small tilt and the sphere reached the floor by step 240 (height about 0.43 m). It now remains on the block at about 2.346 m and sleeps through step 600. The four-box tower top settles near 3.355 m. These are focused fixture results, not general backend equivalence.

Clipped faces now keep each contact's own penetration depth. A coupled displacement solve balances linear and angular contact correction without changing kinetic velocities. After contact correction, articulation projection respects hinge and cone/twist limits before reconnecting anchors. This fixes the ragdoll limit regression exposed by the initial contact-only change.

All 13 tests/owned-*.test.ts files pass, including stack/impact checkpoint continuation, manifolds, bodies, characters, hinges, ragdolls, vehicles, compounds, continuous collision, simulation and room/persistent integration. Type/boundary/wire checks pass. The physical-GPU Chromium atelier check passed settled support and save/nudge/restore (8.7 s); the milestone screenshot was visually reviewed. Try npm run dev:physics and choose 01 — Balance & weight. Rapier remains the default gameplay backend.

Remaining qualification: extreme mass ratios and deep initial penetration, long articulated contact chains, broad CPU/GPU/device budgets and cross-target replay. Solver trajectories change with this engine revision; old recordings remain tied to their original engine. This closes the documented stacking defect, not the full owned-backend replacement gate.

The engine now has its own TypeScript rigid-body solver in packages/physics/owned/, with no Rapier or WASM dependency. This is a working implementation of part of roadmap 16, not yet the production replacement. Rapier remains the default. The owned backend is available in the player, shared rooms and persistent/trusted hosting as described below.

#Try it

On codex/engine-foundations, run npm ci if dependencies need updating, then:

Terminal
npm run dev:physics

Open http://localhost:5182/physics.html. This separate port leaves the editor and room servers alone. The production client build also includes /physics.html for the next deployment; this change does not deploy it.

Choose stacking, pendulums, thin-wall impact, A path underfoot, Weight & intention, Form & balance, or Crossing paths. Nudge or drop a sphere, drag to orbit, scroll to zoom, pause and single-step. Save/restore retains a complete physics moment in browser storage, separately for each study and backend. The Rapier selector runs the same authored fixture and 60 Hz timestep. It resets the study; it does not translate snapshots between solvers. The scene is local and does not change a shared world. WebGPU is required.

#Implemented

  • Fixed, dynamic and targeted kinematic bodies; gravity, force, impulses, quaternion angular motion and primitive inertia.
  • Boxes, spheres, capsules and supplied closed convex hulls; deterministic sweep broad phase, separating-axis narrow phase, clipped polyhedral contacts and rounded-shape contacts.
  • Warm-started sequential impulses, friction, restitution, split translation correction, contact/sensor enter and leave events, connected island sleep/wake.
  • Ball/distance constraints and hinges with angular stops, position/velocity motors and torque budgets; ray queries and translation shape sweeps.
  • Opt-in continuous collision for moving pairs, angular motion and triangle terrain, with shared impact times and remaining-frame motion (limits below).
  • Versioned snapshots including forces, pending kinematic targets, contacts, joints and sleep state. Stable body/pair ordering and same-runtime continuation.
  • A rendered atelier, backend comparison and step timing/body/sleep counters.

#Focused acceptance — 2026-10-26

Four native checks pass: stack support/sleep/wake, friction/bounce, rotated and rounded/convex collision, fast thin-wall impact, ball/distance anchors, moving support, sensors, insertion-order equality, ray queries and exact snapshot continuation. A contact tolerance bug that froze a projectile at its CCD skin was fixed and covered by the fast-impact fixture.

The software-WebGPU browser journey passes running/drop, pause/single-step, save/restore including page reload, study and backend switching, reference save/restore and narrow viewport rendering. Desktop and narrow screenshots were reviewed. Review caught and fixed stale scene generations when switching studies. Type/import checks and client/engine packaging pass. No new hardware qualification or broad regression campaign is claimed.

Terminal
node --import tsx tests/owned-physics.test.ts
npm run physics:compare
npx playwright test tests/browser/owned-physics.spec.ts
npm run check

physics:compare emits measured positions, sleep counts, mean/peak step time and restoration error over the same three 240-step fixtures. It is an observation tool, not a replacement acceptance gate. The initial local run had zero restored position error in both backends; owned means were approximately 0.15–1.14 ms and Rapier 0.02–0.24 ms. These short, un-warmed runs are not performance qualification. Final position differences were approximately 2.49 m in stacks (the sphere rolls off in the owned solver but stays above its block in Rapier), 0.034 m for pendulums, and 0.92 m for impact. The tower also compresses more in the owned solver. These differences are recorded, not waived as equivalence.

#Walking terrain — early testing

Select 04 — A path underfoot in the atelier. Use WASD or the arrow keys to walk, Space to jump, Shift to run, and drag to turn the camera. On-screen direction and jump buttons also accept touch. The ramp leads to an overlook; the steps and moving lift are on the right. Return to the path resets the traveler if you walk off the study. Pause, single-step and save/restore include the character.

The new owned capsule controller handles acceleration/braking, held-jump edges, gravity, wall sliding, bounded step-up, ground snap, walkable/steep slope rules, ceiling blocking, support translation/rotation and bounded impulses to dynamic bodies. Fixed triangle meshes use a deterministic local-space BVH for contacts, rays and shape sweeps. Rendering uses the same course triangles. The OwnedPhysicsScene adapter accepts the existing Place, collision-model, InputFrame, PlayerState, step, state and teleport conventions. Imported collision vertices retain the existing world-space convention.

Four additional native tests pass terrain support for bodies and the motor, walking/braking/jump, wall slide, steps/head clearance, climb/steep slope behavior, moving lift carry, exact world+motor continuation, and authored collision import. The existing four rigid-body checks still pass. Two software-WebGPU browser journeys pass the atelier controls and traveler walking/jump, owned snapshot restore after reload and Rapier reference walking. The traveler/course screenshot was reviewed; type/import and client/engine packaging checks pass.

Terminal
node --import tsx tests/owned-character.test.ts

The common walking comparison now feeds both backends the same input sequence. The initial 240-step run ended about 0.089 m apart horizontally, with zero world-body and motor position error after each backend's own restore/continuation. It is evidence for the runnable path, not full controller equivalence. Local un-warmed means were about 1.92 ms owned and 0.043 ms Rapier for this small course. The existing traveler is reused; this is not the required final character art pass.

Remaining walking/terrain review:

  • The owned motor is currently a swept capsule query with bounded body pushes, not a registered player rigid body. Body-driven hits, player/player occupancy, moving-obstacle crushing and full shared authority/prediction integration remain.
  • The scene adapter explicitly rejects doors, authored platforms, dynamic-body systems and swimming/buoyancy until their integration exists; the atelier itself demonstrates a targeted kinematic lift. Do not select this adapter silently for unsupported production scenes. The reference course uses a small native motor, not the production floating-rider/vehicle/ragdoll integration.
  • Autostep can advance up to 0.2 m horizontally to establish a landing. Qualify narrow ledges, combined slopes/steps, support edges, dynamic support and input feel before finalizing that policy. Step success currently has no transition smoothing. Camera collision and automatic recovery from falling off this bounded study remain review items.
  • Meshes are fixed and two-sided, with up to 65,536 vertices/triangles per shape. Qualify internal-edge smoothing, coplanar contacts, holes/overhangs, deep overlap, degenerate imported topology, large streamed worlds and aggregate mesh budgets. Streaming revisions/unloads and compiled terrain/voxel runtime integration are not yet part of the owned production scene.
  • Exact continuation was checked in one runtime; snapshot hostility, cross-device determinism, full input/replay equivalence, hardware and touch qualification are still open. The walking increment used darkwind-owned-rigid.2; the hinge increment below advances that experimental profile and its scratch save key. Real player/shared-room save formats are unchanged.

#Hinged mechanisms — early testing

Select 05 — Weight & intention. Raise/lower the bridge, choose an angle with the slider, or release the motor and let gravity bring it to its lower stop. The actual angle is displayed separately from the requested target. Drop a sphere onto the mechanism; pause, single-step, and save/restore its motion and motor settings. Rapier runs the same bodies, hinge, limits and force-based motor.

Owned hinges retain local anchors, normalized axes and perpendicular reference frames. They constrain the anchor and two swing axes while leaving one angular degree of freedom. Optional lower/upper stops apply unilateral angular impulses. Position motors use an implicit spring/damper; velocity motors target angular speed. Accumulated motor impulse is capped by torque × timestep, independently of solver iteration count. Motor changes wake the connected bodies; active motors prevent premature sleep. Motor/limit definitions and the reference frames are part of the exact world snapshot.

Four new native tests pass off-axis impact/anchor retention, stops under drive, position targets, release/wake, exact restore/continuation, continuous rotation, per-step torque limits at different solver iteration counts and malformed-frame admission. The prior eight rigid-body/character tests still pass. All three software-WebGPU atelier journeys pass; the motor journey covers raise, target change, release, stops and state restoration in both backends. The mechanism was visually reviewed; type/import and client/engine packaging checks pass.

Terminal
node --import tsx tests/owned-hinge.test.ts

The initial 240-step shared raise/release/retarget sequence ended with bridge centers about 0.030 m apart and zero restored position error in both backends. Local un-warmed mean step times were about 0.90 ms owned and 0.026 ms Rapier. The loose load left the small platform in both solvers: atelier hosts now remove unconnected dynamic props below Y = -15. The comparison reports removed and unmatched bodies explicitly; this figure compares the remaining bridge only. Reset restores the original loose props. This host policy does not change the solver's behavior or production room rules.

Remaining mechanism review:

  • Hinges/limits/motors are implemented in the owned world and exercised in the atelier. Production authored-body links, drawbridges, vehicles and ragdolls still require adapter integration before they can select this backend.
  • Angles wrap to [-π, π]; position targets and limits use that interval. Unlimited velocity motors rotate continuously, but multi-turn position targets, wrap-edge stops, high angular speed, rotated/nonmatching initial frames and hard changes to limits need broader qualification. Cone/twist and other joint kinds remain.
  • Joint rows currently start each step without a retained warm-start impulse; contact warm-starting is separate. Qualify long chains, extreme inertia/mass, motor stalls, loaded equilibrium, large dt and stack/joint interactions.
  • Implicit stiffness and damping do not promise Rapier-identical trajectories. The force limit test is an isolated rotor; it is not a full energy/performance or device-determinism gate. Snapshot-hostility and metadata validation remain part of final qualification.
  • The experimental snapshot profile is darkwind-owned-rigid.3; scratch browser saves use a new key. Prior scratch versions are left in storage but not loaded. Final materials, lighting, control feel and imported mechanism art are deferred.

#Production player integration — early testing

The real Lantern House player now supports /?solo=1&physics=owned on the normal development/player server. Run npm run dev and use the URL printed by Vite with that query, or append it to your existing player URL after restarting its server with this branch. The 5181 editor itself is not the player. This uses the existing world, renderer, controls and story. Owned test saves use separate :physics-owned:save: keys; normal room/local saves remain independent.

Simulation now depends on a shared scene interface. Backend choice survives reset, travel, live revisions and checksummed simulation checkpoints. The owned adapter supports authored primitive/imported terrain collision, door changes, sliding props, moving platforms and route synchronization, plus motor recovery. Platform motion checks local rider clearance. Unsupported extended worlds fail admission explicitly. Owned room links explain the solo requirement; Collapse is enabled by the later owned-ragdoll increment below.

Focused delivery evidence: three owned production-runtime checks cover doors, exact checkpoint continuation, travel/reset, moving platform riders and rejected collision edits. The existing native checkpoint, platform-route and revision suites pass. Two software-WebGPU player journeys cover walking/jumping, separate saves/reload, automatic worker recovery, owned-room rejection and default Rapier startup. Type/import checks pass. The actual player view was reviewed in test-results/owned-player.png. This is an early test path, not the production backend replacement gate.

Follow up during integration/qualification:

  • Dynamic bodies/links, water and initial riders are now connected (see below). Vehicles/seats are now connected (see below). Ragdolls are connected below. Complete shared/trusted execution and admission.
  • Qualify streamed/publication travel and live-editor end-to-end flows, broader replay/save migration and hostile snapshot admission. Current exact restore evidence is same-runtime only.
  • Review tiny platform masses (below the owned body's .001 minimum), large-dt target subdivision, rotating rider obstructions, overlapping door closure, motor reconciliation with platform registries and sliding-prop support changes.
  • Profile scene-scale collision queries and allocation, and review movement feel and desktop/touch devices. Preserve the final character/environment art pass.

#Authored bodies, water and connected decks — early testing

The owned production player now runs authored dynamic boxes (including imported models with box collision), bounded pushes, world hinges with torque-limited motors, passive hinge/ball links, buoyancy and swimming. Body states and hinge targets flow through the existing ECS, presentation, portable saves and exact simulation checkpoints. Live density/limit edits preserve motion; changed body geometry resets its connected assembly, and overlapping collision edits reject before replacing the live scene. The capsule captures dynamic support and carries riders; portable support and cargo admission use the existing support contract.

To try it: in the editor choose New world → Willow causeway, save and publish. Append &solo=1&physics=owned to its playtest link. Walk toward the first deck, press E to raise/lower it, then lower it and walk onto the crossing. Reload retains body motion and the hinge target in the separate owned-physics save. Alder gate and non-vehicle floating bodies also use this path. Shared room links still use Rapier. Vehicles are connected in the next increment below. Posed/character ragdolls are connected in the later increment below.

Delivery checks: three new runtime tests cover linked floaters/push propagation, rider capture, exact continuation and portable restore, live hinge density edits, overlap rejection and swimming. The existing owned rigid, terrain/motor, hinge and production simulation suites pass; the old static-only door-rejection check was updated to verify door removal now that doors are supported. Type/import checks pass. One software-WebGPU journey creates and publishes the actual Willow causeway template, raises its connected decks, reloads the saved target, lowers it and walks onto the deck. Raised/crossing screenshots were visually reviewed (test-results/owned-causeway-raised.png, owned-causeway-crossing.png).

Deferred review and remaining integration:

  • Vehicles/seats are connected below. Ragdolls are connected below. Complete shared/trusted backend selection, authority/recovery and the production replacement gates.
  • Rider support currently carries the capsule with its local offset. Qualify rotation arcs, crushing/clearance, dismounts, offline resume and cargo travel; the standing-player weight/contact model is now shared with solo play (below).
  • Qualify long loaded chains, ball-link assemblies, solver energy, extreme density/force ranges, buoyancy boundaries and swimming entry/exit/bank climbing. Eight water samples use the existing oriented-cell approximation. Full-loop publication/replay/device and multiplayer qualification remains outstanding.
  • Motion admission and live body revisions rebuild affected contact caches; portable saves are not promised to reproduce exact solver history. Exact checkpoints preserve it. Review failure atomicity and hostile checkpoint gravity/iteration/motor policy as part of the final admission audit.
  • Imported collision remains the authored body box. Final foliage, water, environment composition, character models and movement feel remain in the art and polish pass; the screenshots establish usability, not final visual approval.

#Owned vehicles and seats — early testing

Owned solo play now supports the existing raft and cart profiles. Carts use four filtered ground probes, suspension forces, tire traction, steering and neutral coasting. Rafts retain bounded forward/reverse and yaw propulsion only while upright inside the water volume. Driver input reaches the same production simulation path as the existing backend; jumping or losing support releases it. Seat boarding sweeps the upright capsule, rejects blocked destinations and uses the shared seat-position/camera calculation. Exact recovery preserves the local driver and releases held input through the existing recovery flow.

Try New world → Alder court, save/publish, then append &solo=1&physics=owned to the release URL. Press E aboard the cart to take its controls; W/S drive, A/D steer, E releases and Space jumps off. Raft worlds can use the same owned solo URL. Portable reload preserves vehicle motion; retake the controls after a fresh journey reload. Worker checkpoint recovery preserves the occupied driver seat.

Focused evidence: two runtime checks cover cart suspension/driving/steering, seat/driver continuation and raft propulsion bounds. Existing owned-body, owned-rigid and native-seat suites pass. Type/import checks pass. A software-WebGPU journey creates and publishes Alder court, drives and turns, replaces the worker and resumes the driver seat, then releases the controls. The rendered view was reviewed in test-results/owned-cart-driver.png.

Deferred vehicle review:

  • Loaded suspension, ramps/ledges, extreme mass settings, dynamic-obstacle tire contact and airborne landing/steering. Current probes use the owned ray query and intentionally ignore dynamic surfaces, matching native policy.
  • Passenger occupancy, authoritative drive input, cargo transfers, offline resume and multiplayer/trusted execution when the owned room adapter is connected.
  • Blocked/tilted seat boarding and dismounts, broad recovery races and multi-device tests. Review camera clearance and close-up cart materials/geometry in the required final art pass. This is early functionality, not vehicle qualification.

#Continue implementation, then review

The active milestone remains the owned backend. Next connect the implementation to the remaining replacement solver features. Shared relay and persistent/trusted execution are connected below. Authored and player ragdolls, vehicles and seats are now connected. Doors/revisions, authored platforms, dynamic bodies/links, water and initial riders now use the production boundary. The core walking, terrain and mechanism paths are available for early testing; standalone lab additions are not a substitute for this integration. Keep Rapier available until shared fixtures, replay/controller behavior and performance qualify the replacement.

Remaining work and review notes:

  • Coverage: continuous collision and authored box compounds are now connected below; qualify their documented limits before replacing the default backend. Cone/twist constraints and player-rig integration are connected below.
  • Contacts: cached impulses now follow nearby contact points across manifold reordering, with friction projected onto the current tangent plane. Up to four bounded split-position passes reduce stack compression: in one 240-step stack fixture the top box settled at approximately 3.340 m versus 3.276 m before the correction change. Focused reorder and stack checks pass; the stack was visually reviewed in the lab. That historical sphere drift is fixed by the October 27 coupled correction above; broader solver performance is still unqualified. Qualify deep overlap, grazing capsule/convex features, edge manifolds, containment, extreme mass ratios and sustained stacks; retain the new sphere-support regression. Convex inertia and center of mass now use volume integration (below). Further qualify topology admission and ill-conditioned hulls before accepting arbitrary imported shapes.
  • CCD: moving-pair/angular sweeps and remaining-frame motion are implemented below. Qualify initial-contact rotation, grazing features, busy impact budgets and joint-coupled collisions. Ray queries now use direct intersections for boxes, convex hulls, spheres, capsules, triangles, meshes and compounds. A ray starting inside a solid returns distance zero with a normal opposite the ray; mesh triangles are two-sided and a coplanar ray has no hit. Focused fixtures cover rotated shapes, grazing, maximum distance, inside hits and filtering. Broader mesh-edge, device and vehicle/ragdoll behavior remains to qualify.
  • State: qualify hostile snapshots, strict contact-cache invariants and failure atomicity. The production simulation envelope now checksums solver snapshots; standalone atelier snapshots remain scratch state. Full replay qualification is pending. Same-runtime exactness is not evidence of cross-browser or cross-platform determinism.
  • Performance: cache transformed geometry, reduce allocations and profile realistic scenes. The initial backend is limited to 512 bodies and 128 joints; the browser study caps added dynamic bodies at 40. No production budget claim.
  • Presentation: finish art/material/lighting and resolution quality later; review guide-line depth, touch orbit/zoom, accessibility and unavailable/lost GPU recovery. The studies use simple geometric props and are not the final character/environment art pass. Browser saves are local scratch state.

Full 2D/creation modes, final art and accumulated full-program qualification remain required outside this increment.

#Owned ragdolls — early testing

Publish New world → Marionette court, then append &solo=1&physics=owned to its release URL. E tips the mannequin and resets it when the rest pose is clear. Walking into its posed assembly also releases it. R, or Collapse / Get up, releases the player into physical bodies and recovers to nearby clear, supported ground. Local saves retain both fallen states. Exact checkpoints retain the body modes, joint frames, player rig and held-toggle state. Existing traveler skin projection is reused; this increment does not approve the character art.

The owned solver now projects residual joint anchor separation after contact correction. Posed assemblies switch between kinematic and dynamic bodies; mode changes finish before putting the whole assembly to sleep. Solver behavior changed, so the exact snapshot profile and atelier scratch key advance to darkwind-owned-rigid.4 / darkwind.physics-lab.4. Earlier scratch snapshots are not loaded; portable player saves retain their existing separate owned-mode keys. Historical solver comparisons do not qualify this new profile.

Focused evidence: three runtime checks cover collapse/get-up, blocked recovery, held input, mannequin tip/reset, occupied reset rejection, joint separation, portable state and exact continuation. Six existing owned suites pass, as do TypeScript/package boundaries. The published-player software-WebGPU journey passes mannequin tip/reload/reset and player collapse/reload/get-up. The restored mannequin render was reviewed. The fallen capture is obscured by the pause overlay; a clean fallen visual review remains open rather than blocking feature delivery.

Return to these during final review:

  • Anatomical cone/twist limits, damping, energy, nonadjacent limb collisions and long settling. Current physical parts and transitions need the required final character/model/material pass.
  • Fallen-player live-edit clearance: scene collision admission currently skips the upright capsule when ragdolled; qualify edits against the full fallen rig. Review moving-platform changes, recovery clearances and extreme escape bounds.
  • Shared occupancy during mannequin reset, trusted ragdoll admission and remote projection when the room adapter is connected. Shared rooms still use Rapier.
  • Clean fallen and standing visual captures, camera proximity, varied rigs, persistence/replay and browser/device qualification. The passing focused checks do not close these gates.

#Owned shared relay rooms — early testing

Run npm run dev:owned, then open the private editor URL printed by the command. This uses HTTP 5183, relay 8793 and .data/editor-owned.1, separate from the normal editor and its Rapier saves. The printed editor link carries ?physics=owned, which its publication/history/development links retain. Create Marionette court, save and publish; open the invitation in two browser profiles. E tips/resets the shared mannequin; R collapses/recovers your traveler and peers receive the physical pose. The default shared ferry can also be opened at http://localhost:5183/?physics=owned.

The relay owns the owned prop/vehicle/ragdoll scene without a synthetic player. It retains exact solver snapshots, route phases, cargo residence, hinge targets and mannequin modes. Forks and revisions preserve backend choice. Character contacts apply bounded standing weight and pushes in stable actor/body order; resetting a mannequin checks other travelers. The shared scene includes the existing water, vehicle/seat, route and cargo adapter surfaces. Browser players consume the authoritative body frame and retain the owned local motor.

DW_PHYSICS_BACKEND=owned opts a relay into this backend. Session admission and WebSocket hello must match the player's physics=owned selection. The saved room records the backend; switching an existing room's solver in place is rejected. Use a fresh data directory/volume for the experimental room. Rapier remains the default. Both local and Coolify Compose configurations pass the setting through. Pinned invitations retain their original executable; publish a new invitation from this build for owned-room testing.

Focused checks pass for exact room recovery/continuation and forks, occupied mannequin reset, cargo destination recovery, shared standing weight and trusted-motion/client replay. The two-client relay test passes shared push, duplicate receipt handling, host change, reconnect, late join and server restart for both backends. Existing cargo room/transfer and owned bodies/ragdolls suites, deployment config and type/package checks pass. The published-world software-WebGPU journey passes two-player admission, mannequin tip/reconnect/reset and peer-visible player collapse/get-up. The fallen view was reviewed in test-results/owned-room-fallen.png, including the two connected travelers indicator. This also supplies the clean fallen mannequin view deferred by the earlier solo increment. The first browser attempt correctly paused on tab blur; the test now explicitly resumes before moving its player.

Return to these during integration and qualification:

  • Next implementation: wire backend selection through persistent/trusted server startup, durable admission, per-place process owners, routing and deployment profiles. TrustedMotion.prepare/create already accepts owned and passes focused replay checks, but those server entrypoints still default to Rapier. This increment enables shared relay rooms, not all hosting modes.
  • Standing/riding contact geometry, rotation arcs, crushing/clearance and client replica isolation under long latency. Solo standing weight still uses its earlier motor path; complete the common contact policy before replacement.
  • Broad shared cart/raft seating, routes, transferred riders and live revision browser journeys. Restore validates authored ownership and route poses; hostile-state/failure-atomicity and long-run performance review remain open.
  • Existing anatomical and solver limitations above, full fixture/replay/device gates, and final character/environment art. Shared functionality does not approve the current mannequin or traveler models.

#Owned persistent and distributed hosting — early testing

The owned backend now reaches persistent cooperative/trusted servers, durable admission and travel, transactional cargo validation, content-upgrade preparation, per-place subprocesses, authenticated network workers and regional retained room startup. PostgreSQL schema 8 pins each room's backend. HTTP and WebSocket admission must match, and mixed-backend saved snapshots are rejected. The existing schema and retained-engine guards remain; use a new dedicated database to test this schema alongside older deployments. See commands and focused evidence.

The five owned database/hosting checks pass, as do existing persistent/upgrade checks, focused routing checks and type/package boundaries. The packaged trusted browser journey shows two travelers sharing lantern ownership, saving movement to the server and recovering it on reload; its restored render was reviewed. The new backend is still opt-in and its character/environment models are not visually approved.

Next implement the remaining owned contact/rider policy and core replacement features (cone/twist constraints, compound mass properties and continuous collision coverage). Retain full fixture/replay/performance qualification and final art for the finishing pass. Additional hosting review: owned upgrade and backup round trips, distributed cargo failure injection, trusted vehicles/rigs in browsers, loaded worker performance and real-device/network tests. Do not expand those into unrelated diagnostic campaigns before implementation is done.

#Consistent solo and shared rider contact

Solo authored bodies now use the same contact policy as room-owned bodies: an 80 kg standing traveler loads a supporting deck, side collisions apply bounded normal/friction impulses, and angular response uses the contact point. The capsule motor no longer adds a second push to authored bodies. Replicated body frames retain their authoritative state during local movement; only their room owner applies player forces and releases posed mannequins on contact.

Focused checks compare solo and room body states for standing weight and side pushing, and prove that replica stepping leaves published body states unchanged. Existing linked-deck restore, cart driving, swimming, motor, ragdoll and room checks pass. The existing Willow causeway browser journey is the visible acceptance: publish, raise/lower, reload and walk onto the connected deck; it passed and the crossing screenshot was reviewed. Type/package checks pass. This changes physical response, not character art.

Review later: crowded deck loading, rotation arcs and crushing/clearance, seated/passenger weight distribution, high-latency contact timing, extreme mass ratios and long loaded-chain stability. The crossing view also retains the final art/HUD readability review, especially pale objective text against foliage. Final physics qualification remains open.

#Cone/twist limits and player articulation

The owned solver now supports cone-twist joints with local endpoint axes, perpendicular reference vectors, a circular swingLimit in radians, and signed axial limits: [lower, upper]. Swing is measured between endpoint axes; twist is measured after undoing the shortest swing. Accumulated unilateral angular impulses enforce the limits without constraining motion inside them. Both movable endpoints receive the response. The public coneTwistState(id) query returns the current swing and twist angles.

The owned player's neck, shoulders and hips now use five such joints; spine, elbows and knees retain their hinges. These constraints follow the existing solo/shared/trusted player simulation and portable fallen-pose restoration. Press R in an owned player session to collapse and get up. Current models remain placeholders pending the required final character art pass.

The solver snapshot profile is now darkwind-owned-rigid.5, and scratch lab saves use darkwind.physics-lab.5. Older exact solver snapshots are not admitted as the new runtime's state. Retained published/persistent rooms continue using their pinned engine; create a new test room/release to try the updated rig.

Focused verification covers separate swing/twist measurement under rotated parents, sustained forces against all stops, free motion inside limits, out-of-range pose recovery, two dynamic endpoints, exact snapshot continuation, and malformed definition rejection. Existing hinge and player-ragdoll checks pass, including all five player constraints after a fall and portable recovery. The packaged owned two-player browser journey passes collapse, remote skin projection, reload and get-up; test-results/player-ragdoll-shared.png was reviewed. Type/package checks pass. The folded fallen silhouette still needs anatomical tuning in the final character pass.

Review later: anatomical tuning alongside the replacement character models, elliptical swing cones, near-antipodal/high-speed rotations, extreme inertia ratios and long loaded-chain behavior. Generic authored body links/mannequins still use their declared ball/hinge contracts; editor-exposed cone/twist tuning is a follow-up. The reference lab rejects unsupported cone/twist fixtures rather than silently treating them as hinges. Full replacement qualification is open.

#Compound shapes and mass properties

The owned rigid-body API now accepts compound shapes with 1–16 convex children. Each child has shape, position and an optional rotation (identity by default). Boxes, spheres, capsules and convex hulls are supported; nested compounds and triangle-mesh children are rejected. Collision, ray and translation-sweep queries visit the actual children, preserving openings instead of filling the entire bounding box. Contact-cache features retain the child pair identity.

Mass is distributed by child volume at uniform density. Rotated child inertia and parallel-axis offsets produce a full symmetric tensor about the combined center of mass. Overlapping children contribute additive mass, not a geometric union. Convex hulls now use tetrahedral volume integration instead of bounding-box inertia. massProperties(id) exposes mass, local/world center and the local tensor; pointVelocity(id, point) reports velocity at a world-space point. Body positions and joint anchors retain the authored origin, while linear velocity belongs to the center of mass. Forces, contacts, impulses and kinematic targets respect that convention. Free rotation keeps the center fixed when linear velocity is zero.

Try Form & balance in the physics atelier:

Terminal
npm run dev:physics

Open http://localhost:5182/physics.html, choose 06 — Form & balance, nudge the cedar arch, drop a sphere, save/restore, and switch to Rapier for comparison. Both backends use the same compound children and volume-weighted masses. The owned snapshot and scratch-save profiles are now darkwind-owned-rigid.6 and darkwind.physics-lab.6; earlier exact solver snapshots require their retained runtime. Published/persistent rooms still use their pinned engine.

Five focused checks cover analytic mass/tensor values, rotated and offset children, off-center convex hulls, impulse response, center-preserving rotation, kinematic motion, query openings, child contact identities, canonical snapshot continuation, and rejected malformed compounds. Eight existing owned physics/movement/body/ vehicle/ragdoll/room suites pass. The packaged compound browser journey passes rendering, nudge and saved-state restore in both backends; its view was reviewed in test-results/owned-compound-atelier.png. Type/package checks pass.

General world/editor integration is described below. Remaining core review: qualify rotated child/mesh combinations, maximum child counts, highly unequal masses, high-spin gyroscopic behavior and performance. Angular/dynamic-pair CCD, full replay/device qualification and final art remain open.

#Authored compound bodies

Box objects can now contain 1–8 box parts that move as one body. In the editor, select a box, open Weight & water, enable gravity, then Build this body from box parts. Start with an arch creates an open frame; edit each part's position/size, preview and save, then publish or Apply to try it with friends. Use a roughly three-metre-tall box for a walk-through arch. Restart your owned editor with npm run dev:owned to include the new runtime in publications.

World format 36 stores body.compound (compound-boxes.1). Positions and sizes are normalized to the parent box; every part stays inside its bounds. Resizing the parent resizes the assembly. Parts share one material and have no independent rotation. Both physics backends collide with the actual parts, and editor/player presentation shows their gaps. Mass, buoyancy and push budgets use the sum of part volumes; overlaps count twice. Density edits preserve motion; geometry edits reset the connected assembly using the existing clearance checks. Checkpoints, shared frames and cargo travel retain the compound definition and motion.

Five focused native checks cover format admission, authoring, passage through an arch, actual mass, exact continuation, density edits and shared cargo restoration in both backends. Existing owned-body, body-link and buoyancy simulation/authoring suites pass. Type and package-boundary checks pass.

The packaged software-WebGPU browser run exercises editing/saving/reopening the parts, publishing, two connected travelers, walking through the opening, shared push motion and reconnect. Editor, controls and shared-player screenshots were reviewed (test-results/compound-{editor,controls,shared}.png). A clean full browser pass remains unverified: directional/displacement assertions did not account for the tall arch tipping/rocking back; the revised sequence/peer-state check then encountered a closed browser. Keep tests/browser/authored-compound.spec.ts for the qualification pass; do not count it as passing. Native exact checkpoint and shared cargo restoration checks pass independently.

Review later: per-part rotation/materials and visual handles, more compact part controls, picking through openings (the editor selects the parent bounds), multi-part rider support distribution, larger compound/load budgets and water tuning. Tall narrow arches may tip when pushed; qualify stability alongside angular/dynamic-pair CCD. Compound-specific PostgreSQL restart/upgrade and broad hardware/performance runs remain for final qualification. The legacy beta probe adapter still draws primitive bounds; current editor/player use the new paths. Character/environment art remains a separate required final pass.

#Continuous motion and shared impact times

Continuous bodies now advance together to the earliest collision, resolve the impact and use the remaining frame for sliding or further rebounds. Relative motion includes dynamic pairs and moving/rotating kinematic obstacles. Angular casts use conservative separation advancement about the actual center of mass; compound casts visit the children and triangle queries use the terrain BVH. Linked neighbors and sensors remain excluded from solid collision. Transient impacts produce enter/leave events even when separated again by the end of a tick. This is in the common owned world used by solo, shared and hosted simulations.

Try 07 — Crossing paths with npm run dev:physics at http://localhost:5182/physics.html: two spheres meet, a turning paddle hits a post, and a moving gate sweeps a third sphere. Pause/single-step and save/restore work in both the owned and reference backends. Give it a nudge restarts this study. Snapshot profile darkwind-owned-rigid.7 and scratch key darkwind.physics-lab.7 keep the changed integration policy separate from old exact saves; existing publications retain their engine runtime.

Seven focused tests pass moving-pair momentum, multiple rebounds, tangential travel, kinematic ordering, angular impacts between disjoint endpoint poses, compound openings, triangle collision, transient events, bounded fallback, sensor/joint exclusions and exact checkpoint continuation. Existing rigid, character, body, vehicle, ragdoll, compound/cargo and shared-room suites pass. The packaged software-WebGPU study passes stepping, save/restore and reference switching; test-results/owned-crossing-paths.png was visually reviewed.

Review later: CCD activates when relative translation plus the angular travel bound reaches half the smallest shape feature width. Slower motion uses discrete contacts. Starting touching and separating/resting is left to the discrete solver; qualify subsequent contact changes during rotation and glancing thin features. Queries allow 64 conservative advances and a world step allows 32 impacts. On budget exhaustion, remaining motion stops conservatively and stats.ccdLimited reports the limit; ccdClamps counts resolved impacts. Qualify crowded scenes and avoid treating capped motion as full-time integration. Impact response uses the contact solver; joint impulses/projection still run at the final frame boundary. Full articulated-impact, cross-target replay, hardware/performance and reference quality qualification remain required. This increment does not authorize making owned physics the default or waive the final art pass.

End of Owned physics