Commit Graph

8993 Commits

Author SHA1 Message Date
Tero Laxström
c549b9e9a4
Copy stress test settings for many_camera_lights (#19512)
# Objective

- Fixes #17183

## Solution

- Copied the stress settings from the `many_animated_sprite` example
that were mentioned in the ticket

## Testing

- Run the example

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-06-10 01:12:55 +00:00
Alice Cecile
030edbf3fe
Rename bevy_ecs::world::Entry to ComponentEntry (#19517)
# Objective

As discussed in #19285, some of our names conflict. `Entry` in bevy_ecs
is one of those overly general names.

## Solution

Rename this type (and the related types) to `ComponentEntry`.

---------

Co-authored-by: urben1680 <55257931+urben1680@users.noreply.github.com>
2025-06-10 01:12:40 +00:00
Alice Cecile
6ddd0f16a8
Component lifecycle reorganization and documentation (#19543)
# Objective

I set out with one simple goal: clearly document the differences between
each of the component lifecycle events via module docs.

Unfortunately, no such module existed: the various lifecycle code was
scattered to the wind.
Without a unified module, it's very hard to discover the related types,
and there's nowhere good to put my shiny new documentation.

## Solution

1. Unify the assorted types into a single
`bevy_ecs::component_lifecycle` module.
2. Write docs.
3. Write a migration guide.

## Testing

Thanks CI!

## Follow-up

1. The lifecycle event names are pretty confusing, especially
`OnReplace`. We should consider renaming those. No bikeshedding in my PR
though!
2. Observers need real module docs too :(
3. Any additional functional changes should be done elsewhere; this is a
simple docs and re-org PR.

---------

Co-authored-by: theotherphil <phil.j.ellison@gmail.com>
2025-06-10 00:59:16 +00:00
Ayan Das
c35df3ca66
Added async_executor to the array of features enabled by multi_threaded within bevy_tasks crate to prevent compile-time error when default-features are disabled. (#19334)
## Objective

Fixes #19051.

---

## Solution
Originally implemented `compiler_error!()` within bevy_tasks/src/lib.rs
file to provide descriptive message regarding missing feature. However,
a cleaner approach was to add `async_executor` to the array of features
enabled by `multi_threaded` instead. This removes the need for users to
manually add `features = ["multi_threaded", "async_executor"]`
separately as needed to be done previously.

---

## Testing

These changes were tested using a minimal, external project designed to
specifically test whether the standalone `multi_threaded` feature for
`bevy_tasks` with `default-features` disabled worked as intended without
running into any compile-time error.

### How it was tested:
1. A `bevy_tasks_test` binary project was set up in an external
directory.
2. Its `Cargo.toml` was configured to depend on the local `bevy_tasks`,
explicitly disabling default features and enabling only
`multi_threaded`.
3. A simple `bevy_tasks_test/bin/bevy_crates_test.rs` was created and
configured within `Cargo.toml` file where bevy_tasks was set to the
local version of the crate with the modified changes and `cargo add
bevy_platform` was executed through the terminal since that dependency
is also needed to execute the sample examples.
4. Then both the `examples/busy_behavior.rs` and
`examples/idle_behavior.rs` code was added and tested with just the
`multi_threaded` feature was enabled and the code executed successfully.

### Results:
The code executed successfully for both examples where a threadPool was
utilized with 4 tasks and spawning 40 tasks that spin for 100ms.
Demonstrating how the threads finished executing all the tasks
simultaneously after a brief delay of less than a second (this is
referencing `bevy_tasks/examples/busy_behavior.rs`). Alongside the
second example where one thread per logical core was was utilized for a
single spinning task and aside from utilizing the single thread, system
was intended to remain idle as part of good practice when it comes to
handling small workloads. (this is referencing
`bevy_tasks/examples/idle_behavior.rs`).

### How to test:
Reviewers can easily verify this by:
1.  Checking out this PR.
2. Creating `cargo new bevy_tasks_test` and the `Cargo.toml` should look
something like this:
    ```toml
    # bevy/tests/compile_fail_tasks/Cargo.toml
    [package]
    name = "bevy_tasks_test"
    version = "0.1.0"
    edition = "2021"
    publish = false

    [dependencies]
    # path to bevy_tasks sub-crate to test locally
bevy_tasks = { path = "../../bevy_tasks", default-features = false,
features = ["multi_threaded"] }
    bevy_platform = "0.16.1"
    ```
3. Copying the examples within bevy_creates/examples one by one and
testing them separately within `src/main.rs` to check whether the
examples work.
4. Then simply running `cargo run` within the terminal should suffice to
test if the single `multi_threaded` feature works without the need for
separately adding `async_executor` as `multi_threaded` already uses
`async_executor` internally.

### Platforms tested:
macOS (aarch64). As a `#[cfg]` based compile-time check, behavior should
be consistent across platforms.
2025-06-10 00:54:46 +00:00
Guillaume Wafo-Tapa
0e805eb49c
Implement SystemCondition for systems returning Result<bool, BevyError> and Result<(), BevyError> (#19553)
# Objective

Fixes #19403
As described in the issue, the objective is to support the use of
systems returning `Result<(), BevyError>` and
`Result<bool, BevyError>` as run conditions. In these cases, the run
condition would hold on `Ok(())` and `Ok(true)` respectively.


## Solution

`IntoSystem<In, bool, M>` cannot be implemented for systems returning
`Result<(), BevyError>` and `Result<bool, BevyError>` as that would
conflict with their trivial implementation of the trait. That led me to
add a method to the sealed trait `SystemCondition` that does the
conversion. In the original case of a system returning `bool`, the
system is returned as is. With the new types, the system is combined
with `map()` to obtain a `bool`.

By the way, I'm confused as to why `SystemCondition` has a generic `In`
parameter as it is only ever used with `In = ()` as far as I can tell.

## Testing

I added a simple test for both type of system. That's minimal but it
felt enough. I could not picture the more complicated tests passing for
a run condition returning `bool` and failing for the new types.

## Doc

I documenting the change on the page of the trait. I had trouble wording
it right but I'm not sure how to improve it. The phrasing "the condition
returns `true`" which reads naturally is now technically incorrect as
the new types return a `Result`. However, the underlying condition
system that the implementing system turns into does indeed return
`bool`. But talking about the implementation details felt too much.
Another possibility is to use another turn of phrase like "the condition
holds" or "the condition checks out". I've left "the condition returns
`true`" in the documentation of `run_if` and the provided methods for
now.

I'm perplexed about the examples. In the first one, why not implement
the condition directly instead of having a system returning it? Is it
from a time of Bevy where you had to implement your conditions that way?
In that case maybe that should be updated. And in the second example I'm
missing the point entirely. As I stated above, I've only seen conditions
used in contexts where they have no input parameter. Here we create a
condition with an input parameter (cannot be used by `run_if`) and we
are using it with `pipe()` which actually doesn't need our system to
implement `SystemCondition`. Both examples are also calling
`IntoSystem::into_system` which should not be encouraged. What am I
missing?
2025-06-10 00:04:10 +00:00
dependabot[bot]
06bb57c326
Bump crate-ci/typos from 1.32.0 to 1.33.1 (#19551)
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.32.0 to
1.33.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.33.1</h2>
<h2>[1.33.1] - 2025-06-02</h2>
<h3>Fixes</h3>
<ul>
<li><em>(dict)</em> Don't correct <code>wasn't</code> to
<code>wasm't</code></li>
</ul>
<h2>v1.33.0</h2>
<h2>[1.33.0] - 2025-06-02</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1290">May
2025</a> changes</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h2>[1.33.1] - 2025-06-02</h2>
<h3>Fixes</h3>
<ul>
<li><em>(dict)</em> Don't correct <code>wasn't</code> to
<code>wasm't</code></li>
</ul>
<h2>[1.33.0] - 2025-06-02</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1290">May
2025</a> changes</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b1ae8d918b"><code>b1ae8d9</code></a>
chore: Release</li>
<li><a
href="6c5d17de8e"><code>6c5d17d</code></a>
docs: Update changelog</li>
<li><a
href="0a237ba81a"><code>0a237ba</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1311">#1311</a>
from epage/wasn</li>
<li><a
href="79920cf069"><code>79920cf</code></a>
fix(dict): Don't correct <code>wasn't</code></li>
<li><a
href="e99b2b47d9"><code>e99b2b4</code></a>
chore: Release</li>
<li><a
href="2afc152754"><code>2afc152</code></a>
chore: Release</li>
<li><a
href="544a19b4ae"><code>544a19b</code></a>
docs: Update changelog</li>
<li><a
href="2e0ca28a95"><code>2e0ca28</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1310">#1310</a>
from epage/may</li>
<li><a
href="94eb4e7b40"><code>94eb4e7</code></a>
feat(dict): May 2025 updates</li>
<li><a
href="a4cce4ca70"><code>a4cce4c</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1308">#1308</a>
from crate-ci/renovate/schemars-0.x</li>
<li>Additional commits viewable in <a
href="https://github.com/crate-ci/typos/compare/v1.32.0...v1.33.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crate-ci/typos&package-manager=github_actions&previous-version=1.32.0&new-version=1.33.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
Co-authored-by: François Mockers <mockersf@gmail.com>
2025-06-09 23:40:47 +00:00
Lucas Franca
f5f092f2f3
Fix new typos (#19562)
# Objective

Fix new typos found on new version of `typos` (#19551)

## Solution

Fix typos
2025-06-09 22:55:14 +00:00
andriyDev
0381a798e2
Delete System::component_access(). (#19496)
# Objective

- Cleanup related to #19495.

## Solution

- Delete `System::component_access()`. It is redundant with
`System::component_access_set().combined_access()`.

## Testing

- None. There are no callers of this function.
2025-06-09 22:54:52 +00:00
Zion Klinger
a4dd873df8
Fix uninlined format argument lint (#19561)
# Objective
Fixes #19370 

## Solution
Implemented the lint as suggested by clippy.

## Testing
CI tests passed and lint was resolved.
2025-06-09 20:53:19 +00:00
urben1680
1294b71e35
Introduce CheckChangeTicks event that is triggered by World::check_change_ticks (#19274)
# Objective

In the past I had custom data structures containing `Tick`s. I learned
that these need to be regularly checked to clamp them. But there was no
way to hook into that logic so I abandoned storing ticks since then.

Another motivation to open this up some more is to be more able to do a
correct implementation of `System::check_ticks`.

## Solution

Add `CheckChangeTicks` and trigger it in `World::check_change_ticks`.
Make `Tick::check_tick` public.

This event makes it possible to store ticks in components or resources
and have them checked.

I also made `Schedules::check_change_ticks` public so users can store
schedules in custom resources/components for whatever reasons.

## Testing

The logic boils down to a single `World::trigger` call and I don't think
this needs more tests.

## Alternatives

Making this obsolete like with #15683.

---

## Showcase

From the added docs:

```rs
use bevy_ecs::prelude::*;
use bevy_ecs::component::CheckChangeTicks;

#[derive(Resource)]
struct CustomSchedule(Schedule);

let mut world = World::new();
world.add_observer(|tick: Trigger<CheckChangeTicks>, mut schedule: ResMut<CustomSchedule>| {
    schedule.0.check_change_ticks(tick.get());
});
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-06-09 20:44:49 +00:00
Marcel Müller
2768af5d2d
Allow not emitting BundleFromComponents with Bundle derive macro (#19249)
# Objective

Fixes #19136

## Solution

- Add a new container attribute which when set does not emit
`BundleFromComponents`

## Testing

- Did you test these changes?

Yes, a new test was added.

- Are there any parts that need more testing?

Since `BundleFromComponents` is unsafe I made extra sure that I did not
misunderstand its purpose. As far as I can tell, _not_ implementing it
is ok.

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?

Nope

- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

I don't think the platform is relevant

---



One thing I am not sure about is how to document this? I'll gladly add
it

---------

Signed-off-by: Marcel Müller <neikos@neikos.email>
2025-06-09 20:15:42 +00:00
Erick Z
b6e4d171b5
Adding PartialEq to some UI and Text types (#19552)
# Objective

- During the development of
[`bevy_flair`](https://github.com/eckz/bevy_flair) I found [some types
lacking
`PartialEq`](https://github.com/search?q=repo%3Aeckz%2Fbevy_flair%20%20%22Try%20to%20upstream%20it%20to%20bevy%22&type=code)
which made the unit testing a little bit inconvinient.

## Solution

- Adding `PartialEq` for the following types:
  - `LineHeight `
  - `TextShadow`
  - `NodeImageMode`

## Testing

- Letting github actions do the testing, this is not an invasive change
and `cargo run --bin ci` doesn't seem to work in `main` at the moment.
2025-06-09 20:08:17 +00:00
JMS55
bebe7c405d
Make camera controller not trigger change detection every frame (#19547)
Split off from https://github.com/bevyengine/bevy/pull/19058
2025-06-09 20:05:58 +00:00
JMS55
476e644a7d
Add extra buffer usages field to MeshAllocator (#19546)
Split off from https://github.com/bevyengine/bevy/pull/19058
2025-06-09 20:03:57 +00:00
Alice Cecile
155ebf7898
Write real docs for SystemSet (#19538)
# Objective

`SystemSet`s are surprisingly rich and nuanced, but are extremely poorly
documented.

Fixes #19536.

## Solution

Explain the basic concept of system sets, how to create them, and give
some opinionated advice about their more advanced functionality.

## Follow-up

I'd like proper module level docs on system ordering that I can link to
here, but they don't exist. Punting to follow-up!

---------

Co-authored-by: theotherphil <phil.j.ellison@gmail.com>
2025-06-09 20:03:02 +00:00
ickshonpe
02fa833be1
Rename JustifyText to Justify (#19522)
# Objective

Rename `JustifyText`:

* The name `JustifyText` is just ugly.
* It's inconsistent since no other `bevy_text` types have a `Text-`
suffix, only prefix.
* It's inconsistent with the other text layout enum `Linebreak` which
doesn't have a prefix or suffix.

Fixes #19521.

## Solution

Rename `JustifyText` to `Justify`.

Without other context, it's natural to assume the name `Justify` refers
to text justification.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-06-09 19:59:48 +00:00
SpecificProtagonist
437c4d5b25
Minor clear color doc improvements (#19514) 2025-06-09 19:56:58 +00:00
theotherphil
5279863c42
Add missing docs for ImageLoader (#19499)
# Objective

Yet another tiny step towards
https://github.com/bevyengine/bevy/issues/3492.

---------

Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
2025-06-09 19:46:33 +00:00
andriyDev
f163649b48
Use component_access_set to determine the set of conflicting accesses between two systems. (#19495)
# Objective

- Fixes #4381

## Solution

- Replace `component_access` with `component_access_set` when
determining conflicting systems during schedule building.
- All `component_access()` impls just forward to
`&component_access_set().combined_access`, so we are essentially trading
`Access::is_compatible` for `FilteredAccessSet::is_compatible`.
- `FilteredAccessSet::get_conflicts` internally calls
`combined_access.is_compatible` as the first step, so we can remove that
redundant check.

## Testing

- Un-ignored a previously failing test now that it passes!
- Ran the `build_schedule` benchmark and got basically no change in the
results. Perhaps are benchmarks are just not targetted towards this
situation.
```
$ critcmp main fix-ambiguity -f 'build_schedule'
group                                          fix-ambiguity                          main
-----                                          -------------                          ----
build_schedule/1000_schedule                   1.00       2.9±0.02s        ? ?/sec    1.01       2.9±0.05s        ? ?/sec
build_schedule/1000_schedule_no_constraints    1.02     48.3±1.48ms        ? ?/sec    1.00     47.4±1.78ms        ? ?/sec
build_schedule/100_schedule                    1.00      9.9±0.17ms        ? ?/sec    1.06     10.5±0.32ms        ? ?/sec
build_schedule/100_schedule_no_constraints     1.00   804.7±21.85µs        ? ?/sec    1.03   828.7±19.36µs        ? ?/sec
build_schedule/500_schedule                    1.00    451.7±7.25ms        ? ?/sec    1.04   468.9±11.70ms        ? ?/sec
build_schedule/500_schedule_no_constraints     1.02     12.7±0.46ms        ? ?/sec    1.00     12.5±0.44ms        ? ?/sec
```
2025-06-09 19:40:52 +00:00
Eagster
064e5e48b4
Remove entity placeholder from observers (#19440)
# Objective

`Entity::PLACEHOLDER` acts as a magic number that will *probably* never
really exist, but it certainly could. And, `Entity` has a niche, so the
only reason to use `PLACEHOLDER` is as an alternative to `MaybeUninit`
that trades safety risks for logic risks.

As a result, bevy has generally advised against using `PLACEHOLDER`, but
we still use if for a lot internally. This pr starts removing internal
uses of it, starting from observers.

## Solution

Change all trigger target related types from `Entity` to
`Option<Entity>`

Small migration guide to come.

## Testing

CI

## Future Work

This turned a lot of code from 

```rust
trigger.target()
```

to 

```rust
trigger.target().unwrap()
```

The extra panic is no worse than before; it's just earlier than
panicking after passing the placeholder to something else.

But this is kinda annoying. 

I would like to add a `TriggerMode` or something to `Event` that would
restrict what kinds of targets can be used for that event. Many events
like `Removed` etc, are always triggered with a target. We can make
those have a way to assume Some, etc. But I wanted to save that for a
future pr.
2025-06-09 19:37:56 +00:00
SpecificProtagonist
860ff7819b
Remove workaround for image resize warning (#19397)
# Objective

Follow up for #19116 and #19098

## Testing

viewport_node example
2025-06-09 19:32:57 +00:00
Sigma-dev
8cd53162bf
Add a despawn_children method to EntityWorldMut and EntityCommands (#19283)
# Objective

At the moment, if someone wants to despawn all the children of an
entity, they would need to use `despawn_related::<Children>();`.
In my opinion, this makes a very common operation less easily
discoverable and require some understanding of Entity Relationships.

## Solution

Adding a `despawn_children ` makes a very simple, discoverable and
readable way to despawn all the children while maintaining cohesion with
other similar methods.

## Testing

The implementation itself is very simple as it simply wraps around
`despawn_related` with `Children` as the generic type.
I gave it a quick try by modifying the parenting example and it worked
as expected.

---------

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2025-06-09 19:31:40 +00:00
theotherphil
20cd383b31
Mention Mut in QueryData docs, clarify behaviour of Mut vs &mut in Mut docs (#19254)
# Objective

- Fix https://github.com/bevyengine/bevy/issues/13843
- Clarify the difference between Mut and &mut when accessing query data

## Solution

- Mention `Mut` in `QueryData` docs as an example of a type that
implements this trait
- Give example of `iter_mut` vs `iter` access to `Mut` and `& mut`
parameters

## Testing

-
2025-06-09 19:21:04 +00:00
theotherphil
2bda628ecf
Clarify docs for transmute_lens functions (#19233)
# Objective

Make the restrictions of `transmute_lens` and related functions clearer.

Related issue: https://github.com/bevyengine/bevy/issues/12156
Related PR: https://github.com/bevyengine/bevy/pull/12157

## Solution

* Make it clearer that the set of returned entities is a subset of those
from the original query
* Move description of read/write/required access to a table
* Reference the new table in `transmute_lens` docs from the other
`transmute_lens*` functions

## Testing

cargo doc --open locally to check this render correctly

---------

Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
2025-06-09 19:10:59 +00:00
ickshonpe
4836c7868c
Specialized UI transform (#16615)
# Objective

Add specialized UI transform `Component`s and fix some related problems:
* Animating UI elements by modifying the `Transform` component of UI
nodes doesn't work very well because `ui_layout_system` overwrites the
translations each frame. The `overflow_debug` example uses a horrible
hack where it copies the transform into the position that'll likely
cause a panic if any users naively copy it.
* Picking ignores rotation and scaling and assumes UI nodes are always
axis aligned.
* The clipping geometry stored in `CalculatedClip` is wrong for rotated
and scaled elements.
* Transform propagation is unnecessary for the UI, the transforms can be
updated during layout updates.
* The UI internals use both object-centered and top-left-corner-based
coordinates systems for UI nodes. Depending on the context you have to
add or subtract the half-size sometimes before transforming between
coordinate spaces. We should just use one system consistantly so that
the transform can always be directly applied.
* `Transform` doesn't support responsive coordinates.

## Solution

* Unrequire `Transform` from `Node`.
* New components `UiTransform`, `UiGlobalTransform`:
- `Node` requires `UiTransform`, `UiTransform` requires
`UiGlobalTransform`
- `UiTransform` is a 2d-only equivalent of `Transform` with a
translation in `Val`s.
- `UiGlobalTransform` newtypes `Affine2` and is updated in
`ui_layout_system`.
* New helper functions on `ComputedNode` for mapping between viewport
and local node space.
* The cursor position is transformed to local node space during picking
so that it respects rotations and scalings.
* To check if the cursor hovers a node recursively walk up the tree to
the root checking if any of the ancestor nodes clip the point at the
cursor. If the point is clipped the interaction is ignored.
* Use object-centered coordinates for UI nodes.
* `RelativeCursorPosition`'s coordinates are now object-centered with
(0,0) at the the center of the node and the corners at (±0.5, ±0.5).
* Replaced the `normalized_visible_node_rect: Rect` field of
`RelativeCursorPosition` with `cursor_over: bool`, which is set to true
when the cursor is over an unclipped point on the node. The visible area
of the node is not necessarily a rectangle, so the previous
implementation didn't work.

This should fix all the logical bugs with non-axis aligned interactions
and clipping. Rendering still needs changes but they are far outside the
scope of this PR.

Tried and abandoned two other approaches:
* New `transform` field on `Node`, require `GlobalTransform` on `Node`,
and unrequire `Transform` on `Node`. Unrequiring `Transform` opts out of
transform propagation so there is then no conflict with updating the
`GlobalTransform` in `ui_layout_system`. This was a nice change in its
simplicity but potentially confusing for users I think, all the
`GlobalTransform` docs mention `Transform` and having special rules for
how it's updated just for the UI is unpleasently surprising.
* New `transform` field on `Node`. Unrequire `Transform` on `Node`. New
`transform: Affine2` field on `ComputedNode`.
This was okay but I think most users want a separate specialized UI
transform components. The fat `ComputedNode` doesn't work well with
change detection.

Fixes #18929, #18930

## Testing

There is an example you can look at: 
```
cargo run --example ui_transform
```

Sometimes in the example if you press the rotate button couple of times
the first glyph from the top label disappears , I'm not sure what's
causing it yet but I don't think it's related to this PR.

##  Migration Guide
New specialized 2D UI transform components `UiTransform` and
`UiGlobalTransform`. `UiTransform` is a 2d-only equivalent of
`Transform` with a translation in `Val`s. `UiGlobalTransform` newtypes
`Affine2` and is updated in `ui_layout_system`.
`Node` now requires `UiTransform` instead of `Transform`. `UiTransform`
requires `UiGlobalTransform`.

In previous versions of Bevy `ui_layout_system` would overwrite UI
node's `Transform::translation` each frame. `UiTransform`s aren't
overwritten and there is no longer any need for systems that cache and
rewrite the transform for translated UI elements.

`RelativeCursorPosition`'s coordinates are now object-centered with
(0,0) at the the center of the node and the corners at (±0.5, ±0.5). Its
`normalized_visible_node_rect` field has been removed and replaced with
a new `cursor_over: bool` field which is set to true when the cursor is
hovering an unclipped area of the UI node.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-06-09 19:05:49 +00:00
JMS55
bf8868b7b7
Require naga_oil 0.17.1 (#19550)
Split off from https://github.com/bevyengine/bevy/pull/19058

The patch should've been picked up anyways, but now it's required.
2025-06-09 04:54:29 +00:00
JMS55
16440be327
Add CameraMainTextureUsages helper method (#19549)
Split off from https://github.com/bevyengine/bevy/pull/19058
2025-06-09 04:54:14 +00:00
JMS55
ec307bcb9f
Add more wgpu helpers/types (#19548)
Split off from https://github.com/bevyengine/bevy/pull/19058
2025-06-09 04:54:02 +00:00
re0312
56f26cfb02
Unify system state (#19506)
# Objective

- A preparation for the 'system as entities'
- The current system has a series of states such as `is_send`,
`is_exclusive`, `has_defered`, As `system as entites` landed, it may
have more states. Using Bitflags to unify all states is a more concise
and performant approach

## Solution

- Using Bitflags to  unify system state.
2025-06-08 18:18:43 +00:00
SpecificProtagonist
b9754f963f
Gradients example: Fit in initial window (#19520)
# Objective

When running the `gradient` example, part of the content doesn't fit
within the initial window:
![Screenshot from 2025-06-07
11-42-59](https://github.com/user-attachments/assets/a54223db-0223-4a6e-b8e7-adb306706b28)

The UI requires 1830×930 pixels, but the initial window size is
1280×720.

## Solution

Make ui elements smaller:
![Screenshot from 2025-06-07
11-42-13](https://github.com/user-attachments/assets/c1afc01e-51be-4295-8c0f-6a983fbb0969)

Alternative: Use a larger initial window size. I decided against this
because that would make the examples less uniform, make the code less
focused on gradients and not help on web.
2025-06-08 17:26:02 +00:00
Kristoffer Søholm
2c37bdeb47
Fix PickingInteraction change detection (#19488)
# Objective

Fixes #19464

## Solution

Instead of clearing previous `PickingInteractions` before updating, we
clear them last for those components that weren't updated, and use
`set_if_neq` when writing.

## Testing

I tried the sprite_picking example and it still works. 

You can add the following system to picking examples to check that
change detection works as intended:

```rust
fn print_picking(query: Query<(Entity, &PickingInteraction), Changed<PickingInteraction>>) {
    for (entity, interaction) in &query {
        println!("{entity} {interaction:?}");
    }
}
```
2025-06-08 16:29:13 +00:00
theotherphil
6b5289bd5e
deny(missing_docs) for bevy_ecs_macros (#19523)
# Objective

Deny missing docs for bevy_ecs_macros, towards
https://github.com/bevyengine/bevy/issues/3492.

## Solution

More docs of the form

```
/// Does the thing
fn do_the_thing() {}
```

But I don't think the derive macros are where anyone is going to be
looking for details of these concepts and deny(missing_docs) inevitably
results in some items having noddy docs.
2025-06-08 16:28:31 +00:00
Yuki Osada
a16adc751b
Update add flake.nix example (#19321)
# Objective

I can't build a project using bevy under the environment of NixOS, so I
have to create flake.nix file.

## Solution

I add flake.nix example to `linux_dependencies.md`.

## Testing

I checked my NixOS environment in a project using bevy and booted the
project's game successfully.

---

## Showcase

<details>
  <summary>Click to view showcase</summary>

1. Create a GitHub project using bevy.
2. Add a flake.nix file.
3.  Commit to add this file to the GitHub repository.
4. Run `nix develop`

</details>

---------

Co-authored-by: nukanoto <me@nukanoto.net>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Ilia <43654815+istudyatuni@users.noreply.github.com>
2025-06-08 02:15:19 +00:00
JoshValjosh
ddee5cca85
Improve Bevy's double-precision story for third-party crates (#19194)
# Objective

Certain classes of games, usually those with enormous worlds, require
some amount of support for double-precision. Libraries like `big_space`
exist to allow for large worlds while integrating cleanly with Bevy's
primarily single-precision ecosystem, but even then, games will often
still work directly in double-precision throughout the part of the
pipeline that feeds into the Bevy interface.

Currently, working with double-precision types in Bevy is a pain. `glam`
provides types like `DVec3`, but Bevy doesn't provide double-precision
analogs for `glam` wrappers like `Dir3`. This is mostly because doing so
involves one of:

- code duplication
- generics
- templates (like `glam` uses)
- macros

Each of these has issues that are enough to be deal-breakers as far as
maintainability, usability or readability. To work around this, I'm
putting together `bevy_dmath`, a crate that duplicates `bevy_math` types
and functionality to allow downstream users to enjoy the ergonomics and
power of `bevy_math` in double-precision. For the most part, it's a
smooth process, but in order to fully integrate, there are some
necessary changes that can only be made in `bevy_math`.

## Solution

This PR addresses the first and easiest issue with downstream
double-precision math support: `VectorSpace` currently can only
represent vector spaces over `f32`. This automatically closes the door
to double-precision curves, among other things. This restriction can be
easily lifted by allowing vector spaces to specify the underlying scalar
field. This PR adds a new trait `ScalarField` that satisfies the
properties of a scalar field (the ones that can be upheld statically)
and adds a new associated type `type Scalar: ScalarField` to
`VectorSpace`. It's mostly an unintrusive change. The biggest annoyances
are:

- it touches a lot of curve code
- `bevy_math::ops` doesn't support `f64`, so there are some annoying
workarounds

As far as curves code, I wanted to make this change unintrusive and
bite-sized, so I'm trying to touch as little code as possible. To prove
to myself it can be done, I went ahead and (*not* in this PR) migrated
most of the curves API to support different `ScalarField`s and it went
really smoothly! The ugliest thing was adding `P::Scalar: From<usize>`
in several places. There's an argument to be made here that we should be
using `num-traits`, but that's not immediately relevant. The point is
that for now, the smallest change I could make was to go into every
curve impl and make them generic over `VectorSpace<Scalar = f32>`.
Curves work exactly like before and don't change the user API at all.

# Follow-up

- **Extend `bevy_math::ops` to work with `f64`.** `bevy_math::ops` is
used all over, and if curves are ever going to support different
`ScalarField` types, we'll need to be able to use the correct `std` or
`libm` ops for `f64` types as well. Adding an `ops64` mod turned out to
be really ugly, but I'll point out the maintenance burden is low because
we're not going to be adding new floating-point ops anytime soon.
Another solution is to build a floating-point trait that calls the right
op variant and impl it for `f32` and `f64`. This reduces maintenance
burden because on the off chance we ever *do* want to go modify it, it's
all tied together: you can't change the interface on one without
changing the trait, which forces you to update the other. A third option
is to use `num-traits`, which is basically option 2 but someone else did
the work for us. They already support `no_std` using `libm`, so it would
be more or less a drop-in replacement. They're missing a couple
floating-point ops like `floor` and `ceil`, but we could make our own
floating-point traits for those (there's even the potential for
upstreaming them into `num-traits`).
- **Tweak curves to accept vector spaces over any `ScalarField`.**
Curves are ready to support custom scalar types as soon as the bullet
above is addressed. I will admit that the code is not as fun to look at:
`P::Scalar` instead of `f32` everywhere. We could consider an alternate
design where we use `f32` even to interpolate something like a `DVec3`,
but personally I think that's a worse solution than parameterizing
curves over the vector space's scalar type. At the end of the day, it's
not really bad to deal with in my opinion... `ScalarType` supports
enough operations that working with them is almost like working with raw
float types, and it unlocks a whole ecosystem for games that want to use
double-precision.
2025-06-08 02:02:47 +00:00
urben1680
76b8310da5
Replace (Partial)Ord for EntityGeneration with corrected standalone method (#19432)
# Objective

#19421 implemented `Ord` for `EntityGeneration` along the lines of [the
impl from
slotmap](https://docs.rs/slotmap/latest/src/slotmap/util.rs.html#8):
```rs
/// Returns if a is an older version than b, taking into account wrapping of
/// versions.
pub fn is_older_version(a: u32, b: u32) -> bool {
    let diff = a.wrapping_sub(b);
    diff >= (1 << 31)
}
```

But that PR and the slotmap impl are different:

**slotmap impl**
- if `(1u32 << 31)` is greater than `a.wrapping_sub(b)`, then `a` is
older than `b`
- if `(1u32 << 31)` is equal to `a.wrapping_sub(b)`, then `a` is older
than `b`
- if `(1u32 << 31)` is less than `a.wrapping_sub(b)`, then `a` is equal
or newer than `b`

**previous PR impl**
- if `(1u32 << 31)` is greater than `a.wrapping_sub(b)`, then `a` is
older than `b`
- if `(1u32 << 31)` is equal to `a.wrapping_sub(b)`, then `a` is equal
to `b` ⚠️
- if `(1u32 << 31)` is less than `a.wrapping_sub(b)`, then `a` is newer
than `b` ⚠️

This ordering is also not transitive, therefore it should not implement
`PartialOrd`.

## Solution

Fix the impl in a standalone method, remove the `Partialord`/`Ord`
implementation.

## Testing

Given the first impl was wrong and got past reviews, I think a new unit
test is justified.
2025-06-07 22:29:13 +00:00
andriyDev
de79d3f363
Mention in the docs for pointer events that these are in screen-space. (#19518)
# Objective

- Fixes #18109.

## Solution

- All these docs now mention screen-space vs world-space.
- `start_pos` and `latest_pos` both link to `viewport_to_world` and
`viewport_to_world_2d`.
- The remaining cases are all deltas. Unfortunately `Camera` doesn't
have an appropriate method for these cases, and implementing one would
be non-trivial (e.g., the delta could have a different world-space size
based on the depth). For these cases, I just link to `Camera` and
suggest using some of its methods. Not a great solution, but at least it
gets users on the correct track.
2025-06-06 22:20:14 +00:00
Alice Cecile
e1230fdc54
Remove re-exports of cosmic_text types (#19516)
# Objective

As discussed in #19285, we do a poor job at keeping the namespace tidy
and free of duplicates / user-conflicting names in places. `cosmic_text`
re-exports were the worst offender.

## Solution

Remove the re-exports completely. While the type aliases were quite
thoughtful, they weren't used in any of our code / API.
2025-06-06 21:49:02 +00:00
re0312
5df9c53977
Fix regression on the get/get_mut/get_not_found (#19505)
# Objective

- Partial fix #19504
- As more features were added to Bevy ECS, certain core hot-path
function calls exceeded LLVM's automatic inlining threshold, leading to
significant performance regressions in some cases.



## Solution

- inline more functions.


## Performance
This brought nearly 3x improvement in Windows bench (using Sander's
testing code)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-06-06 21:04:27 +00:00
Eagster
8ad7118443
Only get valid component ids (#19510)
# Objective

- #19504 showed a 11x regression in getting component values for
unregistered components. This pr should fix that and improve others a
little too.
- This is some cleanup work from #18173 .

## Solution

- Whenever we expect a component value to exist, we only care about
fully registered components, not queued to be registered components
since, for the value to exist, it must be registered.
- So we can use the faster `get_valid_*` instead of `get_*` in a lot of
places.
- Also found a bug where `valid_*` did not forward to `get_valid_*`
properly. That's fixed.

## Testing

CI
2025-06-06 20:59:57 +00:00
Alice Cecile
7ac2ae5713
Allow new mismatched_lifetime_syntaxes lint (#19515)
# Objective

The new nightly lint produces [unhelpful, noisy
output](http://github.com/bevyengine/bevy/actions/runs/15491867876/job/43620116435?pr=19510)
that makes lifetimes more prominent in our library code than we
generally find helpful.

This needs to be fixed or allowed, in order to unbreak CI for every PR
in this repo.

## Solution

Blanket allow the lint at the workspace level.

## Testing

Let's see if CI passes!
2025-06-06 20:14:15 +00:00
robtfm
3dc6a07d27
generic component propagation (#17575)
# Objective

add functionality to allow propagating components to children. requested
originally for `RenderLayers` but can be useful more generally.

## Solution

- add `HierarchyPropagatePlugin<C, F=()>` which schedules systems to
propagate components through entities matching `F`
- add `Propagate<C: Component + Clone + PartialEq>` which will cause `C`
to be added to all children
more niche features:
- add `PropagateStop<C>` which stops the propagation at this entity
- add `PropagateOver<C>` which allows the propagation to continue to
children, but doesn't add/remove/modify a `C` on this entity itself

## Testing

see tests inline

## Notes

- could happily be an out-of-repo plugin
- not sure where it lives: ideally it would be in `bevy_ecs` but it
requires a `Plugin` so I put it in `bevy_app`, doesn't really belong
there though.
- i'm not totally up-to-date on triggers and observers so possibly this
could be done more cleanly, would be very happy to take review comments
- perf: this is pretty cheap except for `update_reparented` which has to
check the parent of every moved entity. since the entirety is opt-in i
think it's acceptable but i could possibly use `(Changed<Children>,
With<Inherited<C>>)` instead if it's a concern
2025-06-06 00:02:02 +00:00
Carter Anderson
7e9d6d852b
bevyengine.org -> bevy.org (#19503)
We have acquired [bevy.org](https://bevy.org) and the migration has
finished! Meaning we can now update all of the references in this repo.
2025-06-05 23:09:28 +00:00
Carter Anderson
fdf5dd677f
Update FUNDING.yml 2025-06-05 15:04:57 -07:00
ZoOL
a35eed0ea4
fix: Ensure linear volume subtraction does not go below zero (#19423)
fix: [Ensure linear volume subtraction does not go below zero
](https://github.com/bevyengine/bevy/issues/19417)

## Solution
- Clamp the result of linear volume subtraction to a minimum of 0.0
- Add a new test case to verify behavior when subtracting beyond zero

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2025-06-05 03:59:20 +00:00
theotherphil
d0f1b3e9f1
Add a few missing doc comments in bevy_image (#19493)
# Objective

Another tiny step towards
https://github.com/bevyengine/bevy/issues/3492.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-06-04 21:12:02 +00:00
theotherphil
476d79d821
deny(missing_docs) for bevy_state (#19492)
# Objective

Deny missing docs in bevy_state, towards
https://github.com/bevyengine/bevy/issues/3492.
2025-06-04 20:43:47 +00:00
Chris Russell
bd4c960f26
Mention Option and When in the error message for a failing system parameter (#19490)
# Objective

Help users discover how to use `Option<T>` and `When<T>` to handle
failing parameters.

## Solution

Have the error message for a failed parameter mention that `Option<T>`
and `When<T>` can be used to handle the failure.

## Showcase

```
Encountered an error in system `system_name`: Parameter `Res<ResourceType>` failed validation: Resource does not exist
If this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `When<T>` to skip the system when it happens.
```
2025-06-04 16:39:54 +00:00
Kristoffer Søholm
6fee6fe827
Add get_mut_untracked to Assets (#19487)
# Objective

Fixes #13104

## Solution

Add a `get_mut_untracked` method to `Assets`
2025-06-04 16:34:27 +00:00
theotherphil
c5dcef5e61
deny(missing_docs) for bevy_diagnostic (#19482)
# Objective

Deny missing docs in bevy_diagnostic, towards
https://github.com/bevyengine/bevy/issues/3492.
2025-06-04 01:30:10 +00:00
theotherphil
e7a309ff5f
deny(missing_docs) for bevy_derive (#19483)
# Objective

Deny missing docs in bevy_derive, towards
https://github.com/bevyengine/bevy/issues/3492.
2025-06-04 00:06:32 +00:00