以下来自 claude
结论很明确:不支持 Folia,而且差距很大。
---
不兼容的地方
Folia 去掉了"主线程"概念,改为每个区域独立线程。以下 API 在 Folia 上全部会抛异常或直接不存在:
不兼容 API: Bukkit.getScheduler().runTask()
我们的使用次数: 12 处
Folia 替代方案: region.getScheduler().run() 或 entity.getScheduler().run()
────────────────────────────────────────
不兼容 API: new BukkitRunnable().runTask*()
我们的使用次数: 12 处
Folia 替代方案: 同上,BukkitRunnable 在 Folia 完全不可用
────────────────────────────────────────
不兼容 API: Bukkit.isPrimaryThread()
我们的使用次数: 1 处
Folia 替代方案: 无意义,Folia 没有主线程
────────────────────────────────────────
不兼容 API: world.getChunkAtAsync()
我们的使用次数: 1 处
Folia 替代方案: 需要用 Folia 的 region scheduler
────────────────────────────────────────
不兼容 API: Bukkit.createBossBar()
我们的使用次数: 1 处
Folia 替代方案: 需要用 Adventure API 或 region-aware 方式
────────────────────────────────────────
不兼容 API: Bukkit.getScheduler().cancelTasks()
我们的使用次数: 1 处
Folia 替代方案: 需要分别取消各 region 的任务
────────────────────────────────────────
不兼容 API: addPluginChunkTicket()
我们的使用次数: 2 处
Folia 替代方案: Folia 中区块生命周期管理不同
总计:约 30 处 API 调用需要替换,分布在 12 个文件中。
支持 Folia 需要做什么
核心挑战是 Folia 要求所有操作都绑定到特定区域/实体的调度器上:
1. 所有 runTask / runTaskLater → 必须改为:
- 操作某个位置的方块 → Bukkit.getRegionScheduler().execute(plugin, location, task)
- 操作某个实体 → entity.getScheduler().run(plugin, task, retired)
- 全局操作 → Bukkit.getGlobalRegionScheduler().run(plugin, task)
- 异步操作 → Bukkit.getAsyncScheduler().runNow(plugin, task)
2. BukkitRunnable → 完全不能用,需要自己封装或用 Folia 的调度 API
3. 跨区域操作(比如一个建筑跨两个 region)→ 这是最大的难点,Folia 不允许在一个 region tick
里操作另一个 region 的方块
通常的做法是写一个调度器抽象层,运行时检测是否在 Folia 环境下,分别调用不同的
API。社区有现成的库比如
https://github.com/TechnicallyCoded/FoliaLib 可以简化这个过程。
但说实话,对于 BetterStructures 这种重度依赖跨区块方块操作的插件来说,Folia
适配的工作量不小,不是简单替换 API 就能解决的。