Scheduler
Two APIs run work later or elsewhere. Scheduler is the tick-based task API. AsyncRuntime is the managed runtime with limits, cancellation and snapshots, and is the better choice for new background work.
Scheduler
Delays and periods are in ticks.
package dev.example;
import dev.zernyth.api.plugin.JavaPlugin;
public final class TimerPlugin extends JavaPlugin {
@Override
public void onEnable() {
var task = getServer().getScheduler().runTaskTimer(() -> getLogger().info("Tick task"), 20, 200);
getServer().getScheduler().runTaskLater(task::cancel, 2000);
}
}AsyncRuntime
Get the runtime and submit work on the server thread. CPU work uses Endstone workers. I/O work uses virtual threads. Use returnToServer before touching any game object.
package dev.example;
import dev.zernyth.api.plugin.JavaPlugin;
public final class AsyncPlugin extends JavaPlugin {
@Override
public void onEnable() {
var runtime = getServer().getAsyncRuntime();
runtime.submitIo(token -> {
String result = "loaded";
token.throwIfCancellationRequested();
runtime.returnToServer(() -> getLogger().info(result));
});
}
}Limits per plugin
| Limit | Default | Maximum |
|---|---|---|
| Outstanding tasks | 256 | 4096 |
| Concurrent CPU tasks | 1 | 16 |
| Concurrent I/O tasks | 4 | 128 |
| Server callbacks per pulse | 32 | 256 |
Configure RuntimeLimits before any work is outstanding. When capacity is exhausted, TaskRejectedException is thrown and must be handled. Nothing waits or retries automatically.
Cancellation
Queued tasks cancel immediately. Running tasks become CANCEL_REQUESTED and finish only when their code exits. I/O threads receive an interrupt, and CPU work must check its token. warnAfter reports slow work but does not stop it.
Only cancellation, immutable snapshots and returnToServer are safe on workers. Everything else that touches the game must run on the server thread.