Katton.after and Katton.every
Katton.after(...) and Katton.every(...) both return a task ID as their result. that id you have to assign yourself:
val taskId = Katton.after(5.seconds) {
Katton.log.info("five seconds passed!")
}
taskId now holds a number that uniquely identifies this specific scheduled task. later, to cancel it:
Katton.cancel(taskId)
if you never store the return value anywhere, you have no way to cancel that task later (unless you do /katton stop)
Katton.after: runs once
Katton.after(duration) {
// this code runs ONCE, after `duration` has passed
}
@Katton.command(name = "delayedmessage", permission = "all")
function delayedMessage(sender, args) {
sender.sendMessage("&7message incoming in 3 seconds")
Katton.after(3.seconds) {
sender.sendMessage("&ahere it is!")
}
}
Katton.every: runs repeatedly
Katton.every(duration) {
// this code runs EVERY `duration`, forever, until cancelled
}
var repeatingTaskId = 0
@Katton.command(name = "startpinging", permission = "admin")
function startPinging(sender, args) {
repeatingTaskId = Katton.every(10.seconds) {
sender.sendMessage("&7Ping!")
}
}
@Katton.command(name = "stoppinging", permission = "admin")
function stopPinging(sender, args) {
Katton.cancel(repeatingTaskId)
sender.sendMessage("&cStopped")
}
notice how repeatingTaskId is declared as a top level var, not a local val inside startPinging. if you declared it as val taskId = Katton.every(...) inside startPinging, it would go out of scope the moment startPinging finishes running, and stopPinging would have no way to reach it. top level variables are shared across every function in the script, which is exactly what you need here
duration units
any number gets a .ticks, .seconds, or .minutes suffix:
20.ticks // 1 second (20 ticks = 1 second in minecraft)
5.seconds // 5 seconds
2.minutes // 2 minutes
var delay = 5
delay.seconds // works on variables too, not just literals
self cancelling repeating tasks
a very common need: "repeat something a x of times, then stop automatically." since Katton.every's callback can see the same top level variables the rest of the script can, you can cancel it from inside itself!:
var countdown = 3
var countdownTaskId = 0
@Katton.command(name = "startcountdown", permission = "admin")
function startCountdown(sender, args) {
countdown = 3
countdownTaskId = Katton.every(1.seconds) {
for (player in Katton.players.all()) {
player.sendTitle("&e" + countdown, "")
}
countdown = countdown - 1
if (countdown < 0) {
Katton.cancel(countdownTaskId)
}
}
}
countdownTaskId = Katton.every(...), the result of theKatton.everycall (its task ID) is stored incountdownTaskIdimmediately, before the callback has even run once- every second, the callback shows the current
countdownvalue as a title, then goes down by 1 - once
countdowndrops below0, the callback callsKatton.cancel(countdownTaskId), cancelling itself using the ID that was saved in step 1
this works because countdownTaskId is a top level var, so it's still visible and holds the correct value by the time the callback runs and needs it even though the callback runs after the Katton.every(...) call has already returned and been assigned
for a a example on how to use this, see countodwn timer.
avoid nesting Katton.after inside Katton.every
// probably not what you actaully want
Katton.every(20.ticks) {
Katton.after(1.seconds) {
doSomething()
}
}
this schedules a brand new one second delayed task on every single tick of the first repeating timer and since 20.ticks is only 1 second, that means it makes a new nested task every second, stacking up fast and running doSomething() far more often than intended (and burning through your rate limit quickly). if you want something to happen once a second, just use Katton.every(1.seconds) { ... } directly, you don't need to nest
tasks get cleaned up automatically too
you don't strictly need to cancel every task yourself, Katton automatically cancels all of a script's tasks when:
- running
/katton stop, - that script is replaced with
/katton import(a new version), - that script is deleted,
- you are no longer the admin,
- the server restarts,
- a person with op stops it
manual Katton.cancel is for when you want to stop something early based on your own game logic, like a countdown finishing, or an admin running a "stop the game" command
next
- common scheduling patterns, more examples beyond the countdown