Scheduling
This build's scheduler is serial: every region task runs on the global region, which is the main tick loop.
Classic sync scheduling
// Unchanged from Paper 26.3. Runs on the main tick thread.
plugin.getServer().getScheduler().runTaskTimer(plugin, task -> {
// every 20 ticks, on the main thread, exactly as on Paper
}, 0L, 20L);
The global region scheduler
// In this build, the global region IS the main tick loop.
Bukkit.getGlobalRegionScheduler().runAtFixedRate(plugin, task -> {
// delay and period are in TICKS, never milliseconds
}, 1L, 20L);
The region scheduler
// Accepted; executed on the global region here — not a region thread.
Bukkit.getRegionScheduler().run(plugin, location, task -> {
// correct, serial, single-threaded in this build
});
The ownership query
// Present; spatially degenerate in this build. Location implements
// io.papermc.paper.math.FinePosition, so the (World, Position) overload
// at Bukkit.java:2930 accepts it.
if (Bukkit.isOwnedByCurrentRegion(location.getWorld(), location)) {
// "am I on any tick thread" today — not "do I own this chunk"
}
The two async paths
runTaskAsynchronously gives you the async pool exactly as on Paper;
Bukkit.getAsyncScheduler() gives you the Folia-shaped async scheduler. Both
run off the tick loop, both unchanged.
Ticks, not milliseconds
Delays and periods on every scheduler above are ticks, not milliseconds. This is the invariant MeowMC keeps regardless of which execution mode a future build runs in, and it is the reason community shims that convert ticks to milliseconds break the moment TPS drops: they trade a unit the server defines for one a wall clock defines, and the two disagree exactly when the server is under load. Write ticks, and a TPS drop slows your task along with the game instead of desynchronizing from it.