Starting off a script
What is a script
A script is code that runs on top of the Inubot client that manipulates the actual game using our SDK. The Inubot client provides hooks into the game and API functions which you can leverage to write code that can interface with the game.
Basic script structure
For the sake of this tutorial and good practices, we will be covering TaskScript specifically. The main difference with TaskScript
is that it is broken into Task's rather than a single loop, while at the same time being synchronized with the game tick. The game tick is the core at which RuneScape operates and as such, we should be building our scripts around that!
@ScriptMeta(name = "My Script", developer = "Doga", version = 1.0, desc = "My first script!")
public class MyScript extends TaskScript {
@Override
public void initialize() {
Log.info("Starting script!");
}
@Override
public void shutdown() {
Log.info("Stopping script!");
}
@Override
public Class<? extends Task>[] tasks() {
return ArrayUtils.getTypeSafeArray(
MyTask1.class
);
}
}
Initialize and shutdown hook
In a TaskScript
, the initialize()
and shutdown()
methods are optional hooks that are
called when a script starts and stops respectively. You don't need them, but they do exist and are
called on script start and end, so if you have a use for them, feel free to implement them!
Keep in mind that these methods are called at the start and end of a script regardless of what
state the game is in, even if you're logged out. A common mistake is developers using
the initialize()
method to track initial state/data
Declaring tasks
The tasks()
method is where you list tasks that your script should execute.
Task
We will now be covering Task
and how to implement them.
@TaskDescriptor(name = "Task 1")
public class MyTask1 extends Task {
@Override
public boolean execute() {
return true;
}
}
Above is the simplest possible Task you can have. Firstly, each Task requires a TaskDescriptor. The TaskDescriptor
provides 2 things. First is meta data, such as the name of the task. This is used in debug information. Next is how the task should be executed.
Looking at the Javadocs, you'll see multiple possible attributes that you can define.
priority()
is a value defining the priority of execution for this task. A higher priority means that the task will be executed first. If priorities are the same/undefined, then the execution order is simply the order you add the tasks in thetasks()
method. I personally prefer only using priorities when they're needed (e.g. have something take priority over an in-client task such as RestockTask). The benefit of using declaration order is that it's easier to see the order of your tasks rather than having to go through all your classes and look at prioritiesblocking()
is a boolean indicating if further execution of tasks should continue. If a blocking task is ran and theexecute()
method also returned true, then no further tasks will be executed in that tick.blockIfSleeping()
works together withblocking()
. By default, if a blocking task sleeps, it won't continue to block other tasks. Using this property changes that.register()
simply registers the task to the event registry, so that it can receive events such asChatMessageEvent
.stoppable()
should be used if you want the task to stop the script. If a stoppable tasksexecute()
returns true, the script will be stopped.children()
is any child tasks that the task has. Tasks are essentially trees so you can have as many levels of children as you want! They help to keep your script nice and organised while reducing repeated logic, very essential for larger scriptsloginScreen()
is by default false. Since the game tick only runs when logged in, by default tasks don't run on the login screen. In the rare case that you require custom logic for the login screen, you should set this attribute astrue
Examples
We do maintain a GitHub organisation in which we occasionally publish open-source scripts. Feel free to study these, it covers some basic and good practices that you can learn from.