Commit Graph

420 Commits

Author SHA1 Message Date
DavidCrossman 7c77ecd576 Fix documentation typos (#24446)
# Objective

Fix typos and other small issues in the documentation. I can drop the
changes to `bevy_reflect`'s and `bevy_anti_alias`'s crate descriptions
if it's a problem.
2026-06-02 00:52:42 +00:00
Mira 18d106d26a Pass panics to the fallback error handler (#24240)
# Objective

Currently, a panic (whether from engine or user code, as there is little
distinction) takes down the entire app with it. Instead the user should
be able to decide how the error is handled. This is currently not
possible except by writing your own executor and setting it for all
relevant schedules.

See for comparison Godot's policy on exceptions:

> ### [Why does Godot not use
exceptions?](https://docs.godotengine.org/en/stable/about/faq.html#why-does-godot-not-use-exceptions)
> 
> We believe games should not crash, no matter what. If an unexpected
situation happens, Godot > will print an error (which can be traced even
to script), but then it will try to recover as > gracefully as possible
and keep going.

Unity will also log an error and then continue if user code throws an
exception. I believe Unreal does too for exceptions coming from
Blueprints. Similarly, many web servers will respond with an error to a
request that threw an exception, but will not crash the server itself.

This PR does not enable this behavior by default, but makes it
user-configurable.

Also fixes #19109
Also (I think) fixes #7434

## Solution

Instead of rethrowing panics, hand them to the `FallbackErrorHandler`.

If the panic was thrown by an error handler in the first place, we don't
need to pass it back to a handler again. I've added a way for the error
handler to signal that it's the source of the panic.

The constructed error is created without a backtrace, as the default
panic handler already prints it when instructed to via
`RUST_LIB_BACKTRACE`/`RUST_BACKTRACE`.

Panics will not be turned into errors on `no_std` projects.

Potential work for a future PR:
- if a error handler has been specified with e.g. `queue_handled`, use
this error handler instead of the fallback error handler
- if a command panics, still apply the remaining commands in the buffer?

## Testing

See added `panic_to_error` test

---------

Co-authored-by: Gonçalo Rica Pais da Silva <bluefinger@gmail.com>
2026-06-01 19:35:45 +00:00
bytemuck 055f0f51af Added register_boxed_system to Commands. (#24213)
# Objective

Fixes #24017 

## Solution

Added `register_boxed_system` to `Commands`.

## Testing

- Modified `callbacks` example to show our new `register_boxed_system`
method.

---------

Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
2026-05-22 14:21:58 +00:00
ickshonpe b00ff93c87 Remove new_with_ prefix from the TextLayout constuctor functions (#24049)
# Objective

Remove the `new_with_` prefixes from the `TextLayout` constuctor
functions. Generally, the "new" part is redundant and "with" is used by
fluent APIs.

## Solution

Just delete the prefixes, shorten the names (all on `TextLayout`).
* `new_with_justify` -> `justify`
* `new_with_linebreak` -> `linebreak`
* `new_with_no_wrap` -> `no_wrap`
2026-05-01 21:08:18 +00:00
Mark Old 334c242c96 Enable dynamic triggers for observers (#23870)
# Objective

Finish the bevy_ecs dynamic story. Currently you can register observers
with dynamic triggers and runners, but there's no way to actually
trigger these observers dynamically.

## Solution

Adds three new unsafe `World` functions:
- `trigger_dynamic()`
- `trigger_dynamic_targets()`
- `trigger_dynamic_targets_components()`

These enable observers to be triggered with untyped events and trigger
data. Their implementations are just wiring up some existing internal
structure. Structurally, they are based on their non-dynamic
counterparts.

Also exposes `EventKey::new()` and `EventKey::component_id()` for
constructing event keys from dynamic `ComponentId`s.

## Testing

Several new tests

## Showcase

See updated example
2026-04-19 15:55:59 +00:00
Luo Zhihao 1fa8f03949 Use EntityHashMap and EntityHashSet when possible (#23810)
# Objective

Replace `HashMap<Entity, T>` and `HashSet<Entity>` with `EntityHashMap`
and `EntityHashSet` for better performance.

## Solution

Replace them.

## Testing

CI
2026-04-15 15:41:05 +00:00
Freyja-moth 8b0239e6c6 Added map_severity method to ResultSeverityExt (#23749)
# Objective

Part of: #23680

## Solution

Add `map_severity` method onto `ResultSeverityExt` 


## Showcase

```rust
world
        // This entity doesn't exist!
        .spawn_empty_at(Entity::from_raw_u32(12345678).unwrap())
        .map_severity(|e| match e {
            // Not that concerning, we just need to make sure to find a different entity
            SpawnError::AlreadySpawned => Severity::Debug,
            // Oh no
            SpawnError::Invalid(_) => Severity::Error,
        })?;
```
2026-04-12 20:40:46 +00:00
Alice Cecile 5e07be7055 Rename default error handler to fallback error handler (#23610)
# Objective

`DefaultErrorHandler` is a confusing name.

While it is the error handler "used by default" if no alterantive is
provided, it should not be your default choice. Local error handling is
usually better than simply calling `?`.

Moreover, it's quite hard to talk about "the default configuration of
the `DefaultErrorHandler`" in the docs, and very weird to discuss
modifying the default error handler.

## Solution

Rename it to `FallbackErorrHandler`.
Update the docs to match.

This is a better name, since it reflects this pattern's "safety net"
usage, without being confusing to discuss.

Add a deprecated type alias and a migration guide to be nice to users.

EDIT: apparently also mention the new Severity logic in the error
handling example.

---------

Co-authored-by: Mira <specificprotagonist@posteo.org>
Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
2026-04-01 23:33:51 +00:00
Mike 984f7203e3 Make an unsafe accessor for SystemSchedule::systems (#23443)
# Objective

- #23414 made `SystemSchedule::systems` pub, but this can lead to
breaking invariants that `Schedule` expects. For example this allows
mutating the access which is used to prevent race conditions in the
multithreaded executor. This could also allow replacing systems, but
without initializing the access as the `Schedule` is meant to keep track
of which systems are unitialized.

## Solution

- Make the fields of `SystemWithAccess` private to make it harder to
modify the access. This is potentially a breaking change as
`SystemWithAccess` is pub, but the type is not exposed in our public
api's for `Schedule` in 0.18.
- Make an unsafe accessor for the `systems` field and make the field
private again.

## Testing

- Only checked that this compiles
2026-03-22 19:04:45 +00:00
atlv 1aea391609 Support Custom SystemExecutors (#23414)
# Objective

- Audio wants a realtime-safe executor with minimal checking. This means
no command application or multithreading etc.

## Solution

- Make it possible to supply our own executor.

## Testing

- Tests are updated
- New custom executor example

Note: reviewing commits individually is probably easier.
2026-03-19 20:23:33 +00:00
Freyja-moth 055d445da2 Add DespawnWhen helper component for more complex state despawning logic (#23315)
# Objective

Using a predicate to disable entities on state change was proposed
[here](https://github.com/bevyengine/bevy/issues/19087#issuecomment-2870106800),
I felt it would be nice to add it for entity despawning

## Solution

Added `DespawnOnExitWith` and `DespawnOnEnterWith` which despawn an
entity when the state is exited/entered and meets the predicate

## Testing

Updated the state scoped example, had a run and it worked just fine

---

## Showcase

Now stuff like this is possible

```rust
pub enum State {
    Water,
    Land,
    Air,
}

commands.spawn((
    Name::new("Fish"),
    // Poor fish 
    DespawnOnEnterWith(|entered_state| matches!(entered_state, State::Land | State::Air))
));
```
2026-03-16 23:25:03 +00:00
Damon 00b1ff59e4 Extraction Example (#23223)
An example demonstrating automatic and manual extraction of components
from the Main World to the Render World.

This is a common point of confusion for new users that want to do custom
rendering, and I don't think any of the current examples show how to
manually extract components (or aren't at all focused on it at least).

In the future this should probably be changed to be about extraction
between two arbitrary worlds, instead of being specific to the Render
World. Possibly after / if github.com/bevyengine/bevy/pull/22852 is
merged.

---------

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
2026-03-16 19:38:58 +00:00
Chris Russell 753f3ca1be Add write methods to MessageMutator (#23351)
# Objective

Support systems that both read and write messages of the same type.  

This is possible today with various workarounds: Either using
`ParamSet<(MessageReader<M>, MessageWriter<M>)>` or by manually storing
a `Local<MessageCursor<DebugMessage>>` to keep track of the reading
position. But those are both relatively complex for such a simple use
case.

The `ParamSet` workaround would get even more complex if we did #23339,
since it would be necessary to use a fallible system to handle the case
where the `Messages` resource is missing.

## Solution

Create a type that can both read and write messages. It needs to have a
`MessageCursor` and `ResMut<Messages<M>>`... which is exactly what
`MessageMutator<M>` has!

So, rather than creating a new type, simply add `write`, `write_batch`,
and `write_default` to `MessageMutator`.

Update the documentation to point users to use `MessageMutator` rather
than `ParamSet` or `MessageCursor`.
2026-03-14 05:24:07 +00:00
Kevin Chen 846b196cda Deploy Docs - Build Docs step: Resolve most Warnings (#23343)
# Objective

- Resolve most of the warnings in the Build Docs step of Deploy Docs,
you can see them here:
https://github.com/bevyengine/bevy/actions/runs/23021953246/job/66860356132

## Solution

- Resolve most of the warnings
- The `doc_cfg` feature should only be enabled with `docsrs`, not
`docsrs_dep` (I just followed this pattern from other crates tbh like
`bevy_math` and `bevy_material`)
- I unlinked example docs that references non public items within the
example itself
  - I corrected some links

Note: I didn’t fix the warnings concerning the macros in bevy-reflect
for `tuple.rs` because I’m not macro savvy. If someone knows what to do
in those cases (should I just remove the `$(#[$meta])*` lines cause
they’re not in use?), just let me know and I can do it (or you can open
a pull!)

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2026-03-14 02:35:44 +00:00
Alice Cecile b265dc042a Merge SystemParam::validate_param into SystemParam::get_param (#23225)
# Objective

As raised in
[#23174](https://github.com/bevyengine/bevy/pull/23174#discussion_r2868030355_),
we currently duplicate working when looking up our system parameters:
once during validation, and then again when actually fetching the data.

This is (maybe) slow, and would worsen the performance regression
incurred by resources-as-components (#19731).

This strategy also imposes some non-trivial complexity and
maintainability costs. Because "validate" is a distinct step from "use",
it's possible to skip validation! As far as I could tell, this is the
case in a number of places before this PR: particularly in the
unconventional "please just run my system" path. While in most cases
this will simply result in a crash in a different place, it causes these
paths to not handle

Fixes #23179. Fixes #15505.

## Solution

Fundamentally, what we're doing is rolling the
`SystemParam::validate_param` behavior into `SystemParam::get_param`, by
making the latter return a `Result`.

However, there is a tremendous amount of splash damage required to get
that to actually compile and expose the correct semantics. The most
important of these are:

- `SystemState::get` and friends now returns a `Result`
- this leads to a fair bit of assorted unwrap spam in our tests and
weird internal usages
- these tests can probably be refactored to not use `SystemState`
directly in the future now that we have better tools like
`run_system_once`, but eh, not this PR's job
- this is semantically correct, as these params could fail validation
- `System::validate_param_unsafe` has been removed, and validation now
occurs inside of `System::run_unsafe`
- very much a net positive for both abstract robustness and current
correctness
- this impacts the strategy that various executors use: see the next
section

There are a *lot* of moving parts here: I'm sorry that I couldn't get
this into a smaller, more incremental refactor. When reviewing this PR,
you should begin with the migration guide to help get you oriented on
the details: `validation_merging.md`.

From there, the most important files to review are:

1. `system_param.rs`: trait changes and implementers
2. `function_system.rs`: primary implementer of `System`
3. `multithreaded.rs`: the parallel executor

**NOTE TO REVIEWERS:** Please make comments to generate threads; this PR
review might get fairly hairy.

### Performance discussion

For the parallel `MultithreadedExecutor`, validation was previously done
as a cheap pre-validation step,
while checking run conditions.
Now, tasks will be spawned for systems which would fail or are skipped
during validation.

In most cases, avoiding the extra overhead of looking up the required
data twice should dominate.
However, this change may negatively affect systems which are frequently
skipped (e.g. due to `Single`).

### Paths not taken

In this PR, I've decided not to:

- Add another variant
[RunSystemError](https://docs.rs/bevy/latest/bevy/ecs/system/enum.RunSystemError.html),
distinguishing "validation failed" from "system ran but returned an
error".
- While reusing
[RunSystemError::Failed](https://docs.rs/bevy/latest/bevy/ecs/system/enum.RunSystemError.html#variant.Failed)
for both cases is messy, this PR is already a bit of a nightmare to
review.
- Return a result from `ParamSet::get_mut`.
   - Instead, we just `unwrap`.
- Bubbling up the `Result` is technically more correct, but these were
already panicking before if e.g. a resource is missing, and `ParamSet`
is already an ergonomic abomination.

## Testing

I've added a number of new tests to exercise the system param validation
paths, ensuring that validation is done when systems are run.

However, I would appreciate some help benchmarking the net impact on
realistic-ish scenes. `breakout`, `bevy_city` and `many_animated_foxes`
are probably a decent scattering, but I'd be very open to other
suggestions.

Having done this refactor, I think that it's a net improvement for
robustness and clarity even without the perf benefits however, and that
we should proceed unless this is a clear regression.

---------

Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
2026-03-11 19:03:10 +00:00
Alice Cecile 8b2dfb5464 Add an example demonstrating callbacks with one-shot systems (#23197)
# Objective

This is a powerful pattern, but figuring out the exact incantation to
call can be quite challenging!

## Solution

Write a little prototype, turn it into a full example!

## Testing

`cargo run --example callbacks`

---------

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
2026-03-03 17:36:33 +00:00
Trashtalk217 c89541a1af Remove resources from Access (#22910)
# Objective

There's a lot of code duplication in `access.rs`. The same logic is
duplicated between components and resources. This also takes up
unnecessary memory in `Access`, as it relies on bitsets spanning the
entire `ComponentId` range.

## Solution

Since resources are now a special kind of component, this can be
removed.

## Limitations

Since `!Send` data queries used `Access` resources, `!Send` data queries
now conflict with broad queries.
```rust
// 0.18
fn system(q1_: Query<EntityMut>, q2_: NonSend<R>) {} // valid, does not conflict

// 0.19
fn system(q1_: Query<EntityMut>, q2_: NonSend<R>) {} // invalid, does conflict
```
Given how rarely non-send data is used, I recommend using
```
// 0.19
fn system(q1_: Query<EntityMut, Without<R>>, q2_: NonSend<R>) {} // works again
```

If this is also unacceptable, this PR is blocked on the `!Send` data
removal from the ECS (or some hacky workaround).

## Extra Attention

@chescock brought `AssetChanged` to my attention. It has a weird access
pattern. See the following example:
```rust
fn system(c: Query<&mut AssetChanges<Mesh>>, r: Query<(), AssetChanged<Mesh>>) {}
```
System `c` registers access with `add_write` for `AssetChanges<Mesh>`,
while `r` registers access with `add_read` for both `Mesh` and
`AssetChanges<Mesh>`. This system is invalid, and I've added a test to
reflect that. However, since this stuff is tricky, I would like some
extra eyes on it. Currently, it looks *fine*.
2026-03-02 23:48:04 +00:00
Runi-c 1fdf4267ae Add a DelayedCommands helper to support arbitrary delayed commands (#23090)
# Objective

- A generalized mechanism for "doing something later" is desirable for
many games, especially when it comes to gameplay logic and VFX.
- Fixes https://github.com/bevyengine/bevy/issues/15129
- Closes #20155

## Solution

- Build off the work in
https://github.com/bevyengine/bevy/pull/20155#issuecomment-3702483127,
especially @laundmo's comment.
- Add a `DelayedCommands` helper obtainable via `commands.delayed()`
that owns `CommandQueue`s and hands out new `Commands` bound to them.
- When the `DelayedCommands` helper is dropped, push spawn commands onto
the host `Commands` to spawn the queues as `DelayedCommandQueue`
entities.
- The entities are ticked by a new system added by `TimePlugin`. When
the timer fires, the queue is submitted onto that system's `Commands`.

## Testing

- Added a new test in `bevy_time` and it seems to work.
- I'm not very familiar with doing hacky things like using `Drop` like
this and would therefore appreciate careful review and guidance if
changes are requested.

---

## Showcase

```rust
fn my_cool_system(mut commands: Commands) {
    // fairly unobtrusive one-line delayed spawn
    commands.delayed().secs(0.1).spawn(DummyComponent);

    // the DelayedCommands can be stored to reuse more tersely
    let mut delayed = commands.delayed();
    // allocation happens immediately so you can even queue
    // further operations on entities that aren't spawned yet
    let entity = delayed.secs(0.5).spawn_empty().id();
    delayed.secs(0.7).entity(entity).insert(DummyComponent);

    // `delayed.secs` and `delayed.duration` both simply return a
    // `Commands` rebound to the stored `CommandQueue`, so you can additionally
    // just store that and reuse it to queue multiple commands with the same delay
    let mut in_1_sec = delayed.duration(Duration::from_secs_f32(1.0));
    in_1_sec.spawn(DummyComponent);
    in_1_sec.spawn(DummyComponent);
    in_1_sec.spawn(DummyComponent);
}
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2026-02-24 23:29:32 +00:00
Gonçalo Rica Pais da Silva f255b8e57a Upgrade glam, hexasphere, rand & uuid to latest versions (#22928)
# Objective

- `glam`, `hexasphere` & `rand` have released their latest versions,
update Bevy to support them.

## Solution

- The above have been updated to their compatible versions. `rand_distr`
updated as well to match `rand` v0.10 support.
- `rand_chacha` is soft deprecated and no longer used by `rand`, so its
usage has been changed to `chacha20` to match `rand` dep tree.
- `uuid` is in the process of updating to `getrandom` v0.4, which `rand`
v0.10 supports. This PR remains in draft until a new `uuid` release hits
crates.io.
- `RngCore` is now `Rng`, and `Rng` is now `RngExt`, so this required
updating across many files.
- `choose_multiple` method is deprecated, changed to `sample`.

## Testing

- Chase all compiler errors, since this should not regress any already
existing behaviour.
- This must pass CI without regressions.

## Additional Notes

`getrandom` v0.4 doesn't add anything new for Web WASM support, so the
same `wasm_js` feature is used.
2026-02-19 22:17:25 +00:00
Joseph 12952486ef fix: improve semantic clarity for run condition combinators (#22690)
# Objective

We include several run condition combinators, such as `and`, `or`, etc.,
which short-circuit depending on the output of the first condition in
the combinator.

This is incredibly error-prone due to the subtle way that
short-circuiting interacts with change detection -- rather than reacting
to changes frame-by-frame, the second condition in short-circuiting
combinator will react to _the last time that the first condition did not
short circuit_. This can easily lead to confusing bugs if the user does
not expect this, and I suspect that most users will not expect this.
For this reason, when combining multiple run conditions added via
`.run_if()`, all run conditions are intentionally eagerly evaluated.

## Solution

Add new run condition combinators `and_then`, `and_eager`, `or_else`,
`or_eager`, etc., for clarity, and deprecate the previous methods,
pointing users to the new ones.

After the previous combinators have been removed for a few release
cycles, we should consider renaming combinators such as `and_eager` to
simply `and`.

# Migration Guide

Bevy supports run condition combinators (`and`, `or`, `nan`, `nor`),
which have historically short-circuited. While familiar,
short-circuiting interacts with Bevy’s change detection in a subtle way:
when the left-hand condition short-circuits, the right-hand condition is
not evaluated and therefore does not observe changes on that frame.
Instead, it reacts based on the last frame it ran, which can lead to
confusing and non-local bugs.

By contrast, Bevy's scheduler combines multiple .run_if(...) conditions
using eager evaluation, which avoids this known pitfall.

To make intent explicit and reduce footguns, short-circuiting
combinators have been renamed and eagerly-evaluated variants have been
added.

## Examples

Most users should use eager evaluation, which ensures all conditions
participate in change detection every frame:

```rust
// Before (deprecated)
cond_a.and(cond_b)
cond_a.or(cond_b)
cond_a.nand(cond_b)
cond_a.nor(cond_b)

// After (recommended default)
cond_a.and_eager(cond_b)
cond_a.or_eager(cond_b)
cond_a.nand_eager(cond_b)
cond_a.nor_eager(cond_b)
```

If you *intentionally rely on short-circuiting* for correctness, use the
explicit short-circuiting variants:

```rust
// Explicit short-circuiting
cond_a.and_then(cond_b)
cond_a.or_else(cond_b)
cond_a.nand_then(cond_b)
cond_a.nor_else(cond_b)
```

`xor` and `xnor` are unchanged, as they cannot short-circuit by nature.

## Future naming note

The `_eager` suffix exists to ease migration without changing the
behavior of existing code that relied on short-circuiting. After the
deprecated combinators have been removed for a few release cycles, we
expect to revisit naming and likely remove the _eager suffix, keeping
`and_then` / `or_else` as the explicit short-circuiting forms.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Mike <mike.hsu@gmail.com>
2026-02-17 00:13:33 +00:00
Jonas Meyer-Ohle 9ab681c533 Rename on_replace/Replace to on_discard/Discard (#22789)
# Objective

- Rename lifecycle “Replace” hooks/events to “Discard” to reflect actual
semantics (fires on overwrite, remove, and despawn), and free up
“Replace” for a future true replacement event. Addresses #20729.

## Solution

- Renamed Replace/on_replace to Discard/on_discard across hooks,
observers, events, derive macros, docs, examples, and tests.
- Updated UI compile‑fail expectations and added OnDiscard doc alias on
Discard for discoverability.

## Testing

- `cargo run -p ci -- compile-fail`
- `cargo test -p bevy_ecs --lib --tests --features
bevy_ecs/track_location` (fails locally due to missing bevy_ecs/debug
feature in two tests that assert full system names)
2026-02-13 01:03:12 +00:00
Jonas Meyer-Ohle 2297753d81 Observer run conditions (#22602)
# Objective

Allow observers to use run conditions, enabling conditional execution
based on world state - the same pattern that systems use with .run_if().

Fixes #14195
Fixes #21442

## Solution

Add a run_if() method to observer systems via the ObserverSystemExt
trait. Conditions are stored in Observer and checked before execution in
the runner.

Key implementation details:
- ObserverWithCondition<E,B,M,S> wrapper preserves event type info for
compile-time EntityEvent enforcement on entity observers
- Conditions are ReadOnlySystem (enforced by SystemCondition trait),
matching system run conditions
- Multiple conditions chain with AND semantics, short-circuiting on
first false

It's a bit more involved than mentioned
[here](https://github.com/bevyengine/bevy/issues/21442#issuecomment-3765694484)
since we need the full system‑style API: chained run_ifs, entity
observers with compile‑time EntityEvent checks, and use with
add_observer/observe.

That forces a typed wrapper + marker types +
IntoObserver/IntoEntityObserver, and conditions must be initialized at
spawn time (so the hook has to take/init/restore). The runner also needs
a safety‑documented precheck before running the observer.

## Testing

- Added 7 new tests covering:
  - Condition preventing/allowing execution
  - Multiple conditions (all true / one false)
  - Entity observers with conditions
  - Resource-based conditions
  - Builder pattern on Observer::new()
- All existing tests pass (cargo test -p bevy_ecs)
- Updated observers.rs example with Space key toggle

---

## Showcase

```rust
#[derive(Resource)]
struct GameActive(bool);
// Global observer - only runs when game is active
app.add_observer(
    on_damage.run_if(|state: Res<GameActive>| state.0)
);
// Chained conditions (AND semantics)
app.add_observer(
    on_damage
        .run_if(|state: Res<GameActive>| state.0)
        .run_if(|player: Query<&Health, With<Player>>| player.single().is_ok())
);
// Entity observer
commands.spawn(Enemy).observe(
    on_hit.run_if(|game: Res<GameActive>| game.0)
);
// Builder pattern
world.spawn(
    Observer::new(on_event)
        .with_entity(target)
        .run_if(some_condition)
);
```

<details>

<summary>Example from observers.rs</summary>

```rust
#[derive(Resource, Default)]
struct ExplosionsEnabled(bool);

fn toggle_explosions(mut enabled: ResMut<ExplosionsEnabled>, input: Res<ButtonInput<KeyCode>>) {
    if input.just_pressed(KeyCode::Space) {
        enabled.0 = !enabled.0;
        info!("Explosions {}", if enabled.0 { "enabled" } else { "disabled" });
    }
}

fn setup(app: &mut App) {
    app.add_observer(
        explode_mine.run_if(|enabled: Res<ExplosionsEnabled>| enabled.0)
    );
}
```

</details>
2026-02-03 15:44:30 +00:00
Jenya705 b842bcb923 Contiguous access (#21984)
# Objective

Enables accessing slices from tables directly via Queries.

Fixes: #21861 

## Solution

One new trait:
- `ContiguousQueryData` allows to fetch all values from tables all at
once (an implementation for `&T` returns a slice of components in the
set table, for `&mut T` returns a mutable slice of components in the set
table as well as a struct with methods to set update ticks (to match the
`fetch` implementation))

Methods `contiguous_iter`, `contiguous_iter_mut` and similar in `Query`
and `QueryState` making possible to iterate using these traits.

Macro `QueryData` was updated to support contiguous items when
`contiguous(target)` attribute is added (a target can be `all`,
`mutable` and `immutable`, refer to the `custom_query_param` example)

## Testing

- `sparse_set_contiguous_query` test verifies that you can't use
`next_contiguous` with sparse set components
- `test_contiguous_query_data` test verifies that returned values are
valid
- `base_contiguous` benchmark (file is named
`iter_simple_contiguous.rs`)
- `base_no_detection` benchmark (file is named
`iter_simple_no_detection.rs`)
- `base_no_detection_contiguous` benchmark (file is named
`iter_simple_no_detection_contiguous.rs`)
- `base_contiguous_avx2` benchmark (file is named
`iter_simple_contiguous_avx2.rs`)

---

## Showcase

Examples `contiguous_query`, `custom_query_param`

### Example
```rust
// - self.0 is a World
// - self.1 is a QueryState
// - velocity is a slice of components with Vec3 inside.
// - position is a data structure which implements Deref/DerefMut and IntoIterator methods to access the slice
// as well as mechanism to update update ticks (which it does automatically on dereference), 
// which may be bypassed via `bypass_change_detection` methods.
for (velocity, mut position) in self.1.contiguous_iter_mut(&mut self.0).unwrap() {
    assert!(velocity.len() == position.len());
    for (v, p) in velocity.iter().zip(position.iter_mut()) {
        p.0 += v.0;
    }
}
```

### Benchmarks
Code for `base` benchmark:
```rust
#[derive(Component, Copy, Clone)]
struct Transform(Mat4);

#[derive(Component, Copy, Clone)]
struct Position(Vec3);

#[derive(Component, Copy, Clone)]
struct Rotation(Vec3);

#[derive(Component, Copy, Clone)]
struct Velocity(Vec3);

pub struct Benchmark<'w>(World, QueryState<(&'w Velocity, &'w mut Position)>);

impl<'w> Benchmark<'w> {
    pub fn new() -> Self {
        let mut world = World::new();

        world.spawn_batch(core::iter::repeat_n(
            (
                Transform(Mat4::from_scale(Vec3::ONE)),
                Position(Vec3::X),
                Rotation(Vec3::X),
                Velocity(Vec3::X),
            ),
            10_000,
        ));

        let query = world.query::<(&Velocity, &mut Position)>();
        Self(world, query)
    }

    #[inline(never)]
    pub fn run(&mut self) {
        for (velocity, mut position) in self.1.iter_mut(&mut self.0) {
            position.0 += velocity.0;
        }
    }
}
```
Iterating over 10000 entities from **a single** table and increasing a
3-dimensional vector from component `Position` by a 3-dimensional vector
from component `Velocity`

| Name | Time | Time (AVX2) | Description |

|------------------------------|-----------|-------------|--------------------------------------------------------------------|
| base | 5.5828 µs | 5.5122 µs | Iteration over components |
| base_contiguous | 4.8825 µs | 1.8665 µs | Iteration over contiguous
chunks |
| base_contiguous_avx2 | 2.0740 µs | 1.8665 µs | Iteration over
contiguous chunks with enforced avx2 optimizations |
| base_no_detection | 4.8065 µs | 4.7723 µs | Iteration over components
while bypassing change detection through `bypass_change_detection()`
method |
| base_no_detection_contiguous | 4.3979 µs | 1.5797 µs | Iteration over
components without registering update ticks |

Using contiguous 'iterator' makes the program a little bit faster and it
can be further vectorized to make it even faster
2026-02-03 00:02:26 +00:00
ickshonpe 6ca4769128 Minimal responsive FontSize support (#22614)
# Objective

Add responsive font sizes supporting rem and viewport units to
`bevy_text` with minimal changes to the APIs and systems.

## Solution

Introduce a new `FontSize` enum:

```rust
pub enum FontSize {
    /// Font Size in logical pixels.
    Px(f32),
    /// Font size as a percentage of the viewport width.
    Vw(f32),
    /// Font size as a percentage of the viewport height.
    Vh(f32),
    /// Font size as a percentage of the smaller of the viewport width and height.
    VMin(f32),
    /// Font size as a percentage of the larger of the viewport width and height.
    VMax(f32),
    /// Font Size relative to the value of the `RemSize` resource.
    Rem(f32),
}
```

This replaces the `f32` value of `TextFont`'s `font_size` field.

The viewport variants work the same way as their respective `Val`
counterparts.

`Rem` values are multiplied by the value of the `RemSize` resource
(which newtypes an `f32`).

`FontSize` provides an `eval` method that takes a logical viewport size
and rem base size and returns an `f32` logical font size. The resolved
logical font size is then written into the `Attributes` passed to Cosmic
Text by `TextPipeline::update_buffer`.

Any text implementation using `bevy_text` must now provide viewport and
rem base values when calling `TextPipeline::update_buffer` or
`create_measure`.

`Text2d` uses the size of the primary window to resolve viewport values
(or `Vec2::splat(1000)` if no primary window is found). This is a
deliberate compromise, a single `Text2d` can be rendered to multiple
viewports using `RenderLayers`, so it's difficult to find a rule for
which viewport size should be chosen.

### Change detection 

`ComputedTextBlock` has two new fields: `uses_viewport_sizes` and
`uses_rem_sizes`, which are set to true in `TextPipeline::update_buffer`
iff any text section in the block uses viewport or rem font sizes,
respectively.

The `ComputedTextBlock::needs_rerender` method has been modified to take
take two bool parameters:
```rust
    pub fn needs_rerender(
        &self,
        is_viewport_size_changed: bool,
        is_rem_size_changed: bool,
    ) -> bool {
        self.needs_rerender
            || (is_viewport_size_changed && self.uses_viewport_sizes)
            || (is_rem_size_changed && self.uses_rem_sizes)
    }
 ```
This ensures that text reupdates will also be scheduled if one of the text section's uses a viewport font size and the local viewport size changed, or if one of the text section's uses a rem font size and the rem size changed.

#### Limitations

There are some limitations because we don't have any sort of font style inheritance yet:

* "rem" units aren't proper rem units, and just based on the value of a resource. 
* "em" units are resolved based on inherited font size, so can't be implemented without inheritance support.

#### Notes

* This PR is quite small and not very technical. Reviewers don't need to be especially familiar with `bevy_text`. Most of the changes are to the examples.

* We could consider using `Val` instead of `FontSize`, then we could use `Val`'s constructor functions which would be much nicer, but some variants might not have sensible interpretations in both UI and Text2d contexts. Also we'd have to make `Val` accessible to `bevy_text`.

## Testing

The changes to the text systems are relatively trivial and easy to understand.  I already added a minor change to the `text` example to use `Vh` font size for the "hello bevy" text in the bottom right corner. If you change the size of the window, you should see the text change size in response. The text initially flickers before it updates because of some unrelated asset/image changes that mean that font textures aren't ready until the frame after the text update that changes the font size.

Most of the example migrations were automated using regular expressions, and there are bound to be mistakes in those changes. It's infeasible to check every single example thoroughly, but it's early enough in the release cycle that I don't think we should be too worried if a few bugs slip in.

---------

Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
2026-02-02 22:52:33 +00:00
Aevyrie a88af65738 Contact Shadows (#22382)
# Objective

- Implement contact shadows to add fine shadow detail where shadow
cascades cannot.

## Solution

- Extend our existing pbr implementation using our existing raymarching
functions.

---

## Showcase

<img width="1824" height="1180" alt="image"
src="https://github.com/user-attachments/assets/e93b79c5-c596-4a9e-b94d-20bdde1d863b"
/>

<img width="1824" height="1180" alt="image"
src="https://github.com/user-attachments/assets/0fd7dffa-60b8-4b92-8fad-7f993d4d89dd"
/>


https://github.com/user-attachments/assets/e74b190d-9ae3-4aaf-97f0-b520930a0667


https://github.com/user-attachments/assets/e80ccb26-bbaa-4d25-a823-8ea12354c5b9


https://github.com/user-attachments/assets/b04f4b00-92bd-4a2f-b7dd-5157d8fbe0ab

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/b7629908-dd32-48db-8ee7-a4d2dd8f66c2"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/3de0258e-9191-4180-ac57-41b32e1205bd"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/951477f9-e9a9-426f-ae8d-18ae50cc7b85"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/2291453c-da57-4fcc-a6b0-f60f6eac6cbb"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/5820cdff-ea54-4294-b520-2a8d8dc24996"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/3ea16481-7689-4e99-87e2-1589f1532e4c"
/>

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: charlotte 🌸 <charlotte.c.mcelwain@gmail.com>
2026-01-13 21:51:39 +00:00
Lyndon-Mackay fca45967ec DespawnOnExit / DespawnOnEnter fix log spam (#21864)
if entity was despawned such as in a hierachy

# Objective

- DespawnOnExit / DespawnOnEnter logs errors with despawning. 
Most if not all use cases don't care if the item is already despawned.
The user is typically saying "Ensure it is despawned" rather then "You
should be the one to despawn"
- Fixes #21832

## Solution

- Changes the state_scoped code to use try despawn

## Testing

- I updated example state_scoped to include children with
DespawnOnExit/DespawnOnEnter and added a brief explanation then I ran
the examples

---------

Co-authored-by: mgi388 <135186256+mgi388@users.noreply.github.com>
2025-12-09 00:45:11 +00:00
eugineerd a264dd3c85 API for traversing Relationships and RelationshipTargets in dynamic contexts (#21601)
# Objective
Currently there is no way to traverse relationships in type-erased
contexts or to define dynamic relationship components, which is a hole
in the current relationships api.

## Solution
Introduce `RelationshipAccessor` to describe a way to get `Entity`
values from any registered relationships in dynamic contexts and store
it on `ComponentDescriptor`. This allows to traverse relationships
without knowing their type, which is useful for working with entity
hierarchies using non-default components.

## Testing
Added a simple test/example of how to use this api to traverse
hierarchies in a type-erased context.
2025-10-20 21:52:31 +00:00
atlv 44b904ed05 Rename bevy_mesh_picking_backend to mesh_picking (#21436)
# Objective

- Only prefix features bevy_ if they correspond to a crate
- Another step towards #20867

## Solution

- rename it

## Testing

- ci
2025-10-07 23:49:49 +00:00
Carter Anderson 4d74baf1ae BufferedEvent -> Message Rename (#20953)
This renames the concept of `BufferedEvent` to `Message`, and updates
our APIs, comments, and documentation to refer to these types as
"messages" instead of "events". It also removes/updates anything that
considers messages to be "observable", "listenable", or "triggerable".

This is a followup to https://github.com/bevyengine/bevy/pull/20731,
which omitted the `BufferedEvent -> Message` rename for brevity.

See that post for rationale.
2025-09-10 21:04:15 +00:00
Carter Anderson eda118d033 Event Rearchitecture (#20731)
There is general consensus that our terminology for Events, "entity
events", Observers, and BufferedEvents needs clarity. Additionally, many
of us also agree that the current Observer system would benefit from
additional static-ness: currently it is assumed that you can use events
in pretty much any context, and they all go through the exact same code
path.

Alice put forth a proposal to [Overhaul
Observers](https://hackmd.io/@bevy/rk4S92hmlg), and we have already
partially implemented it for 0.17. I think it does a great job of
outlining many of the issues at play, and it solves them reasonably
well. But I _also_ think the proposed solution isn't yet ideal. Given
that it is already partially implemented for 0.17, it is a breaking
change, _and_ given that we have already broken the Observer API a
number of times, I think we need to sort this out before the next
release.

This is a big changeset, but it is _largely_ just a reframing of what is
already there. I haven't fundamentally changed the behaviors. I've just
refined and constrained in a way that allows us to do what we are
currently doing in a clearer, simpler, and more performant way.

First, I'll give some quick notes on Alice's proposal (which you all
should read if you haven't yet!):
### Notes on Alice's Proposal
- I like the move toward a more static API
- I think we've gone too far down the "separate terminology" path. The
proposal introduces a zoo of apis, terms, and "subterms". I think we
need to simplify our concepts and names to make this all easier to talk
about and use in practice.
- BroadcastEvent feels like the wrong name. EntityEvent is also
"broadcast" in the exact same way
- BufferedEvent is a completely different system than EntityEvent and
BroadcastEvent. This muddles concepts too much. It needs its own
standalone, single-word concept name.
- "Universal observers": I think this should be fully context driven,
rather than needing encoding in the API.
- I agree we can't get rid of buffered events, and that merging them
with "broadcast events" isn't helpful
- I'm not quite sure how we'd make the proposed PropagateEvent subtrait
work transparently. This can't be "layered on top" as a trait. It needs
to be baked in at more fundamental level.
* I don't like `app.add_broadcast_observers()`,
`app.add_universal_observers()`, `Observer::entity_observer`,
`Observer::broadcast`, etc. The `On` event should statically determine
whether an observer is an "entity observer" or a "broadcast" Observer.
This would already be encoded in the type system and is therefore
something we can do on the developer's behalf. Likewise, any observer
being registered at a top level is inherently _not_ a specific entity
observer. All of these variants serve to make users guess and poke
around in a way that is unnecessary. I want simple one word concept
names, single constructors, etc.
### Proposed Principals
- Static-ness:
- Events should only be usable in the context they were defined to be
used.
- When triggered, Observers should *only* have access to fields and
behaviors that are relevant:
- Dont return Option or PLACEHOLDER: the field or function shouldn't
exist
- Entity events that don't support propagation shouldn't expose that
functionality
- Don't do unnecessary work at runtime
- Event triggers shouldn't branch through every potential event code
path
- Don't clone potentially large lists of event context unnecessarily
(Ex: we currently clone the component list for every observer
invocation)
- Minimize codegen
	- Don't recompile things redundantly.
	- Don't compile unnecessary code paths.
- Clear and Simple
- Minimize the number of concept names floating around, and lock each
concept down heavily to a specific context
- I'm convinced at this point that "buffered events" and "observer
events" sharing concept names is wrong. We need two clean and clear
terms, and I'm willing to give "buffered events" a slightly worse name
if it means "observer events" can be nicer.
- Don't throw the concept name "Event" out ... it is a very good name.
Instead, constrain it to one specific thing.
	- Minimize our API surface
- Events contain all context, including what used to be the "target".
This lets people define the "target" name that makes the most sense for
the context, and lets the documentation fully describe the context of
that "target".
### Concepts
- **Event** (the thing you "observe")
- Rationale: "Event" is the clear choice for this concept. An "event"
feels like something that happens in real time. "Event observers" are
things that observe events when they occur (are triggered).
Additionally, this is the concept that "propagates", and "event
propagation" is a term people understand.
- **Trigger**: (the verb that "causes" events to happen for targets).
Events are Triggered. This can include additional context/ data that is
passed to observers / informs the trigger behavior. Events have
_exactly_ one Trigger. If you want a different trigger behavior, define
a new event. This makes the system more static, more predictable, and
easier to understand and document. `world.trigger_ref_with` makes it
possible to pass in mutable reference to your own Trigger data, making
it possible to customize the input trigger data and read out the final
trigger data.
- **Observer** (the thing that "observes" events): An event's `Trigger`
determines which observers will run.
- **Event Types**: You can build any "type" of event. The concept of a
"target" has been removed. Instead, define a `Trigger` that expects a
specific kind of event (ex: `E: EntityEvent`).
- **EntityEvent** We add a new `EntityEvent` trait, which defines an
`event.entity()` accessor. This is used by the `Trigger` impls :
`EntityTrigger`, `PropagateEntityTrigger`, and
`EntityComponentsTrigger`.
- **Message** (the buffered thing you "read" and "write")
- `Message` is a solid metaphor for what this is ... it is data that is
written and then at some later point read by someone / something else. I
expect existing consumers of "buffered events" to lament this name
change, as "event" feels nicer. But having a separate name is within
everyone's best interest.
	- **MessageReader** (the thing that reads messages)
	- **MessageWriter** (the thing that writes messages)
### The Changes
- `Event` trait changes
	- Event is now used exclusively by Observers
- Added `Event::Trigger`, which defines what trigger implementation this
event will use
- Added the `Trigger` trait
- All of the shared / hard-coded observer trigger logic has been broken
out into individual context-specific Trigger traits.
- "Trigger Targets" have been removed.
- Instead, Events, in combination with their Trigger impl, decide how
they will be triggered. In general, this means that Events now include
their "targets" as fields on the event.
- APIs like `trigger_targets` have been replaced by `trigger`, which can
now be used for any `Event`
- `EntityEvent` trait changes
- Propagation config has been removed from the `EntityEvent` trait. It
now lives on the `Trigger` trait (specifically the
`PropagateEntityTrigger` trait).
- `EntityEvent` now provides `entity / entity_mut` accessors for the
Event it is implemented for
- `EntityEvent` defaults to having no propagation (uses the simpler
`EntityTrigger`)
- `#[entity_event(propagate)]` enables the "default" propagation logic
(uses ChildOf). The existing `#[entity_event(traversal = X)]` has been
renamed to `#[entity_event(propagate = X)`
- Deriving `EntityEvent` requires either a single `MyEvent(Entity)`, the
`entity` field name (`MyEvent { entity: Entity}`), or `MyEvent {
#[event_entity] custom: Entity }`
- Animation event changes
- Animation events now have their own `AnimationEvent` trait, which sets
the `AnimationEventTrigger`. This allows developers to pass in events
that _dont_ include the Entity field (as this is set by the system). The
custom trigger also opens the doors to cheaply passing in additional
animation system context, accessible through `On`
- `EntityComponentsTrigger`
- The built in Add/Remove/etc lifecycle events now use the
`EntityComponentsTrigger`, which passes in the components as additional
state. This _significantly_ cuts down on clones, as it does a borrow
rather than cloning the list into _each_ observer execution.
	- Each event now has an `entity` field.
- Style changes
- Prefer the event name for variables: `explode: On<Explode>` not
`event: On<Explode>`
- Prefer using the direct field name for the entity on entity events,
rather than `event.entity()`. This allows us to use more specific names
where appropriate, provides better / more contextual docs, and coaches
developers to think of `On<MyEvent>` _as_ the event itself.

Take a look at the changes to the examples and the built-in events to
see what this looks like in practice.

### Downsides
- Moving the "target" into the event adds some new constraints:
- Triggering the same event for multiple entities requires multiple
trigger calls. For "expensive" events (ex: lots of data attached to the
event), this will be more awkward. Your options become:
		-  Create multiple instances of the event, cloning the expensive data
- Use `trigger_ref`, and mutate the event on each call to change the
target.
- Move the "expensive" shared data into the Trigger, and use
`trigger_ref_with``
- We could build a new EntityEvent method that abstracts over the "event
mutation" behavior and provides something like the old `trigger_target`
behavior.
- Use a different `EntityTargetTrigger` (not currently provided by bevy,
but we could), which brings back the old behavior. This would be used
with `trigger_with` to replicate the old pattern:
`world.trigger_with(MyEvent, [e1, e2].into())` (or we could make the
`into()` implicit)
- Bubbling the event involves mutating the event to set the entity. This
means that `trigger_ref` will result in the event's
`EntityEvent::entity()` being the final bubbled entity instead of the
initial entity.
- Some APIs (trivially) benefit from the "target entity" being separate
from the event. Specifically, this new API requires changes to the
"Animation Event" system in AnimationPlayer. I think this is actually a
good change set, as it allows us to:
- Cheaply expose more animation state as part of a new
AnimationEventTrigger impl
- Move that "implict" entity target provided by the AnimationPlayer into
the AnimationEventTrigger
- Encode the "animation event trigger-ness" of the event into the type
itself (by requiring `#[event(trigger = AnimationEventTrigger)]`)
- By not implementing Default for AnimationEventTrigger, we can block
animation events from being fired manually by the user.

### Draft TODO
- [x] Fill in documentation and update existing docs
- [ ] Benchmark: I expect this impl to be significantly faster. There
might also be tangible binary size improvements, as I've removed a lot
of redundant codegen.
- [x] Update release notes and migration guides

### Next Steps
- The `BufferedEvent -> Message` rename was not included to keep the
size down.

Fixes #19648

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2025-09-09 23:48:55 +00:00
Janis 62270640e6 convert more examples to new spawn api (#20876)
# Objective
works on #18238

## Solution

convert calls to `.with_children` to use the `Children::spawn` or
`Children::spawn_one` types or `children!` macro.
This touches the `window`, `2d`, `animation` folders, as well as
`ecs/one_shot_systems.rs`.
`observer_propagation.rs` looks like exactly what `with_children` is
useful for, so I deliberately haven't touched it.
I can break this up into more PRs or squash if desired.

## Testing

I've run the examples before and after this patch and verified visually
that nothing has changed
2025-09-06 10:33:30 +00:00
Jan Hohenheim b43a73df3f Rename DespawnOnExitState to DespawnOnExit (#20872)
# Objective

- `StateScoped` was renamed to `DespawnOnExitState`, and we introduced
`DespawnOnEnterState`
- This is redundant: the type it wraps is already a state
- Often, state enums have `State` in their names, leading to stutter:
`DespawnOnExitState(GameState::Gameplay)`
- This component is *very* common in games. The longer name makes it
clunkier to use, so we should be careful when expanding it. I think the
added clarity is good, but we can do better.

## Solution

- Compromise to `DespawnOnExit`
- Do the same for `DespawnOnEnter`

## Testing

- CI
2025-09-04 21:13:46 +00:00
TheBlckbird 13877fa84d Add a new trait to accept more types in the Val-helper functions (#20551)
# Objective

- Allow the `Val`-helper functions to accept more types besides just
`f32`

Fixes #20549

## Solution

- Adds a new trait that can be implemented for numbers
- That trait has a method that converts `self` to `f32`

## Testing

- I tested it using Rust's testing framework (although I didn't leave
the tests in, as I don't deem them important enough)

<details>
  <summary>Rust test</summary>

```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_val_helpers_work() {
        let p = px(10_u8);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_u16);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_u32);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_u64);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_u128);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i8);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i16);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i32);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i64);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i128);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10.3_f32);
        assert_eq!(p, Val::Px(10.3));

        let p = px(10.6_f64);
        assert_eq!(p, Val::Px(10.6));
    }
}
```
</details>

---

## Showcase

```rust
// Same as Val::Px(10.)
px(10);
px(10_u8);
px(10.0);
```
2025-08-29 20:18:57 +00:00
atlv 72238e3cd0 fix some target comments (#20720)
# Objective

- fix some `target` comments

## Solution

- fix some `target` comments

## Testing

- eyeballs
2025-08-22 22:29:06 +00:00
Carter Anderson 5058f8a9e6 Improve On Terminology (#20648)
# Objective

Fixes #19263 (and expands on it)

Within `Observers`, we have started to distance ourselves from the
"trigger" terminology. Specifically, we have renamed `Trigger` to `On`.
I think this was a very good move, but we're currently in an awkward
middle ground state. Users interact with `On` as if it were an event:
`On<E>` exposes the event and derefs directly to it. I think we should
embrace this mindset fully, in the interest of clarity.

## Solution

- Rename all `trigger: On<SomeEvent>` cases to `event: On<SomeEvent>`.
- Rename `On::target` to `On::entity`. This reads _much_ better when
writing `query.get(event.entity())` and pairs more effectively with the
`EntityEvent` terminology.
- Rename `On::original_target` to `On::original_entity`, for the same
reasons.
- Take advantage of the `Deref` behavior where appropriate

```rust
// Before
entity.observe(|trigger: On<Explode>| {
  println!("{} exploded!", trigger.target());
})

// After
entity.observe(|event: On<Explode>| {
  println!("{} exploded!", event.entity());
})
```
2025-08-21 08:54:28 +00:00
Guillaume Gomez 77966a737c Fix intra-doc link warnings (#20530)
Fixes intra-doc links appearing when generating documentation.
2025-08-20 17:54:32 +00:00
Mys Vac 7b62e857b9 Fix a comment error in example system_stepping.rs (#20663)
# Objective

Examples ECS system_stepping.rs :

```rust
  println!(
      r#"
           ....................................
           in order of one, two, three.  Stepping stops system execution in
           the Update schedule when it encounters the breakpoint for
           update_system_three(). // <------
           ................."#
  );
  let mut stepping = app.world_mut().resource_mut::<Stepping>();
  stepping.set_breakpoint(Update, update_system_two); // <------
  stepping.continue_frame();
  app.update();
  ....................
```

I think this should be "breakpoint for update_system_two()." instead of
"breakpoint for update_system_three().".

## Solution

Change `update_system_three` to `update_system_two` in `println!` .

## Testing

Only modified one comment, not tested.
2025-08-20 05:13:01 +00:00
Afonso Lage c143d4b9dd Fix small typo on ecs error handling example comment (#20616)
Fixed small typo in comments

# Objective

- Fixes a small typo on error handling example comments.

## Solution

N/A

## Testing

N/A

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-08-17 16:51:37 +00:00
François Mockers cb34db6e98 Fix latest lints for rust beta (#20516)
# Objective

- Fix #19679

## Solution

- fix lints
2025-08-11 19:34:18 +00:00
Gonçalo Rica Pais da Silva ef845e0cea Update rand, glam and encase to latest versions (#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](https://github.com/teoxoy/encase/pull/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 <francois.mockers@vleue.com>
2025-08-09 02:09:10 +00:00
James Liu 8e52194d70 CI fixes for Rust 1.89 (#20462)
Adopted from #20456

Notes:

* The origin of the `dead_code` lints were coming from the `ShaderType `
derive macro. This has been reported as
https://github.com/teoxoy/encase/issues/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
https://github.com/rust-lang/rust/issues/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 <alice.i.cecile@gmail.com>
Co-authored-by: Mike <mike.hsu@gmail.com>
2025-08-08 21:14:36 +00:00
IRSMsoso 6e7ee7e305 Change to relationship iter method instead of looping over private vec field in relationship example (#20351)
# Objective

- Fixes #20091 

## Solution

- Changed loop over targeted_by inner private field to use the
RelationshipTarget trait's .iter() method.
2025-07-31 17:30:47 +00:00
shunkie 779bba6091 Fix relationship method names in comments (#20218) 2025-07-21 07:22:11 +00:00
Carter Weinberg 60a1468843 Fixing Minor Sentence Structure Mistake in Events Example Docs (#20217)
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-07-21 06:12:59 +00:00
Tim 57086d4416 Remove the need to derive Event when deriving EntityEvent (#20104)
# 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 early.

Context from
[discord](https://discordapp.com/channels/691052431525675048/1383928409784193024/1393463673137401946).
Related to, and will conflict slightly with #20101.

## Solution

- Derive `Event` as part of the `EntityEvent` derive
- Remove any `Event` derives that were made unnecessary
- Update release notes
2025-07-15 16:45:38 +00:00
Tim 4e9e78c31e Split BufferedEvent from Event (#20101)
# 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

## Solution

- Remove `Event` as a supertrait of `BufferedEvent`
- Remove any `Event` derives that were made unnecessary
- Update release notes

---------

Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
2025-07-14 21:31:48 +00:00
AlephCubed 3aed85a88b Rename send_event and similar methods to write_event (#20017)
Fixes: #18963
Follows up on: #17977
Adopts: #18966

In 0.16, `EventWriter::send` was renamed to `EventWriter::write`, but
many methods were missed (sorry about that). This completes that
refactor by renaming all `send` methods and internals.

| Old | New |

|-------------------------------------|--------------------------------------|
| `World::send_event` | `World::write_event` |
| `World::send_event_default` | `World::write_event_default` |
| `World::send_event_batch` | `World::write_event_batch` |
| `DeferredWorld::send_event` | `DeferredWorld::write_event` |
| `DeferredWorld::send_event_default` |
`DeferredWorld::write_event_default` |
| `DeferredWorld::send_event_batch` | `DeferredWorld::write_event_batch`
|
| `Commands::send_event` | `Commmands::write_event` |
| `Events::send` | `Events::write` |
| `Events::send_default` | `Events::write_default` |
| `Events::send_batch` | `Events::write_batch` |
| `RemovedComponentEvents::send` | `RemovedComponentEvents::write` |
| `command::send_event` | `commmand::write_event` |
| `SendBatchIds` | `WriteBatchIds` |

---------

Co-authored-by: shwwwa <shwwwa.dev@gmail.com>
2025-07-07 22:05:16 +00:00
charlotte 🌸 92e65d5eb1 Upgrade to Rust 1.88 (#19825) 2025-06-26 19:38:19 +00:00
Chris Russell f7e112a3c9 Let query items borrow from query state to avoid needing to clone (#15396)
# Objective

Improve the performance of `FilteredEntity(Ref|Mut)` and
`Entity(Ref|Mut)Except`.

`FilteredEntityRef` needs an `Access<ComponentId>` to determine what
components it can access. There is one stored in the query state, but
query items cannot borrow from the state, so it has to `clone()` the
access for each row. Cloning the access involves memory allocations and
can be expensive.


## Solution

Let query items borrow from their query state.  

Add an `'s` lifetime to `WorldQuery::Item` and `WorldQuery::Fetch`,
similar to the one in `SystemParam`, and provide `&'s Self::State` to
the fetch so that it can borrow from the state.

Unfortunately, there are a few cases where we currently return query
items from temporary query states: the sorted iteration methods create a
temporary state to query the sort keys, and the
`EntityRef::components<Q>()` methods create a temporary state for their
query.

To allow these to continue to work with most `QueryData`
implementations, introduce a new subtrait `ReleaseStateQueryData` that
converts a `QueryItem<'w, 's>` to `QueryItem<'w, 'static>`, and is
implemented for everything except `FilteredEntity(Ref|Mut)` and
`Entity(Ref|Mut)Except`.

`#[derive(QueryData)]` will generate `ReleaseStateQueryData`
implementations that apply when all of the subqueries implement
`ReleaseStateQueryData`.

This PR does not actually change the implementation of
`FilteredEntity(Ref|Mut)` or `Entity(Ref|Mut)Except`! That will be done
as a follow-up PR so that the changes are easier to review. I have
pushed the changes as chescock/bevy#5.

## Testing

I ran performance traces of many_foxes, both against main and against
chescock/bevy#5, both including #15282. These changes do appear to make
generalized animation a bit faster:

(Red is main, yellow is chescock/bevy#5)

![image](https://github.com/user-attachments/assets/de900117-0c6a-431d-ab62-c013834f97a9)


## Migration Guide

The `WorldQuery::Item` and `WorldQuery::Fetch` associated types and the
`QueryItem` and `ROQueryItem` type aliases now have an additional
lifetime parameter corresponding to the `'s` lifetime in `Query`. Manual
implementations of `WorldQuery` will need to update the method
signatures to include the new lifetimes. Other uses of the types will
need to be updated to include a lifetime parameter, although it can
usually be passed as `'_`. In particular, `ROQueryItem` is used when
implementing `RenderCommand`.

Before: 

```rust
fn render<'w>(
    item: &P,
    view: ROQueryItem<'w, Self::ViewQuery>,
    entity: Option<ROQueryItem<'w, Self::ItemQuery>>,
    param: SystemParamItem<'w, '_, Self::Param>,
    pass: &mut TrackedRenderPass<'w>,
) -> RenderCommandResult;
```

After: 

```rust
fn render<'w>(
    item: &P,
    view: ROQueryItem<'w, '_, Self::ViewQuery>,
    entity: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
    param: SystemParamItem<'w, '_, Self::Param>,
    pass: &mut TrackedRenderPass<'w>,
) -> RenderCommandResult;
```

---

Methods on `QueryState` that take `&mut self` may now result in
conflicting borrows if the query items capture the lifetime of the
mutable reference. This affects `get()`, `iter()`, and others. To fix
the errors, first call `QueryState::update_archetypes()`, and then
replace a call `state.foo(world, param)` with
`state.query_manual(world).foo_inner(param)`. Alternately, you may be
able to restructure the code to call `state.query(world)` once and then
make multiple calls using the `Query`.

Before:
```rust
let mut state: QueryState<_, _> = ...;
let d1 = state.get(world, e1);
let d2 = state.get(world, e2); // Error: cannot borrow `state` as mutable more than once at a time
println!("{d1:?}");
println!("{d2:?}");
```

After: 
```rust
let mut state: QueryState<_, _> = ...;

state.update_archetypes(world);
let d1 = state.get_manual(world, e1);
let d2 = state.get_manual(world, e2);
// OR
state.update_archetypes(world);
let d1 = state.query(world).get_inner(e1);
let d2 = state.query(world).get_inner(e2);
// OR
let query = state.query(world);
let d1 = query.get_inner(e1);
let d1 = query.get_inner(e2);

println!("{d1:?}");
println!("{d2:?}");
```
2025-06-16 21:05:41 +00:00
Alice Cecile b7d2cb8547 Provide access to the original target of entity-events in observers (#19663)
# Objective

Getting access to the original target of an entity-event is really
helpful when working with bubbled / propagated events.

`bevy_picking` special-cases this, but users have requested this for all
sorts of bubbled events.

The existing naming convention was also very confusing. Fixes
https://github.com/bevyengine/bevy/issues/17112, but also see #18982.

## Solution

1. Rename `ObserverTrigger::target` -> `current_target`.
1. Store `original_target: Option<Entity>` in `ObserverTrigger`.
1. Wire it up so this field gets set correctly.
1. Remove the `target` field on the `Pointer` events from
`bevy_picking`.

Closes https://github.com/bevyengine/bevy/pull/18710, which attempted
the same thing. Thanks @emfax!

## Testing

I've modified an existing test to check that the entities returned
during event bubbling / propagation are correct.

## Notes to reviewers

It's a little weird / sad that you can no longer access this infromation
via the buffered events for `Pointer`. That said, you already couldn't
access any bubbled target. We should probably remove the `BufferedEvent`
form of `Pointer` to reduce confusion and overhead, but I didn't want to
do so here.

Observer events can be trivially converted into buffered events (write
an observer with an EventWriter), and I suspect that that is the better
migration if you want the controllable timing or performance
characteristics of buffered events for your specific use case.

## Future work

It would be nice to not store this data at all (and not expose any
methods) if propagation was disabled. That involves more trait
shuffling, and I don't think we should do it here for reviewability.

---------

Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2025-06-15 20:53:25 +00:00