Queries: Systems, Twice
Our systems can work just great like normal functions as we've already seen, but what if you actually want to do something with an entity after you spawn it? That's where you need to use a Query. A Query takes a list of components and gives you back all entities who have those components. This is also where you specify how you want to access each component of that entity. Do you want to change something? Then it needs to be Mut<T>. If you only want to reference the component, then Ref<T> is the way to go. If you want to mutate any of the components of your Query, then you must also make the Query mut.
For right now we are only spawning one entity. That makes it very easy to query.
use engine::prelude::*;
mod ffi;
#[system_once]
fn spawn_player() {
let transform = &Transform {
position: Vec2::new(110., 0.),
scale: Vec2::splat(3.0),
..Default::default()
};
let color = &Color::ORANGE;
let circle_render = &CircleRender {
num_sides: 20,
..Default::default()
};
Engine::spawn(bundle!(transform, color, circle_render));
}
#[system]
fn move_player(mut player: Query<Mut<Transform>>) {
player.for_each(|mut transform| {
if (transform.position.x >= 100.) {
transform.position.y += 5.0;
} else if (transform.position.x <= -100.) {
transform.position.y -= 5.0;
}
if (transform.position.y >= 100.) {
transform.position.x -= 5.0;
} else if (transform.position.y <= -100.) {
transform.position.x += 5.0;
}
});
}
Here you can see we've added a new system, queried our player, and we get this beautiful result:

Now, using what we know, I want to add an enemy to the game! Let's add a system in, maybe change up the colors to differentiate them...
use engine::prelude::*;
mod ffi;
#[system_once]
fn spawn_player() {
let transform = &Transform {
position: Vec2::new(110., 0.),
scale: Vec2::splat(3.0),
..Default::default()
};
let color = &Color::new(0.96, 0.65, 0.14, 0.9);
let circle_render = &CircleRender {
num_sides: 20,
..Default::default()
};
Engine::spawn(bundle!(transform, color, circle_render));
}
#[system_once]
fn spawn_enemy() {
let transform = &Transform {
position: Vec2::new(-110., 0.),
scale: Vec2::splat(3.0),
..Default::default()
};
let color = &Color::new(0.2, 0.2, 0.9, 0.9);
let circle_render = &CircleRender {
num_sides: 20,
..Default::default()
};
Engine::spawn(bundle!(transform, color, circle_render));
}
#[system]
fn move_player(mut player: Query<Mut<Transform>>) {
player.for_each(|mut transform| {
if (transform.position.x >= 100.) {
transform.position.y += 5.0;
} else if (transform.position.x <= -100.) {
transform.position.y -= 5.0;
}
if (transform.position.y >= 100.) {
transform.position.x -= 5.0;
} else if (transform.position.y <= -100.) {
transform.position.x += 5.0;
}
});
}

Oh my gosh! What a surprise! They're both moving?
Who could have predicted this?
Queries don't care that you think of them as different things, or call for a player, they'll grab every entity that has the required components. No, if we want to differentiate two very similar entities from each other, we're going to need to learn how to make our own custom components.