Skip to content

Rapier cluster physics: minimum integrationΒ #117

@martinjms

Description

@martinjms

Quick Summary

  • 🟒 Status: implemented β€” commit 131b439 on local branch chore/disable-claude-code-ci (not yet pushed; PR not yet opened).
  • New module arcane-infra::rapier_cluster::RapierClusterSim implements ClusterSimulation and wraps a user's sim, inserting Rapier's PhysicsPipeline::step between user on_tick and ClusterServer::tick.
  • Networking, replication, ws_server, neighbor merge, and persist are unchanged β€” same run_cluster_loop code path.
  • Behind feature flag rapier-cluster (off by default). Vanilla cargo build pulls zero rapier3d into the dep tree.
  • 18 unit tests cover lifecycle, multi-entity, dynamics, user-sim composition, determinism, despawn-respawn round-trip.

Why This Matters

Foundation for the heterogeneous-node vision in #33 β€” lets a cluster run cheap-but-real physics for entities no player is actively watching, while engine-parity nodes (Unreal/Chaos, Unity/PhysX) handle player-visible entities. Delivers the "second backend (Rapier stub)" item in #8 well past stub: a working drop-in.

Scope

  • In: RapierClusterSim wrapper + RapierConfig + arcane-rapier-cluster binary + tests + module docs.
  • Out (separate issues): contact events, per-entity collider shapes, impulse/force commands, raycasts, joints, kinematic neighbor proxies, world-bounds policy, naming-rename sweep (#32).

Action Items

  • Implement RapierClusterSim and RapierConfig in arcane-infra::rapier_cluster
  • Wire feature rapier-cluster + arcane-rapier-cluster binary
  • 18 unit tests across 5 surfaces (lifecycle, multi-entity, dynamics, composition, determinism)
  • Verify vanilla dep tree has zero rapier3d
  • Clippy + doctest pass under both feature configurations
  • Push branch and open PR
  • Review and merge
Architecture

RapierClusterSim IS-A ClusterSimulation that HAS-A user ClusterSimulation. Each tick:

  1. User's on_tick runs first β€” game logic, action handling, velocity intent writes.
  2. Wrapper acquires its Mutex<RapierState> lock.
  3. Despawns bodies for entities in pending_removals and entities that vanished from the entity map.
  4. sync_inputs: spawns first-sight entities at entity.position, sets linvel from entity.velocity for existing bodies. Skips ids in pending_removals to avoid re-spawning bodies the user just asked to drop.
  5. step_with_accumulator: fixed 1/60 s Rapier substeps until accumulator drains.
  6. sync_outputs: writes body.translation β†’ entity.position and body.linvel β†’ entity.velocity for replication.

Contract (documented in module docs)

  • entity.velocity is intent-in.
  • entity.position is output-only after first-sight spawn. User writes are silently overwritten.
  • Despawn driven by pending_removals and entity-map disappearance.
  • Every entity gets a uniform 0.5-radius sphere collider; per-entity shapes deferred.

Industry term

The pattern is pluggable physics backend (Bevy RapierPhysicsPlugin swappable for XpbdPlugin; Unreal PhysicsScene). The composition shape β€” wrapper sim wraps user sim β€” is the Strategy pattern at the design-pattern level.

Files changed
File Change
crates/arcane-infra/Cargo.toml rapier3d = "0.32" (optional = true); feature rapier-cluster = ["cluster-ws", "dep:rapier3d"]; bin entry
crates/arcane-infra/src/lib.rs pub mod rapier_cluster (gated); re-exports RapierClusterSim + RapierConfig
crates/arcane-infra/src/rapier_cluster.rs new β€” wrapper + private RapierState + 18 tests
crates/arcane-infra/src/bin/arcane_rapier_cluster.rs new β€” binary mirror of arcane_cluster.rs
Verification matrix
Build Tests Rapier in dep tree
Vanilla cargo test -p arcane-infra 65 pass 0
--features rapier-cluster 83 pass (18 new) rapier3d v0.32.0
cargo build --bin arcane-cluster (vanilla) builds n/a
cargo build --bin arcane-rapier-cluster --features rapier-cluster builds n/a
cargo clippy both modes silent n/a
Module-level doctest compiles n/a

Reference

  • Parent EPIC: #8 β€” Cluster physics backends β€” Unreal (Chaos) first, multi-engine path
  • Strategic context: #33 β€” Engine-specific node types β€” heterogeneous physics tiers
  • Architecture doc: docs/architecture/physics-backends-and-unreal.md β€” Β§7 "Multi-backend path" + Phase D
  • Commit: 131b439 (local, not yet pushed)
  • Follow-up: #118 β€” Rapier cluster physics: contact events + per-entity collider shapes

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