Queries & Iteration
Queries find entities by their component masks. Since component presence is tracked as bitflags, queries are extremely fast - a single bitmask comparison per archetype table.
Basic Queries
Query entities with specific components using component flags:
#![allow(unused)] fn main() { for entity in world.core.query_entities(LOCAL_TRANSFORM | GLOBAL_TRANSFORM) { if let Some(transform) = world.core.get_local_transform(entity) { let position = transform.translation; } } }
The query returns all entities that have at least the specified components. An entity with LOCAL_TRANSFORM | GLOBAL_TRANSFORM | RENDER_MESH will match a query for LOCAL_TRANSFORM | GLOBAL_TRANSFORM.
Common Query Patterns
Renderable Entities
#![allow(unused)] fn main() { const RENDERABLE: ComponentFlags = LOCAL_TRANSFORM | GLOBAL_TRANSFORM | RENDER_MESH | MATERIAL_REF; for entity in world.core.query_entities(RENDERABLE) { let transform = world.core.get_global_transform(entity).unwrap(); let mesh = world.core.get_render_mesh(entity).unwrap(); } }
Physics Entities
#![allow(unused)] fn main() { for entity in world.core.query_entities(RIGID_BODY | LOCAL_TRANSFORM) { if let Some(rb) = world.core.get_rigid_body(entity) { if rb.body_type == RigidBodyType::Dynamic { // Process dynamic bodies } } } }
Animated Entities
#![allow(unused)] fn main() { for entity in world.core.query_entities(ANIMATION_PLAYER) { if let Some(player) = world.core.get_animation_player_mut(entity) { player.speed = 1.0; } } }
First Match
For singleton-like entities, use iterator methods:
#![allow(unused)] fn main() { let player = world.core.query_entities(CHARACTER_CONTROLLER).next(); if let Some(player_entity) = player { let controller = world.core.get_character_controller(player_entity); } }
Filtering
Combine queries with additional runtime checks:
#![allow(unused)] fn main() { for entity in world.core.query_entities(LIGHT) { let light = world.core.get_light(entity).unwrap(); if light.light_type == LightType::Point { // Process point lights only } } }
Entity Count
#![allow(unused)] fn main() { let renderable_count = world.core.query_entities(RENDER_MESH).count(); let light_count = world.core.query_entities(LIGHT).count(); }
Named Entity Lookup
If entities have the Name component:
#![allow(unused)] fn main() { fn find_by_name(world: &World, name: &str) -> Option<Entity> { for entity in world.core.query_entities(NAME) { if let Some(entity_name) = world.core.get_name(entity) { if entity_name.0 == name { return Some(entity); } } } None } let player = find_by_name(world, "Player"); }
The engine also maintains world.resources.entity_names as a HashMap<String, Entity> for fast name-based lookups.
Children Queries
Query children of a specific parent:
#![allow(unused)] fn main() { if let Some(children) = world.resources.children_cache.get(&parent_entity) { for child in children { if let Some(transform) = world.core.get_local_transform(*child) { // Process child } } } }
Collecting Results
Collect query results for later processing (useful when you need to mutate during iteration):
#![allow(unused)] fn main() { let enemies: Vec<Entity> = world.core.query_entities(ENEMY_TAG | HEALTH).collect(); for enemy in &enemies { apply_damage(world, *enemy, 10.0); } }
Iteration with Index
#![allow(unused)] fn main() { for (index, entity) in world.core.query_entities(RENDER_MESH).enumerate() { // index is the iteration position, not the entity ID } }