This commit makes the
`mark_meshes_as_changed_if_their_materials_changed` system use the new
`AssetChanged<MeshMaterial3d>` query filter in addition to
`Changed<MeshMaterial3d>`. This ensures that we update the
`MeshInputUniform`, which contains the bindless material slot. Updating
the `MeshInputUniform` fixes problems that occurred when the
`MeshBindGroupAllocator` reallocated meshes in such a way as to change
their bindless slot.
Closes#18102.
The test case `query_iter_sorts` was doing lots of comparisons to ensure
that various query arrays were sorted, but the arrays were all empty.
This PR spawns some entities so that the entity lists to compare not
empty, and sorting can actually be tested for correctness.
# Objective
Fixes https://github.com/bevyengine/bevy/issues/17590.
## Solution
`prepare_volumetric_fog_uniforms` adds a uniform for each combination of
fog volume and view. But it only allocated enough uniforms for one fog
volume per view.
## Testing
Ran the `volumetric_fog` example with 1/2/3/4 fog volumes. Also checked
the `fog_volumes` and `scrolling_fog` examples (without multiple
volumes). Win10/Vulkan/Nvidia.
To test multiple views I tried adding fog volumes to the `split_screen`
example. This doesn't quite work - the fog should be centred on the fox,
but instead it's centred on the window. Same result with and without the
PR, so I'm assuming it's a separate bug.

# Objective
Fixes#18095
## Solution
Update the feature gates so that `Taa`, etc are added if
- Not on wasm
- OR using webgpu
## Testing
Check that `Taa` is disabled with appropriate messaging on webgl2
```
cargo run -p build-wasm-example -- --api webgl2 transmission && basic-http-server examples/wasm/
```
Check that `Taa` works on webgpu in chrome
```
cargo run -p build-wasm-example -- --api webgpu transmission && basic-http-server examples/wasm/
```
Check that `Taa` still works in a native build
```
cargo run -example transmission
```
# Objective
The label added in #18064 is the wrong color! It should be an `M-`
(meta) label, not an `S-` (status) label!
## Solution
- Rename the label in the comment that gets left to
`M-Deliberate-Rendering-Change`
- Also make the job check for the right label 🤦🏽♀️
Once this is approved and ready to merge, I'll rename the label on
Github to match.
# Objective
As discussed in #14275, Bevy is currently too prone to panic, and makes
the easy / beginner-friendly way to do a large number of operations just
to panic on failure.
This is seriously frustrating in library code, but also slows down
development, as many of the `Query::single` panics can actually safely
be an early return (these panics are often due to a small ordering issue
or a change in game state.
More critically, in most "finished" products, panics are unacceptable:
any unexpected failures should be handled elsewhere. That's where the
new
With the advent of good system error handling, we can now remove this.
Note: I was instrumental in a) introducing this idea in the first place
and b) pushing to make the panicking variant the default. The
introduction of both `let else` statements in Rust and the fancy system
error handling work in 0.16 have changed my mind on the right balance
here.
## Solution
1. Make `Query::single` and `Query::single_mut` (and other random
related methods) return a `Result`.
2. Handle all of Bevy's internal usage of these APIs.
3. Deprecate `Query::get_single` and friends, since we've moved their
functionality to the nice names.
4. Add detailed advice on how to best handle these errors.
Generally I like the diff here, although `get_single().unwrap()` in
tests is a bit of a downgrade.
## Testing
I've done a global search for `.single` to track down any missed
deprecated usages.
As to whether or not all the migrations were successful, that's what CI
is for :)
## Future work
~~Rename `Query::get_single` and friends to `Query::single`!~~
~~I've opted not to do this in this PR, and smear it across two releases
in order to ease the migration. Successive deprecations are much easier
to manage than the semantics and types shifting under your feet.~~
Cart has convinced me to change my mind on this; see
https://github.com/bevyengine/bevy/pull/18082#discussion_r1974536085.
## Migration guide
`Query::single`, `Query::single_mut` and their `QueryState` equivalents
now return a `Result`. Generally, you'll want to:
1. Use Bevy 0.16's system error handling to return a `Result` using the
`?` operator.
2. Use a `let else Ok(data)` block to early return if it's an expected
failure.
3. Use `unwrap()` or `Ok` destructuring inside of tests.
The old `Query::get_single` (etc) methods which did this have been
deprecated.
# Objective
Documentation correction.
# Reasoning
The `GamepadAxis::RightZ` and `LeftZ` do not map to the trigger buttons
on a gamepad. They are in fact for the twisting/yaw of a flight Joystick
and throttle lever respectively. I confirmed this with two gamepads that
has analog triggers (Logitech F710, 8bitdo ultimate BT controller) and a
HOTAS joystick (Saitek X52).
# Objective
Fixes#18022
## Solution
Canonicalize asset paths
## Testing
I ran the examples `sprite`, `desk_toy` and `game_menu` with the feature
`file_watcher` enabled. All correctly updated an asset when the source
file was altered.
Co-authored-by: Threadzless <threadzless@gmail.com>
# Objective
Fixes#18027
## Solution
Run `redraw_requested` logic in `about_to_wait` on Windows during
initial application startup and when in headless mode
## Testing
- Ran `cargo run --example window_settings` to demonstrate invisible
window creation worked again and fixes#18027
- Ran `cargo run --example eased_motion` to demonstrate no regression
with the fix for #17488
Ran all additional `window` examples.
Notes:
- The `transparent_window` was not transparent but this appears to have
been broken prior to #18004. See: #7544
I noticed this while working on #18017 . Some of the `stderr`
compile_fail tests were updated while I generated the output for the new
tests I introduced in the mentioned PR.
I'm on rust 1.85.0
## Objective
`EntityCommands::trigger` internally uses `Commands::trigger_targets`,
which means it gets queued using `Commands::queue` rather
`EntityCommands::queue`. This previously wouldn't have made much
difference, but now entity commands check whether the entity exists, and
that check never happens in this case.
## Solution
- Add `entity_command::trigger`, which calls the same function as before
(`World::trigger_targets_with_caller`) but through the `EntityWorldMut`
passed to entity commands.
- Change `EntityCommands::trigger` to queue the new entity command
normally.
https://github.com/bevyengine/bevy/pull/17905 replaced `ChildOf(entity)`
with `ChildOf { parent: entity }`, but some deprecation advice was
overlooked. Also corrected formatting in documentation.
## Testing
Added a `set_parent` to a random example. Confirmed that the deprecation
warning shows and the advice can be pasted in.
# Objective
Fixes#17988
## Solution
Added two Debug impls to the `impl_ptr` macro - one for Aligned and one
for Unaligned.
## Testing
No tests have been added. Would a test guaranteeing debug layout be
appropriate?
---
## Showcase
The debug representation of a `Ptr<'_, Aligned>` follows. `PtrMut` and
`OwningPtr` are similar.
`Ptr<Aligned>(0x0123456789ab)`
# Objective
There are currently three ways to access the parent stored on a ChildOf
relationship:
1. `child_of.parent` (field accessor)
2. `child_of.get()` (get function)
3. `**child_of` (Deref impl)
I will assert that we should only have one (the field accessor), and
that the existence of the other implementations causes confusion and
legibility issues. The deref approach is heinous, and `child_of.get()`
is significantly less clear than `child_of.parent`.
## Solution
Remove `impl Deref for ChildOf` and `ChildOf::get`.
The one "downside" I'm seeing is that:
```rust
entity.get::<ChildOf>().map(ChildOf::get)
```
Becomes this:
```rust
entity.get::<ChildOf>().map(|c| c.parent)
```
I strongly believe that this is worth the increased clarity and
consistency. I'm also not really a huge fan of the "pass function
pointer to map" syntax. I think most people don't think this way about
maps. They think in terms of a function that takes the item in the
Option and returns the result of some action on it.
## Migration Guide
```rust
// Before
**child_of
// After
child_of.parent
// Before
child_of.get()
// After
child_of.parent
// Before
entity.get::<ChildOf>().map(ChildOf::get)
// After
entity.get::<ChildOf>().map(|c| c.parent)
```
# Objective
- Comment on PR when getting a rendering change
## Solution
- When something changes in the rendering check CI, add a comment on the
PR to check the results
- Suggest adding the label `S-Deliberate-Rendering-Change` if it's
expected
- Don't comment if the label is already present
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
## Objective
Alternative to #18001.
- Now that systems can handle the `?` operator, `get_entity` returning
`Result` would be more useful than `Option`.
- With `get_entity` being more flexible, combined with entity commands
now checking the entity's existence automatically, the panic in `entity`
isn't really necessary.
## Solution
- Changed `Commands::get_entity` to return `Result<EntityCommands,
EntityDoesNotExistError>`.
- Removed panic from `Commands::entity`.
# Objective
fixes#17896
## Solution
Change ChildOf ( Entity ) to ChildOf { parent: Entity }
by doing this we also allow users to use named structs for relationship
derives, When you have more than 1 field in a struct with named fields
the macro will look for a field with the attribute #[relationship] and
all of the other fields should implement the Default trait. Unnamed
fields are still supported.
When u have a unnamed struct with more than one field the macro will
fail.
Do we want to support something like this ?
```rust
#[derive(Component)]
#[relationship_target(relationship = ChildOf)]
pub struct Children (#[relationship] Entity, u8);
```
I could add this, it but doesn't seem nice.
## Testing
crates/bevy_ecs - cargo test
## Showcase
```rust
use bevy_ecs::component::Component;
use bevy_ecs::entity::Entity;
#[derive(Component)]
#[relationship(relationship_target = Children)]
pub struct ChildOf {
#[relationship]
pub parent: Entity,
internal: u8,
};
#[derive(Component)]
#[relationship_target(relationship = ChildOf)]
pub struct Children {
children: Vec<Entity>
};
```
---------
Co-authored-by: Tim Overbeek <oorbecktim@Tims-MacBook-Pro.local>
Co-authored-by: Tim Overbeek <oorbecktim@c-001-001-042.client.nl.eduvpn.org>
Co-authored-by: Tim Overbeek <oorbecktim@c-001-001-059.client.nl.eduvpn.org>
Co-authored-by: Tim Overbeek <oorbecktim@c-001-001-054.client.nl.eduvpn.org>
Co-authored-by: Tim Overbeek <oorbecktim@c-001-001-027.client.nl.eduvpn.org>
## Objective
`insert_by_id` is unsafe, but I forgot to add that to the
manually-queueable version in `entity_command`.
It also can only insert using `InsertMode::Replace`, when it could
easily be configurable by threading an `InsertMode` parameter to the
final `BundleInserter::insert` call.
## Solution
- Add `unsafe` and safety comment.
- Add `InsertMode` parameter to `entity_command::insert_by_id`,
`EntityWorldMut::insert_by_id_with_caller`, and
`EntityWorldMut::insert_dynamic_bundle`.
- Add `InsertMode` parameter to `entity_command::insert` and remove
`entity_command::insert_if_new`, for consistency with the other
manually-queued insertion commands.
# Objective
Fixes#17828
This fixes two bugs:
1. Exclusive systems should see the effect of all commands queued to
that point. That does not happen when the system is configured with
`*_ignore_deferred` which may lead to surprising situations. These
configurations should not behave like that.
2. If `*_ignore_deferred` is used, no sync point may be added at all
**after** the config. Currently this can happen if the last nodes in
that config have no deferred parameters themselves. Instead, sync points
should always be added after such a config, so long systems have
deferred parameters.
## Solution
1. When adding sync points on edges, do not consider
`AutoInsertApplyDeferredPass::no_sync_edges` if the target is an
exclusive system.
2. when going through the nodes in a directed way, store the information
that `AutoInsertApplyDeferredPass::no_sync_edges` suppressed adding a
sync point at the target node. Then, when the target node is evaluated
later by the iteration and that prior suppression was the case, the
target node will behave like it has deferred parameters even if the
system itself does not.
## Testing
I added a test for each bug, please let me know if more are wanted and
if yes, which cases you would want to see.
These tests also can be read as examples how the current code would
fail.
# Objective
- Fixes#17642
## Solution
- Implemented method `new_bezier(points: [P; 4]) -> Self` for
`CubicSegment<P>`
- Old implementation of `new_bezier` is now `new_bezier_easing(p1: impl
Into<Vec2>, p2: impl Into<Vec2>) -> Self` (**breaking change**)
- ~~added method `new_bezier_with_anchor`, which can make a bezier curve
between two points with one control anchor~~
- added methods `iter_positions`, `iter_velocities`,
`iter_accelerations`, the same as in `CubicCurve` (**copied code,
potentially can be reduced)**
- bezier creation logic is moved from `CubicCurve` to `CubicSegment`,
removing the unneeded allocation
## Testing
- Did you test these changes? If so, how?
- Run tests inside `crates/bevy_math/`
- Tested the functionality in my project
- Are there any parts that need more testing?
- Did not run `cargo test` on the whole bevy directory because of OOM
- Performance improvements are expected when creating `CubicCurve` with
`new_bezier` and `new_bezier_easing`, but not tested
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- Use in any code that works created `CubicCurve::new_bezier`
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
- I don't think relevant
---
## Showcase
```rust
// Imagine a car goes towards a local target
// Create a simple `CubicSegment`, without using heap
let planned_path = CubicSegment::new_bezier([
car_pos,
car_pos + car_dir * turn_radius,
target_point - target_dir * turn_radius,
target_point,
]);
// Check if the planned path itersect other entities
for pos in planned_path.iter_positions(8) {
// do some collision checks
}
```
## Migration Guide
> This section is optional. If there are no breaking changes, you can
delete this section.
- Replace `CubicCurve::new_bezier` with `CubicCurve::new_bezier_easing`
# Objective
`QueryIter::sort_by()` is unsound. It passes the lens items with the
full `'w` lifetime, and a malicious user could smuggle them out of the
closure where they could alias with the query results.
## Solution
Make the sort closures generic in the lifetime parameter of the lens
item. This ensures the lens items cannot outlive the call to the
closure.
## Testing
Added a compile-fail test that demonstrates the unsound pattern.
## Migration Guide
The `sort` family of methods on `QueryIter` unsoundly gave access
`L::Item<'w>` with the full `'w` lifetime. It has been shortened to
`L::Item<'w>` so that items cannot escape the comparer. If you get
lifetime errors using these methods, you will need to make the comparer
generic in the new lifetime. Often this can be done by replacing named
`'w` with `'_`, or by replacing the use of a function item with a
closure.
```rust
// Before: Now fails with "error: implementation of `FnMut` is not general enough"
query.iter().sort_by::<&C>(Ord::cmp);
// After: Wrap in a closure
query.iter().sort_by::<&C>(|l, r| Ord::cmp(l, r));
query.iter().sort_by::<&C>(comparer);
// Before: Uses specific `'w` lifetime from some outer scope
// now fails with "error: implementation of `FnMut` is not general enough"
fn comparer(left: &&'w C, right: &&'w C) -> Ordering { /* ... */ }
// After: Accepts any lifetime using inferred lifetime parameter
fn comparer(left: &&C, right: &&C) -> Ordering { /* ... */ }
# Objective
So far, built-in BRP methods allow users to interact with entities'
components, but global resources have remained beyond its reach. The
goal of this PR is to take the first steps in rectifying this shortfall.
## Solution
Added five new default methods to BRP:
- `bevy/get_resource`: Extracts the value of a given resource from the
world.
- `bevy/insert_resource`: Serializes an input value to a given resource
type and inserts it into the world.
- `bevy/remove_resource`: Removes the given resource from the world.
- `bevy/mutate_resource`: Replaces the value of a field in a given
resource with the result of serializing a given input value.
- `bevy/list_resources`: Lists all resources in the type registry with
an available `ReflectResource`.
## Testing
Added a test resource to the `server` example scene that you can use to
mess around with the new BRP methods.
## Showcase
Resources can now be retrieved and manipulated remotely using a handful
of new BRP methods. For example, a resource that looks like this:
```rust
#[derive(Resource, Reflect, Serialize, Deserialize)]
#[reflect(Resource, Serialize, Deserialize)]
pub struct PlayerSpawnSettings {
pub location: Vec2,
pub lives: u8,
}
```
can be manipulated remotely as follows.
Retrieving the value of the resource:
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "bevy/get_resource",
"params": {
"resource": "path::to::my::module::PlayerSpawnSettings"
}
}
```
Inserting a resource value into the world:
```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "bevy/insert_resource",
"params": {
"resource": "path::to::my::module::PlayerSpawnSettings",
"value": {
"location": [
2.5,
2.5
],
"lives": 25
}
}
}
```
Removing the resource from the world:
```json
{
"jsonrpc": "2.0",
"id": 3,
"method": "bevy/remove_resource",
"params": {
"resource": "path::to::my::module::PlayerSpawnSettings"
}
}
```
Mutating a field of the resource specified by a path:
```json
{
"jsonrpc": "2.0",
"id": 4,
"method": "bevy/mutate_resource",
"params": {
"resource": "path::to::my::module::PlayerSpawnSettings",
"path": ".location.x",
"value": -3.0
}
}
```
Listing all manipulable resources in the type registry:
```json
{
"jsonrpc": "2.0",
"id": 5,
"method": "bevy/list_resources"
}
```
# Objective
Refactor `bevy_gltf`, the criteria for the split is kind of arbitrary
but at least it is not a 2.6k line file.
## Solution
Move methods and structs found in `bevy_gltf/loader.rs` into multiple
new modules.
## Testing
`cargo run -p ci`
# Objective
- Systems that use the task pool, either explicitly or implicitly using
parallel queries, will often end up executing tasks from different
systems.
- This can cause random tasks to block the main or render schedule at
random, adding frame variance and increasing frame times when CPU bound.
- This profile is a common occurrence on `main`.
`propagate_parent_transforms` takes more than twice as long as it
should, blocking the main schedule for that time, because it uses `task
pool.scope`, which has decided to execute tasks from the render schedule
on the main schedule.

## Solution
- In task pool scope execution, prefer to check if the current task is
complete instead of ticking the executor to find new work.
## Testing
- Ran the scene viewer with tracy to look for images like the one in the
objective section.
- Things look much, much better, and I could not find any occurrences:


# Objective
- Fixes#16416
## Solution
- Add a intermediate temporary mutable `RequiredComponents` to get avoid
of the borrowing issues.
## Testing
- I have run `cargo test --package bevy_ecs -- --exact --show-output`
and past all the tests.
# Objective
- Attempts to fix#17876.
## Solution
- Reverted some changes that added a glob pattern to match all
`compile_fail` crates. This should enable Dependabot to create PRs
again.
- Added a TODO comment to not forget that this glob matching failure
should also be fixed in the Dependabot repo.
## Objective
The closure argument for
`EntityClonerBuilder::without_required_components` has `Send + Sync +
'static` bounds, but the closure immediately gets called and never needs
to be sent anywhere. (This was my fault :P )
## Solution
Remove the bounds so that users aren't unnecessarily restricted.
I also took the opportunity to expand the tests a little.
# Objective
- next step for #15918
## Solution
- Move jobs for macOS, Linux and Windows to their own workflow
- Remove running on push to `main` from workflows CI and validation
# Objective
This prevents overflowing the `last_trigger_id` property that leads to a
panic in debug mode.
```bash
panicked at C:\XXX\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.15.2\src\world\unsafe_world_cell.rs:630:18:
attempt to add with overflow
Encountered a panic when applying buffers for system `bevy_sprite::calculate_bounds_2d`!
Encountered a panic in system `bevy_ecs::schedule::executor::apply_deferred`!
```
## Solution
As this value is only used for detecting a change, we can wrap when it
reaches max value.
## Testing
This can be verified by running `cargo run --example observers`
# Objective
Closes#17572
## Solution
Add the `add_one_related` methods to `EntityCommands` and
`EntityWorldMut`.
## Testing
Clippy
---
## Showcase
The `EntityWorldMut` and `FilteredResourcesMut` now include the
`add_one_related` method if you just want to relate 2 entities.
# Objective
It's not always obvious when the issue created by the weekly CI run is
safe to close.
## Solution
Automatically close it when a weekly CI run succeeds so it doesn't get
forgotten.
## Testing
Hope.
Currently, we reload a glTF skin each time we encounter a node that
references it. By checking for duplicates, PR #18013 turned this into a
fatal error. But this was always wasteful. This commit fixes the issue
by caching each skin by its index as we load it.
The Maya babylon.js export plugin likes to emit glTFs with multiple
nodes that reference the same skin, so this effectively unbreaks Maya
rigs.
# Objective
* Fixes https://github.com/bevyengine/bevy/issues/14074
* Applies CI fixes for #16326
It is currently not possible to issues a trigger that targets a specific
list of components AND a specific list of entities
## Solution
We can now use `((A, B), (entity_1, entity_2))` as a trigger target, as
well as the reverse
## Testing
Added a unit test.
The triggering rules for observers are quite confusing:
Triggers once per entity target
For each entity target, an observer system triggers if any of its
components matches the trigger target components (but it triggers at
most once, since we use an internal counter to make sure that an
observer can run at most once per entity target)
(copied from #14563)
(copied from #16326)
## Notes
All credit to @BenjaminBrienen and @cBournhonesque! Just applying a
small fix to this PR so it can be merged.
---------
Co-authored-by: Benjamin Brienen <Benjamin.Brienen@outlook.com>
Co-authored-by: Christian Hughes <xdotdash@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Makes #18010 more easily debuggable. This doesn't solve that issue,
but protects us from it in the future.
## Solution
- Make `LoadContext::add_labeled_asset` and friends return an error if
it finds a duplicate asset.
## Testing
- Added a test - it fails before the fix.
---
## Migration Guide
- `AssetLoader`s must now handle the case of a duplicate subasset label
when using `LoadContext::add_labeled_asset` and its variants. If you
know your subasset labels are unique by construction (e.g., they include
an index number), you can simply unwrap this result.
Even though opaque deferred entities aren't placed into the `Opaque3d`
bin, we still want to cache them as though they were, so that we don't
have to re-queue them every frame. This commit implements that logic,
reducing the time of `queue_material_meshes` to near-zero on Caldera.
Currently, the structure-level `#[uniform]` attribute of `AsBindGroup`
creates a binding array of individual buffers, each of which contains
data for a single material. A more efficient approach would be to
provide a single buffer with an array containing all of the data for all
materials in the bind group. Because `StandardMaterial` uses
`#[uniform]`, this can be notably inefficient with large numbers of
materials.
This patch introduces a new attribute on `AsBindGroup`, `#[data]`, which
works identically to `#[uniform]` except that it concatenates all the
data into a single buffer that the material bind group allocator itself
manages. It also converts `StandardMaterial` to use this new
functionality. This effectively provides the "material data in arrays"
feature.
# Objective
Continuation of #17589 and #16547.
`get_many` is last of the `many` methods with a missing `unique`
counterpart.
It both takes and returns arrays, thus necessitates a matching
`UniqueEntityArray` type!
Plus, some slice methods involve returning arrays, which are currently
missing from `UniqueEntitySlice`.
## Solution
Add the type, the related methods and trait impls.
Note that for this PR, we abstain from some methods/trait impls that
create `&mut UniqueEntityArray`, because it can be successfully
mem-swapped. This can potentially invalidate a larger slice, which is
the same reason we punted on some mutable slice methods in #17589. We
can follow-up on all of these together in a following PR.
The new `unique_array` module is not glob-exported, because the trait
alias `unique_array::IntoIter` would conflict with
`unique_vec::IntoIter`.
The solution for this is to make the various `unique_*` modules public,
which I intend to do in yet another PR.
# Objective
Fixes#17945
## Solution
Check if the view being extracted has OIT enabled and incorporate the
associated bit into the mesh pipeline key.
I basically have no idea what's going on in the renderer, so let me know
if I missed something, which is extraordinarily possible.
## Testing
I modified the `order_independent_transparency` example to put
everything on the default render layer and render a gizmo at the origin.
Previously, this would cause the application to panic.