关于 minecraft-plugin-development
面向 Paper、Spigot 和 Bukkit 生态中 Java 插件开发的 Skill。它指导游戏机制、状态、配置和生命周期相关实现,并提供常见插件架构与验证参考。
主要功能
- 01Paper、Spigot 和 Bukkit 插件开发指导
- 02检查命令与监听器注册
- 03规划游戏状态与对局流程
- 04配置和持久化数据模式
- 05线程、任务与生命周期防护
- 06构建和运行时验证指导
适用场景
- 01实现竞技场或波次小游戏功能
- 02添加命令、监听器或可配置规则
- 03排查玩家状态与对局生命周期问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ github/ awesome-copilot --skill minecraft-plugin-development安装后在 Claude Code 中输入/minecraft-plugin-development确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/bootstrap-registration.mdbuild-test-and-runtime-validation.mdconfig-data-and-async.mdmaps-heroes-and-feature-modules.mdminigame-instance-flow.mdpersistent-progression-and-events.mdproject-patterns.mdstate-sessions-and-phases.md详细介绍
Minecraft 插件开发
在 Paper、Spigot 和 Bukkit 生态中进行 Minecraft 服务端插件开发时,请使用本技能。
本技能尤其适用于玩法密集型的插件,例如战斗系统、波次或 Boss 遭遇、战争或团队模式、竞技场、装备包系统、基于冷却的技能、记分板和配置驱动的游戏规则。
若需基于真实 Paper 插件的落地实现模式,可按需加载以下参考文档:
references/project-patterns.md:真实玩法插件中出现的高层架构模式references/bootstrap-registration.md:onEnable、命令接线、监听器注册和关闭预期references/state-sessions-and-phases.md:玩家会话建模、游戏阶段、对局状态和重连安全逻辑references/config-data-and-async.md:配置管理器、数据库支持的玩家数据、异步刷写和 UI 刷新任务references/maps-heroes-and-feature-modules.md:地图轮换、英雄或职业系统以及模块化功能扩展references/minigame-instance-flow.md:竞技场实例、倒计时、战利品刷新、波次系统、可见性隔离和实体到对局的归属references/persistent-progression-and-events.md:带档案、特长、增益、任务、经济、自定义领域事件和扩展注册表的长周期运行 PvP 服务references/build-test-and-runtime-validation.md:Maven 或 Gradle 打包、shaded 依赖、生成资源、软依赖、配置验证命令和首轮服务测试计划
适用范围
- 范围内:Paper、Spigot、Bukkit 插件开发
- 范围内:
plugin.yml、命令、Tab 补全、监听器、调度器、配置、权限、Adventure 文本、玩家状态、小游戏流程、竞技场实例、地图副本、战利品、波次、持久化档案、特长、增益、任务、经济以及 PvP/PvE 游戏循环 - 范围内:基于 Java 的服务端插件架构、调试、重构和功能实现
- 默认范围外:Fabric mod、Forge mod、客户端 mod、Bedrock 附加包
如果用户说的是 “Minecraft 插件” 但技术栈不明确,请先确定项目是 Paper/Spigot/Bukkit 还是 modding 技术栈。
默认工作方式
当此技能触发时:
- 确定服务端 API 和目标版本。
- 确定构建系统和 Java 版本。
- 检查
plugin.yml、插件主类以及命令或监听器注册。 - 在编辑代码前梳理玩法流程:
- 玩家生命周期
- 游戏阶段
- 计时器和计划任务
- 队伍、竞技场或对局状态
- 配置与持久化
- 做出最小的连贯改动,使注册、配置和运行时行为保持一致。
如果插件玩法密集或包含大量状态,请在编辑前阅读 references/project-patterns.md 和 references/state-sessions-and-phases.md。
如果任务涉及竞技场隔离、地图实例、宝箱或资源补充、波次生成、路线投票、观战者可见性或游戏专属聊天,也请阅读 references/minigame-instance-flow.md。
如果任务涉及持久化玩家进度、档案保存、经济奖励、特权、增益、任务、自定义战斗事件或长时间运行的共享 PvP 服务器,也请阅读 references/persistent-progression-and-events.md。
如果任务涉及构建文件、plugin.yml 元数据、shaded 依赖、生成的资源输出、部署到测试服务器、可选插件集成或发布验证,也请阅读 references/build-test-and-runtime-validation.md。
项目发现清单
存在以下内容时,优先检查:
plugin.ymlpom.xml、build.gradle或build.gradle.kts- 扩展
JavaPlugin的插件主类 - 命令执行器和 tab 补全器
- 监听器类
- 针对
config.yml、消息、套件、竞技场或自定义 YAML 文件的配置初始化代码 - 生成的资源输出,例如
target/classes、build/resources或复制后的插件 jar - 通过 Bukkit 调度器 API 使用的调度器
- 任何玩家数据、队伍状态、竞技场状态或对局状态容器
核心规则
优先使用仓库中具体的服务端 API
- 如果项目已经面向 Paper API,请继续使用 Paper 优先的 API,而不要降级为通用 Bukkit,除非明确要求兼容性。
- 不要假设某个 API 在所有版本中都存在。请先检查现有依赖和周围代码风格。
保持注册同步
在添加命令、权限或监听器时,请在同一次改动中更新相关注册点:
plugin.ymlonEnable中的插件启动注册- 代码中的任何权限检查
- 任何相关的配置或消息键
遵守主线程边界
- 不要在异步任务中触碰世界状态、实体、物品栏、记分板或大多数 Bukkit API 对象,除非该 API 明确允许。
- 使用异步任务处理外部 I/O、繁重计算或数据库工作,然后在应用玩法改动之前切换回主线程。
将玩法建模为状态,而不是分散的布尔值
对于玩法插件,优先使用显式状态对象,而不是重复的标志:
- 对局或游戏阶段
- 玩家角色或职业
- 冷却状态
- 队伍成员身份
- 竞技场分配
- 存活、淘汰、观战或排队状态
当功能影响对局密集型小游戏或持久化乱斗玩法时,请先查找隐藏的状态转换,再修补表象。
对于多竞技场插件,请隔离每局游戏的可见性、聊天接收者、记分板、战利品和实体归属。不要让一个竞技场意外观察或修改另一个竞技场。
倾向于配置驱动的值
当功能包含伤害、冷却、奖励、持续时间、消息、地图设置或开关时:
- 优先使用配置支持的值,而不是硬编码
- 提供合理的默认值
- 保持键名稳定且可读
- 验证或清理缺失的值
注意重载行为
- 除非代码已经很好地支持安全热重载,否则不要承诺这一点。
- 配置重载时,确保内存缓存、计划任务和游戏状态得到一致处理。
实现模式
命令
对于新命令:
- 将命令添加到
plugin.yml - 在需要时实现执行器和 Tab 补全
- 在转换为
Player之前验证发送者类型 - 将解析、权限检查和游戏逻辑分开
- 对无效用法发送清晰的面向玩家的反馈
最小注册形式:
commands:
arena:
description: Join or leave an arena
usage: /arena <join|leave>
@Override
public void onEnable() {
ArenaCommand command = new ArenaCommand(gameService);
PluginCommand arena = getCommand("arena");
if (arena != null) {
arena.setExecutor(command);
arena.setTabCompleter(command);
}
}
监听器
对于事件监听器:
- 尽早保护并尽早返回
- 检查当前玩家、竞技场或游戏阶段是否应处理该事件
- 避免在 move、damage 或 interact 刷屏等高频事件中执行昂贵操作
- 在可行的情况下集中重复检查
计划任务
对于计时器、回合、倒计时、冷却或周期性检查:
- 在需要取消时存储任务句柄
- 在插件禁用以及比赛或竞技场结束时取消任务
- 避免为同一游戏关注点创建多个重叠任务,除非明确有意为之
- 优先使用一个权威游戏循环,而不是许多松散协调的重复任务
- 确保倒计时或补充任务在游戏离开预期状态时自行取消
主线程交接形式:
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
PlayerData data = repository.load(playerId);
Bukkit.getScheduler().runTask(plugin, () -> {
Player player = Bukkit.getPlayer(playerId);
if (player != null && player.isOnline()) {
scoreboard.update(player, data);
}
});
});
玩家与比赛状态
对于按玩家或按比赛的状态:
- 明确定义所有权
- 在退出、踢出、死亡、比赛结束和插件禁用时清理
- 避免以
Player为键的过期 map 导致内存泄漏 - 持久跟踪优先使用
UUID,除非确实需要实时玩家对象
文本与消息
当项目使用 Adventure 或 MiniMessage 时:
- 遵循现有格式化方式
- 避免在没有理由的情况下混用旧式颜色代码和 Adventure 样式
- 当消息面向游戏玩法时,保持消息模板可配置
高风险区域
编辑以下内容时要格外注意:
- 伤害处理和自定义战斗逻辑
- 死亡、重生、旁观和淘汰流程
- 竞技场加入和离开流程
- 记分板或 Boss 栏更新
- 物品栏变更和套装分发
- 异步数据库或文件访问
- 经济、任务、特权和档案变更
- 自定义事件分发或扩展注册表
- 对版本敏感的 API 调用
onDisable中的关闭和清理- 跨竞技场可见性、聊天和广播隔离
- 地图复制、卸载和文件夹删除逻辑
- 怪物、NPC、投掷物或临时实体所有权
- 箱子或资源补充系统
输出期望
实现或修订插件代码时:
- 生成可运行的 Java 代码,而不是伪代码,除非用户只要求设计
- 提及对
plugin.yml、配置文件、构建文件或资源的任何必要更新 - 明确说明版本假设
- 在存在线程安全或 API 兼容性风险时指出这些风险
- 保留项目现有约定和文件夹结构
当请求的更改涉及插件启动、异步数据、比赛流程、职业系统或轮换地图时,请在编辑前查阅匹配的参考文件。
验证清单
完成前,在任务允许范围内尽可能验证以下事项:
- 命令、监听器或功能已正确注册
plugin.yml与已实现行为匹配- import 和 API 类型与目标服务器栈匹配
- 调度器使用安全
- 代码中引用的配置键存在或有默认值
- 比赛结束、玩家退出和插件禁用都有状态清理路径
- 按竞技场的聊天、可见性、记分板和广播相互隔离
- 临时世界、怪物、任务和生成的资源都已清理
- 没有明显的 null、类型转换或生命周期隐患
常见陷阱
- 未经检查就将
CommandSender强制转换为Player - 在异步任务中更新 Bukkit 状态
- 忘记在
plugin.yml中注册监听器或声明命令 - 将
Player对象用作长期存活的 Map 键,而UUID更安全 - 在一轮游戏、竞技场或插件关闭后仍让重复任务保持运行
- 硬编码本应放在配置中的游戏常量
- 在面向 Spigot 的插件中假定使用仅 Paper 提供的 API
- 将 reload 视为无代价操作,尽管有状态的插件在 reload 时常常出错
- 在互不相关的游戏实例之间广播、向玩家展示或应用计分板更改
- 在区块可用之前加载或修改箱子/容器方块
- 忘记从所属游戏中注销已生成的生物或临时实体
- 编辑
target/classes或build/resources下的生成文件,而不是src/main/resources下的源文件
首选回复结构
对于较复杂的请求,按以下结构组织工作:
- 当前插件上下文与假设
- 游戏玩法或生命周期影响
- 代码更改
- 所需的注册或配置更新
- 验证与剩余风险
对于较小的请求,保持回答简洁,但仍需提及任何所需的 plugin.yml、配置或生命周期更新。