Tasks and asynchronous work
Use the plugin scheduler instead of blocking a command or event handler. Keep
the returned TaskHandle when later code may need to cancel the task.
Repeating timer
$handle = $this->context()->scheduler()->delayedRepeating(
delayTicks: 20,
periodTicks: 20,
callback: function (): void {
foreach ($this->context()->server()->getOnlinePlayers() as $player) {
$player->sendPopup('The arena round is still running.');
}
},
);
Async work
Async tasks must receive bounded serializable input. They must not retain live
players, worlds, inventories, entity controllers, or the plugin context. Return
an AsyncTaskValue, then apply the result through a scheduled server-thread
callback after rechecking that the target player or world is still available.
Handle TaskRejectedException and async failures explicitly. Cancellation does
not make already-running external work transactional.
