# Skate 3 physics engine for Zero
`skate_physics` integrates a reconstructed Skate 3 physics engine into Zero. Use this package for Skate 3-style skateboard and rider physics, or use its custom rigid-body solver components independently. It exposes a reconstructed Skate 3-derived Rust solver through editable entities, components and assets: physical bodies, collision volumes, joints, constraints, motors, forces and simulation state. It is a reusable simulation system, not just a skateboarding controller or a park scene.
## Why use it?
Build and tune connected physical assemblies without first writing the integration between a custom solver and Zero. Inspect velocities and forces, change mass and inertia, configure joint limits, and drive mechanisms with spring/damper or hard motors. Motors apply impulses through the solver rather than teleporting bodies. The general body/joint/drive layer does not require a rider or animation clips.
The package connects physics authoring, fixed-step simulation and entity presentation. Use it to experiment with constrained bodies, motor-driven mechanisms and vehicle assemblies; the skateboard and rider are included applications of the system, not its definition.
## What it provides
- `World`: authority-gated fixed-step simulation and publication of solved entity state.
- `Body` and `CollisionVolume`: editable mass, inertia, forces, velocities, primitive/compound collision geometry and bounded static-mesh collision.
- `Joint` and `Drive`: body references, local frames, linear/angular limits and independently configurable motors.
- `API`: in-engine authoring helpers and an explicit-state solver interface.
- Input and actuator components for device-driven or scripted physical assemblies.
- An integrated skateboard/rider system with control maps, rig mapping, visual bindings and animation-slot overrides.
- Example scenes, a modular park, an authored skateboard, and the `GettingStarted` guide.
## Where to start
Read **GettingStarted** for the distinction between the general physics components and the specialized rider integration. The low-level **Demo** workbench illustrates bodies, joints and a vehicle assembly. **SampleScenes** exposes rider, vehicle-only, self-propelled, scripted-control and physics-tuning examples. The world's default **RiderFidelity** scene demonstrates the coupled rider/board system with Zero's avatar and the authored park.
## Integration boundaries
Static mesh collision has documented size limits; see `Body`. The specialized native rider/board integration requires a fixed body layout; that restriction is distinct from authoring assemblies with the general body/joint/drive API.
The rider demo retains converted reference animations for testing, replaceable through normal Zero assets and animation bindings. These are not required by the general motor component. The default showcase uses the authored skateboard and Zero avatar; unused reference character and board models are excluded from publication. See the component documentation for supported shapes, units and solver-specific conventions.
# World.component
Authority-gated fixed-step driver; reads and publishes ordinary Zero entities.
Bodies, joints and drives sort by their editable `solverOrder`, then entity ID.
Existing default-zero orders retain the prior behavior. Presets can preserve
native registration order across clones instead of depending on generated IDs.
## Fixed-step publication
`maxSubsteps` (1..16, default8) bounds fixed steps per publication. Entered NativeGround `body_commands` updates can batch because each step derives fresh native observations from the preceding state. Entry, exit, observe and externally supplied Ground observations stay single-step. Animation/other external targets are sampled before the request and held through its batch; choose1 when a caller requires new external targets each step.
New live body command values apply to the next request and do not invalidate already solved motion. Changes to body state, geometry, configuration, topology or authority still reject stale work. `receivedSeconds`/`simulatedSeconds` reset with restoreState; `droppedSeconds` and `rejectedResults` remain cumulative. `lastStepCount` names the last publication's step count. `onStep` fires once per publication, and readContacts returns the final substep's contacts.
# BoardFeedback
The reconstructed board post-physics phase using actual solved reports, not
speculative contact candidates. Assign a World and its seven physical parts.
Before each solve it runs the original wheel-line query against that World's
static mesh surfaces. After every body has integrated it runs native report
selection, ground-normal/contact classification, acceleration sampling and
contact-time update. Contact-dependent wheel angular drag is then written for
the next step, in the original phase order.
All history and output are in the synchronized, readable state field. Contact
counts, normal and time without contact are also visible directly. Disabling
this component stops its updates; while active it owns wheel angularDrag.
No rider, animation bank, game-disc pack or hidden WASM actor is created.
The up vector, ground-angle limit, probe length and wiping-out mode are explicit
inputs. A matching reference profile must supply matching values; 60 degrees is
an authoring default, not a claim about all game modes. Dynamic-body collisions
are still solved, but this native ground classifier consumes static-world
reports, as in the preserved runtime.
# Drive
An editable Skate solver motor between Body A and Body B in the selected World.
Local anchors and frame quaternions describe frames the motor tries to align.
Animate either frame to drive a limb, suspension or steering assembly. The motor
applies impulses through the same solver as contacts and joints; it never teleports
the bodies. Linear and angular drives have independent disabled, soft and hard modes.
Soft mode uses spring and damping. Hard mode uses maximum correction velocity.
MaxStrength limits each solver axis; zero provides no motor force. Disabled ignores
the saved tuning values, so toggling it preserves tuning without applying impulses.
The reconstructed solver retains its original drive coefficient conventions.
All fields synchronize through Zero. No rider or animation clip is required.
Strength values retain the Rust engine's native coefficient convention. They
are not a direct force in newtons or torque in newton-metres. The solver limits
each row using `dt * dt * maxStrength * inverseEffectiveMass`; the latter is
the reciprocal of the row's inverse-mass/inertia denominator. In particular,
a small-inertia body needs a larger angular strength number to support an
offset load. Check the complete connected assembly, not just a free body.
A native regression uses a 2kg, radius-0.15m root supporting a fixed 10kg load
0.5m to its side. At 120Hz/64 iterations, angular hard strength 1000 saturates;
10000 holds the orientation. This is an explanatory test, not a universal
humanoid tuning preset. Changing collider dimensions changes inertia as well
as contacts; tune limits against the mass properties of the intended body.
# Native ground execution boundary
Calls the reconstructed complete `Ground::UpdateSkateboard` on existing Zero Body entities. It consumes explicit native records supplied by the controller/animation observation producer; it is not a standalone input controller. The live producer connection is still under development.
Bind a World, active BoardFeedback and the two truck Drive entities. Supply the resolved numeric profile, native history after entry, current GroundBoardInput/physical observations and truck base frames. Set `entered` only after the native entry lifecycle has completed; update is refused before that. Enable only after all records are prepared. `inputTick` must match the World tick. Ground uses one substep per observation; stale records are refused. Full ground and standalone BoardSteering cannot own the same feedback binding.
`forcesBefore` preserves any already-queued native point forces before this update appends its records. Every force uses the existing queue and native point-force consumer. Returned history, drive frames, material and linear drag publish on Zero components. No hidden body or second solver is created. Missing required wall-jump trajectory launch/update currently rejects the entire transaction; that provider remains required before this branch is usable. Never treat ordinary-ground success as proof of trajectory support.
Reset restores the explicit controller history and drive frames with the body snapshot. The producer must prepare observations for the reset tick before resuming.
## Live body observation stage
`inputSource` optionally supplies the shared native input-builder record instead of a complete `input` record. Each transaction derives current board motion, mass, wheel normal, contact flags and wheel count from its actual bodies and BoardFeedback. The original native mapping is retained: processed416 is ground-linear velocity; processed720 is angular velocity. `producedInput` exposes the generated record locally for inspection without entering the solver's retained state.
Other observations still require real providers: animation/control attributes, reckoning/pose observations, lifecycle times, pumping and geometry/state-machine results. They must be prepared for `inputTick`; a diagnostic snapshot is not a continuous controller. The live clock/pose/control producer remains unfinished.
## Native input clocks
An `inputSource.lifecycle` record supplies `captured_category`, `signed_ground_step`, and the one-tick `teleported` signal. The native input-clock owner then maintains ground duration, signed ground time, inactivity, teleport frames, spin history and crouch difference in `state.input_clocks`. It advances only in a submitted physics transaction and is restored with the normal World state snapshot. Without this optional record, externally supplied timing remains authoritative.
The category/signed-step signals and per-frame flags must come from their real state/input owners. This does not perform physical Ground entry/exit, update its separate elapsed-state timer, provide pose/geometry observations, or make a continuous controller out of a captured context.
## Exit and observation
Set `operation=exit` with current observations, an entered controller, `inputSource` (the pumping owner), and `standardWheelMaterial` containing explicit static/dynamic friction and restitution. The native exit resets steering history/pumping, clears all seven linear drags, restores wheel material and runs the original animated-velocity clamp when that branch is active. The result clears `entered` and changes `operation` to `observe`.
Observe continues current input observation/history without applying Ground forces or writing wheel materials/drive targets. A separate BoardSteering may own those drives. Exit is required before observing an entered Ground controller. Update after exit is refused until real entry completes. Physical entry and continuous state selection remain under development.
World.restoreState restores the saved drive frames and pumping state; current configuration and unrelated input-source fields remain owned by their producers.
## Explicit physical entry
Set `operation=enter`, bind the existing `hookDrive`, and supply `entrySettings`: explicit `rider_mode`, previous category/state, deck angular drag, powerslide-exit scale, landing strength/offset, and the standard wheels/trucks/deck materials. Entry uses the real source/pumping state and current bodies. `rider_mode=none` means no simulated rider; no hidden body is created. `bound` currently refuses entry until the real Zero rider owners are connected.
The shared native executor initializes physical rates/controllers, disables the actual hook drive, resets pumping/wipeout state and handles the manual/re-entry/landing-force branches. Standard collider enables and materials reach the current solve and the actual Body/CollisionVolume components. The native assembly class is retained separately from Zero's self-collision group. RestoreState restores collider flags and hook parameters and checks their topology first.
This is body-only entry support, not completed rider-bound entry or a continuous gameplay controller.
Fresh entry may use state `{}`; the kernel creates native initial history and then executes entry. Full update/exit still requires entered state.
`inputSource.body_update` opts into the original Ground begin/pumping/prediction/finish sequence for an explicitly riderless rig with `pose.observation.mode="body_com"`. Pumping settings and selected mode remain authored inputs; history is retained in `state.body_update`. Bound-rider target owners and the normal command/geometry producer are not yet connected. This option alone is not a finished playable controller.
`inputSource.kind="body_commands"` enables a fresh riderless producer. Supply native `settings`, `pose` (body_com) and `body_update` tuning. Current commands are the component's editable fields; callers need no captured input/physical record. For first entry, use state/input/physical `{}` and explicit entry settings. W/S/A/D mapping is available through InspectionSession.ground. This path is verified for live push/coast/brake/steer/reset, but sustained rest still fails validation and saved-default/installation acceptance is pending.
The riderless `body_commands` source can now include `flight` settings for native
Ground/Air selection, jump calculation, Air reckoning and the angular hook drive.
Increment `jumpSequence` once per jump; `jumpStrength` selects the configured
height response. Full rider/trajectory/trick integration remains unfinished.
# Native board steering
Runs the fork's steering tilt, contact-dependent truck targets and normalized truck drive frames at 60 Hz. Bind a World, active BoardFeedback, and front/back Drive entities. All references must belong to that World. The component owns those drive frames while active. State, curves, base frames, input and outputs are editable in Zero; no external content pack is read.
This component implements steering only. The complete ground force/state coordinator remains an integration requirement. Do not treat steering movement as proof that skating physics or the package is complete.
`turn` and `hardTurn` are normalized input; `switched`, `pushing`, `balance` and `truckTightness` are explicit controller inputs. The native entry history starts with push scalar 1. Empty `baseFrames` uses the fork's stock truck geometry; supply two `{basis,position}` records for another assembly. The drive endpoints must be the feedback's corresponding truck A and deck B. One steering component may own each feedback/drive pair.
The inspection scene binds A/D, the left stick and the touch stick to `turn`. Reset restores both retained state and authored drive frames. Releasing input clears turn through the normal Zero input map.