Skip to content
ZERNYTH.

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

LimitDefaultMaximum
Outstanding tasks2564096
Concurrent CPU tasks116
Concurrent I/O tasks4128
Server callbacks per pulse32256

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.

Was this page helpful?