
Component Hooks, WMTS, and Same State Transitions
2025-11-17
This week Component Hooks get improvements to authoring ergonomics, Depth of Field gets easier to use, and automatic directional navigation landed! A popular feature request, same-state transitions also makes it in.
A number of crates shared their progress in showcases this week, while Foresight shared their Streaming WMTS renderer and wgsl-analyzer got a major update.
Processing gains experimental WebGPU support through Bevy and more!
Improve Component Hook Ergonomics
Component Hooks have been around for awhile, but with #21800 the derive macros can defer to associated functions impl'd on a type, improving ergonomics around where they can be defined by default.
use bevy_ecs::lifecycle::HookContext;
use bevy_ecs::prelude::*;
use bevy_ecs::world::DeferredWorld;
#[derive(Component)]
#[component(on_add, on_insert, on_despawn, on_remove=on_remove)]
struct Tile;
impl Tile {
fn on_add(_world: DeferredWorld, _context: HookContext) {
println!("added");
}
fn on_insert(_world: DeferredWorld, _context: HookContext) {
println!("inserted");
}
fn on_despawn(_world: DeferredWorld, _context: HookContext) {
println!("despawned");
}
}
fn on_remove(_world: DeferredWorld, _context: HookContext) {
println!("removed");
}
fn main() {
let mut world = World::new();
let entity = world.spawn(Tile);
entity.despawn();
}
Depth of Field Improvements

The Depth of Field effect is physically accurate, which is sometimes confusing for those not familiar with the physical implications! This can be improved by clamping certain values that would lead to "disabling" the Depth of Field effect unintentionally.
Automatic Directional Navigation Graph Generation

In #21668, a lower boilerplate method of generating directional navigation that is resistant to dynamic UI changes.
Now you can add the AutoDirectionalNavigation component to your UI entities, and Bevy will automatically compute navigation connections based on spatial positioning. The system intelligently finds the nearest neighbor in each of the 8 compass directions (North, Northeast, East, etc.), considering:
- Distance: Closer elements are preferred
- Alignment: Elements that are more directly in line with the navigation direction are favored
- Overlap: For cardinal directions (N/S/E/W), the system ensures sufficient perpendicular overlap
commands.spawn((
Button,
Node { /* ... */ },
AutoDirectionalNavigation::default(),
));
Same State Transitions
Same State transitions are when a state is set to the same state that the application currently exists in. As of #19363 this is possible via a new NextStat::set_forced method, which will cause the State's OnExit and OnEnter to fire.
This can be useful for actions like reloading a level.
Cosmic Text 0.15
#21699 updates cosmic-text to 0.15.
Node BorderRadius
#21781 adds a border_radius field to Node.
HitData for window pointer hits
#21802 adds HitData to Pointer<Move> events when an observer is added to the window.
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2d);
commands
.spawn(Window::default())
.observe(|trigger: On<Pointer<Move>>| {
assert!(
trigger.hit.position.is_some(),
"Position should not be None"
);
});
}

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


Scrollbars
showcase
Scrollarea uses space provided by taffy scrollbar_width. It doesn't require manually defining two element hierarchy (grid 2x2 with main element and scrollbars). Instead, if some element has any axis with overflow: scroll, scrollarea overlay (with scrollbars) is inserted as child element with position: absolute.
With these changes any element can be made scrollable by simply enabling overflow: scroll.

Timestep Tester
showcase
A toy application for experimenting with different kinds of timesteps, presentation modes, and the "update loop" of your game. This video is just showing off the Lorenz Attractor.

bevy_flash demos
showcase
This demo uses Ruffle's shaders and SWF parsing alongside a Bevy integration in bevy_flash to play Flash animations

bevy_pointcloud progress
showcase
Rendering octree nodes is one thing, but when multiple octree nodes overlap, it's needed to compute, for each point, the maximum depth at which neighbors will be rendered, so they all have the same size.

2d Procedural Generation
showcase
This project procedurally generates a fully deterministic, infinite, tile-based, 2D pixel art world. Roads can cross multiple chunks and settled areas with houses. The project recently received the ability to generate animated objects.
Source is available: https://github.com/kimgoetzke/procedural-generation-2

Firefly Progress
showcase
A showcase of progress on Firefly, a 3d lighting crate. It's now capable of stopping occluders from casting shadows over specific sprites, either by Entity or simply by their Z value; you can see the character being darkened only when they're behind the object they're carrying.

Crates
New releases to crates.io and substantial updates to existing projects
nano9 0.1.0-alpha.4
crate_release
Nano-9 is Bevy in Pico-8 clothing. It can read Pico-8 carts both .p8 and .png, so you can start with Pico-8 then switch over when you want anything outside Pico-8's bounds—like a different color palette! or more sprites, more code, more sounds, etc. You can code your game in Lua or Rust with the same-ish API.

bevy_animation_graph v0.8.0
crate_release
This crate works as an alternative to most of bevy_animation, and aims to provide a complete animation system and development workflow including animation graphs, animation state machines (i.e. animation controllers) and a graphical editor to create your animation graphs and state machines.
0.17 brings
- Animation-ragdoll integration using Avian, and ragdoll editor
- Custom stateful data store for animation nodes
wgsl-analyzer major update
crate_release
With the new parser in place, we now have top tier error recovery for pretty much any parsing errors. This also fixes a plethora of parsing issues, such as supporting break if. Massive thanks to the developer of the lelwel parser crate, as it made it possible for us to build such a high quality in so little time.
Then we reworked the type-checking. It should be a lot more accurate now, since it implement abstract numbers, supports more builtins and correctly allows shadowing of built-ins. As a bonus, the diagnostics improved in a few places. We also fixed all crashes we found, such as cyclic types causing stack overflows and parsing errors leading to panics.

Devlogs
vlog style updates from long-term projects
A new WebGPU backend for Processing using Bevy.
devlog
A new PR opened against the Processing repo containing some early experimental work on a WebGPU backed for Processing powered by Bevy!
Pathfinding and Dijkstra
devlog
A short thread on pathfinding and one weird use-case for Dijkstra algorithm
Fix memory leak in `EntitySpecializationTicks` authored by EmbersArc
enable same state transitions authored by mockersf
enable tracy subscriber layer on android authored by WireWhiz
Make `WinitMonitors` public authored by SludgePhD
Replace unwrap() calls with proper error handling in font_altas authored by Breakdown-Dog
Change feather's radio control's visibility from visible to inherited authored by AcrylonitrileButadieneStyrene
Fix binding in generated environment map downsampling pipeline authored by ashivaram23
Add Automatic Directional Navigation Graph Generation authored by jbuehler23
Prevent DoF effect disappearing at small `focus_distances` authored by Breakdown-Dog
Improve Component Hook Ergonomics authored by VasanthakumarV
fix: NoAutomaticBatching Copy and Clone authored by lizelive
Update to cosmic-text 0.15 authored by ickshonpe
Change `Bundle::component_ids` to return an iterator authored by hymm
do not require bevy_dev_tools for states example authored by mockersf
Pass position to `HitData` for window pointer hits authored by z-jxy
Relayout text on changes to `LineHeight` authored by ickshonpe
Add `BorderRadius` to `Node` authored by ickshonpe
Remove `viewport_debug` from web examples authored by ickshonpe
Delete unused WeightsCurve, and enable feature for bevy_animation. authored by andriyDev
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
Make default state change trigger self state transitions authored by janhohenheim
`EventFromEntity`: Ergonomics for custom entity events authored by mrchantey
Implement world.trigger_event remote method authored by Lancelotbronner
Improve AssetEvent docs authored by menochs1
Use `web_task` for cancellable wasm tasks authored by Gingeh
Solari: More reactive world cache authored by JMS55
Solari: Clustered world cache hashing authored by JMS55
Rename with_child into spawn_child authored by Sigma-dev
Move more functions off of `ScheduleGraph` authored by ItsDoot
Add support for world space UI authored by MushineLament
SystemRunner param and macro syntax authored by ecoskey
Improve `ThinSlicePtr` API authored by BD103
Remove `bevy_ptr::dangling_with_align()` and inline it authored by BD103
Add vertical slider support to bevy_ui_widgets slider authored by DuckyBlender
Feathers: add override cursor authored by rudderbucky
Improve frustum culling of skinned meshes through per-joint bounds authored by greeble-dev
Tidy up old `SystemCondition` trait hierarchy authored by ItsDoot
feat: Dir3 coordinate system constants authored by lizelive
Opt-in a DirectionalLight for atmospheric scattering authored by hukasu
Add IgnoreParentClip component to ignore parent element clipping authored by PPakalns
Support a custom atmosphere position authored by EmbersArc
Implement per-pixel linked list for OIT authored by beicause
Add a warning for the use of Viewport with Window targets authored by justacec
Trim imports atmosphere shaders authored by hukasu
fix: return current hit for DragDrop event authored by moe-moe-pupil
Fix entity display not working with padding. authored by PhantomMorrigan
Take the rest pose into account when computing the AABBs of skinned meshes in glTF files. authored by pcwalton
Issues Opened this week
Need a way to override EntityCursor authored by viridia
How to serialize/deserialize a resource that holds Entities (ie MapEntities) authored by Sheldonfrith
Add a responsive coords scene to `testbed_ui` authored by ickshonpe
More `testbed_ui` scenes authored by ickshonpe
`UiTransform` `testbed_ui` scene authored by ickshonpe
Investigate deprecated `heapless::mpmc` usage authored by cart
`spirv_shader_passthrough` without `shader_format_spirv` is NOOP authored by hukasu
`prepare_windows` causing frame pacing issues authored by dddnk
`DespawnOnExit` / `DespawnOnEnter` causes log spam when despawning hierarchies authored by Lyndon-Mackay
Long Lived Messages authored by Zefirchiky
Add warning for bevy_camera::Viewport when using Window targets with scaling factors different than 1.0 authored by justacec
Hotpatching causes stack overflow when system function body is very large authored by mutemoon
Add `Observer::add_component` authored by Shatur
Odd bevy_picking's DragDrop event hit position authored by MarkGordeychuk
Crash w/ features `bevy_sprite` and `bevy_dev_tools` w/o `bevy_text` authored by weihnaxbaum





