Skip to content

Rapier physics: gap inventory β€” what's missing, what's blocked on which epicΒ #122

@martinjms

Description

@martinjms

Quick Summary

  • 🟑 Status: living document. This issue is a tracker, not a unit of work. It catalogs every Rapier capability and where it stands in the cluster integration: implemented, in-flight in a sibling issue, blocked on an architectural epic, or deliberately deferred.
  • Goal: zero cluster-imposed limitations vs. local Rapier. A developer running a Rapier sim on the cluster should hit no walls they wouldn't hit running it single-process β€” except for cluster-specific concerns (cross-cluster physics, terrain loading) which are clearly separated.
  • This issue gets updated as sibling issues land and as architectural epics resolve.

Inventory

Status legend:

  • βœ… Implemented in current Rapier integration (#117 / #118)
  • 🚧 In flight β€” has its own ticket
  • 🚫 Blocked on epic β€” needs an architectural decision before it can land
  • πŸ”˜ Deferred β€” not blocking shipping, opens up later
Rapier capability Local Rapier API Cluster-integration status Notes
Per-entity collider shape (Ball / Capsule / Cuboid) ColliderBuilder::ball/capsule_y/cuboid βœ… via RapierClusterSimulation::collider_for Lives in #118.
Compound colliders (multiple shapes per body) Multiple insert_with_parent calls πŸ”˜ One collider per body in current shape. Add when a real game needs it.
Body kind (Dynamic / Kinematic / Fixed) RigidBodyBuilder::dynamic/fixed/kinematic_* 🚧 #120 Currently every body is Dynamic.
Material (friction / restitution / density) ColliderBuilder::friction/restitution/density 🚧 #120 Currently defaults only.
Collision filtering (groups / masks) ColliderBuilder::collision_groups 🚧 #120 Currently every entity collides with every other.
Sensor colliders (events without physical response) ColliderBuilder::sensor(true) 🚧 #120 Currently every collider has physical response.
Apply impulse body.apply_impulse(impulse, wake) 🚧 #121 The flagship missing capability.
Apply force body.add_force(force, wake) 🚧 #121
Apply torque impulse body.apply_torque_impulse(torque, wake) 🚧 #121
Set translation (teleport) body.set_translation(pos, wake) 🚧 #121
Set linvel / angvel body.set_linvel/set_angvel 🚧 #121 Currently linvel is auto-set from entity.velocity only.
Wake / sleep control body.wake_up() / activation API 🚧 #121
Joints (fixed / revolute / prismatic / spherical) ImpulseJointSet::insert 🚧 #121 (single-cluster only) Joints across cluster boundaries are not in scope until cross-cluster physics lands.
Multibody joints (articulated chains) MultibodyJointSet::insert πŸ”˜ Defer; not needed for typical games.
Raycasts query_pipeline.cast_ray(...) 🚧 #121
Shape casts query_pipeline.cast_shape(...) 🚧 #121
Intersection tests query_pipeline.intersections_with_shape(...) 🚧 #121
Contact events (Started / Stopped) ChannelEventCollector βœ… via RapierClusterTickContext::contact_events Lives in #118. One-tick delay by design.
Contact force events ContactForceEventThreshold + collector πŸ”˜ Add when impulse-magnitude reactive gameplay needs it.
Per-cluster gravity step(gravity, ...) βœ… via RapierConfig::gravity Honored on any axis; tested.
Custom physics hooks (filtering / pair modification) PhysicsHooks trait πŸ”˜ Advanced; needed only by games with very custom contact rules.
Cross-cluster physics interaction (N/A β€” Rapier is single-process) 🚫 Blocked on cross-cluster physics epic (not yet filed) Kinematic neighbor proxies for entities owned by adjacent clusters.
Terrain / world geometry collision User inserts mesh / heightfield as fixed bodies 🚫 Blocked on #119 (Terrain epic) Game devs do not insert terrain by hand; the Arcane runtime owns this.
Spatial-binding migration for Fixed entities (N/A β€” local Rapier doesn't have clusters) 🚫 Blocked on clustering-binding epic (not yet filed) Fixed entities (walls, structures) shouldn't migrate by PGP affinity; need spatial binding.
Cross-machine determinism / reconciliation Best-effort; Rapier is deterministic per-process per-build πŸ”˜ Open question for production. May never be exactly deterministic across hardware; partial reconciliation is the goal.
Empty-cluster step skip (no entities β†’ no step) (N/A) πŸ”˜ Trivial optimization; relies on Rapier sleeping for stationary bodies.

What's reachable right now without any architectural epic

The flagged-blocked rows above (3 of them) require architectural decisions / docs / epics. Everything else can land via #120 and #121 without waiting. Those two issues, together, close the per-entity-physics gap inside the existing entity-driven model.

After #120 and #121, a developer can:

  • Run any Rapier simulation that operates on dynamic / kinematic / fixed bodies in a single Rapier world.
  • Use any Rapier feature that doesn't depend on terrain or cross-cluster interaction.
  • Build a self-contained physics demo (entities only, no external map) that's bit-functionally equivalent to the same code running single-process.

After #119 (terrain) lands, the same code starts hitting world geometry β€” without any change to user code (terrain is loaded by the runtime).

After the cross-cluster physics epic lands, entities in neighbor clusters become visible to physics queries.

How this issue is maintained

Update the inventory rows when:

  • A sibling issue lands (βœ… replaces 🚧).
  • A blocking epic lands (cell goes from 🚫 to 🚧 or βœ…).
  • A deferred capability becomes a real need (πŸ”˜ β†’ 🚧 with new sibling issue).

Keep the inventory rather than closing it β€” it's the canonical view of "what's possible on the cluster vs locally" for anyone evaluating Arcane.

Reference

  • Parent EPIC: #8 β€” Cluster physics backends
  • Existing implementation: #117 (minimum integration, RapierClusterSim wrapper), #118 (contact events + per-entity colliders)
  • Sibling work: #120 (spawn-time hooks), #121 (in-tick ops)
  • Architecturally blocked: #119 (Terrain), clustering-binding (not filed), cross-cluster physics (not filed)
  • Architecture doc: docs/architecture/entity-model.md, docs/architecture/physics-backends-and-unreal.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions