Minecraft Plugin Development
GitHubOfficialFirst committed by zixuanjiang332Distributed by GitHub
- Skill
- Tool integration
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides guidance for building, modifying, and debugging Minecraft server plugins. It covers the full lifecycle of plugin development, including project structure, command and listener registration, configuration management, state handling, and integration with server APIs. It emphasizes maintaining synchronization between plugin metadata and code, respecting main-thread boundaries, and implementing robust gameplay state management for minigames and persistent progression systems.
What it does
- Assists with plugin.yml setup and build system configuration for Maven or Gradle.
- Provides patterns for command execution, tab completion, and event listener registration.
- Guides the implementation of gameplay state, including arenas, match phases, and player sessions.
- Supports integration with external APIs and optional dependencies like PlaceholderAPI.
- Offers strategies for persistent data management, economy systems, and custom progression.
- Advises on safe thread management and resource cleanup during plugin shutdown.
When to use it
- When creating a new Minecraft server plugin for Paper, Spigot, or Bukkit.
- When adding new features like custom commands, listeners, or minigame mechanics.
- When debugging plugin behavior, lifecycle issues, or state synchronization problems.
- When refactoring plugin architecture to improve maintainability or performance.
- When configuring build files, dependencies, or plugin metadata.
Advantages
- Ensures consistent registration of commands and listeners across the plugin lifecycle.
- Promotes thread-safe practices when interacting with the Bukkit API.
- Provides structured patterns for managing complex game states and arena instances.
- Helps maintain alignment between configuration files and runtime logic.
- Facilitates clean integration with optional server-side plugins.
Usage examples
- “Create a new command for my Paper plugin that allows players to join an arena.”
- The agent provides the command registration in plugin.yml, the Java executor class, and the necessary logic to handle player state transitions.
- “Fix a listener in my Spigot plugin that is causing issues during server shutdown.”
- The agent identifies potential lifecycle hazards and provides code to safely unregister listeners and clean up resources in the onDisable method.
- “How should I structure my plugin's configuration to support custom kit rewards?”
- The agent suggests a YAML structure for the config file and provides a manager class to load and validate these settings at runtime.
- “Help me implement a persistent economy system for my PvP server.”
- The agent outlines a service-based architecture for handling player profiles, database interactions, and thread-safe UI updates.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/github/minecraft-plugin-development/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip minecraft-plugin-development.zip -d .agents/skills
Documentation by zixuanjiang332
Minecraft Plugin Development
Use this skill for Minecraft server plugin work in the Paper, Spigot, and Bukkit ecosystem.
This skill is especially useful for gameplay-heavy plugins such as combat systems, wave or boss encounters, war or team modes, arenas, kit systems, cooldown-based abilities, scoreboards, and config-driven game rules.
For grounded implementation patterns drawn from real Paper plugins, load these references as needed:
references/project-patterns.mdfor high-level architecture patterns seen in real gameplay pluginsreferences/bootstrap-registration.mdforonEnable, command wiring, listener registration, and shutdown expectationsreferences/state-sessions-and-phases.mdfor player session modeling, game phases, match state, and reconnect-safe logicreferences/config-data-and-async.mdfor config managers, database-backed player data, async flushes, and UI refresh tasksreferences/maps-heroes-and-feature-modules.mdfor map rotation, hero or class systems, and modular feature growthreferences/minigame-instance-flow.mdfor arena instances, countdowns, loot refreshes, wave systems, visibility isolation, and entity-to-game ownershipreferences/persistent-progression-and-events.mdfor long-running PvP servers with profiles, perks, buffs, quests, economy, custom domain events, and extension registriesreferences/build-test-and-runtime-validation.mdfor Maven or Gradle packaging, shaded dependencies, generated resources, soft dependencies, config validation commands, and first-round server test plans
Scope
In scope: Paper, Spigot, Bukkit plugin development
In scope:
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, and PvP/PvE game loopsIn scope: Java-based server plugin architecture, debugging, refactoring, and feature implementation
Out of scope by default: Fabric mods, Forge mods, client mods, Bedrock add-ons
If the user says "Minecraft plugin" but the stack is unclear, first determine whether the project is Paper/Spigot/Bukkit or a modding stack.
Default Working Style
When this skill triggers:
Identify the server API and version target.
Identify the build system and Java version.
Inspect
plugin.yml, the main plugin class, and command or listener registration.Map the gameplay flow before editing code:
player lifecycle
game phases
timers and scheduled tasks
team, arena, or match state
config and persistence
Make the smallest coherent change that keeps registration, config, and runtime behavior aligned.
If the plugin is gameplay-heavy or stateful, read references/project-patterns.md and references/state-sessions-and-phases.md before editing.
If the task touches arena isolation, map instances, chest or resource refills, wave spawning, route voting, spectator visibility, or game-specific chat, also read references/minigame-instance-flow.md.
If the task touches persistent player progression, profile saves, economy rewards, perks, buffs, quests, custom combat events, or long-running shared PvP servers, also read references/persistent-progression-and-events.md.
If the task touches build files, plugin.yml metadata, shaded dependencies, generated resource output, deployment to a test server, optional plugin integrations, or release validation, also read references/build-test-and-runtime-validation.md.
Project Discovery Checklist
Check these first when present:
plugin.ymlpom.xml,build.gradle, orbuild.gradle.ktsthe plugin main class extending
JavaPlugincommand executors and tab completers
listener classes
config bootstrap code for
config.yml, messages, kits, arenas, or custom YAML filesgenerated resource output such as
target/classes,build/resources, or copied plugin jarsscheduler usage through Bukkit scheduler APIs
any player data, team state, arena state, or match state containers
Core Rules
Prefer the concrete server API in the repo
If the project already targets Paper APIs, keep using Paper-first APIs instead of downgrading to generic Bukkit unless compatibility is explicitly required.
Do not assume an API exists across all versions. Check the existing dependency and surrounding code style first.
Keep registration in sync
When adding commands, permissions, or listeners, update the relevant registration points in the same change:
plugin.ymlplugin startup registration in
onEnableany permission checks in code
any related config or message keys
Respect main-thread boundaries
Do not touch world state, entities, inventories, scoreboards, or most Bukkit API objects from async tasks unless the API explicitly permits it.
Use async tasks for external I/O, heavy computation, or database work, then switch back to the main thread before applying gameplay changes.
Model gameplay as state, not scattered booleans
For gameplay plugins, prefer explicit state objects over duplicated flags:
match or game phase
player role or class
cooldown state
team membership
arena assignment
alive, eliminated, spectating, or queued state
When the feature affects match-heavy minigames or persistent-brawl gameplay, look for hidden state transitions first before patching symptoms.
For multi-arena plugins, isolate per-game visibility, chat recipients, scoreboards, loot, and entity ownership. Do not let one arena observe or mutate another arena by accident.
Favor config-driven values
When the feature includes damage, cooldowns, rewards, durations, messages, map settings, or toggles:
prefer config-backed values over hardcoding
provide sensible defaults
keep key names stable and readable
validate or sanitize missing values
Be careful with reload behavior
Avoid promising safe hot reload unless the code already supports it well.
On config reload, ensure in-memory caches, scheduled tasks, and gameplay state are handled consistently.
Implementation Patterns
Commands
For new commands:
add the command to
plugin.ymlimplement executor and tab completion when needed
validate sender type before casting to
Playerseparate parsing, permission checks, and gameplay logic
send clear player-facing feedback for invalid usage
Minimal registration shape:
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);
}
}Listeners
For event listeners:
guard early and return early
check whether the current player, arena, or game phase should handle the event
avoid doing expensive work in hot events such as move, damage, or interact spam
centralize repeated checks where practical
Scheduled Tasks
For timers, rounds, countdowns, cooldowns, or periodic checks:
store task handles when cancellation matters
cancel tasks on plugin disable and when a match or arena ends
avoid multiple overlapping tasks for the same gameplay concern unless explicitly intended
prefer one authoritative game loop over many loosely coordinated repeating tasks
ensure countdown or refill tasks self-cancel when the game leaves the expected state
Main-thread handoff shape:
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 and Match State
For per-player or per-match state:
define ownership clearly
clean up on quit, kick, death, match end, and plugin disable
avoid memory leaks from stale maps keyed by
Playerprefer
UUIDfor persistent tracking unless a live player object is strictly needed
Text and Messages
When the project uses Adventure or MiniMessage:
follow the existing formatting approach
avoid mixing legacy color codes and Adventure styles without a reason
keep message templates configurable when messages are gameplay-facing
High-Risk Areas
Pay extra attention when editing:
damage handling and custom combat logic
death, respawn, spectator, and elimination flow
arena join and leave flow
scoreboard or boss bar updates
inventory mutation and kit distribution
async database or file access
economy, quest, perk, and profile mutation
custom event dispatch or extension registries
version-sensitive API calls
shutdown and cleanup in
onDisablecross-arena visibility, chat, and broadcast isolation
map copy, unload, and folder deletion logic
mob, NPC, projectile, or temporary entity ownership
chest or resource refill systems
Output Expectations
When implementing or revising plugin code:
produce runnable Java code, not pseudo-code, unless the user asks for design only
mention any required updates to
plugin.yml, config files, build files, or resourcescall out version assumptions explicitly
point out thread-safety or API-compatibility risks when they exist
preserve the project's existing conventions and folder structure
When the requested change touches plugin startup, async data, match flow, class systems, or rotating maps, consult the matching reference file before editing.
Validation Checklist
Before finishing, verify as many of these as the task allows:
the command, listener, or feature is registered correctly
plugin.ymlmatches the implemented behaviorimports and API types match the targeted server stack
scheduler usage is safe
config keys referenced in code exist or have defaults
state cleanup paths exist for match end, player quit, and plugin disable
per-arena chat, visibility, scoreboards, and broadcasts are isolated
temporary worlds, mobs, tasks, and generated resources are cleaned up
there are no obvious null, cast, or lifecycle hazards
Common Gotchas
Casting
CommandSendertoPlayerwithout checkingUpdating Bukkit state from async tasks
Forgetting to register listeners or declare commands in
plugin.ymlUsing
Playerobjects as long-lived map keys whenUUIDis saferLeaving repeating tasks alive after a round, arena, or plugin shutdown
Hardcoding gameplay constants that should live in config
Assuming Paper-only APIs in a Spigot-targeted plugin
Treating reload as free even though stateful plugins often break under reload
Broadcasting, showing players, or applying scoreboard changes across unrelated game instances
Loading or mutating chest/container blocks before their chunks are available
Forgetting to unregister spawned mobs or temporary entities from the owning game
Editing generated files under
target/classesorbuild/resourcesinstead of source files undersrc/main/resources
Preferred Response Shape
For substantial requests, structure work like this:
Current plugin context and assumptions
Gameplay or lifecycle impact
Code changes
Required registration or config updates
Validation and remaining risks
For small requests, keep the answer concise but still mention any needed plugin.yml, config, or lifecycle updates.
Files
- ATTRIBUTION.mdAdded by AutoGineer901 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md12.4 KiB
- references/bootstrap-registration.md3.5 KiB
- references/build-test-and-runtime-validation.md6.6 KiB
- references/config-data-and-async.md3.6 KiB
- references/maps-heroes-and-feature-modules.md3.5 KiB
- references/minigame-instance-flow.md7.0 KiB
- references/persistent-progression-and-events.md5.8 KiB
- references/project-patterns.md5.1 KiB
- references/state-sessions-and-phases.md3.4 KiB
references/persistent-progression-and-events.md
Persistent Progression And Event Systems
Use this reference when working on long-running Minecraft server plugins where player progress, economy, perks, buffs, quests, or custom combat events persist beyond a single match.
This is most relevant for Pit-style PvP servers, MMORPG-like hubs, persistent brawl modes, faction-adjacent gameplay, and any plugin where the same player profile is mutated by many independent systems.
Persistent profile boundaries
Large progression plugins often separate durable profile data from temporary runtime state.
Durable examples:
level, prestige, experience, coins, renown, bounty, stats
owned perks, selected perks, quest progress, trade limits, mail, medals
inventory-like storage such as saved kits, ender chests, warehouses, or backups
schema or profile format version
Runtime-only examples:
combat timer
current damage attribution map
active buffs
temporary streak counters
editing mode
last damage timestamp
cached live
ItemStackreferences
Guidance:
Make save boundaries explicit with transient fields, ignored serializer fields, or dedicated DTOs.
Use
UUIDas the durable identity for profile lookup and persistence.Avoid saving live Bukkit objects directly unless the project already has a serializer for them.
Keep a profile version field when the profile shape may migrate over time.
Prefer maps keyed by internal names for hot lookups such as perks, quests, buffs, or unlock states.
Economy and progression mutation
Progression features rarely change only one number. A kill reward may affect coins, experience, bounty, streak, quests, assist credit, scoreboard lines, boss bars, and persistence dirty state.
Guidance:
Route rewards through one service or domain method instead of duplicating math in listeners.
Fire or call a domain-level event before finalizing rewards if other systems can modify the result.
Clamp and validate player-facing amounts such as coins, XP, level, health, bounty, or cooldowns.
Mark profiles dirty after mutation and save in batches when the codebase uses dirty tracking.
Update visible UI from the main thread after persistence or reward computation completes.
Custom domain events
Complex plugins often wrap Bukkit events in plugin-specific events such as damage, kill, assist, reward, quest completion, profile loaded, potion effect, or streak-change events.
Use custom events when:
multiple systems need to observe or modify the same gameplay decision
raw Bukkit events are too low-level for the plugin's rules
rewards, assists, buffs, or perks need a consistent extension point
tests or future features would benefit from a single domain signal
Guidance:
Keep Bukkit listeners thin: translate the raw event into the plugin's domain model, then delegate.
Define whether the custom event is cancellable or mutable.
Document whether listeners may change damage, rewards, target state, or side effects.
Avoid firing custom events from async threads if handlers may touch Bukkit state.
Prevent recursion when a custom event handler triggers another raw Bukkit action.
Perk, buff, quest, and event registries
Feature-heavy plugins often use factories or registries to discover and expose extension modules:
perk registries grouped by interfaces such as damage, kill, assist, respawn, shoot, or tick hooks
buff registries with optional Bukkit listener registration
timed event registries split into normal and major events
quest or medal registries keyed by stable internal names
Guidance:
Require a stable internal name for every registered module.
Keep display names separate from internal names so localization or formatting does not break saved data.
Register Bukkit listeners only for modules that actually implement
Listener.Prefer explicit registration when startup reliability matters; use reflection scanning only if the project already relies on it.
Fail loudly on duplicate internal names.
Expose read-only views when other systems only need to inspect registered modules.
Timed events and rotating server activity
Long-running servers often schedule global events independently of arena matches.
Guidance:
Store active event, next event, cooldown, and preparation phase explicitly.
Separate preparation, active, inactive, and cleanup hooks.
Avoid overlapping global events unless the design supports it.
Keep boss bar, scoreboard, and broadcast updates tied to the active event state.
Cancel or expire timers when the event is replaced, forced, or the plugin disables.
Use configured online-player thresholds before starting high-impact events.
Version and dependency boundaries
Persistent server plugins often depend on multiple optional and required plugins such as permissions, economy, points, protocol, world edit, database drivers, packet libraries, or custom server forks.
Guidance:
Keep
plugin.ymldependandsoftdependaligned with startup code.Detect optional dependencies before using their APIs.
Provide a degraded path or clear warning when a soft dependency is absent.
Isolate NMS, packet, reflection, and custom fork calls behind adapters or utility classes.
Check the target Minecraft version before adding APIs that do not exist on that server line.
Review checklist
Before finishing changes to persistent progression code, verify:
profile mutations happen through the intended service or domain method
durable and runtime fields are not accidentally mixed during serialization
custom events fire once and on the correct thread
perk, buff, quest, or event modules have stable internal names
duplicate modules cannot silently overwrite each other
economy and progression changes update UI and dirty-save state consistently
optional dependencies are checked before use
scheduled global events clean up boss bars, tasks, and active state
Requirements and compatibility
Written for: GitHub Copilot
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- First committed by
zixuanjiang332
- Publisher
- GitHub (Official)
- Distributed by
- GitHub
- Source
- github/awesome-copilot · skills/minecraft-plugin-development · commit 797337f
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- zixuanjiang332
AutoGineer is not affiliated with or endorsed by zixuanjiang332 or GitHub.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download minecraft-plugin-development.zip