Skip to content

Conversation

MrGVSV
Copy link
Member

@MrGVSV MrGVSV commented Aug 24, 2022

Objective

Resolves #4154

Currently, registration must all be done manually:

#[derive(Reflect)]
struct Foo(Bar);

#[derive(Reflect)]
struct Bar(Baz);

#[derive(Reflect)]
struct Baz(usize);

fn main() {
  // ...
  app
    .register_type::<Foo>()
    .register_type::<Bar>()
    .register_type::<Baz>()
    // .register_type::<usize>() <- This one is handled by Bevy, thankfully
  // ...
}

This can grow really quickly and become very annoying to add, remove, and update as types change. It would be great if we could help reduce the number of types that a user must manually implement themselves.

Solution

As suggested in #4154, this PR adds automatic recursive registration. Essentially, when a type is registered, it may now also choose to register additional types along with it using the new GetTypeRegistration::register_type_dependencies trait method.

The Reflect derive macro now automatically does this for all fields in structs, tuple structs, struct variants, and tuple variants. This is also done for tuples, arrays, Vec<T>, HashMap<K, V>, and Option<T>.

This allows us to simplify the code above like:

#[derive(Reflect)]
struct Foo(Bar);

#[derive(Reflect)]
struct Bar(Baz);

#[derive(Reflect)]
struct Baz(usize);

fn main() {
  // ...
  app.register_type::<Foo>()
  // ...
}

This automatic registration only occurs if the type has not yet been registered. If it has been registered, we simply skip it and move to the next one. This reduces the cost of registration and prevents overwriting customized registrations.

Considerations

While this does improve ergonomics on one front, it's important to look at some of the arguments against adopting a PR like this.

Generic Bounds

Since we need to be able to register the fields individually, we need those fields to implement GetTypeRegistration. This forces users to then add this trait as a bound on their generic arguments. This annoyance could be relieved with something like #5772.

This is no longer a major issue as the Reflect derive now adds the GetTypeRegistration bound by default. This should technically be okay, since we already add the Reflect bound.

However, this can also be considered a breaking change for manual implementations that left out a GetTypeRegistration impl or for items that contain dynamic types (e.g. DynamicStruct) since those also do not implement GetTypeRegistration.

Registration Assumptions

By automatically registering fields, users might inadvertently be relying on certain types to be automatically registered. If Foo auto-registers Bar, but Foo is later removed from the code, then anywhere that previously used or relied on Bar's registration would now fail.


Changelog

  • Added recursive type registration to structs, tuple structs, struct variants, tuple variants, tuples, arrays, Vec<T>, HashMap<K, V>, and Option<T>
  • Added a new trait in the hidden bevy_reflect::__macro_exports module called RegisterForReflection
  • Added GetTypeRegistration impl for bevy_render::render_asset::RenderAssetUsages

Migration Guide

All types that derive Reflect will now automatically add GetTypeRegistration as a bound on all (unignored) fields. This means that all reflected fields will need to also implement GetTypeRegistration.

If all fields derive Reflect or are implemented in bevy_reflect, this should not cause any issues. However, manual implementations of Reflect that excluded a GetTypeRegistration impl for their type will need to add one.

#[derive(Reflect)]
struct Foo<T: FromReflect> {
  data: MyCustomType<T>
}

// OLD
impl<T: FromReflect> Reflect for MyCustomType<T> {/* ... */}

// NEW
impl<T: FromReflect + GetTypeRegistration> Reflect for MyCustomType<T> {/* ... */}
impl<T: FromReflect + GetTypeRegistration> GetTypeRegistration for MyCustomType<T> {/* ... */}

@MrGVSV MrGVSV added C-Usability A targeted quality-of-life change that makes Bevy easier to use A-Reflection Runtime information about types X-Controversial There is active debate or serious implications around merging this PR labels Aug 24, 2022
@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch 2 times, most recently from 82108df to 5bc61bb Compare August 24, 2022 21:08
@MrGVSV MrGVSV marked this pull request as ready for review August 24, 2022 21:34
@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch from 5bc61bb to 9dd48e1 Compare August 28, 2022 05:39

#[derive(Reflect)]
struct MyType<T: Reflect> {
struct MyType<T: Reflect + GetTypeRegistration> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like that GetTypeRegistration now becomes something people need to think about for generic type parameters. I thought about adding it as a supertrait to Reflect but DynamicX types don't implement it of course.
With bevyengine/rfcs#56 we can add it as a supertrait, right? (with a where Self: Sized bound to keep object safety)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I’d really like #5772 to get merged. It would combine all these core traits into one that does not need to worry about object-safety

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it still introduces another trait. It would be nice if T: Reflect just worked.

Copy link
Member Author

@MrGVSV MrGVSV Sep 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah but it means we keep it to two traits that a user must know (Reflect or Reflectable), even as we add more and more core traits.

Separating traits is also about readability imo so if we did combine everything then we'd eventually end up with a potentially massive trait

@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch from 9dd48e1 to 0cc73be Compare October 12, 2022 05:41
@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch from 0cc73be to 162c3d0 Compare November 10, 2022 06:43
bors bot pushed a commit that referenced this pull request Nov 23, 2022
# Objective 

Many types in `bevy_render` implemented `Reflect` but were not registered.

## Solution

Register all types in `bevy_render` that impl `Reflect`.

This also registers additional dependent types (i.e. field types).

> Note: Adding these dependent types would not be needed using something like #5781 😉 

---

## Changelog

- Register missing `bevy_render` types in the `TypeRegistry`:
  - `camera::RenderTarget`
  - `globals::GlobalsUniform`
  - `texture::Image`
  - `view::ComputedVisibility`
  - `view::Visibility`
  - `view::VisibleEntities`
- Register additional dependent types:
  - `view::ComputedVisibilityFlags`
  - `Vec<Entity>`
bors bot pushed a commit that referenced this pull request Nov 23, 2022
# Objective 

Many types in `bevy_render` implemented `Reflect` but were not registered.

## Solution

Register all types in `bevy_render` that impl `Reflect`.

This also registers additional dependent types (i.e. field types).

> Note: Adding these dependent types would not be needed using something like #5781 😉 

---

## Changelog

- Register missing `bevy_render` types in the `TypeRegistry`:
  - `camera::RenderTarget`
  - `globals::GlobalsUniform`
  - `texture::Image`
  - `view::ComputedVisibility`
  - `view::Visibility`
  - `view::VisibleEntities`
- Register additional dependent types:
  - `view::ComputedVisibilityFlags`
  - `Vec<Entity>`
cart pushed a commit to cart/bevy that referenced this pull request Dec 1, 2022
…yengine#6725)

Many types in `bevy_render` implemented `Reflect` but were not registered.

Register all types in `bevy_render` that impl `Reflect`.

This also registers additional dependent types (i.e. field types).

> Note: Adding these dependent types would not be needed using something like bevyengine#5781 😉

---

- Register missing `bevy_render` types in the `TypeRegistry`:
  - `camera::RenderTarget`
  - `globals::GlobalsUniform`
  - `texture::Image`
  - `view::ComputedVisibility`
  - `view::Visibility`
  - `view::VisibleEntities`
- Register additional dependent types:
  - `view::ComputedVisibilityFlags`
  - `Vec<Entity>`
@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch from 79fa0d6 to 813e889 Compare December 3, 2022 03:22
taiyoungjang pushed a commit to taiyoungjang/bevy that referenced this pull request Dec 15, 2022
…yengine#6725)

Many types in `bevy_render` implemented `Reflect` but were not registered.

Register all types in `bevy_render` that impl `Reflect`.

This also registers additional dependent types (i.e. field types).

> Note: Adding these dependent types would not be needed using something like bevyengine#5781 😉

---

- Register missing `bevy_render` types in the `TypeRegistry`:
  - `camera::RenderTarget`
  - `globals::GlobalsUniform`
  - `texture::Image`
  - `view::ComputedVisibility`
  - `view::Visibility`
  - `view::VisibleEntities`
- Register additional dependent types:
  - `view::ComputedVisibilityFlags`
  - `Vec<Entity>`
@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch from 813e889 to 196b4d8 Compare December 18, 2022 21:30
alradish pushed a commit to alradish/bevy that referenced this pull request Jan 22, 2023
…yengine#6725)

# Objective

Many types in `bevy_render` implemented `Reflect` but were not registered.

## Solution

Register all types in `bevy_render` that impl `Reflect`.

This also registers additional dependent types (i.e. field types).

> Note: Adding these dependent types would not be needed using something like bevyengine#5781 😉

---

## Changelog

- Register missing `bevy_render` types in the `TypeRegistry`:
  - `camera::RenderTarget`
  - `globals::GlobalsUniform`
  - `texture::Image`
  - `view::ComputedVisibility`
  - `view::Visibility`
  - `view::VisibleEntities`
- Register additional dependent types:
  - `view::ComputedVisibilityFlags`
  - `Vec<Entity>`
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
…yengine#6725)

# Objective 

Many types in `bevy_render` implemented `Reflect` but were not registered.

## Solution

Register all types in `bevy_render` that impl `Reflect`.

This also registers additional dependent types (i.e. field types).

> Note: Adding these dependent types would not be needed using something like bevyengine#5781 😉 

---

## Changelog

- Register missing `bevy_render` types in the `TypeRegistry`:
  - `camera::RenderTarget`
  - `globals::GlobalsUniform`
  - `texture::Image`
  - `view::ComputedVisibility`
  - `view::Visibility`
  - `view::VisibleEntities`
- Register additional dependent types:
  - `view::ComputedVisibilityFlags`
  - `Vec<Entity>`
@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch from 196b4d8 to 3ac6285 Compare February 7, 2023 05:33
@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch from 3ac6285 to a2798d7 Compare March 25, 2023 06:37
@MrGVSV
Copy link
Member Author

MrGVSV commented Mar 25, 2023

We might actually be able to improve the usability here by adding GetTypeRegistration to the where clause of the impl like we do with Reflect 🤔


Tasks

  • Do this

@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch from 3541b65 to 2212a96 Compare April 17, 2023 19:57
@james7132 james7132 self-requested a review April 17, 2023 20:06
@MrGVSV MrGVSV force-pushed the reflect-auto-registration branch 2 times, most recently from a857552 to f40347e Compare April 21, 2023 04:44
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Mar 3, 2024
@alice-i-cecile alice-i-cecile removed this pull request from the merge queue due to a manual request Mar 3, 2024
@alice-i-cecile
Copy link
Member

alice-i-cecile commented Mar 3, 2024

@MrGVSV say the word and I'll merge this in :) @SkiFire13 or @soqb your review on the last batch of changes would be nice too.

@MrGVSV
Copy link
Member Author

MrGVSV commented Mar 3, 2024

@MrGVSV say the word and I'll merge this in :) @SkiFire13 or @soqb your review on the last batch of changes would be nice too.

I mean I’m happy with it haha. We could maybe schedule it to be merged as part of the merge train tomorrow in case anyone has any last minute concerns?

@alice-i-cecile alice-i-cecile removed the X-Controversial There is active debate or serious implications around merging this PR label Mar 4, 2024
@alice-i-cecile
Copy link
Member

Great: removing the controversial label for now so I don't miss it 😅

@james7132
Copy link
Member

One final thing that came to mind was maybe to annotate register_type_dependencies as #[inline(never)] to avoid excessive code generation at compile time.

@MrGVSV
Copy link
Member Author

MrGVSV commented Mar 4, 2024

One final thing that came to mind was maybe to annotate register_type_dependencies as #[inline(never)] to avoid excessive code generation at compile time.

@james7132 Annotate just the default trait method or add it to the generated GetTypeRegistration impls?

@james7132
Copy link
Member

@james7132 Annotate just the default trait method or add it to the generated GetTypeRegistration impls?

The empty default is fine, but the ones that have an actual body need to be annotated to avoid inlining the recursion.

@SkiFire13
Copy link
Contributor

LGTM, although the #[inline(never)] feels like premature optimizations. Is it certain that LLVM will inline that method normally (and that this will actually be bad, since it seems it's only used in one function)?

@alice-i-cecile alice-i-cecile added the X-Controversial There is active debate or serious implications around merging this PR label Mar 4, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Mar 4, 2024
Merged via the queue into bevyengine:main with commit ccb9d05 Mar 4, 2024
@MrGVSV MrGVSV deleted the reflect-auto-registration branch March 4, 2024 21:52
spectria-limina pushed a commit to spectria-limina/bevy that referenced this pull request Mar 9, 2024
# Objective

Resolves bevyengine#4154

Currently, registration must all be done manually:

```rust
#[derive(Reflect)]
struct Foo(Bar);

#[derive(Reflect)]
struct Bar(Baz);

#[derive(Reflect)]
struct Baz(usize);

fn main() {
  // ...
  app
    .register_type::<Foo>()
    .register_type::<Bar>()
    .register_type::<Baz>()
    // .register_type::<usize>() <- This one is handled by Bevy, thankfully
  // ...
}
```

This can grow really quickly and become very annoying to add, remove,
and update as types change. It would be great if we could help reduce
the number of types that a user must manually implement themselves.

## Solution

As suggested in bevyengine#4154, this PR adds automatic recursive registration.
Essentially, when a type is registered, it may now also choose to
register additional types along with it using the new
`GetTypeRegistration::register_type_dependencies` trait method.

The `Reflect` derive macro now automatically does this for all fields in
structs, tuple structs, struct variants, and tuple variants. This is
also done for tuples, arrays, `Vec<T>`, `HashMap<K, V>`, and
`Option<T>`.

This allows us to simplify the code above like:

```rust
#[derive(Reflect)]
struct Foo(Bar);

#[derive(Reflect)]
struct Bar(Baz);

#[derive(Reflect)]
struct Baz(usize);

fn main() {
  // ...
  app.register_type::<Foo>()
  // ...
}
```

This automatic registration only occurs if the type has not yet been
registered. If it has been registered, we simply skip it and move to the
next one. This reduces the cost of registration and prevents overwriting
customized registrations.

## Considerations

While this does improve ergonomics on one front, it's important to look
at some of the arguments against adopting a PR like this.

#### Generic Bounds

~~Since we need to be able to register the fields individually, we need
those fields to implement `GetTypeRegistration`. This forces users to
then add this trait as a bound on their generic arguments. This
annoyance could be relieved with something like bevyengine#5772.~~

This is no longer a major issue as the `Reflect` derive now adds the
`GetTypeRegistration` bound by default. This should technically be okay,
since we already add the `Reflect` bound.

However, this can also be considered a breaking change for manual
implementations that left out a `GetTypeRegistration` impl ~~or for
items that contain dynamic types (e.g. `DynamicStruct`) since those also
do not implement `GetTypeRegistration`~~.

#### Registration Assumptions

By automatically registering fields, users might inadvertently be
relying on certain types to be automatically registered. If `Foo`
auto-registers `Bar`, but `Foo` is later removed from the code, then
anywhere that previously used or relied on `Bar`'s registration would
now fail.

---

## Changelog

- Added recursive type registration to structs, tuple structs, struct
variants, tuple variants, tuples, arrays, `Vec<T>`, `HashMap<K, V>`, and
`Option<T>`
- Added a new trait in the hidden `bevy_reflect::__macro_exports` module
called `RegisterForReflection`
- Added `GetTypeRegistration` impl for
`bevy_render::render_asset::RenderAssetUsages`

## Migration Guide

All types that derive `Reflect` will now automatically add
`GetTypeRegistration` as a bound on all (unignored) fields. This means
that all reflected fields will need to also implement
`GetTypeRegistration`.

If all fields **derive** `Reflect` or are implemented in `bevy_reflect`,
this should not cause any issues. However, manual implementations of
`Reflect` that excluded a `GetTypeRegistration` impl for their type will
need to add one.

```rust
#[derive(Reflect)]
struct Foo<T: FromReflect> {
  data: MyCustomType<T>
}

// OLD
impl<T: FromReflect> Reflect for MyCustomType<T> {/* ... */}

// NEW
impl<T: FromReflect + GetTypeRegistration> Reflect for MyCustomType<T> {/* ... */}
impl<T: FromReflect + GetTypeRegistration> GetTypeRegistration for MyCustomType<T> {/* ... */}
```

---------

Co-authored-by: James Liu <[email protected]>
Co-authored-by: radiish <[email protected]>
Co-authored-by: Carter Anderson <[email protected]>
mtsr pushed a commit to mtsr/bevy that referenced this pull request Mar 15, 2024
# Objective

Resolves bevyengine#4154

Currently, registration must all be done manually:

```rust
#[derive(Reflect)]
struct Foo(Bar);

#[derive(Reflect)]
struct Bar(Baz);

#[derive(Reflect)]
struct Baz(usize);

fn main() {
  // ...
  app
    .register_type::<Foo>()
    .register_type::<Bar>()
    .register_type::<Baz>()
    // .register_type::<usize>() <- This one is handled by Bevy, thankfully
  // ...
}
```

This can grow really quickly and become very annoying to add, remove,
and update as types change. It would be great if we could help reduce
the number of types that a user must manually implement themselves.

## Solution

As suggested in bevyengine#4154, this PR adds automatic recursive registration.
Essentially, when a type is registered, it may now also choose to
register additional types along with it using the new
`GetTypeRegistration::register_type_dependencies` trait method.

The `Reflect` derive macro now automatically does this for all fields in
structs, tuple structs, struct variants, and tuple variants. This is
also done for tuples, arrays, `Vec<T>`, `HashMap<K, V>`, and
`Option<T>`.

This allows us to simplify the code above like:

```rust
#[derive(Reflect)]
struct Foo(Bar);

#[derive(Reflect)]
struct Bar(Baz);

#[derive(Reflect)]
struct Baz(usize);

fn main() {
  // ...
  app.register_type::<Foo>()
  // ...
}
```

This automatic registration only occurs if the type has not yet been
registered. If it has been registered, we simply skip it and move to the
next one. This reduces the cost of registration and prevents overwriting
customized registrations.

## Considerations

While this does improve ergonomics on one front, it's important to look
at some of the arguments against adopting a PR like this.

#### Generic Bounds

~~Since we need to be able to register the fields individually, we need
those fields to implement `GetTypeRegistration`. This forces users to
then add this trait as a bound on their generic arguments. This
annoyance could be relieved with something like bevyengine#5772.~~

This is no longer a major issue as the `Reflect` derive now adds the
`GetTypeRegistration` bound by default. This should technically be okay,
since we already add the `Reflect` bound.

However, this can also be considered a breaking change for manual
implementations that left out a `GetTypeRegistration` impl ~~or for
items that contain dynamic types (e.g. `DynamicStruct`) since those also
do not implement `GetTypeRegistration`~~.

#### Registration Assumptions

By automatically registering fields, users might inadvertently be
relying on certain types to be automatically registered. If `Foo`
auto-registers `Bar`, but `Foo` is later removed from the code, then
anywhere that previously used or relied on `Bar`'s registration would
now fail.

---

## Changelog

- Added recursive type registration to structs, tuple structs, struct
variants, tuple variants, tuples, arrays, `Vec<T>`, `HashMap<K, V>`, and
`Option<T>`
- Added a new trait in the hidden `bevy_reflect::__macro_exports` module
called `RegisterForReflection`
- Added `GetTypeRegistration` impl for
`bevy_render::render_asset::RenderAssetUsages`

## Migration Guide

All types that derive `Reflect` will now automatically add
`GetTypeRegistration` as a bound on all (unignored) fields. This means
that all reflected fields will need to also implement
`GetTypeRegistration`.

If all fields **derive** `Reflect` or are implemented in `bevy_reflect`,
this should not cause any issues. However, manual implementations of
`Reflect` that excluded a `GetTypeRegistration` impl for their type will
need to add one.

```rust
#[derive(Reflect)]
struct Foo<T: FromReflect> {
  data: MyCustomType<T>
}

// OLD
impl<T: FromReflect> Reflect for MyCustomType<T> {/* ... */}

// NEW
impl<T: FromReflect + GetTypeRegistration> Reflect for MyCustomType<T> {/* ... */}
impl<T: FromReflect + GetTypeRegistration> GetTypeRegistration for MyCustomType<T> {/* ... */}
```

---------

Co-authored-by: James Liu <[email protected]>
Co-authored-by: radiish <[email protected]>
Co-authored-by: Carter Anderson <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Aug 12, 2024
# Objective

- Implements the [Unique Reflect
RFC](https://github.com/nicopap/rfcs/blob/bevy-reflect-api/rfcs/56-better-reflect.md).

## Solution

- Implements the RFC.
- This implementation differs in some ways from the RFC:
- In the RFC, it was suggested `Reflect: Any` but `PartialReflect:
?Any`. During initial implementation I tried this, but we assume the
`PartialReflect: 'static` in a lot of places and the changes required
crept out of the scope of this PR.
- `PartialReflect::try_into_reflect` originally returned `Option<Box<dyn
Reflect>>` but i changed this to `Result<Box<dyn Reflect>, Box<dyn
PartialReflect>>` since the method takes by value and otherwise there
would be no way to recover the type. `as_full` and `as_full_mut` both
still return `Option<&(mut) dyn Reflect>`.

---

## Changelog

- Added `PartialReflect`.
- `Reflect` is now a subtrait of `PartialReflect`.
- Moved most methods on `Reflect` to the new `PartialReflect`.
- Added `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect}`.
- Added `PartialReflect::{try_as_reflect, try_as_reflect_mut,
try_into_reflect}`.
- Added `<dyn PartialReflect>::{try_downcast_ref, try_downcast_mut,
try_downcast, try_take}` supplementing the methods on `dyn Reflect`.

## Migration Guide

- Most instances of `dyn Reflect` should be changed to `dyn
PartialReflect` which is less restrictive, however trait bounds should
generally stay as `T: Reflect`.
- The new `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect, try_as_reflect, try_as_reflect_mut,
try_into_reflect}` methods as well as `Reflect::{as_reflect,
as_reflect_mut, into_reflect}` will need to be implemented for manual
implementors of `Reflect`.

## Future Work

- This PR is designed to be followed up by another "Unique Reflect Phase
2" that addresses the following points:
- Investigate making serialization revolve around `Reflect` instead of
`PartialReflect`.
- [Remove the `try_*` methods on `dyn PartialReflect` since they are
stop
gaps](#7207 (comment)).
- Investigate usages like `ReflectComponent`. In the places they
currently use `PartialReflect`, should they be changed to use `Reflect`?
- Merging this opens the door to lots of reflection features we haven't
been able to implement.
- We could re-add [the `Reflectable`
trait](https://github.com/bevyengine/bevy/blob/8e3488c88065a94a4f72199587e59341c9b6553d/crates/bevy_reflect/src/reflect.rs#L337-L342)
and make `FromReflect` a requirement to improve [`FromReflect`
ergonomics](bevyengine/rfcs#59). This is
currently not possible because dynamic types cannot sensibly be
`FromReflect`.
  - Since this is an alternative to #5772, #5781 would be made cleaner.

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Gino Valente <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Aug 6, 2025
# Objective
This PR adds automatic registration of non-generic types annotated with
`#[derive(Reflect)]`.
Manually registering all reflect types can be error-prone, failing to
reflect during runtime if some type is not registered. #5781 fixed this
for nested types, improving ergonomics of using reflection dramatically,
but top-level types still need to be registered manually. This is
especially painful when prototyping and using inspector to change values
of components.
```rs
// from #5781
#[derive(Reflect)]
struct Foo(Bar);

#[derive(Reflect)]
struct Bar(Baz);

#[derive(Reflect)]
struct Baz(usize);

fn main() {
  // ...
  app.register_type::<Foo>() // <- can still forget to add this
  // ...
}
```

Fixes #3936.

## Solution
Automatically register all types that derive Reflect. This works for all
non-generic types, allowing users to just add `#[derive(Reflect)]` to
any compatible type and not think about where to register it.
```rs
fn main() {
  // No need to manually call .register_type::<Foo>()
  App::new()
    .add_plugins(DefaultPlugins)
    .add_systems(Startup, setup)
    .run();
}

#[derive(Reflect)]
pub struct Foo {
  a: usize,
}

fn setup(type_registry: Res<AppTypeRegistry>) {
  let type_registry = type_registry.read();
  assert!(type_registry.contains(TypeId::of::<Foo>()));
}
```

Automatic registration can be opted-out of by adding
`#[reflect(no_auto_register)]` reflect attribute to a type:
```rs
#[derive(Reflect)]
#[reflect(no_auto_register)]
pub struct Foo {
  a: usize,
}
```

Registration normally happens at app creation time, but `TypeRegistry`
itself has a new `register_derived_types` method to register all
collected types at any appropriate time:

```rs
#[derive(Reflect)]
struct Foo {
  name: Option<String>,
  value: i32
}

let mut type_registry = TypeRegistry::empty();
type_registry.register_derived_types();

assert!(type_registry.contains(TypeId::of::<Foo>()));
```

## Testing
- Tested by running `reflect` example and removing explicit type
registration, both on native and on `wasm32-unknown-unknown`.
- Added a doctest to `register_derived_types`

Impact on startup time is negligible: <40ms on debug wasm build and
<25ms on debug native build for 1614 registered types .

Wasm binary size comparison. All sizes are in KB as reported by `du` on
the modified `reflection` example.

| | **auto register, KiB** | **no auto register, KiB** | **abs diff,
KiB** | **% diff** |
| ---------------------------- | ---------------------- |
------------------------- | ----------------- | ---------- |
| wasm-release && wasm-bindgen | 27000 | 24224 | 2776 | 11.46% |
| wasm-opt -Oz | 16376 | 15340 | 1036 | 6.75% |
| wasm-opt -Os | 17728 | 16424 | 1304 | 7.94% |
| wasm-opt -Oz && gzip -c | 5620 | 5364 | 256 | 4.77% |


## Considerations
While automatic type registration improves ergonomics quite a bit for
projects that make heavy use of it, there are also some problems:
- Generic types can't be automatically registered. However, as long as
top-level reflect types don't need generics, recursive registration can
take care of the rest.
- Wasm bundle size increase is not insignificant. This is mostly due to
registering various engine types that weren't registered before. Size
overhead of automatic registration of types instead of manual is
relatively small, as can be see from this (somewhat outdated but still
relevant) table (see last 2 rows):

<details>

<summary>1000 simple structs with reflect wasm size comparison, no
engine types</summary>

| | auto register, KiB | no auto register, KiB | abs diff, KiB | % diff
|
| --------------------------------------------- | ------------- |
---------------- | -------- | ------ |
| wasm-release && wasm-bindgen | 27944 | 21644 | 6300 | 22.55% |
| wasm-release && wasm-bindgen +register_type | 28084 | 27764 | 320 |
1.14% |
| wasm-opt -Oz | 15612 | 13928 | 1684 | 10.79% |
| wasm-opt -Oz +register_type | 15676 | 15580 | 96 | 0.61% |
| wasm-release && wasm-bindgen (manual vs auto) | 27944 | 27764 | 180 |
0.64% |
| wasm-opt -Oz (manual vs auto) | 15612 | 15580 | 32 | 0.2% |

</details>

---------

Co-authored-by: Gino Valente <[email protected]>
Co-authored-by: Carter Anderson <[email protected]>
cart added a commit to cart/bevy that referenced this pull request Aug 9, 2025
* Release notes for generic component propagation (bevyengine#20354)

# Objective

Fixes bevyengine#20143.

## Solution

These release notes were adopted from the PR description and docs added
in bevyengine#17575 by @robtfm.

When writing these, I've focused on providing context, potential
applications, and breaking down the complex generics for newer Bevy
users.

* Solari specular scene/PT support (bevyengine#20242)

* Adds roughness, metallic, and reflectance properties to solari's
material system
* Always calculate and expose world_tangent in ResolvedRayHitFull
* Add brdf.wgsl with mixed diffuse/specular BRDF
* Add GGX VNDF importance sampling functions to sampling.wgsl
* Rewrite the pathtracer to use the specular BRDF
* MIS for NEE/BRDF sampling implemented in the pathtracer thanks to
@SparkyPotato

Note that specular support for the realtime lighting plugin will come at
a future date. I think I want to focus on getting GI more stable and
hooking up a denoiser first. This is _just_ support for the material
properties in RaytracingScenePlugin, and specular lighting in the
PathtracingPlugin.

<img width="2564" height="1500" alt="image"
src="https://github.com/user-attachments/assets/e322b770-179d-4255-84ce-996c531ce811"
/>

---------

Co-authored-by: SparkyPotato <[email protected]>
Co-authored-by: Alice Cecile <[email protected]>

* use transpose not inverse in shadow map transform (bevyengine#20359)

# Objective

- minor simplification + precision/performance improvement

## Solution

- inverse is transpose for rotation matrices

## Testing

- shadow_bias example

* enable wayland by default (bevyengine#19232)

# Objective

- Fixes bevyengine#4106
- Fixes bevyengine#13340

## Solution

Just one commit to add `wayland` to the default features indeed

### Why should it be merged?

The discussion in bevyengine#4106 seems to be overwhelmingly positive toward
adding `wayland` to the default features, as it can greatly improve user
experience for Linux users who use Wayland.

Many of the most popular Linux Desktop Environments (DE) like KDE Plasma
Desktop and GNOME have Wayland support. With the release of Plasma 6,
Wayland is now used by default, and in GNOME, Wayland has been the
default for quite a while now.

With Plasma and GNOME, the most popular Linux DEs, now defaulting to
Wayland, it seems like enabling Wayland support would truly indeed
positively affect quite a lot of Linux users indeed.

Copied from bevyengine#10792

* Upgrade to `wgpu` version `26.0` (bevyengine#19868)

# Objective

- Upgrading to the latest wgpu version is good for features, bug fixes
and performance improvements.
- Also fixes bevyengine#19626.

## Solution

- Upgrade dependency version.

---------

Co-authored-by: atlas dostal <[email protected]>

* fix reflect import in bevy_app propagate (bevyengine#20382)

# Objective

Fix building bevy_app without default features

## Solution

Since bevyengine#20197 some imports to
reflect are not properly gates

## Testing

```
cargo build --package bevy_app --no-default-features
```

* Side: Fix `ci` tool when running with `--test-threads` (bevyengine#20346)

# Objective

`ci` tool fails if you run with `--test-threads` because `cargo test
--benches` does not take `--test-threads`

## Solution

Split the command that call `cargo test` into one for `--benches` and
other for `--lib --bins --tests`.

## Testing

Ran `cargo run -p ci -- --build-jobs 4 --test-threads 4`

## Note

This is a cherry-pick of a commit that was added to bevyengine#19011 but was
unrelated to the PR

* dont depend on bevy_render in bevy_scene (bevyengine#20388)

# Objective

- dont depend on bevy_render in bevy_scene

## Solution

- dont depend on bevy_render in bevy_scene

## Testing

- cargo check --examples

* reduce bevy_gltf dependency on render and pbr (bevyengine#20390)

# Objective

- make bevy_gltf not depend on bevy_render/bevy_pbr

## Solution

- use bevy_light and bevy_camera

## Testing

- cargo check --examples

* Clean `bevy_tasks` features (Adopted) (bevyengine#20369)

adopts bevyengine#19091.

Work in progress.

Co-authored-by: Zac Harrold <[email protected]>

* Deduplicate Default Font Data (bevyengine#20397)

# Objective

The data for the default font is included twice with `include_bytes!`.
This is not a big problem as the data gets deduplicated at some point
during optimization, so this PR only saves 50 bytes~ instead of 20kb,
but we're still wasting time during compilation copying this file around
twice.

# Solution

Use the `DEFAULT_FONT_DATA` constant introduced in bevyengine#14406 for setting
the default font instead of including the bytes a second time via
`load_internal_binary_asset`.

* Reflect non-callback components and resources in bevy_core_widgets and bevy_feathers (bevyengine#20339)

# Objective

- Reflecting public components and resources is essential to allow them
to be saved to scenes and function properly in inspectors
- Fixes bevyengine#20040.

## Solution

- Derive reflect for all of the public components and resources that
didn't have it
- Various components that store a `Callback`, like `CoreButton`, are a
notable exception
- Because Callbacks are not type-erased, and the reflect derive only
works when all generics are reflect, I could not get this to work nicely
- If you can get this working, please let me know and we can do this in
follow-up!
- I also slapped a missing Debug derive on the theme resource because it
seems extremely useful and I noticed it

## Notes to reviewers

- this is not feature-gated: see bevyengine#20337 for the steps needed to
meaningfully do so. Fixing that is out of scope for the 0.17 release.
- I've opted to separate the Reflect derive from the other derives
wherever rustfmt would let me. While this looks dumb right now, it will
reduce the diff noise when fixing bevyengine#20337.
- I could add reflection to the callback-containing components with an
ignore for the callback fields, but I don't think this is particularly
useful

* fix some camera component links (bevyengine#20392)

# Objective

- fix some camera component links

## Solution

- fix some camera component links

## Testing

- ci

* More UI gradients fixes (bevyengine#20035)

# Objective

Improve the gradients implementation further.

## Solution
More UI gradients improvements:
* Use the more accurate gamma correction function from bevyengine#12939.
* Fixed hsl and hsv conversion functions.
* Ignore hues and don't interpolate if the chroma or saturation is close
to zero.

before:
<img width="239" alt="colors"
src="https://github.com/user-attachments/assets/39443400-e550-49f5-a7de-4a07c5fe537a"
/>

after:
<img width="194" alt="image"
src="https://github.com/user-attachments/assets/a5977b97-aa1d-4254-9ef3-0d2355f2ab18"
/>

## Testing

The `testbed_ui` and `gradients` examples can be used for testing.

* Move bevy_mikktspace out of tree (bevyengine#19798)

# Objective

- Have safe bevy_mikktspace by landing bevyengine#9050
- Don't have C in-tree

Related issues and PRs:

- Closes bevyengine#9050
- Closes bevyengine#8429 
- Fixes bevyengine#7372

## Solution

- Rebase to main
- Remove glam dependency so lock-step update is not necessary anymore
- Make it standalone: https://github.com/atlv24/bevy_mikktspace
- Transfer to bevy org

## Testing

- Test suite made by Layl

* Make WgpuWrapper public again (bevyengine#20409)

# Objective

- WgpuWrapper was public in 0.16 and is is needed to be able to call
RenderCreation::manual.

## Solution

- Make it public again after the revert bevyengine#20220

## Testing

- cargo build

* add ref doc and extract a couple vars and skip a sqrt in shadow cascades (bevyengine#20361)

# Objective

- ref doc is hard to find
- expression is big
- sqrt is extra

## Solution

- add ref doc
- extract a couple vars
- skip a sqrt

## Testing

- shadow biases example

---------

Co-authored-by: James Liu <[email protected]>

* MainPassResolutionOverride changes (bevyengine#20403)

Lots of changes extracted from bevyengine#19864.

I haven't added support for MainPassResolutionOverride to every
rendering feature yet. Mostly just Solari and some of the main passes as
a proof of concept.

* use iterators and zip instead of enumeration and indexing in shadow map cascades (bevyengine#20360)

# Objective

- refactor code to be easier to understand

## Solution

- use iterator methods like zip chain map instead of if statements and
indexing

## Testing

- shadow_biases example

* Improve `WithRelated` ergonomics (bevyengine#20423)

# Objective

Recommending users to use `WithRelated([child2, child3].into_iter())`
feels a bit weird.

## Solution

Add `WithRelated::new`, which uses `IntoIterator` to do the conversion
more cleanly and succinctly. The old way is still left as an option for
those wanting it.

## Testing

Updated the test to use the `new` function.

* Fix examples REAMDE markdown (bevyengine#20428)

# Objective

- Markdownlint doesn't allow more than 1 h1 heading in a file

## Solution

- Add one more level to everything

## Testing

N/A

* compute world_from_cascade analytically (bevyengine#20364)

# Objective

- doc comment says numeric inverse is avoided because of precision
issues, but its still used in two places anyways (the other being fixed
by bevyengine#20359)
- dont do that lmao

## Solution

- calculate it manually instead of using a numeric inverse
- also rename some variables to match new x_from_y style while im at it

## Testing

- shadow biases example

* use the wasm-release profile for smaller bins and longer builds (bevyengine#20419)

# Objective

- `cargo run -p build-wasm-example -- --api webgl2 breakout
--optimize-size` produces files that are too big for the website

## Solution

- Use the `wasm-release` profile which reduce the file size at the cost
of compile time


https://github.com/bevyengine/bevy/blob/e11a9e1167764235819b1803f629b40f9ac5131c/Cargo.toml#L4380-L4384

* Move advanced shader examples to separate category (bevyengine#20415)

# Objective

- Some shader examples are much more complicated than others. It can be
confusing for new users that simple example and advanced examples are
next to each other

## Solution

- Introduce a new "shader_advanced" example category
- I'm open to other names, but I named it like that so both folders are
next to each other

## Testing

N/A

## Notes

We should maybe consider a different name than "shader" because some of
them aren't that much about shaders. It could be advanced_rendering or
something like that.

I'm opened to moving more example to this. I just picked the one that
felt the most advanced to me.

I didn't move the compute_game_of_life example because, while it is
complex, the complexity is unavoidable if you want to run a compute
shader right now. I also plan on simplifying it a bit and introduce a
plugin to make it much easier but as it is today I think it's okay to
stay there.

* `CubicSegment::iter_uniformly` should be public (bevyengine#20417)

# Objective
`CubicSegment::iter_uniformly` should be public, as there is no harm to
it being public

## Solution
made `CubicSegment::iter_uniformly` public

## Testing

* Fix security issues on actions (bevyengine#20416)

# Objective

- CodeQL is reporting some issues on actions

<img width="930" height="379" alt="Screenshot 2025-08-04 at 19 25 24"
src="https://github.com/user-attachments/assets/7de5efe1-4962-4d15-9031-13ce3e1ac202"
/>

## Solution

- Fix them
- Follow
https://securitylab.github.com/resources/github-actions-untrusted-input/
for the code injection
- Set default permissions to every workflow that doesn't specify some

## Testing

- Not entirely sure permissions specified are enough, but I guess CI
will fail if they aren't

* Fix full_ui example overflowing scroll position (bevyengine#20401)

# Objective
The `testbed_full_ui` example has a system listening to `MouseWheel`
events and is applying the deltas to the hovered scroll position nodes.

However, this implementation does not clamp the range of the scroll
position to the content size (unlike `CoreScrollBar`). If you keep
scrolling you will notice that it over-/underflows despite already
having hit the "visible" end.

## Solution

Clamp `scroll_position.y` to the content size using the same logic as
[here](https://github.com/bevyengine/bevy/blob/197cbcb68ae1ccc8aa4e33cc3ab80afd960cf8a2/crates/bevy_core_widgets/src/core_scrollbar.rs#L209-L212).

## Testing

`cargo run --example testbed_full_ui`

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: ickshonpe <[email protected]>

* Validate directional light shadow map size is power of two (bevyengine#20375)

# Objective

- cascade construction code assumes shadowmap sizes are power of two
- this invariant is not enforced anywhere

## Solution

- automatically correct and warn when its not POT
- document

## Testing

- tried setting it to non-pot in shadow_biases example:
```
2025-08-02T02:30:44.379967Z  WARN bevy_light::directional_light: Non-power-of-two DirectionalLightShadowMap sizes are not supported, correcting 2442 to 4096
```

* Add light_consts::lumens::VERY_LARGE_CINEMA_LIGHT (bevyengine#20363)

# Objective

- Point light default has no constant
- shadow_biases example uses some arbitrary weird lumen value

## Solution

- Add a constant inspired by the doc comment on point light default

## Testing

- run shadow_biases example and press L

* Use the default directional light intensity constant (bevyengine#20362)

# Objective

- Pressing L twice to cycle light type in shadow_biases ends up with a
different brightness of light

## Solution

- Use the correct default so the brightness matches

## Testing

- run shadow_biases example

* Virtual keyboard widget (bevyengine#20350)

# Objective

Minimal virtual keyboard widget implementation.

## Solution

Added a `virtual_keyboard` module to `bevy_feathers::controls` with a
single function also called `virtual_keyboard`.
`virtual_keyboard` takes a list of rows of keys and a system ID for the
key press handler and returns a bundle of buttons representing the keys
arranged into rows.

Lot of limitations:
* No modifier keys.
* No styling for individual keyboard buttons.
* The keyboard buttons can only display text, no image support. 
* The keys don't repeat when held.
* Doesn't have any navigation support for use with a controller.
* Doesn't support tall keys that span multiple rows.

#

I deliberately didn't spend even a moment thinking about the design,
this is just meant to be a super basic implementation that I can hook up
to the text input widget for testing. Still looks quite neat, even so.

## Testing

```
cargo run --example virtual_keyboard --features="experimental_bevy_feathers"
```
---

## Showcase

<img width="1042" height="573" alt="virtual_keyboard"
src="https://github.com/user-attachments/assets/f882cbec-ccdf-4df1-a32e-255c063454d4"
/>

---------

Co-authored-by: Alice Cecile <[email protected]>

* Untangle Cursor Dependencies (bevyengine#20427)

# Objective

Fixes bevyengine#20182
Fixes bevyengine#20381
Alternative to bevyengine#20384

## Solution

The root cause of the problems above is that `bevy_window` includes
`bevy_window::ANDROID_APP`, which prevents it from behaving as a
backend-agnostic window API. This forces `bevy_asset` to take a
dependency on `bevy_window` just to provide android support, which is
unnecessary. This in turn prevents `bevy_window` from owning the
relevant CursorIcon / CustomCursor types, because it would need to
depend on `bevy_asset`, which creates a circular dependency.

The solution is to move `ANDROID_APP` to a new `bevy_android` crate,
which `bevy_asset` can then depend on. This allows the
"backend-agnostic" cursor types to live in `bevy_window`, which then
allows `bevy_feathers` to remove its dependency on `bevy_winit`.

While I was touching this code I also chose to make `CustomCursor::Url`
available on all platforms. This is up to the backends to implement (or
not implement). It also means that users no longer need to know the
magic `#[cfg]` block to make their code compile on all platforms.
`bevy_winit` currently logs a `error_once` if it is ever used on a
platform where it is not supported.

* Clean up specialized_mesh_pipeline (bevyengine#20107)

# Objective

- The example doesn't work on webgl2
- It tries to reimplement logic for batching instead of using existing
abstractions which breaks on webgl2
- It only uses batching

## Solution

- Use existing abstractions and remove code related to batching
	- This fixes the webgl2 issue
	- It also makes it use multi draw indirect instead of just batching

## Testing

- Tested the example with the bevy cli for webgl and wegpu and also ran
the example locally

* Remove generic parameter from `Access`, since it's always `ComponentId` (bevyengine#20288)

# Objective

Simplify code that uses `Access`. Following bevyengine#19143, we no longer use
`Access<ArchetypeComponentId>` anywhere, only `Access<ComponentId>`. We
can simplify the code by removing the generic and having `Access` only
use `ComponentId`.

## Solution

Remove the generic parameter from `Access`, `AccessFilters`,
`FilteredAccess`, and `FilteredAccessSet`, replacing it with
`ComponentId`. Also remove the parameter from `FormattedBitSet`, but use
plain `usize` to make the output more concise.

* Implement field_at[_mut] for Struct DynamicVariant (bevyengine#20424)

# Objective

This implements the field_at methods for Struct DynamicEnum Variants
instead of only the Tuple variants. This brings it inline with
DynamicStructs and the docs for the Enum trait.

Fixes bevyengine#20402 

## Solution

Instead of only matching on the Tuple variant, it matches on the Struct
variant as well

## Testing

Let me know if there's some place where unit tests should be added. I
couldn't see any existing ones, but I can add them if needed.

* Color sliders (bevyengine#20422)

# Objective

Part of bevyengine#19236 

## Solution

This PR adds the color slider widgets, now that HSL gradients are
working.

An earlier version of this PR included Oklab sliders, but those have
been removed for now (Oklab requires a more sophisticated color picker).

# Showcase

<img width="381" height="233" alt="color-sliders-new"
src="https://github.com/user-attachments/assets/11b2c77f-35e2-41a3-abe4-fad598ed4240"
/>

* Make `HierarchyPropagatePlugin` scheduling configurable (bevyengine#20433)

# Objective

Make the schedule that propagation systems run within configurable

---------

Co-authored-by: Carter Anderson <[email protected]>

* Reflect auto registration (bevyengine#15030)

# Objective
This PR adds automatic registration of non-generic types annotated with
`#[derive(Reflect)]`.
Manually registering all reflect types can be error-prone, failing to
reflect during runtime if some type is not registered. bevyengine#5781 fixed this
for nested types, improving ergonomics of using reflection dramatically,
but top-level types still need to be registered manually. This is
especially painful when prototyping and using inspector to change values
of components.
```rs
// from bevyengine#5781
#[derive(Reflect)]
struct Foo(Bar);

#[derive(Reflect)]
struct Bar(Baz);

#[derive(Reflect)]
struct Baz(usize);

fn main() {
  // ...
  app.register_type::<Foo>() // <- can still forget to add this
  // ...
}
```

Fixes bevyengine#3936.

## Solution
Automatically register all types that derive Reflect. This works for all
non-generic types, allowing users to just add `#[derive(Reflect)]` to
any compatible type and not think about where to register it.
```rs
fn main() {
  // No need to manually call .register_type::<Foo>()
  App::new()
    .add_plugins(DefaultPlugins)
    .add_systems(Startup, setup)
    .run();
}

#[derive(Reflect)]
pub struct Foo {
  a: usize,
}

fn setup(type_registry: Res<AppTypeRegistry>) {
  let type_registry = type_registry.read();
  assert!(type_registry.contains(TypeId::of::<Foo>()));
}
```

Automatic registration can be opted-out of by adding
`#[reflect(no_auto_register)]` reflect attribute to a type:
```rs
#[derive(Reflect)]
#[reflect(no_auto_register)]
pub struct Foo {
  a: usize,
}
```

Registration normally happens at app creation time, but `TypeRegistry`
itself has a new `register_derived_types` method to register all
collected types at any appropriate time:

```rs
#[derive(Reflect)]
struct Foo {
  name: Option<String>,
  value: i32
}

let mut type_registry = TypeRegistry::empty();
type_registry.register_derived_types();

assert!(type_registry.contains(TypeId::of::<Foo>()));
```

## Testing
- Tested by running `reflect` example and removing explicit type
registration, both on native and on `wasm32-unknown-unknown`.
- Added a doctest to `register_derived_types`

Impact on startup time is negligible: <40ms on debug wasm build and
<25ms on debug native build for 1614 registered types .

Wasm binary size comparison. All sizes are in KB as reported by `du` on
the modified `reflection` example.

| | **auto register, KiB** | **no auto register, KiB** | **abs diff,
KiB** | **% diff** |
| ---------------------------- | ---------------------- |
------------------------- | ----------------- | ---------- |
| wasm-release && wasm-bindgen | 27000 | 24224 | 2776 | 11.46% |
| wasm-opt -Oz | 16376 | 15340 | 1036 | 6.75% |
| wasm-opt -Os | 17728 | 16424 | 1304 | 7.94% |
| wasm-opt -Oz && gzip -c | 5620 | 5364 | 256 | 4.77% |


## Considerations
While automatic type registration improves ergonomics quite a bit for
projects that make heavy use of it, there are also some problems:
- Generic types can't be automatically registered. However, as long as
top-level reflect types don't need generics, recursive registration can
take care of the rest.
- Wasm bundle size increase is not insignificant. This is mostly due to
registering various engine types that weren't registered before. Size
overhead of automatic registration of types instead of manual is
relatively small, as can be see from this (somewhat outdated but still
relevant) table (see last 2 rows):

<details>

<summary>1000 simple structs with reflect wasm size comparison, no
engine types</summary>

| | auto register, KiB | no auto register, KiB | abs diff, KiB | % diff
|
| --------------------------------------------- | ------------- |
---------------- | -------- | ------ |
| wasm-release && wasm-bindgen | 27944 | 21644 | 6300 | 22.55% |
| wasm-release && wasm-bindgen +register_type | 28084 | 27764 | 320 |
1.14% |
| wasm-opt -Oz | 15612 | 13928 | 1684 | 10.79% |
| wasm-opt -Oz +register_type | 15676 | 15580 | 96 | 0.61% |
| wasm-release && wasm-bindgen (manual vs auto) | 27944 | 27764 | 180 |
0.64% |
| wasm-opt -Oz (manual vs auto) | 15612 | 15580 | 32 | 0.2% |

</details>

---------

Co-authored-by: Gino Valente <[email protected]>
Co-authored-by: Carter Anderson <[email protected]>

* Material bind group shader def (bevyengine#20069)

Use a shader def for the material bind group index to make it easier for
when we want to switch back to group 2 in the future without breaking
everyone again.

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: atlv <[email protected]>
Co-authored-by: atlas dostal <[email protected]>

* Trim dependencies. (bevyengine#20426)

# Objective

Remove unneeded dependencies.

## Solution

Found using `cargo-shear`, `cargo-machete`, and `cargo-udeps`. They all
do the same thing (identify unused dependencies), they are all so-so at
it (with lots of false negatives and positives) but the combination of
all three is enough to get a useful outcome.

## Testing

- I double-checked all the removals by grepping for each removed
dependency's name within the affected crate, to make sure there weren't
any uses remaining. I think they're all ok.
- `cargo run -p ci`

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: James Liu <[email protected]>

* Record render diagnostics for all engine passes (bevyengine#19191)

# Objective

- Fixes bevyengine#16742

## Solution

- Adds GPU spans for all the engine's render and compute passes. Related
passes have been grouped into a single span (following the same
convention as bloom, which was already implemented).

## Testing

- Tested all the various rendering features on Windows 11 + Vulkan and
also some on DirectX.

## Showcase

A tracy graph with lots of rendering features enabled:


![tracy-profiler_K9YpjdqJL5](https://github.com/user-attachments/assets/62ac41cf-394e-4cc1-b448-4cab26340501)

## Follow up

* Nesting spans - there are 2 problems I encountered that stopped me
from implementing this
1. Spans have to be declared in the same scope so it's not clear how to
group passes across nodes in the render graph. Possibly a skill issue on
my part :)
2. Nested spans appear incorrectly in tracy (all on the same y axis). I
don't know if this is a bug in tracy, a bug in the tracy_client crate or
something to do with the multithreading workaround `end_zone()` hack but
I couldn't really get it to work. I left a nested span in
meshlet_visibility_buffer_raster for each shadow view so you can see
what it looks like by trying the meshlet example (let me know if I
should remove it).
* Improve developer usability - after writing the same code over and
over I started to feel like bevy should have its own create
render/compute pass functions so it can instrument them automatically.
It would also make it less likely for future PRs to forget to add
diagnostics.

## Additional notes

There were talks on render crate refactors happening - I think the
changes are small enough that rebases won't be difficult but also feel
free to delay merging until later if it'll get in the way.

---------

Co-authored-by: atlv <[email protected]>

* Improve error for when you try running a one-shot system with wrong `SystemId` type (bevyengine#19011)

# Objective

Improve error message when running a one-shot system with a `SystemId`
of wrong type.

## Solution

Added a resource to keep track of running one-shot systems, and return
`Recursive` error if a system gets run before the end of their previous
invocation. The error for not being able to `take` a `RegisteredSystem`
is now `MaybeWrongType`.

## Testing

Minimal reproduction from bevyengine#19005

## Showcase

```
// Old
2025-05-01T12:42:54.305283Z  WARN bevy_ecs::error::handler: Encountered an error in command `bevy_ecs::system::commands::command::run_system<()>::{{closure}}`: System SystemId(4v1#4294967300) tried to run itself recursively
2025-05-01T12:42:54.305311Z  WARN bevy_ecs::error::handler: Encountered an error in command `bevy_ecs::system::commands::command::run_system_with<bevy_ecs::system::input::In<&str>>::{{closure}}`: System SystemId(5v1#4294967301) tried to run itself recursively

// New
2025-05-05T14:21:44.918145Z  WARN bevy_ecs::error::handler: Encountered an error in command `bevy_ecs::system::commands::command::run_system<()>::{{closure}}`: Could not get system from `SystemId`, entity was `SystemId<(), Result<(), BevyError>>`
2025-05-05T14:21:44.918177Z  WARN bevy_ecs::error::handler: Encountered an error in command `bevy_ecs::system::commands::command::run_system_with<bevy_ecs::system::input::In<&str>>::{{closure}}`: Could not get system from `SystemId<In<&str>>`, entity was `SystemId<In<&str>, Result<(), BevyError>>`
```

## TODO
- [x] Add `TypeId` to `SystemIdMarker`
- [x] Migration guide for new enum variant

---------

Co-authored-by: Alice Cecile <[email protected]>

* `spec_v2` style and patterns (bevyengine#20348)

# Objective

- Adds some util methods to remove some boilerplate from specializers.
More will probably be added later but `set_target` and `set_layout` will
be the most used I think.
- Note: Specializers can't rely on their input descriptor having a
certain shape, so instead of just `push`ing to each vec, the methods pad
the length of the vec if necessary and set the value directly.
- After migrating a few engine `Specializer`s, `GetBaseDescriptor` &
`SpecializedCache: Resource` both seem like anti-patterns, especially
with dynamic materials on the horizon
- Also removes `user_specializer`s. If anyone needs that functionality
they can easily make a wrapper for it.

## Solution

- Add the things
- Nuke the stuff
- update the migration guide

* Use the hierachy plugin to propagate `ComputedNodeContext` (bevyengine#20432)

# Objective

From tim-blackbird on discord:
```
Spawning an entity (without Node) as a child of a parent Node and then adding a Node component to that child a frame later causes the child not to appear (same for Text as in the given example).
Setting the system to run at the first frame (FrameCount(0)) makes it function as expected 
```
```rust
use bevy::{diagnostic::FrameCount, prelude::*};

fn main() {
    App::new()
    .add_plugins(DefaultPlugins)
    .add_systems(Startup, setup)
    .add_systems(Update, insert_text.run_if(resource_equals(FrameCount(1))))
    .run();
}

fn setup(mut commands: Commands) {
    commands.spawn((Node::default(), children![Text::new("Gamer"), Marker]));
    commands.spawn(Camera3d::default());
}

fn insert_text(entity: Single<Entity, With<Marker>>, mut commands: Commands) {
    commands.entity(*entity).insert(Text::new("remaG"));
}

#[derive(Component)]
struct Marker;
```

## Solution

Use the hierarchy plugin to propagate `ComputedNodeContext`.

The problem was that the `ComputedNodeContext` isn't updated immediately
and so the text isn't rendered because the extraction function can't
find a render target.

## Testing

Run the example above.

---------

Co-authored-by: Tim Blackbird <[email protected]>

* Remove Manual Type Registrations (bevyengine#20435)

# Objective

Thanks to bevyengine#15030, we no longer need manual type registrations. This
should only be merged after bevyengine#15030.

## Solution

Remove all manual (non generic) type registrations.

* CI fixes for Rust 1.89 (bevyengine#20462)

Adopted from bevyengine#20456

Notes:

* The origin of the `dead_code` lints were coming from the `ShaderType `
derive macro. This has been reported as
teoxoy/encase#102, and a temporary
workspace-wide `allow` added to the top level Cargo.toml.
* One of the lints pointed out that `PartialEq` and `Eq` may not work as
expected for function pointers, so `CloneBehavior` no longer implements
either trait, and pattern matching is used in instead.

Original PR Description:
># Objective
>
>Unbreak CI.
>
> ## Solution
>
> Fix the lints.
>
>I've opted for anonymous lifetimes in every revealed case so far;
please let me know if you think I should used named lifetimes in
specific cases and why.
>
>## Testing
>
>Is CI green?
>
>## Context
>
> This lint originally had a much larger splash damage, with fairly
negative effects on Bevy. See
rust-lang/rust#131725.
>
> The more restricted former is much more helpful, despite the large
diff in this PR. Bevy is a large code base!
>
>## TODO
>
>- [x] discuss proposed lifetime lint fixes
>,- [x] use cargo clippy --fix to fix newly uncovered docs misformatting
>- [x] fix newly revealed dead code issues
>- [x] ensure CI is green

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Mike <[email protected]>

* try to fix GitHub Actions permissions (bevyengine#20431)

# Objective

- since bevyengine#20416 GitHub Actions complains that:
```
Invalid workflow file
The workflow is not valid. .github/workflows/example-run-report.yml (Line: 71, Col: 3): Error calling workflow 'bevyengine/bevy/.github/workflows/send-screenshots-to-pixeleagle.yml@caafa03'. The workflow is requesting 'contents: read', but is only allowed 'contents: none'.
```

## Solution

- I couldn't find it in the documentation, but I suppose that
permissions are inherited through workflow calls so I'm adding the
permission to the parent workflow

🤞

* Update docs to use MATERIAL_BIND_GROUP (bevyengine#20458)

# Objective

- Make the docs consistent with the shaders

## Solution

- Fix them

## Testing

- its docs

* Make shadows respect render layers (bevyengine#20327)

Adopted from and closes bevyengine#18747. Original work by @Adriigbs.

Shadows and render layers are a bit complicated. Ideally, this filtering
would be done at a higher level, but the camera entity just holds a list
of references to the light entities for that view. Those light entities
then compute what entities are visible from their perspective. We don't
actually get a chance to filter camera and light visible entity until we
queue the shadow pass, which is where this PR chooses to filter out
entities that aren't visible in a camera from casting shadows.

The alternative would be to store a per camera per light list of
entities, which would greatly increase the amount of memory required for
visible entities in multi-camera setups.

---------

Signed-off-by: Adrian Graur <[email protected]>
Co-authored-by: Adrian Graur <[email protected]>
Co-authored-by: Adrian Graur <[email protected]>

* Update toml_edit requirement from 0.22.7 to 0.23.2 (bevyengine#20441)

# Objective

- Closes bevyengine#20410

## Solution

- Updated a deprecated type alias name (`ImDocument` -> `Document`).

## Testing

- CI checks

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James Liu <[email protected]>

* Update `rand`, `glam` and `encase` to latest versions (bevyengine#18047)

# Objective

New `rand` version, which means updating `glam` and `encase` to support
the newer ecosystem update. Does mean that this changes how WASM builds
need to be done in order to configure `getrandom` correctly, but this
can be remedied with updated docs.

## Solution

Updating all needed dependencies to their compatible versions. ~~This PR
is currently blocked by `encase`, which is waiting on [this
PR](teoxoy/encase#88) to be merged and then a
new version published.~~ ~~This PR is no longer blocked~~,
~~`hexasphere` is blocking this PR now due to not yet having a new
release with the latest `glam` version support~~, The PR is all good to
go now, everything in order across glam/rand deps.

## Testing

- Must pass CI for all checks, tests, not introduce breaking changes.

---

## Migration Guide

With newer versions of `glam` & `encase`, the updated versions don't
seem to have introduced breakages, though as always, best to consult
their docs [1](https://docs.rs/glam/latest/glam/)
[2](https://docs.rs/encase/0.11.0/encase/) for any changes.

`rand` changes are more extensive, with changes such as `thread_rng()`
-> `rng()`, `from_entropy()` -> `from_os_rng()`, and so forth. `RngCore`
is now split into infallible `RngCore` and fallible `TryRngCore`, and
the `distributions` module has been renamed to `distr`. Most of this
affects only internals, and doesn't directly affect Bevy's APIs. For the
full set of changes, see `rand` [migration
notes](https://rust-random.github.io/book/update-0.9.html).

`getrandom` is also updated, and will require additional configuration
when building Bevy for WASM/Web (if also using `rand`). The full details
of how to do this is in the `getrandom` docs
[1](https://github.com/rust-random/getrandom?tab=readme-ov-file#opt-in-backends)
[2](https://github.com/rust-random/getrandom?tab=readme-ov-file#webassembly-support).

---------

Co-authored-by: François Mockers <[email protected]>

* Add VERBOSE_SHADER_ERROR (bevyengine#20448)

# Objective

- Make it easier to debug shader def problems in shader libraries

## Solution

- print context of where the shader module's entry point is and what the
shader defs are

## Testing

- intentionally broke a shader and ran 3d_scene, logs are added when env
var is set.
<img width="917" height="259"
alt="{9D77F6EF-9813-4C18-90A9-51E81388D681}"
src="https://github.com/user-attachments/assets/7ae42479-e548-40bf-8d26-ee61bab7c279"
/>

* stop re-exporting RenderAssetUsages from bevy_render (bevyengine#20470)

# Objective

- I believe I left this here to ease migration in the previous release,
but shouldn't be re-exported long-term.

## Solution

- yeet

## Testing

- ci

---------

Signed-off-by: Adrian Graur <[email protected]>
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: JMS55 <[email protected]>
Co-authored-by: SparkyPotato <[email protected]>
Co-authored-by: atlv <[email protected]>
Co-authored-by: Benjamin Brienen <[email protected]>
Co-authored-by: charlotte 🌸 <[email protected]>
Co-authored-by: François Mockers <[email protected]>
Co-authored-by: Lucas Franca <[email protected]>
Co-authored-by: Miles Silberling-Cook <[email protected]>
Co-authored-by: Zac Harrold <[email protected]>
Co-authored-by: ickshonpe <[email protected]>
Co-authored-by: Simon Hausmann <[email protected]>
Co-authored-by: James Liu <[email protected]>
Co-authored-by: Christian Hughes <[email protected]>
Co-authored-by: IceSentry <[email protected]>
Co-authored-by: Kees van Beilen <[email protected]>
Co-authored-by: neko <[email protected]>
Co-authored-by: Carter Anderson <[email protected]>
Co-authored-by: Chris Russell <[email protected]>
Co-authored-by: Jackson Garner <[email protected]>
Co-authored-by: Talin <[email protected]>
Co-authored-by: eugineerd <[email protected]>
Co-authored-by: Gino Valente <[email protected]>
Co-authored-by: atlv <[email protected]>
Co-authored-by: Nicholas Nethercote <[email protected]>
Co-authored-by: jf908 <[email protected]>
Co-authored-by: Emerson Coskey <[email protected]>
Co-authored-by: Mike <[email protected]>
Co-authored-by: Adrian Graur <[email protected]>
Co-authored-by: Adrian Graur <[email protected]>
Co-authored-by: Martín Maita <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Gonçalo Rica Pais da Silva <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Reflection Runtime information about types C-Usability A targeted quality-of-life change that makes Bevy easier to use M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide M-Needs-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Controversial There is active debate or serious implications around merging this PR
Projects
Status: Responded
Status: In Progress
Development

Successfully merging this pull request may close these issues.

Recursive Type Registration
8 participants