# Objective
Support an arbitrary number of `Scene` entries (ex: component patches)
in the `bsn!` macro.
## Solution
Auto nest the resulting `bsn!` tuple.
# Objective
Make the behavior of `World::remove_resource` and
`World::remove_resource_by_id` consistent. Currently, `remove_resource`
will leave the entity in the `ResourceEntities` map so that
re-initializing the resource keeps the same `Entity`, but
`remove_resource_by_id` will remove it from the map.
## Solution
Change `remove` to `get` in `remove_resource_by_id`.
## Testing
Updated the existing unit test to ensure that re-initializing the
resource keeps the same `Entity`.
# Objective
- Improve macro hygiene.
## Solution
- Use absolute paths in ECS macros.
## Testing
- `cargo run -p ci -- compile`
## Note
- The `SettingsGroup` derive is unhygienic (bare `impl SettingsGroup for
...`). I tried prepending the path from `BevyManifest` and adding
`extern crate self as bevy_settings` to `bevy_settings`'s lib. This
worked for the unit tests in `bevy_settings`, but the examples using
`bevy_settings` failed to resolve the path. I haven't investigated
further to keep this PR simple, but I can open an issue for fixing the
hygiene of `#[derive(SettingsGroup)]`.
- Many other macros in Bevy don't use absolute paths as much as they
could, such as in `bevy_reflect`. I'll open another PR if this one is
accepted.
# Objective
Reduce memory usage for resources, and maybe improve performance of
resource lookups.
Related to #23039, but not a solution.
## Solution
Change `ResourceEntities` from a `SparseSet` to a `SparseArray`.
`SparseArray` is `pub (crate)`, so simply exposing it through `Deref`
would cause privacy errors. Instead, remove the `Deref` impl and add
wrapper methods for `iter`, `get`, and `remove`. Change the return types
from `&Entity` to `Entity` now that they aren't generic.
As background: A `SparseArray` is a simple `Vec<Option<V>>`, while a
`SparseSet` is a `SparseArray` that maps keys to dense indexes, combined
with dense arrays of keys and values. That requires a second array
operation to find the actual value, but can be much better for memory
usage when the values are large, since missing items only take up space
for a single index instead of an entire value.
But the values in `ResourceEntities` are `Entity`, which are already
small! A `SparseArray` will always be smaller on 64-bit systems, since
an `Entity` is the same size as a `usize`, and we don't need to store
the additional `dense` and `indices` arrays. So switching to
`SparseArray` will save a lookup *and* save memory.
One drawback is that we can no longer use the dense lists to iterate all
resources, so methods like `iter_resources` now need to scan all
component ids. I don't expect this to be a problem in practice, though.
`iter_resources` is rarely used, and O(components) isn't all that much
worse than O(resources). If it turns out to be an issue, it's also
possible to recover this data by querying the `IsResource` component.
## Testing
Inconclusive.
I attempted to run benchmarks, both `bevymark` as in the linked issue
and `cargo bench -p benches --bench ecs`, but the results were too noisy
on my machine to reach any conclusions. And now that I look more
closely, we don't have many benches that even use resources!
---------
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
# Objective
Add constructors for making `BevyError`s with a specific severity.
Closes#23676.
## Solution
Add a `new` constructor plus 1 constructor for every possible
`Severity`.
## Testing
My eyes and a simple test case that constructs an error and tests if the
downcasting works.
---
## Showcase
A `BevyError` now has multiple constructor to create one with an
expected severity
```rust
use bevy::ecs::error::{BevyError, Severity};
let debug_error = BevyError::new(Severity::Debug, "This works with strings");
let warn_error = BevyError::warn("There's a constructor for each severity level");
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Ben Frankel <ben.frankel7@gmail.com>
# Objective
The aim is to simplify the example somewhat. This also removes the
jitter that some experience when running the example.
Fixes#14239Fixes#2349
## Solution
Use `Update` instead of `FixedUpdate` schedule.
## Testing
```sh
cargo run --example breakout
```
and
```sh
cargo run --features bevy_debug_stepping --example breakout
```
# Objective
Feathers text input widget
Part of #19236
## Solution
Build a wrapper around `EditableText` that has feathers styling and
themes.
## Testing
WiP
---------
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
# Objective
- In the asset pack used for bevy_city the tires of all the cars are
separate meshes from the car body. In some of the cars even the doors
are also separate meshes.
- Since we don't animate these elements of the car we can trivially
combine all the meshes of each car scene into one single car mesh. This
helps a lot to keep performance manageable and eventually increase the
scale of bevy_city.
## Solution
- Wait for the assets to load and once they are loaded loop over all the
car scenes and combine their meshes. This is mainly possible because the
entire asset pack uses a single texture so we don't need a separate
material for each part of the mesh.
- To do this I also refactored a bit how each step happens when starting
the app. I also made sure that each step is reflected on the loading
screen.
- I also added a bit more docs
## Testing
- I ran bevy_city and confirmed that the tires are where they should be
relative to the mesh and that performance was better. I went from 90fps
to 112fps on my machine
---
## Showcase
https://github.com/user-attachments/assets/c2a10681-d148-4394-a3ca-fffe928fa09c
# Objective
* Parley's `GlyphRun::positioned_glyphs()` doesn't emit byte indices,
the byte_index and byte_length on `PositionedGlyph` aren't set to the
correct values.
* The `line_index` is set from an enumeration on the inner loop in
`editable_text_system` but it's the outer loop that iterates per line.
## Solution
* Remove the `byte_index` and `byte_length` fields from
`PositionedGlyph`.
* Enumerate the outer loop in `editable_text_system`.
# Objective
Sometimes being generic on the scene type isn't desirable (ex: `field:
Option<S: Scene>` requires defining `S`, even if you aren't setting the
scene).
Being able to erase scene types while still using them in scenes is
critical functionality.
## Solution
- Impl `Scene` for `Box<dyn Scene>`
- Impl `SceneList` for `Box<dyn SceneList>`
(I also snuck in a minor unrelated style fix. Forgive me 😄 )
# Objective
A lot of Bevy's built in types don't derive FromTemplate, which is what
makes things like asset handles "templatable" in BSN:
```rust
bsn! {
ImageNode { image: "path_to_image.png" }
}
```
## Solution
Derive `FromTemplate` for components that have handles.
In cases of fields with `Option<SOME_TEMPLATED_TYPE>`, I've added the
`#[template(OptionTemplate<XTemplate>)]` attribute, as these cases can't
use the blanket `Default + Clone` template implementation (which doesn't
do templating on the internal type). Later I'm likely to propose
something like `#[template(built_in)]` for standard "collection types"
to make this a little less boilerplatey.
# Objective
We want to use `World::run_system` where possible - especially in older
code that did not have the benefit of using it when it was written.
This is a small step towards #23238. More work is needed on the unit
tests and possibly elsewhere if this approach has been verified.
## Solution
- Instead of `SystemState` I used a closure system and registered it.
- I called the registered system with `World::run_system` inside the
bench.
## Testing
I ran the benches effected and found that they did not regress on my
machine.
Quick check:
```sh
cargo bench -p benches --bench ecs -- 50000_entities_table
```
# Objective
The design and purpose of `SparseSet` is not immediately obvious, and
there is very little documentation explaining it.
## Solution
Write more doc comments for `SparseSet` and `SparseArray`.
## Objective
Allow crates other than `bevy_asset` to derive `VisitAssetDependencies`
- previously it was private.
`VisitAssetDependencies` is useful when an asset contains non-asset
types with dependencies:
```rust
#[derive(Asset)]
struct AssetStruct(#[dependency] NonAssetStruct)
#[derive(VisitAssetDependencies)]
struct NonAssetStruct(#[dependency] Handle<Image>);
```
There are workarounds - `NonAssetStruct` could derive `Asset` instead,
or it could manually implement the `VisitAssetDependencies` trait. But
exposing `VisitAssetDependencies` seems the simplest solution.
## Solution
```diff
-pub use bevy_asset_macros::Asset;
+pub use bevy_asset_macros::{Asset, VisitAssetDependencies};
```
## Testing
The PR adds a compilation test.
```sh
cargo test -p bevy_asset
```
# Objective
`EditableText`'s selection rects are currently drawn on top of the text.
Instead they should be drawn below with an option to draw the selected
text in an alternative color.
## Solution
* New field on `selected_text_color: Option<Color>` on
`TextCursorStyle`.
* In `extract_text_sections`, if `selected_text_color` is `Some` and the
glyph is inside a selection rect, use `selected_text_color` to draw the
glyph.
* The z offset for text selection rects is changed so the selection
rects are drawn behind the glyphs.
## Testing
```
cargo run --example multiline_text_input
```
---------
Co-authored-by: Daniel Skates <zeophlite@gmail.com>
# Objective
- Once PR #23651 is merged we need a migration guide for breaking
changes to Bevy's atmosphere.
- Post the release note changes as a new PR to review grammar/writing
separately
## Solution
- Write a migration guide detailing the breaking changes
- Adhere to a friendly non-technical tone
- Explain the new way of scaling the atmosphere with `Transform`
## Out of scope
- Explain how to customize the apparent up axis (i.e. horizon's
orientation) -> this should follow intuitively but maybe I should add
this too? or maybe this belongs in a release note instead?
# Objective
Enable the use of `NotShadowReceiver` in `bsn!` by implementing `Clone`
(`Default` is already implemented).
```rust
error[E0277]: the trait bound `NotShadowReceiver: Clone` is not satisfied
--> src/spawn_circle.rs:375:27
|
375 | world.spawn_scene(bsn! {
| ___________________________^
376 | | #SpawnCircle
377 | | SpawnCircle
378 | | SpawnEventToTrigger({self.event})
... |
394 | | )]
395 | | });
| |_________^ the trait `Clone` is not implemented for `NotShadowReceiver`
|
```
I also noticed `TransmittedShadowReceiver` would have the same issue, so
added `Clone` there as well.
---
An alternative would be to implement `FromTemplate` instead of `Default`
and `Clone`. I'm not sure which solution is preferred in general, but
these are Marker components so don't require any additional values.
# Objective
- Fixes#23643
- Some methods for BRP have `params` as an `Option`. `id` itself also
seems to be an `Option`. If these are not provided in the request
object, it should not panic on the deserialization level. Individual
methods should handle it, and they do already when its necesssary.
## Solution
- during deserialization, `params` and `id` should just flatten the
nested `Option` instead of `unwrap` and assuming something is there
## Testing
- Wrote a regression test
- Tested executing a curl while the `server` example without params, and
it works
`curl -d'{"jsonrpc":"2.0","method":"world.list_components","id":1}' -X
POST -H "Accept: applcation/json" -H "Content-Type: application/json"
http://127.0.0.1:15702`
- Tested `schedule.graph` to ensure that it panics without params
provided on its own (it does) and that params are still read correctly
when provided (it does)
# Objective
- Fixes#22822
## Solution
- Adds ALLOW_SAME_STATE_TRANSITIONS = false to ComputedStates in
computed_states example
## Testing
- Tested by running example on x86_64 Linux 4.19 + KDE. Behavior noted
in #22822 no longer occurs.
---------
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
# Objective
**Anecdotal feedback:**
- no floating origin support for implementing large-scale worlds, forked
Bevy's atmosphere at
https://github.com/philpax/veldera/blob/main/crates/bevy_pbr_atmosphere_planet/NOTICE.md
- no custom up axis support, resorted to using a custom sky shader for
flight simulator with Z up coordinate system. Bevy's atmosphere appears
tilted at a 90 degree angle with no way of changing it.
## Solution
- Atmosphere component can be spawned stand-alone
- AtmosphereSettings remains on camera
- A closest-to-camera heuristic is used to pick the primary atmosphere
to render. Deliberately no multi-atmosphere support to keep the scope of
this PR small and self contained. See
https://github.com/mate-h/bevy/pull/19 at an attempt.
- `scene_units_to_m` removed in favor of using `Transform`
- Z up now possible by offsetting the viewer position to the equator
- Floating origin systems now possible
- Simplify the `AtmosphereBuffer` / `AtmosphereData` structs to just use
the plain extracted `GpuAtmosphere` struct. this reduces the complexity
of the struct in the mesh view bindings. Since atmosphere settings is
coupled with the rendering pipeline of the atmosphere this makes sense
architecturally.
- We no longer hard code the offset to the north pole from the planet
center in places.
**Why not multi atmosphere:**
The atmosphere uses multiple LUTs (lookup textures) to accelerate the
rendering performance. Some of them are not view dependent:
- Transmittance LUT
- Multiple scattering LUT
- Scattering / density LUTs
These can be coupled and rendered for each atmosphere individually.
However the remainder of the pipeline is view dependent:
- Aerial View LUT
- Sky View LUT
- Render Sky pass
In raymarched rendering mode, these LUTs can be skipped and only the
render sky pass runs sampling on all of the atmospheres with a raymarch
in screen space.
Further, the Sky View LUT uses a local reference frame to concentrate
texel density along the horizon's local up axis. This in turn means it's
coupled with both a _specific_ atmosphere's local coordinates as well as
the view's transform matrix. We cannot consider rendering both
atmospheres into a single LUT for this reason. So it has to be unique
for each pair of (view, atmosphere). Given two views and two atmospheres
we would need 4 of these Sky View LUTs and at some point, raymarched
rendering will become the less expensive option.
Lastly the Render Sky pass needs to happen once per view, we cannot
realistically composite them in sequence with simple dual-source
blending as we do with the scene, this would result in incorrect
scattering integration. This in turn means we need to bind ALL of the
luts calculated previously so a single render sky pass and render aerial
view lut - perhaps making use of array textures. Rely on unified
volumetric ingegration in the raymarching loop: for each light,for each
atmosphere, attenuate inscattering and transmittance along the path
integral. It is suffice to say this change is overall _too complex_ for
the time being and is likely the reason Unreal Engine also do not
support multiple atmospheres. For context: our research is based heavily
on Sebastian Hillarie's work, one of the Unreal graphics engineers.
That being said about multiple atmospheres - I am thinking of this PR as
a segway into unified volumetrics in Bevy. that is: Render the FogVolume
and Atmosphere in a single pass! Making use of the frustum aligned voxel
grid "froxel" approach to accelerate the rendering. This would
drastically increase the performance for scenes wanting to make use of
both the atmosphere and local fog volumes.
## Testing
- Ran the `examples/3d/atmosphere.rs` example.
---
## Showcase
(example screenshot unchanged compared to main.)
```rs
// Spawn earth atmosphere
commands.spawn(Atmosphere::earth(earth_medium));
commands.spawn((
Camera3d::default(),
// Can be adjusted to change the rendering quality
AtmosphereSettings::default(),
));
```
---------
Co-authored-by: Emerson Coskey <emerson@coskey.dev>
# Objective
- A step towards #10981.
- Allow us to extract data from an app about the schedules.
Here are also some **non-goals** for this PR. These are left as future
work:
- Extract every piece of data in the schedule. I've focused on a rough
set of information that should let us visualization the most important
parts.
- Provide utilities for interpreting the data. This PR is focused on
just extracting the data, interpreting it comes next.
- Any sort of dot graph tools.
## Solution
- Create ser/de compatible structs for representing schedule data.
- Create a function to get schedule data from an initialized `Schedule`.
- Create a plugin to automatically extract the schedule data for every
schedule in the `App`.
- Note this doesn't include other subapps, I'll also leave that to
another PR.
- Make `bevy_ecs` return edges that build passes added.
- Make `bevy_ecs` return the "build metadata" to the caller, and also
trigger as an event.
## Testing
- Added tests!
- Added an example - it outputs a ron file. I assume its all valid.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
# Objective
Reduce the size of the `target` directory with Bevy builds.
## Solution
I found this
[blog](https://kobzol.github.io/rust/rustc/2025/06/02/reduce-cargo-target-dir-size-with-z-no-embed-metadata.html)
about `-Zno-embed-metadata`, Cargo flag that reduces the size of the
`target` directory by avoiding duplicate metadata or something.
## Testing
I compiled the `main` branch with and without this branch and the size
of the `target` directory went from 11.61G without the flag to 11.15G
with the flag. Not a huge difference, but still a 4% decrease.
# Objective
`template_value` is not in the prelude, but seems useful enough to be.
It seems like the main way to include an existing component value in a
`bsn!` declaration since using `{transform}` and similar expressions
doesn't work.
```rust
// some Transform, maybe from an `In<Transform>` or other argument.
let transform = Transform::from_xyz(5., 0., 5.);
bsn! {
#SomeThing
template_value(transform)
}
```
## Solution
Add `template_value` to the prelude.
# Objective
Attempt to fix a performance regression from adding the `ComponentSet`
type in #23384. See #23464.
## Solution
Add `#[inline]` attributes to the new trait impls. I had added them to
the inherent methods, but forgot about the traits!
## Testing
I have not tested this at all, so I don't know whether it will actually
fix the issue! I don't even understand how #23384 could have affected
those benchmarks in the first place, since they don't seem to call any
methods on `Access` during the loop.
But these trait methods all simply delegate to methods on `FixedBitSet`,
so marking them `#[inline]` seems harmless at worst.
# Objective
- Partially addresses
https://discord.com/channels/691052431525675048/749332104487108618/1489425547598762095
- Currently BSN will attempt to load a string whenever a handle is seen.
Unfortunately, BSN treats nothing to mean the empty string. The asset
system then tries to load the empty string and returns various unhelpful
error messages depending on your OS.
- This doesn't totally fix the issue - BSN should probably not be
loading these paths at all. But more generally the asset system should
just ignore empty paths entirely since it should never load a meaningful
path.
## Solution
- In every load variant, add a check for the empty path and log an error
or return an error in that case. We also return a default handle in that
case (where necessary).
- Intentionally don't handle `load_folder`. You could theoretically want
to load the root folder!
To address some alternative implementations:
- There isn't a common loading API that all roads lead to! Each one is a
little different, so we need to handle them in each case. We should
investigate collapsing some of these though.
- `AssetPath` still needs to be allowed to parse an empty path, since
for stuff like joining asset paths, that needs to support cases like
"only a subasset label", or "joining the empty path with some subdir
path".
## Testing
- Added a test to test all the load variants on `AssetServer`.
# Objective
- Show how a Bevy app can be automated through BRP
## Solution
- Example app_under_test is a basic app with a randomly placed button.
when the button is clicked, the app quit
- Example automated_test click that button through BRP using
`WindowEvent` so that it goes through the whole of Bevy
## Testing
- Run both example and they both exit
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
# Objective
- https://github.com/bevyengine/bevy/pull/23446/changes#r3036236068
spotted that we enable reflect in render unnecessarily
## Solution
- Remove it
## Testing
- CI
- `cargo run --example server --features="bevy_remote"` + `curl
-d'{"jsonrpc":"2.0","method":"schedule.graph","id":1,"params":{"schedule_label":"Render"}}'
-X POST -H "Accept: applcation/json" -H "Content-Type: application/json"
http://127.0.0.1:15703` still works
# Objective
Add basic support for scrolling text horizontally and vertically to
EditableText.
## Solution
* New component `TextScroll`. Wraps a Vec2 offset that can be used to
set the scroll position.
* Clip overflowing editable text content automatically.
* New system `scroll_editable_text` sets `TextScroll` to keep the cursor
within view inside the `EditableText`'s content box.
* New `allow_newline` flag on `EditableText`. Allows insertion of
newlines with the enter key.
* `editable_text_system` previously ignored `TextLayout::linebreak`. Now
it's possible to change the line break settings.
* Scrolling only happens after a `TextEdit` is applied.
The implementation here is extremely simple but it has some flaws:
* Depending on the width of the node sometimes the cursor can get
clipped.
* `allow_newlines: false` doesn't block pasting in a section of text
with a newline
* No support for scroll margins yet.
* Drag-to-scroll seems to work, but I'm not super confident in it and it
may need some changes.
Went back and forth over whether `ScrollPosition` should be used instead
of a dedicated component, I think it's probably simpler with
`TextScroll` but not certain. Clipping doesn't use `Node`'s overflow API
and is handled automatically during extraction, always targeting the
content box.
## Testing
```
cargo run --example multiline_text_input
```
# Objective
- Example `editable_text` crashes because of duplicated plugins
## Solution
- Remove the duplicated plugins
## Testing
- `cargo run -example editable_text`
# Objective
- Not setting any value to a handle in BSN results in BSN attempting to
load an empty path! This is not handled well (see #23654 for some fixes
there).
- Even with #23654, we would still get errors in the logs which is not
ideal.
## Solution
- Use the Handle variant for the template!
# Objective
- Make it possible to enable `bevy_remote` feature on wasm target
without the `bevy_remote/http` feature (which doesn't compile on wasm),
thus allowing to use the transport-agnostic `RemotePlugin`.
- Retain behavior of `bevy_remote` having the `bevy_remote/http` feature
by default on non-wasm targets, so no breaking changes for users.
## Solution
- Disable default features (so no `http`) in
`bevy_internal/bevy_remote`.
- Enable default features (including `http`) on non-wasm builds in
`bevy_internal/bevy_remote`.
- Fix `bevy_remote` having some dependencies only used by the HTTP
transport (and not wasm-compatible) not under the `http` feature flag.
## Testing
Tested locally with a temporary example not included in this PR that
enabled `bevy_remote`, added `RemotePlugin` but not `RemoteHttpPlugin`,
and verified that it compiled for both native and wasm targets, as well
as building the other bevy_remote examples on native.
---
Try yourself by creating a new crate with the following dependencies on
`Cargo.toml`:
```toml
[dependencies]
bevy = { git = "https://github.com/splo/bevy.git", branch = "fix-bevy_remote-wasm", features = [
"bevy_remote",
] }
```
Add the following to `main.rs`:
```rust
use bevy::{prelude::*, remote::RemotePlugin};
fn main() {
App::new().add_plugins(DefaultPlugins).add_plugins(RemotePlugin::default()).run();
}
```
And build both for native and wasm targets to verify it compiles
successfully.
```shell
cargo build --target wasm32-unknown-unknown # Fails on main branch.
cargo build
```
Part 2 of #23619
In **Bevy 0.19** we are landing a subset of Bevy's Next Generation Scene
system (often known as BSN), which now lives in the `bevy_scene` /
`bevy::scene` crate. However the old `bevy_scene` system still needs to
stick around for a bit longer, as it provides some features that Bevy's
Next Generation Scene system doesn't (yet!):
1. It is not _yet_ possible to write a World _to_ BSN, so the old system
is still necessary for "round trip World serialization".
2. The GLTF scene loader has not yet been ported to BSN, so the old
system is still necessary to spawn GLTF scenes in Bevy.
For this reason, we have renamed the old `bevy_scene` crate to
`bevy_world_serialization`. If you were referencing `bevy_scene::*` or
`bevy::scene::*` types, rename those paths to
`bevy_world_serialization::*` and `bevy::world_serialization::*`
respectively.
Additionally, to avoid confusion / conflicts with the new scene system,
all "scene" terminology / types have been reframed as "world
serialization":
- `Scene` -> `WorldAsset` (as this was always just a World wrapper)
- `SceneRoot` -> `WorldAssetRoot`
- `DynamicScene` -> `DynamicWorld`
- `DynamicScene::from_scene` -> `DynamicWorld::from_world_asset`
- `DynamicSceneBuilder` -> `DynamicWorldBuilder`
- `DynamicSceneRoot` -> `DynamicWorldRoot`
- `SceneInstanceReady` -> `WorldInstanceReady`
- `SceneLoader` -> `WorldAssetLoader`
- `ScenePlugin` -> `WorldSerializationPlugin`
- `SceneRootTemplate` -> `WorldAssetRootTemplate`
- `SceneSpawner` -> `WorldInstanceSpawner`
- `SceneFilter` -> `WorldFilter`
- `SceneLoaderError` -> `WorldAssetLoaderError`
- `SceneSpawnError` -> `WorldInstanceSpawnError`
Note that I went with `bevy_world_serialization` over
`bevy_ecs_serialization`, as that is what all of the internal features
described themselves as. I think it is both more specific and does a
better job of making itself decoupled from `bevy_ecs` proper.
Bumps
[dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from
efa25f7f19611383d5b0ccf2d1c8914531636bf9 to
3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/dtolnay/rust-toolchain/commit/3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9"><code>3c5f7ea</code></a>
Add 1.94.1 patch release</li>
<li>See full diff in <a
href="https://github.com/dtolnay/rust-toolchain/compare/efa25f7f19611383d5b0ccf2d1c8914531636bf9...3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Objective
Need serde(Default) for Transform. I think it would be very useful in
cases where someone wants to add an object to their scene but doesn't
want to have to specify rotation or scale, e.g.:
```
5: (
components: {
"common::types::GameObjectKind": Rifle,
"bevy_transform::components::transform::Transform": (
translation: (1.5, 800.0, 0.0),
),
},
),
```
## Solution
Added `#[cfg_attr(feature = "serialize", serde(default))]` before the
Transform struct.
## Testing
Successfully built bevy, but haven't tested extensively. Theoretically
shouldn't break existing functionality, since Deriving Transform was
invalid before this PR.
# Objective
Update `ComputedNode` for scrollbar thumbs in `update_scrollbar_thumb`
to avoid delays and system ambiguities.
## Solution
* Removed `Node` from scrollbar thumb node entities.
* Renamed `CoreScrollbarThumb` to `ScrollbarThumb`.
* `ScrollbarThumb` now requires all the UI components and gains `border`
and `border_radius` fields.
* `update_scrollbar_thumb` now updates `ScrollbarThumb` node's
`UiGlobalTransform` and `ComputedNode` in `PostLayout`.
## Testing
```
cargo run --example scrollbars
```
We need a better scrollbars example, added an issue #23622.
---------
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
https://github.com/DioxusLabs/taffy/releases/tag/v0.10.0
## Solution
* Updated taffy dependency to version `0.10`.
* Added new enum to `ui_node` `InlineDirection`, maps to `Direction` in
taffy (Bevy already has a `Direction` type in `bevy_ecs`).
* `Node` has a new `direction: InlineDirection` field.
---------
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
# Objective
If a `GpuImage` was modified (`Assets<Image>::insert`) in the same frame
as a Material2d that used it, it could create a race, potentially
leading to the old `TextureView` reference being read when creating the
`Material2d` bind group, leading to the material bind group never
getting the updated `GpuImage` reference.
## Solution
Register `GpuImage` as a dependency of `PreparedMaterial2d`.
Not all `Material2d` implementations might use `Image` handles, so I
guess this potentially has some cost in terms of performance. Ideally
we'd add some sort of mechanism so this dependency is only added when
needed, but this fix focuses on the minimal change to make the current
implementation correct.
## Testing
I ran into this problem when trying to get bevy_magic_light_2d working
on bevy 0.18 together with bevy_ecs_tilemap.
Minimal(ish) test case:
For some reason it only triggers on 0.18.1 though, not on current main.
```
//! Test: Material2d reading a render target image that gets replaced on resize.
//!
//! Without the fix (PreparedMaterial2d depending on GpuImage), the red spinner
//! rendered through the Material2d quad stops updating after a window resize.
use bevy::{
asset::uuid_handle,
camera::{visibility::RenderLayers, RenderTarget},
ecs::message::MessageReader,
prelude::*,
render::{
render_asset::RenderAssets,
render_resource::*,
texture::GpuImage,
Render, RenderApp, RenderSystems,
},
shader::ShaderRef,
sprite_render::{Material2d, Material2dPlugin, PreparedMaterial2d},
window::WindowResized,
};
const RENDER_TARGET: Handle<Image> = uuid_handle!("8bdbc7e2-ddc0-4264-9701-0a40476a4de6");
const SHOW_MATERIAL: Handle<ShowTextureMaterial> =
uuid_handle!("9a2cb207-fe74-45ed-b2c8-7ad4fc504c57");
#[derive(AsBindGroup, Clone, TypePath, Asset)]
struct ShowTextureMaterial {
#[texture(0)]
#[sampler(1)]
image: Handle<Image>,
}
impl Material2d for ShowTextureMaterial {
fn fragment_shader() -> ShaderRef {
"examples/show_texture.wgsl".into()
}
}
#[derive(Component)]
struct Spinner;
fn main() {
let mut app = App::new();
app.add_plugins((
DefaultPlugins,
Material2dPlugin::<ShowTextureMaterial>::default(),
));
// Adding a system with Commands to PrepareAssets perturbs the system
// ordering enough to trigger the bug.
app.sub_app_mut(RenderApp).add_systems(
Render,
(|_commands: Commands| {}).in_set(RenderSystems::PrepareAssets),
);
app
.add_systems(Startup, setup)
.add_systems(PreUpdate, handle_resize)
.add_systems(Update, spin)
.run();
}
fn setup(
mut commands: Commands,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<ShowTextureMaterial>>,
mut meshes: ResMut<Assets<Mesh>>,
) {
images
.insert(RENDER_TARGET.id(), create_render_target_image(1280, 720))
.expect("insert");
// Camera rendering to image target
commands.spawn((
Camera2d,
Camera::default(),
RenderTarget::Image(RENDER_TARGET.clone().into()),
Name::new("target_camera"),
));
// Camera rendering to screen
commands.spawn((
Camera2d,
Camera { order: 1, ..default() },
RenderLayers::layer(1),
Name::new("screen_camera"),
));
// Red spinner rendered to image target
commands.spawn((
Sprite {
color: Color::srgb(1.0, 0.0, 0.0),
custom_size: Some(Vec2::splat(100.0)),
..default()
},
Transform::default(),
Spinner,
));
// Blue spinner rendered to screen directly
commands.spawn((
Sprite {
color: Color::srgb(0.0, 0.0, 1.0),
custom_size: Some(Vec2::splat(100.0)),
..default()
},
Transform::from_xyz(300.0, 0.0, 0.0),
RenderLayers::layer(1),
Spinner,
));
// Material2d quad showing the render target on screen
materials
.insert(SHOW_MATERIAL.id(), ShowTextureMaterial {
image: RENDER_TARGET.clone(),
})
.expect("insert material");
commands.spawn((
Mesh2d(meshes.add(Mesh::from(Rectangle::new(400.0, 300.0)))),
MeshMaterial2d(SHOW_MATERIAL.clone()),
Transform::from_xyz(-200.0, 0.0, 1.0),
RenderLayers::layer(1),
));
}
fn spin(mut q: Query<&mut Transform, With<Spinner>>, time: Res<Time<Real>>) {
for mut t in &mut q {
t.rotation = Quat::from_rotation_z(time.elapsed_secs());
}
}
fn handle_resize(
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<ShowTextureMaterial>>,
mut resize_events: MessageReader<WindowResized>,
mut last_size: Local<UVec2>,
) {
for event in resize_events.read() {
let w = event.width as u32;
let h = event.height as u32;
if w == 0 || h == 0 {
continue;
}
let new_size = UVec2::new(w, h);
if new_size == *last_size {
continue;
}
*last_size = new_size;
images
.insert(RENDER_TARGET.id(), create_render_target_image(w, h))
.expect("insert image");
// Re-insert material so its bind group gets recreated with the new GpuImage
materials
.insert(SHOW_MATERIAL.id(), ShowTextureMaterial {
image: RENDER_TARGET.clone(),
})
.expect("insert material");
}
}
fn create_render_target_image(w: u32, h: u32) -> Image {
let size = Extent3d { width: w, height: h, ..default() };
let mut image = Image {
texture_descriptor: TextureDescriptor {
label: Some("render_target"),
size,
dimension: TextureDimension::D2,
format: TextureFormat::bevy_default(),
mip_level_count: 1,
sample_count: 1,
usage: TextureUsages::TEXTURE_BINDING
| TextureUsages::COPY_DST
| TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
},
..default()
};
image.resize(size);
image
}
```
Without the fix the red rectangle will stop spinning after resizing the
window.
# Objective
The first part of #23606.
## Solution
Rename `bevy_scene` to `bevy_ecs_serialization`. No other changes were
made.
## Testing
The `scene` example still works as expected.
# Objective
This originated from playing around with the `bsn!` macro to find out
how well the lsp integration works during actual usage when typing new
fields etc.
It started by adding `new_spanned` to report errors. I restructured as I
saw fit for now as some of the locations were quite heavily indented,
although I'm not opposed to doing it differently. I do think it is an
improvement overall.
## Changes
- reduces nesting and indents significantly.
- remove/cleanup some dead/unused code, see comments.
- adds `BsnCodegenCtx` to clean up the function signatures and to allow
accumulation of errors
- adds usage of `syn::Result` return types, allowing for optional short
circuit behavior.
- adds error handling to the parsing like duplicate detection etc.
- small tweaks here and there to fail gracefully/continue parsing.
- improve/fix parsing in `is_const`, add tests.
- add a `BsnTokenStream` trait
## Notes
- the PR is not about fmt support for the macro content.
- it's not perfect, but I think it's a good base and much better than
what we have now from a devex pov.
- uses proc tests for both `is_const` and `path_type`, making them real
unit tests that follow AAA without taking more space to do it, we can
also type them all out if that's not alright but I think it's okay here
for these tests.
## Testing
`cargo test`
`cargo bench`
`cargo run --example bsn`
<img width="1392" height="772" alt="image"
src="https://github.com/user-attachments/assets/6dfd9c8c-fd68-4e74-b30d-e7e79d81aa1e"
/>
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>