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 Making a bot that does something :D

Was this helpful to users trying to become bot authors?

  • Yes, please add more!

    Votes: 28 75.7%
  • Yes, I am well off now.

    Votes: 3 8.1%
  • No, please add more!

    Votes: 0 0.0%
  • No, it wasn't useful.

    Votes: 3 8.1%
  • No, it is too confusing.

    Votes: 4 10.8%

  • Total voters
    37
Go check out new bots and give helpful feedback.
Joined
Jan 31, 2016
Messages
5,413
Hello aspiring botters!
I am a pretty new bot author know on Runemate as @awesome123man
In real life I am just starting my first year of college, and have taken one java class in High School.

This tutorial is for those who have not taken any Java classes or who don't understand how to use the Runemate API.

Here is how i will teach you guys, i will show a piece of code, and translate it to english to the best that i can.

Code:
public class ExampleBot extends LoopingBot {

@Override
public void onStart(String... args) {//Begins onStart method

}//Ends onStart Method

@Override
public void onLoop() {//Begins onLoop method

}//Ends onLoop method

}//Ends class ExampleBot

Translation:
create a class named "ExampleBot" that uses LoopingBot(onLoop()).

Create an onStart method with no return value, meaning the method is for completing actions, not getting a value, that will execute when the bot is started.

Create an onLoop method with no return value to loop while bot is running.

Code:
public GameObject obj;
//Put this inside the class, but outside(before) the onStart and onLoop methods.

Translation:
create a variable of GameObject type called "obj".

Code:
obj = GameObjects.newQuery().names("Insert name here in these quotes").results().nearest();
//Put this inside the onLoop method.

Translation:
set the value of the varible "obj" to the GameObject returned from the statement to the right of the equals sign.

Code:
if(obj != null){

}
//Also in onLoop method.

Translation:
if the statement inside the parenthesis is true, execute what is inside the the brackets of the if statement. This particular statement checks if obj has a value or is null(does not). Do this whenever there is a possibilty that a variable could not have a value assigned to it.

Code:
if(obj.interact("Action here", "name here(optional)"){

}
//Inside of the if statement's braces above.

Translation:
tries to interact with the GameObject "obj" using the action and name, if the mouse successfully clicks it, the statement is true, otherwise, it's false.

Code:
Execution.delayUntil(() -> Players.getLocal().getAnimationId() != -1, 5000);
//Put this inside the if statement above that has the interaction

Translation:
Stop the bot from doing anything else until the players animation Id is not -1, which happens to mean that the player is not static and is animating. (Very useful). Also notice the 5000, which is the max delay, so if the player's animation Id is always == -1, then after 5000 ms, or 5 seconds, the delay will stop. (aka. Max delay time)

Now for an actual bot Example. Make sure you create all the classes and methods, but leave out the stuff inside the onLoop, for i am going to create a few unsophisticated sample bots.
Code:
//Put this inside onLoop method
//This is a sample bot that cuts Trees only
obj = GameObjects.newQuery().names("Tree").results.nearest();
if(obj != null){
if(obj.interact("Chop down", obj.getDefinition().getName())){
Execution.delayUntil(() -> !obj.isValid(), 10000);
}
}

Translation:
sets obj to the nearest Tree, or null if no trees are nearby
if the tree was found, execute the inside of the if
if the tree was successfully clicked to chop down, execute the inside of the if
Delay the bot until the tree is no longer there or has changed somehow.

And that's about it! You will need a manifest to go along with this, but there are good tutorials out there like This one :D

To make things a bit more organized with larger bots/more sophistication, you use things called helper methods.

To call a helper method, simply use its name and any local variables it has inside of parenthesis.
For example, findPlace(obj.getPosition()).
This set's the local variable known as place in the method below called findPlace to the obj position.

Here is how you create them and what they do
This is a helper method to check if the player is animating
Code:
public boolean isAnimating() {
    Player me = Players.getLocal();
    if (me != null) {
        return me.getAnimationId() != -1;
    }
    return true;
}

Translation:
Creates a public helper method called isAnimating that returns a boolean(True or false)
Get's the current player and set's it to the local variable, "me"
Checks to see if me is not null(null means that no player was found)
If the player was found return if the animationId is not equal to -1,
If the player was not found(null), return true because (A convention for me).

Here is another helper method that does walking for your player.
Code:
public void findPlace(Coordinate place){
    path = RegionPath.buildTo(place);
    if(path != null) {
        path.step();
    }
}

Translation:
Creates the helper method findPlace, that returns a void(nothing) meaning it does an action
Notice that inside the parenthesis of the method declaration there is "Coordinate place"
That is a local variable only accessible inside that method, and that value is set when you call the method in your bot.
path is a variable declared in the Class that is of type Path, and set to the RegionPath created.
if the path was created, take a step. Inside the parenthesis you can put true to run and false to walk.

This style of scripting is the least organized. Consider looking into TaskScript and TreeScript soon to be TaskBot and TreeBot as they are much more organized. The syntax of the actions and variable declarations/setters is still the same, just more organized.
 
Last edited:
Joined
Sep 22, 2015
Messages
1,610
Code:
public boolean isAnimating() {
    Player me = Players.getLocal();
    if (me != null) {
        return me.getAnimationId() != -1;
    }
    return false; // false m8, otherwise this boolean will always return true
}
 
Go check out new bots and give helpful feedback.
Joined
Jan 31, 2016
Messages
5,413
Code:
public boolean isAnimating() {
    Player me = Players.getLocal();
    if (me != null) {
        return me.getAnimationId() != -1;
    }
    return false; // false m8, otherwise this boolean will always return true
}
I want it to be true. So if got some reason the player is null then isAnimating is true and it wont do anything. I usually do if (!isAnimating) outside my main part of code.
 
Super Bot Author
Joined
Jun 24, 2016
Messages
151
This is good for new bot developers, thank you for making this. However, I have a few notes that may help (help you or anyone else reading this). First I would recommend using TaskScript, as it is much easier to make more modular, OOP bots while using it.

This is a helper method to check if the player is animating
Code:
public boolean isAnimating() {
    Player me = Players.getLocal();
    if (me != null) {
        return me.getAnimationId() != -1;
    }
    return true;
}

Translation:
Creates a public helper method called isAnimating that returns a boolean(True or false)
Get's the current player and set's it to the local variable, "me"
Checks to see if me is not null(null means that no player was found)
If the player was found return if the animationId is not equal to -1,
If the player was not found(null), return true because (A convention for me).
I've seen you post this method in a few places before, and every time I see it I ask myself, "Wouldn't it be easier to just call #getAnimationId() directly?". In all of the places where "isAnimating()" is used, it can be replaced with "player.getAnimationId() != -1" (assuming the nullcheck on "player" have been done). What are the advantages to this over calling #getAnimationId() directly?

Here is another helper method that does walking for your player.
Code:
public void findPlace(Coordinate place){
    path = RegionPath.buildTo(place);
    if(path != null) {
        path.step();
    }
}

Translation:
Creates the helper method findPlace, that returns a void(nothing) meaning it does an action
Notice that inside the parenthesis of the method declaration there is "Coordinate place"
That is a local variable only accessible inside that method, and that value is set when you call the method in your bot.
path is a variable declared in the Class that is of type Path, and set to the RegionPath created.
if the path was created, take a step. Inside the parenthesis you can put true to run and false to walk.
This is a good method, its very similar to the method that I use to travel in my bots. The only thing that I would change is the naming. "findPlace" sounds like it would return an Area, instead it goes to the given coordinate. In my code, my equivalent method is "goToCoordinate(Coordinate coordinate)". This is just a minor nitpick that I believe would make code that uses this method more understandable.

Please don't take this negatively, I like the guide, I hope that it encourages more people to make bots for RuneMate and make the client even better.
 
Go check out new bots and give helpful feedback.
Joined
Jan 31, 2016
Messages
5,413
This is good for new bot developers, thank you for making this. However, I have a few notes that may help (help you or anyone else reading this). First I would recommend using TaskScript, as it is much easier to make more modular, OOP bots while using it.


I've seen you post this method in a few places before, and every time I see it I ask myself, "Wouldn't it be easier to just call #getAnimationId() directly?". In all of the places where "isAnimating()" is used, it can be replaced with "player.getAnimationId() != -1" (assuming the nullcheck on "player" have been done). What are the advantages to this over calling #getAnimationId() directly?


This is a good method, its very similar to the method that I use to travel in my bots. The only thing that I would change is the naming. "findPlace" sounds like it would return an Area, instead it goes to the given coordinate. In my code, my equivalent method is "goToCoordinate(Coordinate coordinate)". This is just a minor nitpick that I believe would make code that uses this method more understandable.

Please don't take this negatively, I like the guide, I hope that it encourages more people to make bots for RuneMate and make the client even better.
Great advice! Would you mine giving a quick task script tutorial?
 
Go check out new bots and give helpful feedback.
Joined
Jan 31, 2016
Messages
5,413
Top