# 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.
# Joint.component
Typed body references, local frames and angular/linear constraint limits.
`separateLinearFrame` enables an independent parent orientation for the three
linear constraint axes: `linearFrameBX/BY/BZ/BW` is a unit quaternion in body B's
authored frame. The angular axes still use `frameBX/BY/BZ/BW`. When disabled,
linear axes follow the angular frame, preserving existing joints. JSON callers
use optional `linear_rotation_b`; omission uses `rotation_b`. Both frames are
converted through the body's mass frame before solving.
The reconstructed character requires this distinction for all22 skeleton joints.
The private121frame reference comparison checks every consumed frame word and
the full96word constraint workspace for all2662joint states. Two unused anchor
padding lanes are excluded from frame-byte comparison (native signed zero there
does not enter the decoder); constraint workspaces still match bit-for-bit.
This verifies joint-frame representation, not complete character simulation.
## Angular modes and independent speed limits
`free` permits all angular directions selected by the joint. Native swing mode 3
is exposed as `hinge`, not `free`: it retains a constrained perpendicular axis.
`limited_hinge` preserves native swing mode 2. Stock board wheel joints explicitly
use `hinge` and retain their original speed allowances.
Angular velocity allowances are independent relative-speed limits in radians per
second. Zero is a zero-speed limit, not an unlimited value. New generic joints
default to 1,000,000 rad/s so an open angular limit does not accidentally act as
a brake. Explicitly authored values (including zero) remain authoritative.
Migration: stock-board definitions using the former `free` spelling for native
mode 3 must use `hinge`. Rebuild the provided scene after changing the kernel and
component together. Old generic joints with explicit zero velocity allowances
must be reviewed; do not overwrite intentional speed limits automatically.
## Native rider slots
A Joint beneath NativeRiderDriver.constraintsRoot may reference two rider
NativeActorPart entities from the same physicsRoot. Set world to that physicsRoot
and nativeRiderSlot to 0..21. readRiderJointDefinitions() on a ready driver returns
the current slot, endpoints, anchors and frames for authoring. Body A is the
native child and body B its parent. Preserve the separate linear frame when
copying definitions. Each slot may have one override; other slots remain native.
nativeRiderAngular defaults to native: mode-dependent normal/ragdoll angular
settings still come from the native owner. Select authored to use this Joint's
angular fields instead. nativeRiderEnabled=false suppresses that slot's rows.
Deleting the override restores the native slot. These edits survive R recovery.
Animation drives remain active and can resist contradictory anchor edits.
Mixed board/rider endpoints are explicitly unsupported by this adapter.
A copied default slot passed the full 520-frame Zero replay unchanged. A 20 mm
anchor edit produced approximately 19.1 mm in the ragdoll test; native mode
limits, authored angular values, disabling, reset and restoration were checked.
# CollisionVolume
Put this component on a direct child of a Body whose shape is `compound`.
Edit the child's local position and rotation with Zero's normal transform tools.
Positive uniform scale on the body and child is included in collision dimensions;
nonuniform/mirrored scale is rejected. Shape fields define sphere, rounded-box
core, Z-axis capsule, or triangle geometry. Triangle transforms are baked into
vertices when the Body reads its state, preserving native mass conventions.
Give each child a unique integer `order`. It preserves the authored accumulation
order independently of entity IDs. `collisionEnabled=false` suppresses contacts
but retains mass. Delete a child to remove both its geometry and mass contribution.
The Body supplies material and total mass. It may have at most64 volume children.
Use `API.attachVolume(child, settings)` to attach this component and automatically
choose the next free order; the child's parent must already be a compound Body.
All properties and transforms are ordinary synchronized Zero entity data.
## Native actor bodies
CollisionVolume can also be a direct child of a NativeActorPart with role=board or role=rider.
One or more volume children replace that body's native contact geometry; parts
without volume children inherit their defaults. Removing the last child restores
the defaults. Disabled children suppress contacts; use a disabled child when the
intent is no contacts rather than inherited defaults. Child local transforms are
in the body entity's centre-of-mass frame. No host files are needed.
For native bodies, geometry editing does NOT recalculate mass or inertia: those
remain separate NativeActorPart fields. It also does not alter the animation or
wheel-probe/controller profile. Materials and controller collision gating stay
native. Rider shapes retain native mode-dependent enable flags, collision groups and
materials. A shape cannot enable a body the current native mode disables.
The ready NativeRiderDriver:readColliderDefinitions() method reads current
body-local native geometry, including disabled children, for inspection or
in-engine authoring. Spheres were checked with actual Zero physical response,
reset and restoration. Rounded boxes, capsules with offsets/rotation, and two
triangle volumes were also checked against their calculated support height.
Disabling the triangles removed their support; deleting them restored all 15
default deck children. Rider sphere authoring, disable/reset/restore and native masking have been
checked. Additional rider multi-volume/self-contact scenarios remain to verify.
The ready driver readRiderColliderDefinitions() method returns each rider body
with its current native enabled flag, volume_group, and body-local shapes.
Vehicle-only mode returns an empty rider list and rejects rider shape input.
# NativeActorPart
Entity-owned native physical state exchanged with the full rider loop. Role and index identify the part; state contains its complete rates and inertia. Shape/constraint authoring integration is unfinished.
# Native truck motor
The front or rear motor's native linear/angular drive parameters. Native steering
continues producing its target frame; these fields control how the motor drives
toward it. Disable active to remove its drive response. The actor's separate
animation-controlled hook and rider motors retain their existing behavior.
# NativeRiderMotor
<!-- zero:scaffolded-readme -->
<!-- Replace the line below with what this component provides and who
consumes it, then delete both comment lines. -->
TODO: describe this component.