Sleeps
Non-blocking sleeps
Our Task
modules offer a unique sleep system. Contrary to other bot APIs, our sleeps do not
block the entire thread or utilise busy waiting.
Instead, it only halts execution of the task that you have called sleep in. The benefit of this
is that you can continue running your other tasks instead of having a sleep block the entire
execution of the script.
Static tick sleeps
We offer a sleep(int)
function where the parameter is the number of ticks to sleep for. This
makes static sleeps very precise as it is consistent with the game.
sleep(5)
will sleep for 5 ticks
Conditional (dynamic) sleeps
Conditional sleeps are different to normal sleeps in the sense that you don't need to declare a static amount of ticks to sleep for. Instead, you can declare a condition that the task should wait for.
sleepUntil(BooleanSupplier condition, int timeout)
The BooleanSupplier
argument is the condition to sleep until, and the timeout
is the number
of ticks to timeout at as a failsafe.
An example would be interacting with a tree and then sleeping until your player is actually cutting the tree.
tree.interact("Chop-down");
sleepUntil(() -> Players.self().isAnimating(), 5);
return true;
In the above example, your player will interact with a tree and then sleep until either your player starts an animation, or 5 ticks have passed.
Reset conditions
In addition to the aforementioned sleepUntil, this function includes an additional reset condition means it can reset the waiting process under certain conditions to keep checking and avoid early completion of the sleep.
sleepUntil(BooleanSupplier condition, BooleanSupplier reset, int timeout)
Example
Imagine you're crafting an inventory of gold bars and gems into jewellery. After crafting each item, there’s a small pause where your character stops animating, and then starts animating again when crafting the next piece.
Main condition: You want the function to stop sleeping when either you run out of crafting materials or you’re no longer crafting (i.e., no animation).
Reset condition: You want to reset the sleep if your character is animating again, which means you’re actively crafting the next item, so the wait needs to start fresh.
Poor sleep practices
Sleeping for 1 tick
Since scripts are executed once per tick, sleep(1)
is the same as
not sleeping at all! Think of 1
as the default sleep
Unnecessarily sleeping or overusing sleeps
On non-tick-based scripting platforms, it's common for you to need to do this, if the APIs already don't do it internally
if (self.isMoving()) {
return false;
}
if (!Bank.isOpen()) {
Bank.open();
sleepUntil(Bank::isOpen, ...);
return true;
}
Why? Well, since scripts are ran on MS based loops which are typically way more frequent than
the game tick and not synchronized, simply calling Bank.open()
without sleeping would result in
spam opening the bank resulting in rubber-banding between an open and closed state of the bank.
With a tick based system, if you open a bank, then in the next tick it'll be open (or you'll move to it if you're not in a position to open it). In that case you can omit the sleep entirely. This example applies to pretty much everything in game, so don't overuse sleeps!