1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

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

Discussion in 'Tutorials & Resources' started by Guru, Apr 5, 2017.

  1. Guru

    Joined:
    Dec 31, 2015
    Messages:
    602
    Likes Received:
    175
    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 (Text):
        1. 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 (Text):
        1. 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 (Text):
        1. Npcs.newQuery()
    • Interface
      • For finding any open interfaces.
      • Javadocs
      • Code (Text):
        1. 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 (Text):
    1. 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 (Text):
    1. 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 (Text):
    1. 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 (Text):
    1. 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 (Text):
    1. .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 (Text):
    1. GameObjects.newQuery().names("Door").actions("Open").on( new Coordinate( 1000, 1000, 0 ) ).results().first();

    Find the nearest result to the Player.
    Code (Text):
    1. 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 (Text):
    1. GameObjects.newQuery().names("Door").actions("Open").on( new Coordinate( 1000, 1000, 0 ) ).results().nearestTo()



    Hopefully this guide has been useful.
     
    #1 Guru, Apr 5, 2017
    Last edited: Jun 13, 2017
  2. Snufalufugus

    Joined:
    Aug 23, 2015
    Messages:
    1,961
    Likes Received:
    757
    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 :)
     
    Wet Rag and Swych like this.
  3. Wet Rag

    Wet Rag easily triggered ✌

    Joined:
    Dec 31, 2015
    Messages:
    4,457
    Likes Received:
    1,695
    This.

    Very nice read tho :)
     
  4. Cloud

    Cloud Engineer

    Joined:
    Jul 28, 2013
    Messages:
    2,777
    Likes Received:
    1,124
    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.
     
    sickness0666 likes this.
  5. NexusCore

    Joined:
    Jun 27, 2017
    Messages:
    6
    Likes Received:
    0
    Quick question: Are the filers executed in the specific order of calling them or is this filtered further by RuneMate?

    Example:
    Code (Text):
    1. 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.
     
  6. Wet Rag

    Wet Rag easily triggered ✌

    Joined:
    Dec 31, 2015
    Messages:
    4,457
    Likes Received:
    1,695
    YES
     
  7. Cloud

    Cloud Engineer

    Joined:
    Jul 28, 2013
    Messages:
    2,777
    Likes Received:
    1,124
    no...
     
  8. qverkk

    Joined:
    Sep 22, 2015
    Messages:
    1,603
    Likes Received:
    381
    All methods used in the query will be generated after calling results, so it doesn't matter in what order you add them up, am i correct?
     
    Miami 369 and Swych like this.
  9. Swych

    Joined:
    Dec 9, 2016
    Messages:
    3,057
    Likes Received:
    1,032
    Correct
     
    qverkk likes this.
  10. Sinning

    Joined:
    Aug 9, 2017
    Messages:
    20
    Likes Received:
    0
    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 :)
     
  11. Emrys

    Joined:
    Sep 21, 2018
    Messages:
    21
    Likes Received:
    2
    how would one go about filtering a whole area out of their query?
     

Share This Page

Loading...