feat(lambda-rs): 2D rigid body support#185
Conversation
…to assign IDs on creation.
…eate/query/mutate/apply forces
✅ Coverage Report📊 View Full HTML Report (download artifact) Overall Coverage
Changed Files in This PR
PR Files Coverage: 90.85% (924/1017 lines) Generated by cargo-llvm-cov · Latest main coverage Last updated: 2026-02-15 07:46:45 UTC · Commit: |
There was a problem hiding this comment.
Pull request overview
This PR adds comprehensive 2D rigid body support to the lambda-rs physics engine with a backend-agnostic public API, a Rapier-backed implementation, extensive test coverage, a working demo, and thorough documentation.
Changes:
- Introduces
RigidBody2D,RigidBody2DBuilder, andRigidBodyType(Static, Dynamic, Kinematic) with world-scoped generational handles - Implements fixed-timestep integration with symplectic Euler for dynamics, force accumulation, and impulse application
- Adds comprehensive unit tests validating physics behavior, error handling, and handle validation
- Provides a runnable demo (
physics_rigid_bodies_2d) showcasing all body types with manual boundary constraints - Includes complete documentation: spec, tutorial, and feature guide updates
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
crates/lambda-rs/src/physics/rigid_body_2d.rs |
Public API with handles, builder, error types, and comprehensive unit tests |
crates/lambda-rs/src/physics/mod.rs |
Module integration, world ID allocation, and force clearing per step |
crates/lambda-rs-platform/src/physics/rapier2d.rs |
Backend implementation with slot-based storage and physics integration |
crates/lambda-rs-platform/src/physics/mod.rs |
Backend type exports |
demos/physics/src/bin/physics_rigid_bodies_2d.rs |
Demo binary with dynamic, kinematic, static bodies and manual boundaries |
demos/physics/Cargo.toml |
Binary entry configuration |
docs/specs/physics/rigid-bodies-2d.md |
Complete specification with API surface, behavior, and integration semantics |
docs/specs/README.md |
Spec index update |
docs/tutorials/physics/basics/rigid-bodies-2d.md |
Step-by-step tutorial with implementation guidance |
docs/tutorials/README.md |
Tutorial index update |
docs/features.md |
Feature documentation update for rigid bodies |
.pre-commit-config.yaml |
Clippy toolchain adjustment |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| types: [rust] | ||
| - id: clippy | ||
| entry: rustup run nightly cargo clippy --workspace --all-targets -- -D warnings | ||
| entry: cargo clippy --workspace --all-targets -- -D warnings |
There was a problem hiding this comment.
This change removes the nightly toolchain requirement from the clippy pre-commit hook. However, the fmt hook on line 20 still uses rustup run nightly cargo fmt --, creating an inconsistency. If the intention is to remove nightly toolchain requirements entirely, both hooks should be updated. If nightly is required for fmt, document why clippy doesn't need it.
| last_updated: "2026-02-12T23:33:50Z" | ||
| version: "0.2.0" | ||
| engine_workspace_version: "2023.1.30" | ||
| wgpu_version: "26.0.1" |
There was a problem hiding this comment.
The wgpu_version metadata field shows "26.0.1", but this conflicts with other documentation files in the repository which consistently use "28.0.0". This version inconsistency should be corrected to match the standard used across the repository, which is "28.0.0" as seen in the tutorial file.
| wgpu_version: "26.0.1" | |
| wgpu_version: "28.0.0" |
| last_updated: "2026-02-13T20:47:25Z" | ||
| version: "0.1.16" | ||
| engine_workspace_version: "2023.1.30" | ||
| wgpu_version: "26.0.1" |
There was a problem hiding this comment.
The wgpu_version metadata field shows "26.0.1", but this conflicts with the tutorial file which uses "28.0.0" (line 9 of docs/tutorials/physics/basics/rigid-bodies-2d.md). Both documents should use the same wgpu version for consistency across the repository documentation.
| wgpu_version: "26.0.1" | |
| wgpu_version: "28.0.0" |
| let id = NEXT_WORLD_ID.fetch_add(1, Ordering::Relaxed); | ||
| if id != 0 { | ||
| return id; | ||
| } |
There was a problem hiding this comment.
The world ID allocation logic has a subtle bug: when the AtomicU32 wraps around from u32::MAX back to 0, the function will infinite loop because it skips zero but never increments past it. While this is unlikely in practice (requiring 4 billion+ world creations), a more robust implementation would handle the wraparound case explicitly, for example by returning an error after detecting a wraparound or by using a checked increment pattern.
| let id = NEXT_WORLD_ID.fetch_add(1, Ordering::Relaxed); | |
| if id != 0 { | |
| return id; | |
| } | |
| // Load the current value and compute the next non-zero ID. | |
| let current = NEXT_WORLD_ID.load(Ordering::Relaxed); | |
| let mut next = current.wrapping_add(1); | |
| // Skip zero, which is reserved as an invalid world identifier. | |
| if next == 0 { | |
| next = 1; | |
| } | |
| // Attempt to update the counter; retry on contention. | |
| if NEXT_WORLD_ID | |
| .compare_exchange(current, next, Ordering::Relaxed, Ordering::Relaxed) | |
| .is_ok() | |
| { | |
| return next; | |
| } |
Summary
Add 2D rigid body support to
PhysicsWorld2Dwith a backend-agnostic public API in
lambda-rs, a Rapier-backed implementation inlambda-rs-platform, and supporting documentation + a runnable demo.This work adds:
Static,Dynamic, andKinematicbodies.Related Issues
Changes
RigidBodyType,RigidBody2D, andRigidBody2DBuilder.WorldMismatch,InvalidHandleBodyNotFoundInvalidPosition,InvalidRotation,InvalidVelocity,InvalidForce,InvalidImpulse,InvalidMassKgUnsupportedOperation { body_type }PhysicsWorld2D::step().aliasing when slots are reused.
lambda-demos-physicsrunnable demo:physics_rigid_bodies_2d.(programmatic motion), and a static reference body.
collision shapes/response).
docs/specs/physics/rigid-bodies-2d.mdand update spec index.docs/tutorials/physics/basics/rigid-bodies-2d.mdand updatetutorial index.
docs/features.mdfor the new physics-2D feature surface withoutpinning a specific Rapier version.
Type of Change
Affected Crates
lambda-rslambda-rs-platformlambda-rs-argslambda-rs-logginglambda-demos-physicsChecklist
cargo +nightly fmt --all)cargo clippy --workspace --all-targets -- -D warnings)cargo test --workspace)Testing
Commands run:
Recommended additional verification:
cargo build --workspace cargo test --workspace cargo clippy --workspace --all-targets -- -D warningsManual verification steps:
cargo run -p lambda-demos-physics --bin physics_rigid_bodies_2d --features physics-2dScreenshots/Recordings
Platform Testing
Additional Notes
are explicit logic to keep bodies visible.