logo
pub unsafe trait WorldQuery: for<'w> WorldQueryGats<'w, _State = Self::State> {
    type ReadOnly: ReadOnlyWorldQuery
    where
        <Self::ReadOnly as WorldQuery>::State == Self::State
; type State: FetchState; fn shrink<'wlong, 'wshort>(
        item: <Self::Fetch as Fetch<'wlong>>::Item
    ) -> <Self::Fetch as Fetch<'wshort>>::Item
    where
        'wlong: 'wshort
; }
Expand description

Types that can be queried from a World.

Notable types that implement this trait are &T and &mut T where T implements Component, allowing you to query for components immutably and mutably accordingly.

See Query for a primer on queries.

Basic WorldQuery’s

Here is a small list of the most important world queries to know about where C stands for a Component and WQ stands for a WorldQuery:

  • &C: Queries immutably for the component C
  • &mut C: Queries mutably for the component C
  • Option<WQ>: Queries the inner WorldQuery WQ but instead of discarding the entity if the world query fails it returns None. See Query.
  • (WQ1, WQ2, ...): Queries all contained world queries allowing to query for more than one thing. This is the And operator for filters. See Or.
  • ChangeTrackers<C>: See the docs of ChangeTrackers.
  • Entity: Using the entity type as a world query will grant access to the entity that is being queried for. See Entity.

Bevy also offers a few filters like Added, Changed, With, Without and Or. For more information on these consult the item’s corresponding documentation.

Derive

This trait can be derived with the super::WorldQuery macro.

You may want to implement a custom query with the derive macro for the following reasons:

  • Named structs can be clearer and easier to use than complex query tuples. Access via struct fields is more convenient than destructuring tuples or accessing them via q.0, q.1, ... pattern and saves a lot of maintenance burden when adding or removing components.
  • Nested queries enable the composition pattern and makes query types easier to re-use.
  • You can bypass the limit of 15 components that exists for query tuples.

Implementing the trait manually can allow for a fundamentally new type of behaviour.

The derive macro implements WorldQuery for your type and declares an additional struct which will be used as an item for query iterators. The implementation also generates two other structs that implement Fetch and FetchState and are used as WorldQuery::Fetch and WorldQuery::State associated types respectively.

The derive macro requires every struct field to implement the WorldQuery trait.

Note: currently, the macro only supports named structs.

use bevy_ecs::query::WorldQuery;

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

#[derive(WorldQuery)]
struct MyQuery {
    entity: Entity,
    // We must explicitly list out all lifetimes, as we are defining a struct
    foo: &'static Foo,
    bar: Option<&'static Bar>,
}

fn my_system(query: Query<MyQuery>) {
    for q in &query {
        // Note the type of the returned item.
        let q: MyQueryItem<'_> = q;
        q.foo;
    }
}

Mutable queries

All queries that are derived with the WorldQuery macro provide only an immutable access by default. If you need a mutable access to components, you can mark a struct with the mutable attribute.

use bevy_ecs::query::WorldQuery;

#[derive(Component)]
struct Health(f32);
#[derive(Component)]
struct Buff(f32);

#[derive(WorldQuery)]
#[world_query(mutable)]
struct HealthQuery {
    health: &'static mut Health,
    buff: Option<&'static mut Buff>,
}

// This implementation is only available when iterating with `iter_mut`.
impl<'w> HealthQueryItem<'w> {
    fn damage(&mut self, value: f32) {
        self.health.0 -= value;
    }

    fn total(&self) -> f32 {
        self.health.0 + self.buff.as_deref().map_or(0.0, |Buff(buff)| *buff)
    }
}

// If you want to use it with `iter`, you'll need to write an additional implementation.
impl<'w> HealthQueryReadOnlyItem<'w> {
    fn total(&self) -> f32 {
        self.health.0 + self.buff.map_or(0.0, |Buff(buff)| *buff)
    }
}

fn my_system(mut health_query: Query<HealthQuery>) {
    // Iterator's item is `HealthQueryReadOnlyItem`.
    for health in &health_query {
        println!("Total: {}", health.total());
    }
    // Iterator's item is `HealthQueryItem`.
    for mut health in &mut health_query {
        health.damage(1.0);
        println!("Total (mut): {}", health.total());
    }
}

Mutable queries will also have a read only version derived:

use bevy_ecs::query::WorldQuery;

#[derive(Component)]
pub struct MyComponent;

#[derive(WorldQuery)]
#[world_query(mutable)]
pub struct Foo {
    my_component_yay: &'static mut MyComponent,
}

fn my_system(mut my_query: Query<(FooReadOnly, FooReadOnly)>) {
    for (i1, i2) in &mut my_query {
        let _: FooReadOnlyItem<'_> = i1;
        let _: FooReadOnlyItem<'_> = i2;
    }
}

Note: if you omit the mutable attribute for a query that doesn’t implement ReadOnlyWorldQuery, compilation will fail. We insert static checks as in the example above for every query component and a nested query. (The checks neither affect the runtime, nor pollute your local namespace.)

use bevy_ecs::query::WorldQuery;

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

#[derive(WorldQuery)]
struct FooQuery {
    foo: &'static Foo,
    bar_query: BarQuery,
}

#[derive(WorldQuery)]
#[world_query(mutable)]
struct BarQuery {
    bar: &'static mut Bar,
}

Derives for items

If you want query items to have derivable traits, you can pass them with using the world_query(derive) attribute. When the WorldQuery macro generates the structs for query items, it doesn’t automatically inherit derives of a query itself. Since derive macros can’t access information about other derives, they need to be passed manually with the world_query(derive) attribute.

use bevy_ecs::query::WorldQuery;

#[derive(Component, Debug)]
struct Foo;

#[derive(WorldQuery)]
#[world_query(mutable, derive(Debug))]
struct FooQuery {
    foo: &'static Foo,
}

fn assert_debug<T: std::fmt::Debug>() {}

assert_debug::<FooQueryItem>();
assert_debug::<FooQueryReadOnlyItem>();

Nested queries

Using nested queries enable the composition pattern, which makes it possible to re-use other query types. All types that implement WorldQuery (including the ones that use this derive macro) are supported.

use bevy_ecs::query::WorldQuery;

#[derive(Component)]
struct Foo;
#[derive(Component)]
struct Bar;
#[derive(Component)]
struct OptionalFoo;
#[derive(Component)]
struct OptionalBar;

#[derive(WorldQuery)]
struct MyQuery {
    foo: FooQuery,
    bar: (&'static Bar, Option<&'static OptionalBar>)
}

#[derive(WorldQuery)]
struct FooQuery {
    foo: &'static Foo,
    optional_foo: Option<&'static OptionalFoo>,
}

// You can also compose derived queries with regular ones in tuples.
fn my_system(query: Query<(&Foo, MyQuery, FooQuery)>) {
    for (foo, my_query, foo_query) in &query {
        foo; my_query; foo_query;
    }
}

Ignored fields

The macro also supports ignore attribute for struct members. Fields marked with this attribute must implement the Default trait.

This example demonstrates a query that would iterate over every entity.

use bevy_ecs::query::WorldQuery;

#[derive(WorldQuery, Debug)]
struct EmptyQuery {
    empty: (),
}

fn my_system(query: Query<EmptyQuery>) {
    for _ in &query {}
}

Filters

Using super::WorldQuery macro we can create our own query filters.

use bevy_ecs::{query::WorldQuery, component::Component};

#[derive(Component)]
struct Foo;
#[derive(Component)]
struct Bar;
#[derive(Component)]
struct Baz;
#[derive(Component)]
struct Qux;

#[derive(WorldQuery)]
struct MyFilter<T: Component, P: Component> {
    _foo: With<Foo>,
    _bar: With<Bar>,
    _or: Or<(With<Baz>, Changed<Foo>, Added<Bar>)>,
    _generic_tuple: (With<T>, Without<P>),
}

fn my_system(query: Query<Entity, MyFilter<Foo, Qux>>) {
    for _ in &query {}
}

Safety

component access of ROQueryFetch<Self> must be a subset of QueryFetch<Self> and ROQueryFetch<Self> must match exactly the same archetypes/tables as QueryFetch<Self>

Required Associated Types

Required Methods

This function manually implements variance for the query items.

Implementations on Foreign Types

SAFETY: access of &T is a subset of &mut T

SAFETY: ROQueryFetch<Self> is the same as QueryFetch<Self>

Implementors

SAFETY: no component or archetype access

SAFETY: Self::ReadOnly is Self