Skip to content
This repository was archived by the owner on Sep 24, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ jobs:
run: cargo clippy --verbose -p bevy_rapier2d --examples
- name: Clippy for bevy_rapier3d
run: cargo clippy --verbose -p bevy_rapier3d --examples
- name: Clippy for bevy_rapier2d (debug-render, simd, serde)
run: cargo clippy --verbose -p bevy_rapier2d --features debug-render-2d,simd-stable,serde-serialize,picking-backend
- name: Clippy for bevy_rapier3d (debug-render, simd, serde)
run: cargo clippy --verbose -p bevy_rapier3d --features debug-render-3d,simd-stable,serde-serialize,picking-backend
- name: Clippy for bevy_rapier2d (debug-render, simd8, serde)
run: cargo clippy --verbose -p bevy_rapier2d --features debug-render-2d,simd8,serde-serialize,picking-backend
- name: Clippy for bevy_rapier3d (debug-render, simd8, serde)
run: cargo clippy --verbose -p bevy_rapier3d --features debug-render-3d,simd8,serde-serialize,picking-backend
- name: Test for bevy_rapier2d
run: cargo test --verbose -p bevy_rapier2d
- name: Test for bevy_rapier3d
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## Unreleased

### Modified

- Update to bevy `0.20` (currently tracking bevy’s `main` branch).
- Update from rapier `0.34` to rapier `0.35`.
See [rapier's changelog](https://github.com/dimforge/rapier/blob/master/CHANGELOG.md) for details.
- Removed the `simd-stable` and `simd-nightly` features: SIMD is now always enabled in rapier.
The new `simd8` feature widens the solver’s SIMD from 4 to 8 lanes (f32 only, needs an AVX2-capable
target). Just drop `simd-stable`/`simd-nightly` from your `Cargo.toml`.
- `SolverContactView::point` is now derived from the contact’s per-body anchors, and
`SolverContactView::{friction, restitution}` report the value of the contact’s manifold, since
rapier made both coefficients per-manifold instead of per-contact.
- The `enhanced-determinism` and `serde-serialize` features can’t currently be enabled together:
`enhanced-determinism` turns on `glam/scalar-math`, for which glam doesn’t implement `serde` on
`BVec3A`/`BVec4A`, which `bevy_reflect` requires when bevy’s `serialize` feature is on.

## v0.35.0 (12 July 2026)

### Modified
Expand Down
13 changes: 3 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ members = ["bevy_rapier2d", "bevy_rapier3d", "bevy_rapier_benches3d", "ci"]
resolver = "2"

[workspace.dependencies]
rapier2d = "=0.33.0-alpha"
rapier3d = "=0.33.0-alpha"
rapier2d = "0.35.0"
rapier3d = "0.35.0"

[profile.dev]
# Use slightly better optimization by default, as examples otherwise seem laggy.
Expand All @@ -14,13 +14,6 @@ opt-level = 1
codegen-units = 1

[patch.crates-io]
#nalgebra = { path = "../nalgebra" }
#parry2d = { path = "../parry/crates/parry2d" }
#parry3d = { path = "../parry/crates/parry3d" }
#rapier2d = { path = "../rapier/crates/rapier2d" }
#rapier3d = { path = "../rapier/crates/rapier3d" }
#nalgebra = { git = "https://github.com/dimforge/nalgebra", branch = "dev" }
#parry2d = { git = "https://github.com/dimforge/parry", branch = "master" }
#parry3d = { git = "https://github.com/dimforge/parry", branch = "master" }
#rapier2d = { git = "https://github.com/dimforge/rapier", branch = "character-controller" }
#rapier3d = { git = "https://github.com/dimforge/rapier", branch = "character-controller" }
bevy = { git = "https://github.com/bevyengine/bevy", rev = "87a24bf95af15ed707fe634969994852155a2eac" }
39 changes: 26 additions & 13 deletions bevy_rapier2d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ debug-render-3d = [
rapier-debug-render = ["rapier2d/debug-render"]

parallel = ["rapier2d/parallel"]
simd-stable = ["rapier2d/simd-stable"]
simd-nightly = ["rapier2d/simd-nightly"]
simd8 = ["rapier2d/simd8"]
serde-serialize = ["rapier2d/serde-serialize", "bevy/serialize", "serde"]
enhanced-determinism = ["rapier2d/enhanced-determinism"]
headless = []
# Depends on bevy_egui / bevy-inspector-egui / bevy_mod_debugdump which don't support bevy main yet.
egui-examples = []
picking-backend = ["bevy/bevy_picking", "bevy/bevy_render"]
async-collider = [
"bevy/bevy_asset",
Expand All @@ -64,15 +65,15 @@ async-collider = [
to-bevy-mesh = ["bevy/bevy_render", "bevy/bevy_asset"]

[dependencies]
bevy = { version = "0.19.0", default-features = false, features = ["std"] }
nalgebra = { version = "0.34.2", features = ["convert-glam032"] }
bevy = { version = "0.20.0-dev", default-features = false, features = ["std"] }
nalgebra = { version = "0.35", features = ["convert-glam033"] }
rapier2d = { workspace = true }
bitflags = "2.10.0"
log = "0.4"
serde = { version = "1", features = ["derive"], optional = true }

[dev-dependencies]
bevy = { version = "0.19.0", default-features = false, features = [
bevy = { version = "0.20.0-dev", default-features = false, features = [
"x11",
"bevy_state",
"bevy_window",
Expand All @@ -92,10 +93,10 @@ bevy = { version = "0.19.0", default-features = false, features = [
] }
oorandom = "11"
approx = "0.5.1"
glam = { version = "0.32.1", features = ["approx"] }
bevy-inspector-egui = "0.37.0"
bevy_egui = "0.40.0"
bevy_mod_debugdump = "0.16.0"
glam = { version = "0.33", features = ["approx"] }
#bevy-inspector-egui = "0.37.0" # FIXME: re-enable once it supports bevy main
#bevy_egui = "0.40.0" # FIXME: re-enable once it supports bevy main
#bevy_mod_debugdump = "0.16.0" # FIXME: re-enable once it supports bevy main
serde_json = "1.0"

[package.metadata.docs.rs]
Expand All @@ -104,14 +105,26 @@ features = ["debug-render-2d", "serde-serialize"]

[package.metadata.cargo-all-features]

denylist = ["simd-nightly"]

# Features "dim2" and "dim3" are incompatible, so skip permutations including them
skip_feature_sets = [["enhanced-determinism", "simd-stable"]]
# Features "dim2" and "dim3" are incompatible, so skip permutations including them.
# `enhanced-determinism` + `serde-serialize` is skipped because the former enables
# `glam/scalar-math`, for which glam doesn’t implement `serde` on `BVec3A`/`BVec4A`,
# which `bevy_reflect` needs when bevy’s `serialize` feature is on.
skip_feature_sets = [
["enhanced-determinism", "simd8"],
["enhanced-determinism", "serde-serialize"],
]

always_include_features = ["dim2"]

# The maximum number of features to try at once. Does not count features from `always_include_features`.
# This is useful for reducing the number of combinations run for a crate with a large amount of features,
# since in most cases a bug just needs a small set of 2-3 features to reproduce.
max_combination_size = 1

[[example]]
name = "testbed2"
required-features = ["egui-examples"]

[[example]]
name = "debugdump2"
required-features = ["egui-examples"]
38 changes: 24 additions & 14 deletions bevy_rapier3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ debug-render-3d = [
rapier-debug-render = ["rapier3d/debug-render"]

parallel = ["rapier3d/parallel"]
simd-stable = ["rapier3d/simd-stable"]
simd-nightly = ["rapier3d/simd-nightly"]
simd8 = ["rapier3d/simd8"]
serde-serialize = ["rapier3d/serde-serialize", "bevy/serialize", "serde"]
enhanced-determinism = ["rapier3d/enhanced-determinism"]
headless = []
# Depends on bevy_egui / bevy-inspector-egui / bevy_mod_debugdump which don't support bevy main yet.
egui-examples = []
picking-backend = ["bevy/bevy_picking", "bevy/bevy_render"]
async-collider = [
"bevy/bevy_asset",
Expand All @@ -65,18 +66,19 @@ async-collider = [
to-bevy-mesh = ["bevy/bevy_render", "bevy/bevy_asset"]

[dependencies]
bevy = { version = "0.19.0", default-features = false, features = ["std"] }
nalgebra = { version = "0.34.2", features = ["convert-glam032"] }
bevy = { version = "0.20.0-dev", default-features = false, features = ["std"] }
nalgebra = { version = "0.35", features = ["convert-glam033"] }
rapier3d = { workspace = true }
bitflags = "2.10.0"
log = "0.4"
serde = { version = "1", features = ["derive"], optional = true }

[dev-dependencies]
bevy = { version = "0.19.0", default-features = false, features = [
bevy = { version = "0.20.0-dev", default-features = false, features = [
"bevy_window",
"x11",
"tonemapping_luts",
"zstd_rust",
"bevy_state",
"bevy_debug_stepping",
"bevy_text",
Expand All @@ -86,21 +88,25 @@ bevy = { version = "0.19.0", default-features = false, features = [
"bevy_gizmos_render",
] }
approx = "0.5.1"
glam = { version = "0.32.1", features = ["approx"] }
bevy-inspector-egui = "0.37.0"
bevy_egui = "0.40.0"
bevy_mod_debugdump = "0.16.0"
glam = { version = "0.33", features = ["approx"] }
#bevy-inspector-egui = "0.37.0" # FIXME: re-enable once it supports bevy main
#bevy_egui = "0.40.0" # FIXME: re-enable once it supports bevy main
#bevy_mod_debugdump = "0.16.0" # FIXME: re-enable once it supports bevy main

[package.metadata.docs.rs]
# Enable all the features when building the docs on docs.rs
features = ["debug-render-3d", "serde-serialize", "async-collider"]

[package.metadata.cargo-all-features]

denylist = ["simd-nightly"]

# Features "dim2" and "dim3" are incompatible, so skip permutations including them
skip_feature_sets = [["enhanced-determinism", "simd-stable"]]
# Features "dim2" and "dim3" are incompatible, so skip permutations including them.
# `enhanced-determinism` + `serde-serialize` is skipped because the former enables
# `glam/scalar-math`, for which glam doesn’t implement `serde` on `BVec3A`/`BVec4A`,
# which `bevy_reflect` needs when bevy’s `serialize` feature is on.
skip_feature_sets = [
["enhanced-determinism", "simd8"],
["enhanced-determinism", "serde-serialize"],
]

always_include_features = ["dim3"]

Expand All @@ -115,4 +121,8 @@ required-features = ["picking-backend"]

[[example]]
name = "testbed3"
required-features = ["picking-backend"]
required-features = ["picking-backend", "egui-examples"]

[[example]]
name = "debugdump3"
required-features = ["egui-examples"]
5 changes: 3 additions & 2 deletions bevy_rapier_benches3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ description = "Custom benchmarks for bevy_rapier."
readme = "./README.md"
license = "Apache-2.0"
edition = "2021"
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rapier3d = { workspace = true }
rapier3d = { workspace = true, features = ["profiler"] }
bevy_rapier3d = { version = "0.35", path = "../bevy_rapier3d" }
bevy = { version = "0.19.0", default-features = false }
bevy = { version = "0.20.0-dev", default-features = false }

[dev-dependencies]
divan = "0.1"
Expand Down
3 changes: 2 additions & 1 deletion ci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
name = "ci"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
bevy = "0.19.0"
bevy = { version = "0.20.0-dev" }
bevy_rapier3d = { version = "0.35", path = "../bevy_rapier3d" }
bevy_rapier2d = { version = "0.35", path = "../bevy_rapier2d" }

Expand Down
98 changes: 80 additions & 18 deletions publish.sh
Original file line number Diff line number Diff line change
@@ -1,25 +1,87 @@
#!/bin/sh
set -e
#! /bin/bash
#
# Publishes both bevy_rapier crates to crates.io with a single
# `cargo publish --workspace` invocation:
#
# - bevy_rapier2d / bevy_rapier3d
#
# Cargo computes the dependency order itself and waits for each crate to become
# available on the registry before publishing the ones that depend on it. The
# `bevy_rapier_benches3d` and `ci` crates are marked `publish = false`, so
# `--workspace` skips them.
#
# Why this script exists
# ----------------------
# Both crates share a single source tree at `<repo>/src`, referenced from each
# manifest as `path = "../src/lib.rs"`. That path points outside the crate
# directory, which `cargo publish` refuses to package.
#
# To work around it *only during publishing*, this script temporarily, for each
# affected crate:
# 1. rewrites the `[lib] path` to a crate-local one (i.e. `src/lib.rs`), and
# 2. creates a symlink inside the crate pointing at the shared source tree.
#
# Cargo follows the symlink and bundles the real source into each `.crate`. A
# trap restores the manifests and removes the symlinks on exit (including on
# error or Ctrl-C), leaving the tree exactly as it was.
#
# Extra arguments are forwarded to `cargo publish`, e.g.:
# ./publish.sh --dry-run
# ./publish.sh --token "$CARGO_TOKEN"
#
# Requires cargo >= 1.90 (for `cargo publish --workspace`).

tmp=$(mktemp -d)
set -euo pipefail

echo "$tmp"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT"

cp -r src "$tmp"/.
cp -r LICENSE README.md "$tmp"/.
# Crates sharing `src/lib.rs`.
SRC_CRATES=(bevy_rapier2d bevy_rapier3d)

### Publish the 2D version.
sed 's#\.\./src#src#g' bevy_rapier2d/Cargo.toml > "$tmp"/Cargo.toml
gawk -i inplace '{ gsub("../README.md", "README.md") }; { print }' "$tmp"/Cargo.toml
currdir=$(pwd)
cd "$tmp" && cargo publish
cd "$currdir" || exit
# Refuse to run on a dirty tree: the only diff during publishing must be our own
# temporary edits, so the restore at the end is guaranteed to be correct.
if [ -n "$(git status --porcelain)" ]; then
echo "error: working tree is not clean. Commit or stash changes before publishing." >&2
exit 1
fi

backup_dir="$(mktemp -d)"

### Publish the 3D version.
sed 's#\.\./src#src#g' bevy_rapier3d/Cargo.toml > "$tmp"/Cargo.toml
gawk -i inplace '{ gsub("../README.md", "README.md") }; { print }' "$tmp"/Cargo.toml
cp -r LICENSE README.md "$tmp"/.
cd "$tmp" && cargo publish
cleanup() {
for crate in "${SRC_CRATES[@]}"; do
# Remove the symlink we created (only if it is in fact a symlink).
[ -L "$crate/src" ] && rm -f "$crate/src"
# Restore the original manifest.
if [ -f "$backup_dir/$crate.Cargo.toml" ]; then
cp "$backup_dir/$crate.Cargo.toml" "$crate/Cargo.toml"
fi
done
rm -rf "$backup_dir"
}
trap cleanup EXIT INT TERM

rm -rf "$tmp"
# Apply the temporary symlink layout: the shared `src` dir lives at the repo
# root and is linked into each crate, while the manifest's `[lib] path` is made
# crate-local.
link_shared() {
local crate="$1"
local manifest="$crate/Cargo.toml"

cp "$manifest" "$backup_dir/$crate.Cargo.toml"

local tmp
tmp="$(mktemp)"
sed 's#path = "\.\./src/lib.rs"#path = "src/lib.rs"#' "$manifest" > "$tmp"
mv "$tmp" "$manifest"

ln -s ../src "$crate/src"
}

for crate in "${SRC_CRATES[@]}"; do
link_shared "$crate"
done

# Publish the whole workspace. `--allow-dirty` is required because our temporary
# edits make the tree dirty; the clean-tree check above keeps that safe.
cargo publish --workspace --allow-dirty "$@"
Loading
Loading