The Query API is powerful tool used to find any "thing" in-game, providing a wide array of filters that can be used to isolate the entity you are searching for. Queries are highly optimized, and results are evaluated lazily, so query builders can be re-used.
There are many kinds of query builders, each of which way may have filters to make identifying entities easier. Here are the main types (and their inheritance structure):
Utility methods like these exist for the more common inventory types. Queries can be constructed for uncommon inventories by passing an inventory to the SpriteItemQueryBuilder:
new SpriteItemQueryBuilder(Inventories.Documented.INVENTORY)
The InterfaceComponentQueryBuilder can be used to search for InterfaceComponents, and can be created using the following:
Interfaces.newQuery()
Like the GameObjectQueryBuilder, this can be quite an expensive call, but query speed can be improved signficantly by filtering on type and container:
A GameObjectQueryBuilder is used to search for GameObjects (trees, doors etc.), and can be created using the following:
GameObjects.newQuery()
GameObject queries are rather expensive, and can take a significant time to run if not optimized correctly. Query speed can be reduced by about 90% by filtering on type and location:
//By single coordinate
Coordinate coordinate = ...;
GameObjects.newQuery().types(GameObject.Type.PRIMARY).on(coordinate)
//By area
Area area = ...;
GameObjects.newQuery().types(GameObject.Type.PRIMARY).within(area)
The ProjectileQueryBuilder can be used to find projectiles, and the builder can be created using the following:
Projectiles.newQuery()
The GroundItemQueryBuilder can be used to find ground items, and the builder can be created using the following:
GroundItems.newQuery()
The WorldQueryBuilder can be used to identify WorldOverviews from the world list, which can be used to identify appropriate worlds to hop to. The builder can be created as follows:
Worlds.newQuery()
Query Results
QueryResults are evaluated lazily when QueryBuilder#results() is invoked, so builders can be re-used. QueryResults are a mutable Collection, so can be iterated and mutated. Some convenience methods are available to make accessing your desired result easier:
//Getting the first "Cake" in your inventory
SpriteItem cake = Inventory.newQuery().names("Cake").results().first();
//Get the last "Cake" in your inventory
SpriteItem cake = Inventory.newQuery().names("Cake").results().last();
//Get a random "Cake" in your inventory
SpriteItem cake = Inventory.newQuery().names("Cake").results().random();
//Finding the nearest tree to your player
GameObject tree = GameObjects.newQuery().names("Tree").results().nearest();
//Finding the nearest logs on the floor next to the tree
GroundItem logs = GroundItems.newQuery().names("Logs").results().nearestTo(tree);
Remember your null checks! RuneScape is a dynamic game and queries are not guaranteed to succeed, so failing to properly null check may result in crashes due to NullPointerExceptions.