Skip to content

Folia support: migrate Bukkit scheduler usage to SchedulerUtils#12

Open
GenOpenDiesel wants to merge 1 commit into
emanondev:masterfrom
GenOpenDiesel:feature/folia-scheduler
Open

Folia support: migrate Bukkit scheduler usage to SchedulerUtils#12
GenOpenDiesel wants to merge 1 commit into
emanondev:masterfrom
GenOpenDiesel:feature/folia-scheduler

Conversation

@GenOpenDiesel

Copy link
Copy Markdown

Why

plugin.yml already declares folia-supported: true, but the plugin still scheduled work through the global BukkitScheduler / BukkitRunnable, which throws on Folia. There was even a leftover //TODO folia fix in Usable. On Folia reload() would also blow up because EquipmentChangeListenerBase started a runTaskTimer on the global scheduler.

What

Migrated every scheduler call to ItemEdit's Folia-aware SchedulerUtils, scoping each task to the player it acts on so it runs on that entity's region thread.

One-shot delayed tasks (runTaskLater / BukkitRunnable):

  • customflags/Usable (removes the //TODO folia fix)
  • customflags/EquipmentFlag
  • customflags/RenamableOld
  • command/itemtag/WearPermission
  • command/itemtag/EffectsResurrectListener
  • command/itemtag/Effects (respawn + milk-bucket consume)
  • actions/DelayedAction
  • activity/action/DelayedActionType

Equipment change listener:

  • SlotCheck no longer extends BukkitRunnable — it implements Runnable and exposes schedule() backed by SchedulerUtils.runLater(plugin, player, 1L, this). All new SlotCheck(...).runTaskLater(...) call sites (Base + EquipmentChangeListener + UpTo1_13 + UpTo1_8) now call .schedule().
  • The periodic equipment poll keeps the existing BukkitRunnable timer off Folia (unchanged behaviour, including max_checked_players_per_tick spreading). On Folia it self-reschedules through SchedulerUtils and fans each player's check out to that player's own region thread.
  • equips / clickDrop are backed by thread-safe collections on Folia (mirrors the existing ActionHandler ConcurrentHashMap handling), since they are now touched from per-player region threads.

Notes

  • No new dependency: SchedulerUtils ships with ItemEdit (already a compile dependency).
  • Non-Folia behaviour is intentionally left identical — only the Folia branch is new.
  • Builds cleanly with mvn package against spigot-api 1.21.x. I don't have a Folia server to runtime-test the equipment-poll path, so that part would benefit from a check on a live Folia instance.

🤖 Generated with Claude Code

ItemTag declared folia-supported but still scheduled tasks through the
global BukkitScheduler / BukkitRunnable, which throws on Folia (and left a
`//TODO folia fix` in Usable).

- Replace all one-shot runTaskLater / BukkitRunnable delayed tasks with
  ItemEdit's Folia-aware SchedulerUtils, scoped to the relevant player so
  they run on that entity's region thread (Usable, EquipmentFlag,
  RenamableOld, WearPermission, EffectsResurrectListener, Effects,
  DelayedAction, activity DelayedActionType).
- EquipmentChangeListener: SlotCheck no longer extends BukkitRunnable; it
  implements Runnable and exposes schedule() backed by SchedulerUtils.
- Equipment poll timer: keep the BukkitRunnable timer off Folia; on Folia
  self-reschedule via SchedulerUtils and fan each player check out to its
  own region thread. Back equips/clickDrop with thread-safe collections on
  Folia (mirrors ActionHandler).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant