Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

Sign up now!

Tutorial Query Builders, How to find pretty much any "thing" in RuneScape

Joined
Dec 31, 2015
Messages
602
Query Builders
What are they?
Query builds are the crux of gathering any information in RuneMate, almost every process is driven off query builders. There are a vast array of different query builders to use to fit your needs. Query builders lazy load their data, which means you can preemptively create the query used to get the data without any performance loss. This means that when you call results on the query that you it will process the query only then.

Why use them?
QueryBuilders are multithreaded and offer extensive filtering. They are efficient and very cache efficient. The use of getLoaded() has been deprecated so the future is in QueryBuilders.

What Query Builders Can I Use?

  • Inventory
    • For finding items within your inventory
    • Javadocs
    • Code:
      Inventory.newQuery()
  • GameObject
    • For finding GameObjects that are loaded into the game, a game object is generally defined by an object that can be interacted with or is immovable.
    • Javadocs
    • Code:
      GameObjects.newQuery()
  • Npc
    • For finding any loaded npcs, NPCs are generally determined by the fact they can move, this movement doesn't have to be path movements but if the object itself moves its likely an NPC. A weird outlier in this situation is Fishing spots are NPC's.
    • Javadocs
    • Code:
      Npcs.newQuery()
  • Interface
    • For finding any open interfaces.
    • Javadocs
    • Code:
      Interfaces.newQuery()

How do I use them?

This one is quite simple, check out any of the above and you have created your first QueryBuilder. However there is a lot more to know. Each of these have a large subset of useful filters you can place on your Query.

Scenarios

Finding a specific object with a name
Code:
GameObjects.newQuery().names( "Door" );
We just loaded all game objects with the name of door! Ok sweet. Now what if we want only ones that can be opened? Well lets try this.
Code:
GameObjects.newQuery().names( "Door" ).actions("Open");
Now these should be self explanatory but, here we are now fetching any loaded game objects that have the name of Door and one of their actions is "Open". What if we needed a very specific door?
Code:
GameObjects.newQuery().names("Door").actions("Open").on( new Coordinate( 1000, 1000, 0 ) );
And now we have passed a specific coordinate into this function, it will only find game objects on that specific tile.

Having an extensive look at the API and all the query builders you can do some very powerful queries, but what if none of these queries match what you would like to do? Well would you look at that we have a method.
Code:
GameObjects.newQuery().filter( o -> {  return false; });
Here you can see filter takes a Predicate, which simply gives you the game object, you can do some checks on it and then return whether or not to include it in the results. What this means is that you can essentially filter any thing you want for the type.

How do I get Results From These Queries?
Simple! After finishing all your filters in your query you can add
Code:
.results()
. This will return a custom collection, (See Javadocs for more information). This means you can use it as if it was a list, or you could use some of the useful methods provided by RuneMate to make your life easier.


Here are a few ones you could use
Find the first result it found, returns a single GameObject
Code:
GameObjects.newQuery().names("Door").actions("Open").on( new Coordinate( 1000, 1000, 0 ) ).results().first();
Find the nearest result to the Player.
Code:
GameObjects.newQuery().names("Door").actions("Open").on( new Coordinate( 1000, 1000, 0 ) ).results().nearest();
Nearest to requires a input of what you want to check against, you could give it another GameObject, or an Area or a specific co-ordinate, it is very powerful
Code:
GameObjects.newQuery().names("Door").actions("Open").on( new Coordinate( 1000, 1000, 0 ) ).results().nearestTo()


Hopefully this guide has been useful.
 
Last edited:
Joined
Aug 23, 2015
Messages
1,961
Excellent guide. I feel it would be helpful to expand a bit on the following areas:
  • How to use filters
  • How to vary the GameObject taken from the results of the query
  • How to speed up queries (ex: avoiding reachable, or using container for interface query)
Overall very well organized and to the point :)
 
easily triggered ✌
Joined
Dec 31, 2015
Messages
4,585
Excellent guide. I feel it would be helpful to expand a bit on the following areas:
  • How to use filters
  • How to vary the GameObject taken from the results of the query
  • How to speed up queries (ex: avoiding reachable, or using container for interface query)
Overall very well organized and to the point :)
This.

Very nice read tho :)
 
Engineer
Joined
Jul 28, 2013
Messages
2,776
I'd recommend mentioning that using .types(type) on gameobjects will significantly speed up game object queries and mention that we use lazy querying meaning we don't try applying any of those filters until results is called.
 
Joined
Jun 27, 2017
Messages
6
Quick question: Are the filers executed in the specific order of calling them or is this filtered further by RuneMate?

Example:
Code:
GameObjects.newQuery().names("Door").actions("Open").on( new Coordinate( 1000, 1000, 0 ) ).results().first();

This means it'll first search for every object named "Door" then the actions and then the Coordinate?
Wouldn't this process be faster if the Coordinate was passed first, since this would eliminate looping through all objects and comparing names. I know this is simply for demonstration purposes, but I was curious.
 
easily triggered ✌
Joined
Dec 31, 2015
Messages
4,585
Quick question: Are the filers executed in the specific order of calling them or is this filtered further by RuneMate?

Example:
Code:
GameObjects.newQuery().names("Door").actions("Open").on( new Coordinate( 1000, 1000, 0 ) ).results().first();

This means it'll first search for every object named "Door" then the actions and then the Coordinate?
Wouldn't this process be faster if the Coordinate was passed first, since this would eliminate looping through all objects and comparing names. I know this is simply for demonstration purposes, but I was curious.
YES
 
Joined
Aug 9, 2017
Messages
20
Excellent job and a fantastic post! I think it'd be very helpful if you go into more detail on the filters though. Give us an example and use case :)
 
Top