Skip to content

Ergonomic observer queries: SystemInput-taking SystemParam edition - #25686

Draft
ItsDoot wants to merge 3 commits into
bevyengine:mainfrom
ItsDoot:ecs/inputsystemparam
Draft

Ergonomic observer queries: SystemInput-taking SystemParam edition#25686
ItsDoot wants to merge 3 commits into
bevyengine:mainfrom
ItsDoot:ecs/inputsystemparam

Conversation

@ItsDoot

@ItsDoot ItsDoot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Objective

Solution

SystemParams now take the SystemInput by reference when fetching the data for the system:

  1. Add trait SystemParamFetch<I: SystemInput>: SystemParam, a new super trait of SystemParam.
  2. Move SystemParam::get_param to SystemParamFetch, and add a new argument to it that accepts a reference to the SystemInput.
  3. Implement SystemParamFetch for any I: SystemInput for all current SystemParam implementations, and move the get_param implementation over.
  4. Add functions to SystemState to work with non-() system inputs.
  5. Update FunctionSystem trait machinery from P: SystemParam to P: SystemParamFetch<System::In>.
  6. Add TargetEntity trait and Target<D, F> query type. The latter is similar to Single<D, F>, but fetches the query data for the target entity rather than the unique entity that matches the query.
    a. Target<D, F> is bounded to only work with SystemInputs that take a type that implements TargetEntity.

Benefits of this approach:

  • Compile-time checked: if you use Target<D, F> in a normal scheduled system (which has no input), you get an error when trying to register the system via add_systems.
  • No hidden state: The target Entity used by Target<D, F> is the same data available via On<E>.
  • Extensible: supports SystemParam fetching based on any SystemInput
    • Which means you could implement an OriginalTarget<D, F> for propagating events, for example.

Drawbacks of this approach:

  • Type complexity: while custom SystemParam implementations are already in advanced territory, complicating the API surface further does have an impact.
    • This can be (and has partly been) remediated with documentation on good practices.

Testing

Added a test for Target<D, F>.


Showcase

Ergonomic target entity queries are here!

fn my_observer(on: On<Interact>, button: Target<&Name, With<Button>>) {
    // The observer's function only executes if the Target query matches the target entity
    let name = *button;
    println!("Button {name} was interacted with");
}

app.add_observer(my_observer);

@ItsDoot ItsDoot added A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Complex Quite challenging from either a design or technical perspective. Ask for help! X-Contentious There are nontrivial implications that should be thought through D-Unsafe Touches with unsafe code in some way S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Sep 5, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in ECS Sep 5, 2026
@Zeophlite Zeophlite added the S-Merge-Conflicts Merge conflicts :( Add this label on top of other S- labels. label Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Complex Quite challenging from either a design or technical perspective. Ask for help! D-Unsafe Touches with unsafe code in some way S-Merge-Conflicts Merge conflicts :( Add this label on top of other S- labels. S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged X-Contentious There are nontrivial implications that should be thought through

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

Provide easy access to components of targeted entity in observers

2 participants