---
id: kw-query
name: query
category: ecs
kind: keyword
tokens: query
sig: query [PropA, PropB, {Tag}]
tip: Match every model instance carrying all the listed properties.
order: 2
---
A query selects every live model instance that carries all the listed properties, and is the core way handlers reach data. Use it in a `for (…) in query [...]` loop, where you write one loop variable per bound property in declaration order; each pass binds those properties for one matching instance and `self()` gives that instance. A `{Model}` term in tag position filters by model kind without binding a variable, so `query [Position, {Player}]` walks only players. Add a `where` clause to filter on field values (`where health.current > 0`). Matching is lazy and re-checked per instance as the loop reaches each id, not snapshotted, so spawns and despawns during the loop follow well-defined rules.
```ludic
program Collisions {
property Position { column: int = 0, row: int = 0 }
property Health { current: int = 100, maximum: int = 100 }
model Enemy { Position, Health }
handler Boot phase Start {
spawn Grunt { Position { column: 5, row: 5 }; Health { current: 10 } }
}
handler DrawWorld phase Render {
Screen.clear(Color.MidnightBlue)
for (position, health) in query [Position, Health, {Enemy}] where health.current > 0 {
Screen.fill_rectangle(x: position.column * 16, y: position.row * 16, width: 16, height: 16, color: Color.Crimson)
}
Screen.show()
}
}
```