
Avian Character Controllers, DespawnOnExitState, and SystemParams
2025-05-12
0.16 is out and honestly I'm already seeing features land that make me want 0.17 :D
The Avian Character Control Working Group (discord invite) is an ad-hoc group of people with a shared interest in building kinematic character controllers with Avian. If that sounds like you, move and slide your way over into the dedicated Discord to find links to the prototype GitHub repo.
fn filter_spawned_after(
entities: impl IntoIterator<Item = Entity>,
world: &World,
tick: Tick,
) -> impl Iterator<Item = Entity> {
let now = world.last_change_tick();
entities.into_iter().filter(move |entity| world
.entity(*entity)
.spawned_at()
.is_newer_than(tick, now)
)
}
SystemParam for Option and Result
A SystemParam
is a type like Query
, Res
, Local
, Commands
, EventWriter/EventReader
that is used as an argument to a system.
Previously there were explicit SystemParam
implementations for types like Option<Res<T>>
for optional Resources. As of #18766, there are generic implementations for Option<T>
and Result<T, SystemParamValidationError>
.
This opens up using Option
with third party SystemParam
implementations and more immediately enables approaches like Option<EventReader>
.
When
Contrary to the aforementioned Option
SystemParam, the new
When
SystemParamintroduced in [#18765](https://github.com/bevyengine/bevy/pull/18765) will silently skip a system if parameter validation fails. This means you can configure a system to only run if a
Resource` is available by writing
fn my_system(res: When<Res<MyResource>>) {}
clone_behavior in derive Component
#18811 introduces the ability to specify the clone behavior when deriving Component, which impacts usage when taking advantage of Entity Cloning.
StateScoped renamed to DespawnOnExitState
If you've used States before, you might be familiar with StateScoped
, the Component that will despawn Entities when exiting a state. In #18818 StateScoped
has been renamed to DespawnOnExitState
and a new DespawnOnEnterState
has also been added.
It seems like there may be more forms of this coming in the future as well.
Infinite children!
In 0.16, the children!
macro supports up to twelve children at once. #18865 expands the children!
macro to remove that limit. You are now bound by Rust's recursion limits instead, which seem to be 1400-ish children! but spawning 1400 children is probably not the best approach so you'll likely be using this with 10s of children, not thousands.
FooSystems
A new convention for naming SystemSets has arisen in #18900. Sets of systems are now generally expected to be named with a *Systems postfix. Examples include:
- AnimationSystems
- TransformSystems
- TimeSystems
Allows bypass for DefaultQueryFilters
0.16 introduced DefaultQueryFilters
which means that Query
s can have, well, Default filters... #18192 introduces the ability to bypass these filters, since sometimes it can be useful to ignore the filters.
Customizing Default Log Formatting
#17722 enables changing the default log formatting Bevy uses. This can be useful for reducing the amount of noise by removing timestamps, or making other adjustments.
2025-05-10T19:33:16.753152Z INFO kinematic_character_controller::kcc: current_velocity_magnitude=0.46875
Here's how it works
fn fmt_layer(_app: &mut App) -> Option<bevy::log::BoxedFmtLayer> {
Some(Box::new(
bevy::log::tracing_subscriber::fmt::Layer::default()
.without_time()
.with_writer(std::io::stderr),
))
}
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(bevy::log::LogPlugin {
fmt_layer,
..default()
}))
.run();
}
Viewport UI Widget
A new examples/ui/viewport_node.rs
introduced in #17253 shows off a new ViewportNode
, which can turn a UI Node into a viewport.
This viewport uses a camera to determine what to show and can even handle picking (including dragging in and out of the viewport).
Text Background Colors
#18892 introduces background colors for text using a new TextBackgroundColor
Component! Note that this effect works best on monospace fonts. If you use a proportional font the backgrounds might not line up with each letter in the same exact way.

Showcase
Bevy work from the #showcase channel in Discord and around the internet. Use hashtag #bevyengine.

Bevy Inspection
showcase
An alternative VSCode inspector that prioritizes tight coupling with VSCode’s UI capabilities for real-time interaction. It focuses on answering two questions:
- Can we make component editing in Bevy feel as seamless as debugging in Unity/Unreal?,
- How far can we push VSCode’s extension API for game dev tooling?


Foxtrot: TheDarkMod
showcase
Progress on a port of TheDarkMod fan mission "Volta I: The Stone". The intended use is as a Foxtrot template demo.

Slavic Castles
showcase
Slavic Castles is an old card game prototype that was recently updated to Bevy 0.16.


Gnome Village
showcase
Gnome Village is an open source cozy colony sim. Implemented features include world generation, settlers taking on jobs, chopping stuff down, building stuff up, and watering plants.

Bevy Tanks
showcase
Bevy Tanks is a simple 3d tank game with projectiles, particles, and of course: tanks, on an open plane. Its the authors first published Bevy project and makes use of bevy_rapier, bevy_tnua, bevy_enhanced_input, and bevy_rand.
Source is available on GitHub

Crates
New releases to crates.io and substantial updates to existing projects
Lightyear 0.20
crate_release
Lightyear is a full-featured server-client networking library for bevy.
0.20 brings no-std support, batch replication, and a hierarchy replication refactor.
seldom_state
crate_release
seldom_state is a plugin that adds a StateMachine component that you can add to your entities. The state machine will change the entity's components based on states, triggers, and transitions that you define.
This update also adds StateMachine::on_exit_from, StateMachine::on_enter_to, etc so you can detect when the state machine transitions from and to given states. The former runs before the transition occurs and the latter runs after.
bevy_rand v0.11
crate_release
bevy_rand is a plugin to integrate rand for ECS optimized RNG for the Bevy game engine.
This is a small but breaking change release, as bevy_rand now has optional bevy_reflect dependency, allowing for bevy_rand to be even leaner for no_std. For most people using bevy_rand with default features, this changes nothing. Those who are in no_std land and need bevy_reflect now need to specify it explicitly in features
bevy_fix_cursor_unlock_web
crate_release
bevy_fix_cursor_unlock_web
A tiny plugin that fixes Bevy not reporting when the cursor is unlocked on web
To use it, just add FixPointerUnlockPlugin
, done.
Now, Window::cursor_options::grab_mode
is automatically set to CursorGrabMode::None
for you when unlocking the cursor on web.
This fixes https://github.com/bevyengine/bevy/issues/8949
bevy_play_card 0.2
crate_release
bevy_play_card is a card crate with support for observer and Component based APIs.
bevy_aseprite_ultra v0.6
crate_release
Hot reload animations and slices directly from an aseprite binary file.
0.6 brings new default render targets (Sprite, Ui and 3D), support for custom material targets, and a new simpler to use API.
Avian Physics 0.3 🪶
crate_release
Avian is an ECS-driven physics engine for Bevy.
v0.3 is another huge release, with several new features, quality-of-life improvements, and important bug fixes. Highlights include:
- Opt-in contact reporting: Collision events are now only sent for entities that have the
CollisionEventsEnabled
component, reducing unwanted overhead and iteration. - Observable collision events: Observers finally support collision events, making it easy to define per-entity collision handlers.
- Collision hooks: Users can "hook into" the collision pipeline, making it possible to efficiently filter and modify contacts.
- Per-manifold material properties: Friction, restitution, and tangent velocity can be modified for contact manifolds, allowing the simulation of non-uniform materials and conveyor belts.
- Collider context: Custom colliders that implement
AnyCollider
have aContext
for ECS access. - Physics diagnostics: Avian has built-in diagnostics and a debug UI for runtime physics profiling.
- Reworked contact pair management: Contacts have been massively reworked to reduce allocations and unnecessary work while increasing parallelism.
- Faster collisions and spatial queries: Collisions and spatial queries have much less overhead.
- Bevy 0.16 support: Avian has been updated to the latest version of Bevy, and is taking advantage of relationships for attaching colliders to rigid bodies.
Check out the announcement blog post for a more in-depth overview of what has changed and why. A changelog and migration guide can be found on GitHub.
bevy-mesh-text-3d
crate_release
bevy-mesh-text-3d is a small crate to create extruded 3d text via cosmic text
schminput 0.3.0
crate_release
an input manager for bevy, using actions and action sets, built with bevy_mod_openxr in mind.
Add TextureAtlas convenience methods authored by mnmaita
Fix `rotate_by` implementation for `Aabb2d` authored by kyon4ik
Implement `RelationshipSourceCollection` for `IndexSet` authored by Brezak
Implement `RelationshipSourceCollection` for `BTreeSet` authored by Brezak
Create a `When` system param wrapper for skipping systems that fail validation authored by chescock
refactor ui/borders example to use new children! macro authored by ChristopherBiscardi
Add NonNilUuid support to bevy_reflect authored by tmstorey
Text background colors authored by ickshonpe
Fix tonemapping example when using a local image authored by mcobzarenco
Prevent exclusive systems from being used as observers authored by chescock
Fix occlusion culling not respecting device limits authored by greeble-dev
Sprite picking docs fix authored by akimakinai
Upgrade `atomicow` version authored by hukasu
ignore files starting with . when loading folders authored by mockersf
Add a viewport UI widget authored by chompaa
feat(log): support customizing default log formatting authored by JeanMertz
Remove `insert_or_spawn` function family authored by ElliottjPierce
Add Allows filter to bypass DefaultQueryFilters authored by NiseVoid
Let `FilteredEntity(Ref|Mut)` receive access when nested. authored by chescock
Bump crate-ci/typos from 1.31.1 to 1.32.0 authored by greeble-dev
Update ktx2 to 0.4.0 authored by rparrett
Update `sysinfo` version to `0.35.0` authored by GuillaumeGomez
Strip unused features from `bevy_asset` dependencies authored by bushrat011899
Ignore RUSTSEC-2023-0089 until postcard is updated authored by Zeophlite
Stop using `ArchetypeComponentId` in the executor authored by chescock
Fix sparse set components ignoring `insert_if_new`/`InsertMode` authored by JaySpruce
Added `StableInterpolate` implementations for linear colors. authored by mintlu8
Add `BundleRemover` authored by ElliottjPierce
Move initializing the `ScreenshotToScreenPipeline` to the `ScreenshotPlugin`. authored by andriyDev
Speed up ECS benchmarks by limiting variations authored by greeble-dev
Add `world` and `world_mut` methods to `RelatedSpawner` authored by urben1680
Missing punctuation authored by SpecificProtagonist
Remove remaining internal use of `!Send` resources authored by joshua-holmes
Add image sampler configuration in GLTF loader authored by axlitEels
Increase upper limit of `children!` authored by CorvusPrudens
Adopt consistent `FooSystems` naming convention for system sets authored by Jondolf
Implemented `Alpha` for `f32`. authored by mintlu8
Use new `run_without_applying_deferred` method in `SingleThreadedExecutor` authored by chescock
Merge ObserverState and Observer into single component authored by re0312
deprecate `SimpleExecutor` authored by ElliottjPierce
Derive `clone_behavior` for `Components` authored by Bleachfuel
Create `bevy_platform::cfg` for viral feature management authored by bushrat011899
The toml workflow job will now install taplo-cli using cargo-binstall authored by LikeLakers2
Rename `StateScoped` to `DespawnOnExitState` and add `DespawnOnEnterState` authored by mgi388
Add `EntityWorldMut::reborrow_scope()` authored by SOF3
implement MapEntities for higher-order types authored by HanKruiger
Add `IntoSystem::with_input` and `::with_input_from` system wrappers authored by ItsDoot
Expose CustomCursorUrl authored by UkoeHB
Make `entity::index` non max authored by ElliottjPierce
Add system ticks to EntityRef/Mut WorldQuery authored by cBournhonesque
Generic `SystemParam` impls for `Option` and `Result` authored by chescock
Deprecated Begone! 0.16 Cleanup authored by bushrat011899
Make `NonSendMarker` `!Send` authored by bushrat011899
Track spawn `Tick` of entities, offer methods, query data `SpawnDetails` and query filter `Spawned` authored by urben1680
Make entity generation a new type and remove identifier authored by ElliottjPierce
fix `.insert_related` index bound authored by databasedav
Fix macro pollution in SystemParam derive authored by Cyberboss
Want to contribute to Bevy?
Here you can find two types of potential contribution: Pull Requests that might need review and Issues that might need to be worked on.
Pull Requests Opened this week
Initial raytraced lighting progress (bevy_solari) authored by JMS55
Use Component Column ids in tables to skip component maps in queries authored by ElliottjPierce
Clean up phantom data for ExtractComponentPlugin authored by Sorseg
Fix: Provide CPU mesh processing with MaterialBindingId authored by dsgallups
Extract members of `PickingPlugin` and `PointerInputPlugin` into new types authored by hukasu
Remove `YAxisOrientation` from `bevy_text` authored by ickshonpe
Environment Map Filtering GPU pipeline authored by mate-h
Bare Minimum `no_std` support for `bevy_asset` authored by bushrat011899
Fix panic when specializing materials for entities spawned in `PostUpdate` authored by grind086
Simplify `bevy_utils` Features authored by bushrat011899
Simplify `bevy_tasks` Features authored by bushrat011899
Fix `AssetChanged` code documentation to mention the `PostUpdate` schedule authored by Henauxg
Add test that repros #11111 (different loader settings produce same asset) authored by greeble-dev
Add test for `GltfLoaderSettings::override_sampler` and mipmap rendering authored by greeble-dev
Cache component columns in archetypes authored by ElliottjPierce
Derive `PartialEq` for `ImageSampler` authored by Noxmore
viewport_node example: Remove main world image initialization authored by SpecificProtagonist
Add list of supported KHR extensions to bevy_gltf's docs authored by jf908
Reduce operations in `RayCast2d::circle_intersection_at` using cross product authored by kumikaya
Naive clipboard support authored by ickshonpe
replace `async-std` with `async-io` authored by VitalyAnkh
Remove warning from Image::resize authored by SpecificProtagonist
Fix a `NestedLoader` code path that failed to use its meta transform authored by greeble-dev
Fix glTF importer wrongly ignoring sampler filters authored by greeble-dev
Simplify `bevy_reflect` Features authored by bushrat011899
Adjust texture filtering presets. authored by axlitEels
use Children::spawn and SpawnIter/Spawn in ui/box_shadow.rs authored by ChristopherBiscardi
Provide physical dimensions to wgpu `Device::create_texture_with_data` authored by atlv24
Nonmax all rows authored by ElliottjPierce
Fragmenting value components authored by eugineerd
Redo component sparse set authored by ElliottjPierce
fix distinct directional lights per view authored by robtfm
Have `System::run_unsafe` return `Result`. authored by chescock
Remove `ArchetypeComponentId` and `archetype_component_access` authored by chescock
Added `.pop_child`, `.pop_related`, `.despawn_first_related`, `.despawn_last_related` authored by MuongKimhong
fix windows wasm embedded assets authored by atlv24
ReadOnlySystem diagnostics and type alias authored by ItsDoot
bevy_reflect: `match_type` macro authored by MrGVSV
Use embedded_asset to load PBR shaders authored by atlv24
Move away from std::Path in bevy_assets authored by lielfr
Updating `GlobalVolume` now updates the volume of any playing (Spatial)AudioSinks authored by Cyberboss
Bump accesskit to 0.19 and accesskit_winit to 0.27 authored by DataTriny
bevy_reflect: Fix `FromReflect` derive for opaque remote wrappers authored by MrGVSV
Tilemap rendering authored by ConnerPetzold
Issues Opened this week
Dependency coupling between widgets and input focus authored by alice-i-cecile
example async_compute.rs uses the discontinued async-std authored by MushineLament
Feature `bevy_tasks/multi_threaded` does not compile alone authored by kpreid
1-frame hover delay on newly-spawned entities authored by benfrankel
Rethink query / system access system to better account for `Allows` query filter authored by alice-i-cecile
Clean up configuring log formatting authored by alice-i-cecile
Re-add an `ArchetypeComponentId` parallel schedule executor authored by alice-i-cecile
Feature: a way to scale a Primitive2d/Primitive3d shape directly authored by laundmo
add unit test for sparse set components insertion mode authored by mockersf
Type system should prevent the use of exclusive systems as observers authored by alice-i-cecile
Move away from std::Path in bevy_assets authored by alice-i-cecile
Support normal maps when no tangents exist authored by janhohenheim
docs: picking requires RenderAssetUsages::MAIN_WORLD authored by francisdb
Consider builder pattern for adding images authored by torsteingrindvik
Loading non-color maps as sRGB in `StandardMaterial` silently looks wrong authored by Noxmore
Add state-driven entity disabling using a `EnabledInState` component authored by alice-i-cecile
Support `KHR_texture_basisu` in bevy_gltf authored by jf908
Panics cannot be caught on iOS authored by arcln
Bevy picking fails after camera movment. Picking has wrong positions for entities after camera viewport is moved authored by aDecoy
Rename `Condition` into `SystemCondition` authored by Shatur
Gizmos will not render from a registered system authored by Threadzless
TonemappingTest.gltf is rendered with incorrect texture filtering authored by rparrett
Timer appears to be broken in headless setups authored by lyonbeckers
Mouse motion delta malfunction when accessing app from remote desktop authored by Galedon
Rename `Timer::paused` to `Timer::is_paused` and `Timer::finished` to `Timer::is_finished` authored by mgi388
Sometimes, lights have an effect through walls authored by janhohenheim
0.16 regression in macro hygiene in SystemParam derive authored by nsabovic
Importing cube maps is hard authored by janhohenheim
Atmosphere does not render below a certain height authored by hukasu
Prepass fragment shader does not influence opaque material shadows on 0.16 authored by hansler
`DepthPrepass` doesn't respect changing `alpha_mode` from `Opaque` to `Blend`. authored by eero-lehtinen
`ImageSampler::get_or_init_descriptor()` changes the sampler. authored by axlitEels
Reading depth prepass in shader extension broken on webgpu authored by OptimisticPeach
docs: Clicking on link to `Node` required component on `ImageNode` page does nothing authored by rparrett
bevy_image ktx2 reorders data instead of using wgpu `MipXLayerYFaceZ` authored by atlv24
Support fields with bundle effects in `Bundle` derive macro authored by nfagerlund
Expose the current monitor a window is on authored by benfrankel
When using 2D and 3D cameras, moving the 2D UI camera to a nondefault render layer causes a crash on Wasm authored by janhohenheim
When using 2D and 3D cameras, moving the 2D UI camera to a nondefault render layer makes shadows flicker authored by janhohenheim
Extract common UI shader code from `ui.wgsl` for reuse in custom materials authored by djeedai
Crash occurs when attempting to minimize the window authored by Fodesu
Transparent meshes with nothing opaque behind it don't render parts of it when below sea level with Atmosphere on authored by hukasu
Unintuitive Tab Navigation Order authored by jansenMurphy