Guides Paper, Spigot, and Bukkit Minecraft server plugin development for plugin.yml setup, JavaPlugin bootstrap, commands, listeners, schedulers, player state, arenas, minigames, persistent progression, economy, configuration, Adventure text, and version-safe API usage. Use this skill when asked to build a Minecraft plugin, add a Paper command, fix a Bukkit listener, implement minigame mechanics, add perks or quests, or debug server plugin behavior.
Build and modify Java Minecraft server plugins in the Paper, Spigot, and Bukkit ecosystem, including gameplay-heavy, cooldown-based, config-driven, multi-arena, match-heavy, and persistent-brawl systems. Keep runtime registration, thread safety, gameplay state, configuration, persistence, and validation aligned with the project’s targeted server API.
When to invoke
"Build a Minecraft plugin."
"Add a Paper command and plugin.yml entry."
"Fix this Bukkit listener."
"Implement a minigame mechanic with arenas and phases."
"Add a perk, quest, economy, or persistent profile system."
Out of scope by default: Fabric mods, Forge mods, client mods, and Bedrock add-ons.
If the user says "Minecraft plugin" but the stack is unclear, determine whether the project is Paper/Spigot/Bukkit or a modding stack before editing.
Project discovery
Check these files and concepts before changing behavior:
plugin.yml
pom.xml, build.gradle, or build.gradle.kts
main class extending JavaPlugin
command executors and tab completers
listener classes
config bootstrap for config.yml, messages, kits, arenas, or custom YAML files
generated resource output such as target/classes, build/resources, or copied plugin jars
scheduler usage through Bukkit scheduler APIs
player data, team state, arena state, or match state containers
Identify the server API and version target, build system, Java version, startup registration, gameplay lifecycle, timers, scheduled tasks, teams, arenas, match state, config, and persistence before making a coherent change.
Core implementation rules
Area
Rule
Server API
If the project targets Paper APIs, keep using Paper-first APIs unless Spigot/Bukkit compatibility is explicitly required. Do not assume an API exists across versions; check dependencies and surrounding style.
Registration
When adding commands, permissions, or listeners, update plugin.yml, startup registration in onEnable, permission checks, and related config/message keys together.
Main thread
Do not touch world state, entities, inventories, scoreboards, or most Bukkit API objects from async tasks unless the API explicitly permits it. Use async for I/O or heavy work, then switch back to the main thread.
State modeling
Prefer explicit match/game phase, player role/class, cooldown, team membership, arena assignment, and alive/eliminated/spectating/queued state over scattered booleans.
Arena isolation
Isolate per-arena and per-game visibility, chat recipients, scoreboards, loot, broadcasts, and entity ownership. Do not let one arena observe or mutate another.
Config
Keep damage, cooldowns, rewards, durations, messages, map settings, and toggles config-backed with stable names, defaults, and validation.
Reloads
Avoid promising safe hot reload unless the code already supports it; reload must handle caches, scheduled tasks, and gameplay state consistently.
Commands, listeners, tasks, and state
For commands, add the plugin.yml declaration, implement executor and tab completion when needed, validate CommandSender before casting to Player, separate parsing from permission and gameplay logic, and send clear feedback.
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);
}
}
For listeners, guard early, verify player/arena/phase ownership, avoid expensive work in hot events such as move, damage, or interact spam, and centralize repeated checks.
For scheduled tasks, store task handles when cancellation matters, cancel tasks in onDisable and when a match or arena ends, avoid overlapping tasks for the same concern, prefer one authoritative game loop, and make countdown or refill tasks self-cancel when the game leaves the expected state.
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);
}
});
});
For per-player, per-match, and long-lived player state, define ownership clearly, clean up on quit, kick, death, match end, and plugin disable, avoid stale maps keyed by Player, and prefer UUID for persistent tracking unless a live player object is strictly needed.
When the project uses Adventure or MiniMessage, follow the existing formatting approach for player-facing and game-specific text, avoid mixing legacy color codes and Adventure styles without a reason, and keep gameplay-facing messages configurable.
High-risk areas
Pay extra attention when editing damage handling, custom combat logic, death/respawn/spectator/elimination flow, arena join/leave flow, scoreboards, boss bars, inventory mutation, kit distribution, async database or file access, economy, quest, perk and profile mutation, custom event dispatch, extension registries, version-sensitive API calls, shutdown and cleanup in onDisable, cross-arena visibility/chat/broadcast isolation, map copy/unload/folder deletion, mob/NPC/projectile/temporary entity ownership, and chest/container or resource refill systems, and in-memory caches.
Procedure
Identify the server API/version, build system, Java version, main plugin class, plugin.yml, commands, listeners, and relevant config.
Map player lifecycle, game phases, scheduled tasks, team/arena/match state, persistence, and generated resources before editing.
Read bundled references on demand for the feature area named below.
Implement the smallest coherent code, resource, and registration change.
references/persistent-progression-and-events.md: long-running PvP servers with profiles, perks, buffs, quests, economy, custom domain events, and extension registries.
references/build-test-and-runtime-validation.md: Maven or Gradle packaging, shaded dependencies, generated resources, soft dependencies, config validation commands, and first-round server test plans.
Gotchas
Never cast CommandSender to Player without checking: console and command blocks can execute commands.
Never mutate Bukkit world state from async tasks: use the scheduler to hand off to the main thread.
Forgetting listener registration or plugin.yml command declarations makes correct Java code unreachable.
Long-lived maps keyed by Player can leak; use UUID for persistent state.
Repeating tasks must stop after round, arena, or plugin shutdown.
Hardcoded gameplay constants should usually live in config.
Paper-only APIs break Spigot targets unless compatibility is explicit.
Stateful plugins often break under reload; treat reload as a lifecycle feature, not a free operation.
Broadcasting, showing players, or applying scoreboards across unrelated game instances breaks arena isolation.
Generated files under target/classes or build/resources are not source; edit src/main/resources instead.
Output expectations
Produce runnable Java code, not pseudo-code, unless the user asks for design only. For substantial requests, report current plugin context and assumptions, gameplay or lifecycle impact, code changes, required registration or config updates, validation, remaining risks, and thread-safety notes.
Config keys exist or have defaults and validation.
State cleanup covers player quit, kick, death, match end, and onDisable where relevant.
Per-arena chat, visibility, scoreboards, broadcasts, temporary worlds, mobs, tasks, and generated resources are isolated or cleaned up.
Build/test/runtime validation from the project’s existing Maven or Gradle setup was run when available.
1---2name: minecraft-plugin-development3description: Guides Paper, Spigot, and Bukkit Minecraft server plugin development for plugin.yml setup, JavaPlugin bootstrap, commands, listeners, schedulers, player state, arenas, minigames, persistent progression, economy, configuration, Adventure text, and version-safe API usage. Use this skill when asked to build a Minecraft plugin, add a Paper command, fix a Bukkit listener, implement minigame mechanics, add perks or quests, or debug server plugin behavior.4---56<!-- Generated from harness/github-copilot/skills/minecraft-plugin-development/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# Minecraft plugin development910Build and modify Java Minecraft server plugins in the Paper, Spigot, and Bukkit ecosystem, including gameplay-heavy, cooldown-based, config-driven, multi-arena, match-heavy, and persistent-brawl systems. Keep runtime registration, thread safety, gameplay state, configuration, persistence, and validation aligned with the project’s targeted server API.1112## When to invoke1314- "Build a Minecraft plugin."15- "Add a Paper command and plugin.yml entry."16- "Fix this Bukkit listener."17- "Implement a minigame mechanic with arenas and phases."18- "Add a perk, quest, economy, or persistent profile system."1920## Limits2122- In scope: Paper, Spigot, Bukkit plugin development; `plugin.yml`; commands; tab completion; listeners; schedulers; configs; permissions; Adventure text; player state; minigame flow; arena instances; map copies; loot; waves; persistent profiles; perks; buffs; quests; economy; PvP/PvE game loops; Java-based architecture, debugging, refactoring, and feature implementation.23- Out of scope by default: Fabric mods, Forge mods, client mods, and Bedrock add-ons.24- If the user says "Minecraft plugin" but the stack is unclear, determine whether the project is Paper/Spigot/Bukkit or a modding stack before editing.2526## Project discovery2728Check these files and concepts before changing behavior:2930- `plugin.yml`31- `pom.xml`, `build.gradle`, or `build.gradle.kts`32- main class extending `JavaPlugin`33- command executors and tab completers34- listener classes35- config bootstrap for `config.yml`, messages, kits, arenas, or custom YAML files36- generated resource output such as `target/classes`, `build/resources`, or copied plugin jars37- scheduler usage through Bukkit scheduler APIs38- player data, team state, arena state, or match state containers3940Identify the server API and version target, build system, Java version, startup registration, gameplay lifecycle, timers, scheduled tasks, teams, arenas, match state, config, and persistence before making a coherent change.4142## Core implementation rules4344| Area | Rule |45| --- | --- |46| Server API | If the project targets Paper APIs, keep using Paper-first APIs unless Spigot/Bukkit compatibility is explicitly required. Do not assume an API exists across versions; check dependencies and surrounding style. |47| Registration | When adding commands, permissions, or listeners, update `plugin.yml`, startup registration in `onEnable`, permission checks, and related config/message keys together. |48| Main thread | Do not touch world state, entities, inventories, scoreboards, or most Bukkit API objects from async tasks unless the API explicitly permits it. Use async for I/O or heavy work, then switch back to the main thread. |49| State modeling | Prefer explicit match/game phase, player role/class, cooldown, team membership, arena assignment, and alive/eliminated/spectating/queued state over scattered booleans. |50| Arena isolation | Isolate `per-arena` and per-game visibility, chat recipients, scoreboards, loot, broadcasts, and entity ownership. Do not let one arena observe or mutate another. |51| Config | Keep damage, cooldowns, rewards, durations, messages, map settings, and toggles config-backed with stable names, defaults, and validation. |52| Reloads | Avoid promising safe hot reload unless the code already supports it; reload must handle caches, scheduled tasks, and gameplay state consistently. |5354## Commands, listeners, tasks, and state5556For commands, add the `plugin.yml` declaration, implement executor and tab completion when needed, validate `CommandSender` before casting to `Player`, separate parsing from permission and gameplay logic, and send clear feedback.5758```yaml59commands:60 arena:61 description: Join or leave an arena62 usage: /arena <join|leave>63```6465```java66@Override67public void onEnable() {68 ArenaCommand command = new ArenaCommand(gameService);69 PluginCommand arena = getCommand("arena");70 if (arena != null) {71 arena.setExecutor(command);72 arena.setTabCompleter(command);73 }74}75```7677For listeners, guard early, verify player/arena/phase ownership, avoid expensive work in hot events such as move, damage, or interact spam, and centralize repeated checks.7879For scheduled tasks, store task handles when cancellation matters, cancel tasks in `onDisable` and when a match or arena ends, avoid overlapping tasks for the same concern, prefer one authoritative game loop, and make countdown or refill tasks self-cancel when the game leaves the expected state.8081```java82Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {83 PlayerData data = repository.load(playerId);84 Bukkit.getScheduler().runTask(plugin, () -> {85 Player player = Bukkit.getPlayer(playerId);86 if (player != null && player.isOnline()) {87 scoreboard.update(player, data);88 }89 });90});91```9293For per-player, per-match, and long-lived player state, define ownership clearly, clean up on quit, kick, death, match end, and plugin disable, avoid stale maps keyed by `Player`, and prefer `UUID` for persistent tracking unless a live player object is strictly needed.9495When the project uses Adventure or MiniMessage, follow the existing formatting approach for player-facing and game-specific text, avoid mixing legacy color codes and Adventure styles without a reason, and keep gameplay-facing messages configurable.9697## High-risk areas9899Pay extra attention when editing damage handling, custom combat logic, death/respawn/spectator/elimination flow, arena join/leave flow, scoreboards, boss bars, inventory mutation, kit distribution, async database or file access, economy, quest, perk and profile mutation, custom event dispatch, extension registries, version-sensitive API calls, shutdown and cleanup in `onDisable`, cross-arena visibility/chat/broadcast isolation, map copy/unload/folder deletion, mob/NPC/projectile/temporary entity ownership, and chest/container or resource refill systems, and in-memory caches.100101## Procedure1021031. Identify the server API/version, build system, Java version, main plugin class, `plugin.yml`, commands, listeners, and relevant config.1042. Map player lifecycle, game phases, scheduled tasks, team/arena/match state, persistence, and generated resources before editing.1053. Read bundled references on demand for the feature area named below.1064. Implement the smallest coherent code, resource, and registration change.1075. Validate build output, resource generation, config defaults, and runtime lifecycle paths.108109## Progressive disclosure and bundled resources110111Load these references only when the task touches the named area:112113- `references/project-patterns.md`: high-level architecture patterns seen in real gameplay plugins.114- `references/bootstrap-registration.md`: `onEnable`, command wiring, listener registration, and shutdown expectations.115- `references/state-sessions-and-phases.md`: player session modeling, game phases, match state, and reconnect-safe logic.116- `references/config-data-and-async.md`: config managers, database-backed player data, async flushes, and UI refresh tasks.117- `references/maps-heroes-and-feature-modules.md`: map rotation, hero/class systems, and modular feature growth.118- `references/minigame-instance-flow.md`: arena instances, countdowns, loot refreshes, wave systems, visibility isolation, and entity-to-game ownership.119- `references/persistent-progression-and-events.md`: long-running PvP servers with profiles, perks, buffs, quests, economy, custom domain events, and extension registries.120- `references/build-test-and-runtime-validation.md`: Maven or Gradle packaging, shaded dependencies, generated resources, soft dependencies, config validation commands, and first-round server test plans.121122## Gotchas123124- **Never cast `CommandSender` to `Player` without checking**: console and command blocks can execute commands.125- **Never mutate Bukkit world state from async tasks**: use the scheduler to hand off to the main thread.126- Forgetting listener registration or `plugin.yml` command declarations makes correct Java code unreachable.127- Long-lived maps keyed by `Player` can leak; use `UUID` for persistent state.128- Repeating tasks must stop after round, arena, or plugin shutdown.129- Hardcoded gameplay constants should usually live in config.130- Paper-only APIs break Spigot targets unless compatibility is explicit.131- Stateful plugins often break under reload; treat reload as a lifecycle feature, not a free operation.132- Broadcasting, showing players, or applying scoreboards across unrelated game instances breaks arena isolation.133- Generated files under `target/classes` or `build/resources` are not source; edit `src/main/resources` instead.134135## Output expectations136137Produce runnable Java code, not pseudo-code, unless the user asks for design only. For substantial requests, report current plugin context and assumptions, gameplay or lifecycle impact, code changes, required registration or config updates, validation, remaining risks, and thread-safety notes.138139## Output template140141```markdown142## Minecraft plugin change — <feature or bug>143144**Status:** implemented | design only | blocked145**Server API:** Paper | Spigot | Bukkit | unknown146**Version assumptions:** <API and Java version>147148### Current plugin context149- Main class: `<class extending JavaPlugin>`150- Registration touched: `plugin.yml`, `onEnable`, listeners, commands, permissions151- Gameplay lifecycle impact: <players, arenas, tasks, persistence>152153### Changes154| File | Change | Reason |155| --- | --- | --- |156| `src/main/java/...` | <code behavior> | <why> |157| `src/main/resources/plugin.yml` | <command/permission> | <why> |158159### Validation160- Build: pass | fail | not run161- Runtime registration: verified | not verified162- Thread-safety and cleanup paths: verified | risks listed163```164165## Quality gate166167- [ ] The targeted server API and version assumptions are explicit.168- [ ] `plugin.yml` matches implemented commands, permissions, and main class behavior.169- [ ] Command sender types are checked before casting to `Player`.170- [ ] Listener and command registration is wired through `onEnable`.171- [ ] Scheduler usage respects Bukkit main-thread boundaries.172- [ ] Config keys exist or have defaults and validation.173- [ ] State cleanup covers player quit, kick, death, match end, and `onDisable` where relevant.174- [ ] Per-arena chat, visibility, scoreboards, broadcasts, temporary worlds, mobs, tasks, and generated resources are isolated or cleaned up.175- [ ] Build/test/runtime validation from the project’s existing Maven or Gradle setup was run when available.
Run npx skillmds@latest add paulasilvatech/minecraft-plugin-development in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Guides Paper, Spigot, and Bukkit Minecraft server plugin development for plugin.yml setup, JavaPlugin bootstrap, commands, listeners, schedulers, player state, arenas, minigames, persistent progression, economy, configuration, Adventure text, and version-safe API usage. Use this skill when asked to build a Minecraft plugin, add a Paper command, fix a Bukkit listener, implement minigame mechanics, add perks or quests, or debug server plugin behavior. It is listed under Integrations & APIs on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
paulasilvatech (@paulasilvatech) published this skill. Their other Agent Skills are listed on their SkillMD profile.