强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

PaperMC 插件开发完全指南 / 第 1 章:插件开发概述

第 1 章:插件开发概述

了解 Minecraft 服务端生态系统,明确 PaperMC 的定位与优势。


1.1 Minecraft 服务端生态全景

Minecraft Java Edition 的服务端(Server)并非只有一种实现。多年来,社区围绕 Mojang 官方服务端衍生出了多个分支,形成了层次分明的生态系统。

主流服务端对比

服务端 维护者 核心特点 插件生态 适用场景
Vanilla Server Mojang 官方原版,无插件支持 纯原版游戏
CraftBukkit SpigotMC 最早的插件服务端 Bukkit 插件 历史项目
Spigot SpigotMC CraftBukkit 优化版 Bukkit/Spigot 插件 中小型服务器
Paper PaperMC Spigot 下游,性能极佳 Bukkit/Spigot/Paper 插件 推荐首选
Folia PaperMC Paper 分区多线程 Paper 插件(需适配) 超大型服务器
Purpur PurpurMC Paper 下游,趣味功能 Paper 插件 休闲服务器
Velocity PaperMC 代理服务器(Bungee 替代) 代理插件 跨服网络

发展脉络

Mojang Vanilla Server
        │
   CraftBukkit (2011)
        │
     Spigot (2012)
        │
      Paper (2016)
       ┌──┴──┐
    Folia  Purpur

1.2 Bukkit API 基础

Bukkit API 是 Minecraft 插件开发的基石。它定义了一套标准接口(Interface),让插件开发者无需关心服务端内部实现细节。

核心设计思想

  1. 面向接口编程: 插件只依赖 API 接口,不依赖具体实现
  2. 事件驱动: 通过监听游戏事件来响应玩家行为
  3. 插件隔离: 每个插件有独立的类加载器,互不干扰

Bukkit API 核心包结构

包名 职责 常用类
org.bukkit 核心接口 Server, World, Location
org.bukkit.entity 实体相关 Player, Entity, LivingEntity
org.bukkit.event 事件系统 Event, Listener, EventHandler
org.bukkit.command 命令系统 Command, CommandExecutor
org.bukkit.plugin 插件系统 JavaPlugin, PluginManager
org.bukkit.inventory 物品/背包 ItemStack, Inventory
org.bukkit.scheduler 调度器 BukkitScheduler, BukkitTask
org.bukkit.scoreboard 计分板 Scoreboard, Team, Objective

最小插件示例

package com.example.myplugin;

import org.bukkit.plugin.java.JavaPlugin;

public class MyPlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        // 插件启用时调用
        getLogger().info("MyPlugin 已启用!");
    }

    @Override
    public void onDisable() {
        // 插件禁用时调用
        getLogger().info("MyPlugin 已禁用!");
    }
}

注意: JavaPlugin 是所有插件的基类,必须继承它。onEnable()onDisable() 是生命周期钩子(Lifecycle Hook)。


1.3 Paper API 的优势

Paper 在完全兼容 Bukkit/Spigot API 的基础上,提供了大量扩展 API 和性能优化。

Paper 独有 API 示例

API 说明 替代的 Bukkit 方式
Player.getScheduler() 原生异步任务 Bukkit.getScheduler()
ServerTickManager 服务器 TPS 管理 手动计算
AsyncChatEvent 原生异步聊天事件 同步事件 + 手动异步
PaperAdventure Adventure API 集成 自行集成
io.papermc.paper.entity 扩展实体接口 Bukkit 基础接口

Paper 的性能优化

Paper 内置了大量性能补丁(Patches),这些优化对插件开发者透明:

  1. 更快的区块加载: 改进了区块加载和卸载的 I/O 效率
  2. 实体激活范围: 根据距离动态降低非活跃实体的处理频率
  3. 异步区块生成: 减少主线程阻塞
  4. 优化的寻路: 改进了生物寻路算法的性能
  5. 改进的碰撞检测: 减少了实体碰撞的计算量

异步事件支持

Paper 原生支持事件的异步处理,这是一个重大优势:

// Paper 原生异步聊天事件(非阻塞主线程)
@EventHandler
public void onAsyncChat(AsyncChatEvent event) {
    // 使用 Adventure API 的 Component
    Component message = event.message();
    // 这里的处理不会阻塞主线程
    Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
        // 可以安全地进行数据库操作等耗时任务
    });
}

1.4 Spigot 与 Paper 的兼容性

API 层级关系

Bukkit API  ← 最基础,所有服务端都支持
   ↑
Spigot API  ← 扩展了 Bukkit(如 SpigotConfig、更多事件)
   ↑
Paper API   ← 扩展了 Spigot(如异步事件、Adventure API)

编写兼容插件的策略

策略 做法 适用场景
仅用 Bukkit API 只引用 org.bukkit.* 需要兼容所有服务端
使用 Spigot API 可用 SpigotConfig 仅需兼容 Spigot/Paper
使用 Paper API 可用所有扩展 API 仅需兼容 Paper

依赖声明示例

<!-- 仅 Bukkit(兼容性最广) -->
<dependency>
    <groupId>org.bukkit</groupId>
    <artifactId>bukkit</artifactId>
    <version>1.21.4-R0.1-SNAPSHOT</version>
    <scope>provided</scope>
</dependency>

<!-- Paper(推荐,API 最丰富) -->
<dependency>
    <groupId>io.papermc.paper</groupId>
    <artifactId>paper-api</artifactId>
    <version>1.21.4-R0.1-SNAPSHOT</version>
    <scope>provided</scope>
</dependency>

注意: scope 必须设为 provided,因为这些 API 由服务端在运行时提供,不需要打包进插件 JAR。


1.5 插件的生命周期

插件从加载到卸载经历以下阶段:

构造函数 → onLoad() → onEnable() → [运行中] → onDisable()

各阶段说明

阶段 时机 可执行操作
构造函数 类实例化 初始化简单字段,不要访问 Bukkit API
onLoad() 插件加载时(早于 onEnable) 注册命令(部分场景)、读取配置
onEnable() 插件启用时 注册事件监听、启动任务、连接数据库
onDisable() 插件禁用时 保存数据、关闭连接、取消任务

完整生命周期示例

public class MyPlugin extends JavaPlugin {

    @Override
    public void onLoad() {
        // 阶段 1: 加载(早于大多数插件启用)
        getLogger().info("正在加载...");
    }

    @Override
    public void onEnable() {
        // 阶段 2: 启用
        // 注册事件
        getServer().getPluginManager().registerEvents(new MyListener(), this);
        // 注册命令
        getCommand("mycommand").setExecutor(new MyCommand());
        // 加载配置
        saveDefaultConfig();
        getLogger().info("已启用!");
    }

    @Override
    public void onDisable() {
        // 阶段 3: 禁用
        // 保存数据、清理资源
        getLogger().info("已禁用!");
    }
}

1.6 业务场景:为什么需要写插件?

常见需求场景

场景 需求描述 推荐方案
经济系统 服务器货币、商店、交易 Vault API + 自定义插件
领地保护 保护玩家建筑不被破坏 自定义或 WorldGuard
小游戏 PVP 竞技、跑酷、解谜 自定义插件(事件系统为核心)
RPG 元素 等级、技能、装备属性 自定义插件 + 数据库
管理工具 反作弊、日志、权限 多插件组合
自定义合成 新配方、新物品 Bukkit Recipe API + NBT

插件 vs Mod 的选择

维度 插件(Plugin) Mod
安装端 仅服务端 服务端 + 客户端(通常)
玩家要求 无需安装任何东西 需要安装对应 Mod
功能范围 逻辑层面,不能改渲染 可改渲染、添加方块等
开发语言 Java / Kotlin Java / Kotlin
代表平台 Bukkit / Paper Forge / Fabric

1.7 扩展阅读


1.8 本章小结

要点 内容
Paper 定位 Spigot 的下游分支,兼容性好、性能佳、API 丰富
Bukkit API 所有插件的基础,面向接口、事件驱动
Paper API 在 Bukkit/Spigot 基础上扩展,推荐首选
生命周期 构造函数 → onLoad → onEnable → [运行] → onDisable
推荐策略 新项目直接用 Paper API,按需保持兼容性

下一章: 第 2 章:开发环境搭建 — 学习如何使用 Maven/Gradle 初始化项目,配置 Paper 依赖。