Another week, another #bevymergetrain for the #bevy crew :) As is now tradition, I'm going to go over the community-approved (that means you!) PRs for our #opensource #rust game engine.

Despite cleaning them all out last week, there's apparently another 33 PRs already?? https://github.com/bevyengine/bevy/pulls?q=is%3Aopen+is%3Apr+label%3AS-Ready-For-Final-Review

1. https://github.com/bevyengine/bevy/pull/18916

Ha, minimized windows: the bane of #gamedev. So many divide-by-zero bugs! Today, we're fixing a crash when minimizing a window with custom viewports. We've managed to fix a dozen of these already, so it make sense that this is niche. LGTM, merging :)

Fixing a crash when minimizing a window with custom viewport. (#16704) by RuelYasa · Pull Request #18916 · bevyengine/bevy

Objective Fix a crash when minimizing a window. (#16704) It happens when the window contains Camera with a custom Viewport. Solution Remove ExtractedCamera when the corresponding camera in main wor...

GitHub

2. https://github.com/bevyengine/bevy/pull/19117

An edge case bug in our asset loading. The `meta_transform` here is "how to modify the asset metadata".

This is incorrect by inspection, so I'm going to merge it. We do badly need more tests for bevy_assets still though: so many edge cases. Maybe we can fuzz?

Fix a `NestedLoader` code path that failed to use its meta transform by greeble-dev · Pull Request #19117 · bevyengine/bevy

Solution While poking around NestedLoader I noticed that one code path fails to pass on the loader's meta transform. - .get_or_create_path_handle(path, None) + .get_or_create_path_handle(path, ...

GitHub

3. https://github.com/bevyengine/bevy/pull/19138

More on_unimplemented custom diagnostics for #rust :D I love this feature so much. Very simple diagnostic (just "this isn't a read-only system"), but should still make a big difference. The type alias is perfectly sensible too.

Merge conflicts, so pinging the OP.

ReadOnlySystem diagnostics and type alias by ItsDoot · Pull Request #19138 · bevyengine/bevy

Objective Improve usability of read-only systems. Solution Added on_unimplemented diagnostics for types/functions that aren't read-only systems. Added BoxedReadOnlySystem type alias, similar...

GitHub

4. https://github.com/bevyengine/bevy/pull/19559

PR description looks reasonable: a code quality / usability fix to how we handle glyph positions. But uh, what the +40k/-17k diff?! Oh, git screwed up :( This needs to be rebased, which should fix the diff. Author has already been pinged, but let me try on Discord...

Object-centered text layout by ickshonpe · Pull Request #19559 · bevyengine/bevy

Objective In the text layout the glyph sprites are objected-centered but their positions are relative to the top-left corner of the text layout. For the sake of consistancy, use object-centered coo...

GitHub

5. https://github.com/bevyengine/bevy/pull/19586

Oh-ho-ho: improvements to our scrolling example. I'm excited to continue improving our UI examples, since we have the bare bones of a real widget library now: both headless and via bevy_feathers.

This is rebased, so it's time to merge :)

Robust Scrolling Example by tim-blackbird · Pull Request #19586 · bevyengine/bevy

Objective A more robust scrolling example that doesn't require Pickable { should_block_lower: false, .. } or Pickable::IGNORE, and properly handles nested scrolling nodes. The current example s...

GitHub

6. https://github.com/bevyengine/bevy/pull/19922

A simple cleanup of our reflection code (which will help a tiny bit with compile times). The interesting bit here is my back-and-forth with nnethercote about why we use squash-on-merge. TL;DR: it's really nice to be able to bisect the history.

Squashing and merging ;)

bevy_reflect: Use `active_types` instead of `active_fields` where appropriate by nnethercote · Pull Request #19922 · bevyengine/bevy

Objective Follow on fixes for #19876, using active_types instead of active_fields where appropriate. Helps a tiny bit with #19873. Solution Describe the solution used to achieve the objective abov...

GitHub

7. https://github.com/bevyengine/bevy/pull/19999

More RenderStartup! I really love this set of changes: it makes the ordering of our rendering initialization much more controllable and explicit. And it reduces the stupid "plugin initialization order dependency' woes.

I'm surprised this is negative LOC! LGTM; merging.

Use `RenderStartup` for `bevy_pbr` for some basic cases. by andriyDev · Pull Request #19999 · bevyengine/bevy

Objective Progress towards Use RenderStartup instead of a FromWorld impl whenever possible #19887. Solution For cases that don't need to conditionally add systems, we can just replace FromWo...

GitHub

8. https://github.com/bevyengine/bevy/pull/20002

And a second RenderStartup PR :D Thank goodness for having at least *some* automated rendering testing now: it makes these changes much more reliable.

Same deal here: merging.

Use `RenderStartup` for all basic cases in `bevy_core_pipeline`. by andriyDev · Pull Request #20002 · bevyengine/bevy

Objective Progress towards Use RenderStartup instead of a FromWorld impl whenever possible #19887. Solution Convert FromWorld impls into systems. Run those systems in RenderStartup. Testing Ra...

GitHub

9. https://github.com/bevyengine/bevy/pull/20016

A TOCTOU bug in our ECS internals. No, no, not the cryptocurrency scammer! For those with an unconventional background in #programming like myself, TOCTOU means Time of Check Time of Use: a common class of bugs that's caused by the data changing after your check.

Prevent TOCTOU bugs in ComponentsQueuedRegistrator by SkiFire13 · Pull Request #20016 · bevyengine/bevy

Objective Fix ComponentsQueuedRegistrator::queue_register_component does not ensure components are registered only once #20014 Solution Don't make the force_register_ family of functions alw...

GitHub
Good fix though, and it it even comes with a regression test! The original bug itself is stochastic, so we're repeating the test 1000 times. Nice work by SkiFire13: it's always fun to see skilled engineers at work.

10. https://github.com/bevyengine/bevy/pull/20023

Apparently we missed adding release notes for light textures! Well, that's an easy fix, and it's nice we can just make a follow-up PR.

These are a little rough and will need editing, but that's an expected part of our release workflow. I'm just glad we remembered!

Add release note for light textures by atlv24 · Pull Request #20023 · bevyengine/bevy

Objective Fixes Light textures are missing a release note #19982 Solution add note Testing left as an exercise for the reader

GitHub

11. https://github.com/bevyengine/bevy/pull/20053

Another missed release note: this time about the faster zstd backend. I think this needs more context about what zstd is and why this is important enough to warrant a release note, but we can hash that out in the final editing process. Sure, merging.

Add zstd release note by atlv24 · Pull Request #20053 · bevyengine/bevy

Objective Add a release note for the new zstd backend. Doing so, I realized it was really cumbersome to enable this feature because we default-enable ruzstd AND make it take precedence if both are...

GitHub

12. https://github.com/bevyengine/bevy/pull/20055

A feature flag fix: you *really* only want to enable dependency features in #rust if you actually need it, because features are additive and cannot be later disabled.

Perfectly reasonable fix: merging. Boy i wish there was better tooling for this though.

Fix core widgets unconditionally enabling bevy_ui_picking_backend by atlv24 · Pull Request #20055 · bevyengine/bevy

Objective Fixes bevy_ui_picking_backend feature can't be disabled #19742 Solution Initially I made it an optional feature on bevy_core_widgets and piped it through to bevy_internal, but then...

GitHub

13. https://github.com/bevyengine/bevy/pull/20065

A really interesting PR that allows us to move components from one entity to another even if they aren't `Clone`. Intuitively makes a lot of sense, but the details were tricky. Very high quality engineering by eugineerd, and excellent review by urben.

Merging :)

allow `EntityCloner` to move components without `Clone` or `Reflect` by eugineerd · Pull Request #20065 · bevyengine/bevy

Objective Fix #18079 Solution EntityCloner can now move components that don't have Clone or Reflect implementation. Components with ComponentCloneBehavior::Ignore will not be moved. Components...

GitHub

> I believe fixing known bugs outweighs [code cleanup] for now.

Good take! This is the way: fix the bugs, add tests, then refactor to something cleaner. I increasingly think that we're sharing too much between moving / cloning components, but I trust them to figure out a solution in the future.

14. https://github.com/bevyengine/bevy/pull/20077

Why is it always edge cases? Rendering features are so tricky to ship because of the complex interaction between features. Good work detecting this bug, and good job fixing it.

We could use more rendering tests to test all these combinations, but merging the fix now.

Fix anisotropy not working when material is lit by environment map light by marlyx · Pull Request #20077 · bevyengine/bevy

Fixes objects being lit by environment map light not having the anisotropy effect applied correctly. The contribution of light from the environment map with anisotropy is calculated but immediately...

GitHub

15. https://github.com/bevyengine/bevy/pull/20082

Shape sampling for rhombuses! Sure, I can see this being useful to someone at some point. Maybe isometric tile-based games? I like that the trait-based design lets us gradually add these methods one at a time while ensuring consistency.

Merging.

Rhombus sampling by lynn-lumen · Pull Request #20082 · bevyengine/bevy

Objective Implement ShapeSample for Rhombus Testing The results can be verified visually. Showcase Boundary Interior

GitHub

16. https://github.com/bevyengine/bevy/pull/20083

Another bug fix from the author before. Clearly a skilled rendering engineer, but they're new around these parts. Neat! Only a partial fix for forward rendering only, but that's better than nothing.

Spinning up a follow-up and merging.

Fix AmbientLight::affects_lightmapped_meshes not working by marlyx · Pull Request #20083 · bevyengine/bevy

Objective Fix lightmapped materials not respecting the AmbientLight::affects_lightmapped_meshes setting. NOTE: This only makes the setting work on the forward renderer. Making it work on the deferr...

GitHub

17. https://github.com/bevyengine/bevy/pull/20089

Ah, Jan's work to carefully document how to move your camera when working with a fixed timestep. This is a massive pain in the ass to do right. I wish it was easier to do right, but for now, documenting the arcane arrangement is really nice.

Port the physics in fixed timestep example to 3D by janhohenheim · Pull Request #20089 · bevyengine/bevy

Objective Since I originally wrote this example, many people on Discord have asked me specifically how to handle camera movement in and around fixed timesteps. I had to write that information up ma...

GitHub

Extremely clear and helpful. Lots of words, but I think it's warranted here.

Interestingly, even when we have a built-in fly cam, I wouldn't replace this! These details are critical to users: we should present them directly, rather than hiding them.

I'm happy with this: let's merge it in :)

18. https://github.com/bevyengine/bevy/pull/20090

Bevy uses the "latest stable" #rust as its MSRV. That means we can use let chains today to clean things up! Oh yeah baby, give me that +17/-34 diff :D

Merging.

Refactor `2d_viewport_to_world` example with let chains by tim-blackbird · Pull Request #20090 · bevyengine/bevy

Objective Make use of let chains to reduce LoC where we previously used let else to cut down on indentation. Best of both worlds. Hmm, déjà vu?

GitHub

19. https://github.com/bevyengine/bevy/pull/20096

Oh nice, some doc tests demonstrating how to use `camera_to_world`. They even mention the timing needed to ensure that transform propagation has taken place! Very terse, I love it. Bevy really is a research project some days, but that extends to API design.

Merging.

Add doc examples to `viewport_to_world(_2d)` by tim-blackbird · Pull Request #20096 · bevyengine/bevy

Objective Add doc examples to viewport_to_world and viewport_to_world_2d. With Single and let chains these can be very concise now :) Rendered: I changed my mind on how much to limit the decimal ...

GitHub

20. https://github.com/bevyengine/bevy/pull/20097

A broken link to the shiny new bevy_solari logo. We can't be having that! The link now works: it's merging time :D I love love love tiny PRs: they're so easy to just merge.

Fix link to `bevy_solari` logo by BD103 · Pull Request #20097 · bevyengine/bevy

Objective The bevy_solari logo doesn't load in the dev-docs: This is because the link to the image, https://raw.githubusercontent.com/bevyengine/bevy/assets/branding/bevy_solari.svg, returns a...

GitHub

21. https://github.com/bevyengine/bevy/pull/20098

Speaking of tiny PRs: slap some const on that function. Yay const floating point arithmetic for making this possible. Merging.

I poked at this for bevy_color the other day, but we need const trait methods to really improve things there :( const fn lighten plz!

Constify `gradients` helper functions by ickshonpe · Pull Request #20098 · bevyengine/bevy

Objective Constify some of the helper functions in the UI's gradients module.

GitHub

22. https://github.com/bevyengine/bevy/pull/20101

Another iteration (within 0.17) on our event trait hierarchy. This time, we're finally killing the shared trait between buffered and observer traits entirely. Cart's on board with this too, so I marked this Blessed.

Split `BufferedEvent` from `Event` by tim-blackbird · Pull Request #20101 · bevyengine/bevy

Objective I think we should axe the shared Event trait entirely It doesn't serve any functional purpose, and I don't think it's useful pedagogically @alice-i-cecile on discord Solutio...

GitHub
The diff is trivial, which really demonstrates how vestigial this shared trait is. I'm going to merge this, since it reduces boilerplate and tech debt now, but I think we're going to have to do another round of bikeshedding on the existing shape of the observer trait. Maybe associated types?

23. https://github.com/bevyengine/bevy/pull/20104

And a second PR in this vein: automatically deriving the root `Event` trait (shared by both targeted and untargeted observer events). I'm not super-keen on how implicit the "also derive this other trait" pattern is, but I understand Cart's aversion to boilerplate.

Remove the need to derive `Event` when deriving `EntityEvent` by tim-blackbird · Pull Request #20104 · bevyengine/bevy

Objective Since we are planning to remove the need to derive both Event and EntityEvent in 0.17 either way, I'm choosing to do the easy thing in this PR so we can get the churn out of the way e...

GitHub
I *think* that an associated type or constant on `Event` is going to be nicer (no more Entity::PLACEHOLDER return values please!), but this will reduce the diffs needed to get there and is a better intermediate state. Letting 20101 merge, then I'll merge this after the merge conflicts are fixed.

24. https://github.com/bevyengine/bevy/pull/20108

Want to clone some struct and you can't? Tell us why you're trying to do that and then slap some Clone on that struct. I'm pretty sure this particular request is for some cursed meta-scheduling abstraction lol.

I'm fine with that though: let's merge this.

feat: implement clone for IntoPipeSystem by mrchantey · Pull Request #20108 · bevyengine/bevy

Objective Implement Clone for IntoPipeSystem, allowing for T: IntoSystem + Clone patterns. Precedence Same clone implementation/docs as CombinatorSystem

GitHub

25. https://github.com/bevyengine/bevy/pull/20112

Hang on, GPU memory allocation isn't blocking? What on earth is going on here. This is definitely over my head: I'm going to ask Rob Swain, my fellow maintainer and rendering expert for his help. This whole API feels off, and I'm not confident here.

26. https://github.com/bevyengine/bevy/pull/20118

Ah, this is more my speed of rendering PR: assorted cleanups! These changes all look fine: merging.

We should really be linting for .get_resource + .unwrap: lemme ask the CLI group....

27. https://github.com/bevyengine/bevy/pull/20120

I see folks are making good use of the `HierarchyPropagatePlugin` :D Very nice little feature! We should probably call that out in the release notes. Issue time.

This particular PR just adds some traits to `NotShadowCaster`: trivial and very reasonable. Merging :)

28. https://github.com/bevyengine/bevy/pull/20124

`RenderStartup` again! This time for examples :D Good stuff: it's nice to teach this to users. Merging :)

Switch most examples to use `RenderStartup` instead of `finish` and `FromWorld`. by andriyDev · Pull Request #20124 · bevyengine/bevy

Objective Progress towards Use RenderStartup instead of a FromWorld impl whenever possible #19887. I am avoiding dealing with the occlusion_culling example since it is kinda annoying to resolve ni...

GitHub

29. https://github.com/bevyengine/bevy/pull/20126

Another reflection cleanup / compile time optimization PR. TIL that you can rely on default method impls to improve compile times in #rust. I mean, it makes sense! I'd just never connected the dots. Merging :) Thanks for getting nerd-sniped so thoroughly :D

30. https://github.com/bevyengine/bevy/pull/20127

Crosslinks to a little ECS helper: `ComponentIdFor`. I call these sort of documentation crosslinks "bread crumbs" (since you can follow the trail and get gobbled up by a witch), and they're shockingly useful to users. That's level design baby!

Very reasonable; merging.

31. https://github.com/bevyengine/bevy/pull/20130

Math for #gamedev is weird: there's a ton of little tasks that you need to do constantly, but you can't assume your users are particularly good at the fundamentals needed to derive it from scratch. Very happy to have a "closest point to this line segment" method!

This PR is particularly lovely though: it comes with ASCII art comments, tests and clear code. TIL you can use full words for variable names in math code ;)

Thanks: this sort of work really exemplifies how I feel tools should work. Think about the common cases and make them easy. Merging.

And phew! We're done! Looks like my fellow maintainers have snagged a few of the PRs while I was doing this, so our count was off :p

The merge trains are a big time and energy commitment, but I really love doing them. They force me to reflect on each PR, and communicate a lot of silent context.

Thanks for following along, and please don't hesitate to comment and ask follow-up questions! Those are always my favorite <3

If you love these threads too, please consider contributing or donating to #bevy. I am so grateful I can do this as my fulltime job, and never want that to change.

@alice_i_cecile sure is! this one is for Route Handlers as Entities, get ready for a very bevy server 🐦🌐