指南

如何制作 Folia 插件

更新于 2026年10月18日

Folia 是 Paper 的一个分支,它把世界划分成区域,并在不同线程上分别运行它们的 tick,让大型服务器能用上多个 CPU 核心。这里不再有唯一的主线程,常用的 Bukkit 调度器也因此失效。Folia 插件就是按这种模型编写的 Paper 插件,并且必须在 plugin.yml 中声明这一点。

一个包含 Folia 所需时间细节的示例。

用 Codexe 生成这个

分步说明

  1. 1.确认你真的需要 Folia

    Folia 适合玩家很多、分散在世界各处的服务器。大多数服务器跑的是 Paper;很多热门插件不支持 Folia,所以先检查你依赖的那些插件。

  2. 2.基于 Folia API 构建

    在 Maven 或 Gradle 项目中,使用 PaperMC 仓库中对应你版本的 folia-api 依赖,作用域为 provided。

  3. 3.替换 Bukkit 调度器

    Bukkit.getScheduler() 在 Folia 上无法使用。某个位置上的工作用区域调度器,针对玩家或生物的工作用实体调度器,全世界范围的任务用全局区域调度器,I/O 用异步调度器。

  4. 4.只在所属区域内操作对象

    只在拥有某个方块或实体的线程上修改它。用 teleportAsync 代替 teleport,并在修改目标之前先调度到它所在的区域。

  5. 5.声明支持 Folia

    在 plugin.yml 中加上 folia-supported: true。没有它,Folia 会拒绝加载插件。

  6. 6.在 Folia 服务器上测试

    编译通过只能证明代码能基于 Folia API 构建,不能证明它是线程安全的。在 Folia 测试服务器上运行它,并让几名玩家分散在不同地方。

四种调度器

调度器获取方式用途
区域Bukkit.getRegionScheduler()在世界中某个位置上的工作:放置方块、生成实体
实体entity.getScheduler()针对某个玩家或生物的工作,会跟随它跨越区域
全局区域Bukkit.getGlobalRegionScheduler()世界时间、天气,以及与位置无关的事情
异步Bukkit.getAsyncScheduler()数据库、文件、网络请求,绝不操作世界

通常会出问题的地方

  • 针对所有玩家的重复任务:遍历所有在线玩家的单个循环不再可行;改为在每个玩家的实体调度器上分别调度任务。
  • 传送和预热:“3 秒后传送”需要用实体调度器和 teleportAsync。
  • 共享数据:在多个区域中使用的映射表和计数器必须是线程安全的,例如使用并发集合。
  • 依赖:调用 Bukkit 调度器的库在 Folia 上会抛出 UnsupportedOperationException。

一个插件同时支持 Paper 和 Folia

在当前版本中,区域、实体、全局和异步调度器也是 Paper API 的一部分,所以只使用这些调度器并声明 folia-supported: true 的插件,可以同时在 Paper 和 Folia 上运行。这通常是最好的目标:一个 .jar 适用于所有服务器。

用 Codexe

选择 Folia 类型。生成的插件使用区域、实体、全局区域和异步调度器安排工作,声明 folia-supported: true,并用 Maven 基于 Folia API 构建。在标记为就绪之前,它会被编译和检查。

在需求中写明时间细节(“每分钟对每个在线玩家”“3 秒后传送”):Folia 代码与普通代码差别最大的就是这里。“立即试用”暂时还不支持 Folia 服务器,所以请在你自己的 Folia 服务器上测试 .jar。

常见问题

Paper 插件能在 Folia 上运行吗?

只有专门为它编写并声明了 folia-supported: true 的才行。使用 Bukkit 调度器的普通 Paper 插件会被拒绝加载或运行失败。

Folia 插件能在 Paper 上运行吗?

能,只要它只用 Paper 也有的 API,在当前的 Paper 版本中这也包括 Folia 的调度器。

我的 Folia 插件抛出了和调度器有关的异常

有些代码(通常来自某个库)仍在使用 Bukkit 调度器。在项目聊天中要求把它改到区域调度器或实体调度器上。

制作 Folia 插件

这条提示词打开后即可直接发送:

“一个名为 RTP 的 Folia 1.21.4 插件:/rtp 在 3 秒预热(移动即取消)后,把玩家传送到 5000 格范围内的随机安全位置,使用实体调度器和 teleportAsync,每个玩家冷却 10 分钟并保存在 SQLite 中,folia-supported: true,半径、冷却和消息在 config.yml 中。”

用 Codexe 生成这个
如何制作 Folia 插件(区域调度器) | Codexe