Queries¶
Most roguelikes involve systems where you need to efficiently find actors or entities with certain components—such as all enemies, or everyone at a specific location. Prism provides a built-in query system to make this easy and efficient.
Basic usage¶
To start a query, call IQueryable.query
with the component types you want to require. This
interface is implemented by Level
, MapBuilder
, and ActorStorage
.
local query = level:query(prism.components.Controller, prism.components.Collider)
This creates a Query
object. You can add more required components later with
Query:with()
.
query:with(prism.components.Senses)
You can also restrict the query to a single tile with Query:at()
.
query:at(10, 5)
Iterating over results¶
Use Query:iter()
to get an iterator over matching actors and their components:
for actor, controller, collider, senses in query:iter() do
-- do stuff
end
Alternatively, use Query:each()
to apply a function to each match:
query:each(function(actor, controller, collider, senses)
-- do stuff
end)
Gathering results¶
To gather results into a list, use Query:gather()
:
local results = query:gather()
for _, actor in ipairs(results) do
-- Do something with them
end
Getting a single result¶
Use Query:first()
to get the first match:
local actor, playerController = level:query(prism.components.PlayerController):first()
Good for singleton components like if your game has only one actor with a PlayerController. First calls iter behind the scenes and discards the iterator after the first result.
Putting it together¶
Here’s an example of it all put together:
local query = level:query(prism.components.Controller, prism.components.Senses)
:with(prism.components.Senses)
:at(x, y)
for actor, controller, collider, senses in query:iter() do
-- do stuff
end
Note
Query performance is optimized internally based on your filters. Position-based queries and single-component queries are particularly fast.