Queries
If our tick based system is the bread of our API, then you could say that queries are the butter - providing a smooth, efficient way to interact with the game world dynamically and flexibly.
Queries allow you to dynamically search for entities using powerful high level conditions that adapt to the current game environment.
Most APIs will allow you to search for an entity by name or ID and have you pass in a custom condition for anything more than that.
Example
Npcs.query()
.names("Zombie")
.actions("Attack")
.within(3)
.reachable()
.results()
.nearest()
This query searches for a Zombie with the "Attack" option that's reachable within 3 tiles of you. Instead of having to write every condition yourself, this saves you a lot of time and looks cleaner.
Queries also come with internal optimization. It doesn't matter what order you make the chain calls in, internally we optimize so that lightweight calls are always first and heavy calls such as checking if an npc is reachable will go last.
Queries come with all sorts of creative options. Here's a neat little trick to perform an action in 1 line with a query
Inventories.backpack().query().nameContains("seed pod").results().limit(1).forEach(x -> x.interact("Commune"));
Results
While queries are something, results are another beast in itself. All queries have a results()
function that terminates the query by transforming it into a lookup and giving you the results.
In the aforementioned example we used nearest()
, but results offers a lot more than that! Here
is an example randomly selecting between the 2 nearest zombies
Npcs.query()
.names("Zombie")
.actions("Attack")
.within(3)
.reachable()
.results()
.sortByDistance
.limit(2)
.random();
Results themselves are a collection, so you can perform the same things you can with any other collection, such as iterating over it:
for (Item item : inv.query().names(...).results()) {
// ...
}