Contenido generado con IA — puede contener errores.

Fundamentos

Tareas e hilos

Un scheduler que corre en Spigot, Paper y Folia sin una sola rama en tu código.

Folia no tiene hilo principal. Tiene hilos por región, y una tarea que toca una entidad tiene que correr en el hilo dueño de esa entidad. Escribir para ambos significa escribir cada llamada dos veces — o llamar a este módulo, que decide por ti.

TaskScheduler tasks = Tasks.of(this);
 
tasks.run(() -> broadcast());
tasks.runLater(20L, () -> start());
tasks.runTimer(0L, 20L, () -> tick());

Dónde corre una tarea

LlamadaCorre en
run, runLater, runTimerEl hilo global — el principal de Bukkit, o la región global de Folia.
runAsync, runAsyncLater, runAsyncTimerUn hilo del pool. Nunca toques la API de Bukkit desde uno.
runAtEntity, runAtEntityLater, runAtEntityTimerEl hilo dueño de esa entidad. En Folia, su región.
runAtLocation, runAtLocationLater, runAtLocationTimerEl hilo dueño de esa ubicación.
executeAhora si ya estás en el hilo correcto, programado si no.
Todo lo que va sobre un jugador es `runAtEntity`

Teletransportar, cambiar inventario, mandar un título, leer su ubicación: todo eso pertenece al hilo del propio jugador. run es para trabajo sobre el servidor entero — un broadcast, un contador global. Equivocarse es invisible en Paper y un crash en Folia.

Cancelar

Cada llamada devuelve un TaskHandle:

TaskHandle timer = tasks.runTimer(0L, 20L, () -> tick());
timer.cancel();

Una tarea repetitiva que necesita cancelarse a sí misma recibe el handle como argumento:

tasks.runTimer(0L, 20L, handle -> {
    if (--countdown <= 0) {
        handle.cancel();
        return;
    }
    show(countdown);
});

runAtEntity acepta además un callback retired, que se ejecuta si la entidad desapareció antes que la tarea:

tasks.runAtEntity(player, () -> give(player, kit), () -> queueForLater(player));

Preguntar dónde estás

if (!tasks.isOwnedBy(player)) {
    tasks.runAtEntity(player, () -> act(player));
    return;
}
act(player);
LlamadaResponde
isGlobalThread()Si este es el hilo global.
isOwnedBy(entity)Si este hilo puede tocar esa entidad.

Volver de una consulta a la base de datos es el motivo habitual de preguntar: el future se completa en un hilo del pool, y todo lo que quieras hacer con la respuesta pertenece al jugador.

kits.find(id).thenAccept(found ->
        tasks.runAtEntity(player, () -> found.ifPresent(kit -> give(player, kit))));

Ticks

Retrasos y periodos van en ticks: 20 ticks es un segundo. La librería mantiene ticks donde una API de Bukkit los mantendría, así que un número copiado de una config antigua sigue significando lo mismo.

Limpieza

Las tareas de un plugin se cancelan cuando se desactiva. Los menús se cierran primero, para que un botón no pueda responder un último clic hacia un classloader moribundo.

¿Falta algo en esta página? Dínoslo en Discord