EventPractice is a full-scale practice infrastructure plugin. The local source checkout is version 2.6.9, compiles with Java 21 bytecode release, and references Paper API 26.3 build 211. Its plugin descriptor declares API baseline 1.21, requires WorldEdit and declares Folia support. These source metadata do not establish the exact Minecraft server releases supported by a published binary. Core systems include WorldEdit-based automatic arena cloning, menu-based player events, unranked/ranked queue with live occupancy badges, per-mode ELO, shared/private FFA, TrainingBot bot duels, lobby spawn management, personal kits and kitroom, ticket economy, kill cosmetics, visual replay and SQLite/MySQL storage. This documentation walks you through setting up every system from scratch.
A complete PvP backbone plugin that delivers practice, duel, ranked queue, FFA, player-run events, bot training and match replay inside a single plugin. Beyond the classic "admin starts an event" flow, it is a player self-service combat hub.
Practice servers, PvP event servers, duel/ranked servers, KitPvP/FFA networks and TrainingBot-powered training servers; also modern Paper plugin packages distributed as premium resources.
The plugin descriptor declares api-version: 1.21 and folia-supported: true. The POM references Paper API 26.3 build 211, and the source contains a Folia scheduler adapter. Confirm exact server-version compatibility against the release binary.
Steps to place the plugin jar on the server. Installation makes the plugin boot; the First Setup section prepares it for production.
Do not replace plugin jars while the server is running. Always back up the EventPractice folder and database before updating.
Upload WorldEdit to the /plugins folder.EventPractice hard-depends on WorldEdit via depend: [WorldEdit] in plugin.yml. Without WorldEdit, EventPractice will not start and you will see a dependency warning in console.
Upload the EventPractice jar to /plugins.You can also install optional hooks at this stage: TrainingBot (bot duel), Citizens (replay NPC visuals), packetevents (team glow), PlaceholderAPI (placeholders).
Start the server once.The plugin folder is created under plugins/EventPractice/ and config.yml, messages.yml, match-modes.yml, kitroom.yml, kits.yml, arenas.yml, kill-cosmetics.yml, scoreboard.yml, tablist.yml and the menus/ files are generated automatically.
Enter the license key into license-key in config.yml.If the license is invalid the plugin stops safely before starting its core systems; database, queue and replay modules never end up half-initialized.
Choose the storage type.config.yml → database.method is either SQLite (single server, recommended starting point) or MySQL (network/production). Details in the Storage section.
Restart the server and check the enable logs.Verify manager startup lines in console and hook messages such as TrainingBot found. Hooked into BotDeathListener successfully.
Copy the entire plugins/EventPractice/ folder to a backup location (including arenas/*.schem).
Export the SQL database when using SQL storage.
Note plugin version, server version and storage type next to the backup.
Do not use tab characters in YAML files; indent with spaces. Tabs break a YAML file.
Arena commands (/arena save, /arena setspawn1 etc.) write to arenas.yml instantly; no reload is needed for them. Likewise /kitadmin save writes to kits.yml immediately.
The arena system is built on templates (schematics), categories, centers and spawn points. Queue, events, duels and FFA all pull arenas from these categories. No match can start without arenas.
Build arena templates inside the arenas-world world (default Arenasworld) before recording them. Spawn and center coordinates are stored relative to that world.
Template: An admin builds an arena once and records it as a WorldEdit schematic with /arena save (plugins/EventPractice/arenas/<category>.schem).
Cloning: When queue/duel/event needs an arena, the system pastes the template into a free spot inside Arenasworld; hundreds of matches on the same category run in parallel without ever mixing.
Category: Each match mode pulls arenas from the categories listed in its arena-category list. CrystalPvP and NetheritePot can use separate arena pools.
Auto-assignment: A newly registered category is automatically added to every match mode that has no categories yet.
Removes the category, schematic file and pool records
eventpractice.arena.remove
Step by step: registering your first arena standard setup
Go to Arenasworld. Teleport to the Arenasworld world from console or with a teleport plugin. If the world does not exist yet, the plugin creates it as a void world during the first arena operation; still make sure the world exists before building.
Build the arena. Create the floor, decoration and spawn platforms inside this world. You will stand near the center of the template.
Stand at the center and save:
/arena save crystal 60
This command takes your location as the center and saves the whole region (60-block radius on x/z, full height from Y -64 to 256) as arenas/crystal.schem. The category center is set at the same time, and the category is auto-added to every match mode that has no categories.
Set the duel spawn points. Spawn locations on a cloned arena are computed as offsets from the template's recorded positions, so record them from within the template itself:
/arena setspawn1 crystal # run while standing on player 1's spot
/arena setspawn2 crystal # run while standing on player 2's spot
(Optional) Add breakable blocks. Hold the block item in your hand (e.g. OBSIDIAN) and run:
/arena addblock crystal
The block type is appended to the breakable-blocks list in arenas.yml; only listed blocks can be broken during matches.
(Optional) Assign a menu icon. Hold the icon item and run:
/arena seticon crystal
Pregenerate the pool. Keep spare arenas ready so the first queue match starts instantly during busy hours:
/arena pregen crystal 3
The command sends a progress message every second (percentage, completed/total, elapsed time) and a completion message once all pastes finish.
Verify:
/arena list
The output shows category, arena id, state (e.g. GENERATING/AVAILABLE) and owner info.
The radius defines the template coverage. 30-50 is typical for small flat arenas, 60-100 for large build arenas. A very large radius increases paste time and disk usage.
Step by step: category-based arena pools mode-specific arenas
Register a template per PvP type with separate categories: /arena save crystal 60, /arena save netheritepot 40, /arena save builduhc 80 etc.
Write the categories into each mode's arena-category list in match-modes.yml:
Start a match from the mode's queue menu and confirm the arena comes from the correct pool.
Empty list behavior
Leaving arena-category: [] makes the mode use every registered category (default behavior). Keep the list empty if you do not want to narrow the pool.
Spawn offsets
On a cloned arena, spawn1/spawn2 are recomputed from the x offset between the recorded positions and the center; therefore record spawns at their real positions inside the template instead of mirroring them around the center.
Step by step: deleting and re-recording arenas updating templates
To remove a category completely:
/arena remove crystal
This deletes the arenas/crystal.schem file, the category record in arenas.yml and the persisted pooled instance records together.
To only update a template, do not use remove; fix the build and run /arena save crystal 60 again with the same category name. The schematic file is overwritten.
Re-apply center/spawn points with the same commands afterwards.
Do not change a template while matches are running on that category. Safest approach: wait for matches to finish or update during low traffic.
arenas.yml and Arenasworld world isolation
All arena pastes happen in the config.yml → arenas-world world (default Arenasworld). Your lobby and survival worlds stay clean of match blocks.
# config.yml
arenas-world: "Arenasworld"
When the world is missing the plugin creates a void world automatically. To use a different world name, change arenas-world and restart the server.
You do not need to edit arenas.yml by hand; every arena command keeps it up to date. The structure looks roughly like this:
For build-enabled modes, limit the Y levels players can place/break with config.yml → y-coordinate.min/max (default -64 / 256).
World border
World border radius and damage per category/event; players can also adjust them from the event menu. Global bounds live under config.yml → world-border.
There are two kit flows: admin kits (the registered kit content) and player personal kits (their own inventory layout). The Kitroom is the layout editor area.
A match mode without a kit cannot start matches. Every mode's kit: field must point to a registered kit.
Step by step: registering your first kits /kitadmin
Fill your own inventory with the content you want to register (armor included, with the hotbar arrangement — this layout is used when a player has no personal kit).
Save the kit:
/kitadmin save CrystalPvP
The inventory is written to kits.yml instantly and you receive the "Kit has been saved successfully." message.
Check the registered kits:
/kitadmin list
Test the kit by applying it to yourself:
/kitadmin load CrystalPvP
Bind the kit to a match mode. Write the exact kit name into the mode's kit field in match-modes.yml:
modes:
crystalpvp:
kit: "CrystalPvP"
Run /eventpractice reload, start a short match from the queue and confirm the kit arrives correctly.
Kit management commands kitadmin reference
Command
Description
Permission
/kitadmin
Opens the kit management GUI
menu access
/kitadmin save <kit>
Saves your inventory as a kit
eventpractice.kit.admin.save
/kitadmin list
Lists all kits
eventpractice.kit.admin.list
/kitadmin load <kit>
Applies a kit to your inventory
eventpractice.kit.admin.load
/kitadmin seticon <kit>
Makes the held item the kit icon (shown in menus)
eventpractice.kit.admin.seticon
/kitadmin remove <kit>
Deletes the kit and its kits.yml record
eventpractice.kit.admin.remove
Update the match modes that use a kit before deleting it; otherwise those modes cannot give kits.
Editing kitroom categories kitroom.yml
The Kitroom is the editor area where players customize the item layout of their match kit. kitroom.yml defines categories; each category carries a slot-based item list like a chest GUI page. The default file ships with example crystal-pvp, potions and misc categories.
Edit via GUI (recommended): Hold the item you want to register, then
/kitroom edit crystal-pvp
to enter editor mode (permission: eventpractice.kitroom.edit). Slots you place items on are written into kitroom.yml live.
If you prefer manual editing, the kitroom.yml structure is slot → item:
Players open their own editing area with /kitroom (eventpractice.kitroom.use, open to everyone by default). Layout saving is independent of the match flow.
Potion effect syntax
Under potion-effects you provide the effect name, duration (ticks) and amplifier. Tipped arrows and splash potions use the same structure.
Player personal kits /kit and custom layouts
A personal kit lets a player customize hotbar and inventory placement without changing the admin kit's content: which slot potions go to, where the sword sits, pearl/gapple positions are saved per player.
The player opens the personal kit menu with /kit or /k (permission: eventpractice.kit.use).
They pick the kit and rearrange the layout from the menu; the layout is stored permanently in the database (personal-kits storage).
When a match starts, the player's personal layout is applied if they have one; otherwise the admin kit's default layout is given.
Personal kit data is stored in the database, so players keep their layout across logout/login. Remember to migrate the data when switching from SQLite to MySQL.
Full kit flow for a new PvP mode end-to-end example
Arrange the inventory and register it with /kitadmin save BuildUHC.
Set the menu icon with /kitadmin seticon BuildUHC using a held item.
Add the mode to match-modes.yml (using the template in the Match Modes & Queue section) and set kit: "BuildUHC".
If the mode is build-enabled, register an arena category (/arena save builduhc 80) and add it to the arena-category list.
If players should see mode-specific items in the Kitroom, add a category in kitroom.yml.
Reload, enter a test match from the queue, and verify the kit and arena pairing.
A match mode is not just a menu icon; it is an independent PvP profile carrying the kit, arena category, rules, potions, damage multiplier, enderpearl cooldown and bot profile.
The default file ships CrystalPvP, NetheritePot and DiamondPot examples. Adjust them for your server or add new modes.
You can add and edit modes from menus instead of touching YAML.
Command
Description
/queue
Opens the unranked queue menu
/queue add <mode>
Creates a new match mode + queue menu item
/queue edit <mode>
Opens the mode editor (kit, arenas, rules, bot profile)
/queue remove <mode>
Removes the mode
These commands require eventpractice.queue.admin. The queue editor lists TrainingBot profiles when TrainingBot is installed (menus/queue-editor.yml).
Live queue indicator:menus/queue.yml and menus/ranked.yml use main-menu.queue-indicator. The default amount is queued players + 1, so one waiting player appears as 2. Refresh is sync and only sends GUI updates when the amount changes.
Step by step: adding a match mode via YAML match-modes.yml
Open match-modes.yml, copy an existing template under modes: and add a new key (key = mode id, lowercase recommended):
Register the kit (/kitadmin save NoDebuff) and an arena category (/arena save nodebuff 40).
Run /eventpractice reload.
Confirm the new mode appears in the /queue menu and test the kit + arena pairing.
Never rename a mode id; ranked ratings, queue records and bot profiles are bound to it. Instead add a new mode and set the old one to enabled: false.
Step by step: adding a mode via menus /queue add
As an admin run /queue add nodebuff. The command:
creates a new MatchMode record in match-modes.yml,
adds a default PAPER item to menus/queue.yml (queue menus) named &9nodebuff with active players and queue status lore,
syncs the menus automatically.
Open the editor with /queue edit nodebuff and configure the mode: display name, kit, arena categories, rules, border, damage multiplier, enderpearl cooldown and (with TrainingBot) the bot profile.
Once kit and arena are ready, start a test match from the queue menu.
The command fails if a mode with the same name exists ("match mode exists"). Use /queue remove <mode> to delete a mode.
What the match mode rules do rules field
Rule
Effect
ITEM_DROP
Whether players can drop items
ITEM_PICK
Whether players can pick items up
ITEM_DAMAGE
Item damage/breakage simulation
ELYTRA
Allow elytra usage
BUILD
Block place/break (together with y-coordinate limits)
PUBLIC_PLAY
Event open participation
PUBLIC_SPECTATE
Event open spectating
The config.yml → default-game-rules section defines the defaults for rules that are not overridden per mode or event.
The ranked system tracks a separate rating per match mode. Instead of a single global ELO, CrystalPvP ELO and NetheritePot ELO are calculated independently.
Opening ranked queue to players requires eventpractice.ranked.use (open to everyone by default).
Step by step: enabling the ranked system config.yml
Make sure at least one active match mode with kit and arena is ready (previous sections).
Tune the ELO parameters in config.yml:
elo:
default-rating: 1000 # starting score for new players
k-factor: 32 # score change coefficient
minimum-rating: 100 # rating floor
matchmaking:
base-range: 100 # initial search range (+/- ELO)
range-increase: 50 # ELO added per expansion
increase-every-seconds: 10 # expansion interval
Configure the ping-based matchmaking filter:
queue:
ping-range:
enabled: true
default: 60 # player's default ping gap limit (ms)
minimum: 10
maximum: 200
step: 10 # increase/decrease step in the menu
fallback-player-ping: 150 # used when ping cannot be read
Reload. Players pick a mode from the Ranked Queue lobby item or /ranked and enter the queue.
Smart matchmaking
The search starts within a ±100 ELO band; the band widens by +50 every 10 seconds while the player waits. You get fair matches without leaving anyone stuck in queue.
Ping range
Players set their own ping limit from the profile menu (/settings); they will not be matched against opponents beyond that ping gap. This keeps ranked fair on ping.
Bot duel lets players train against bots when no opponent is online. The system hooks into the TrainingBot plugin with a soft-depend; when TrainingBot is absent, bot flows stay safely disabled.
Dependency declaration: plugin.yml → softdepend: [TrainingBot, Citizens, packetevents]. TrainingBot is not mandatory but required for bot duels.
Step by step: bot duel setup TrainingBot + EventPractice
Install TrainingBot. Place the TrainingBot jar into /plugins and configure it according to its own docs (bot behaviors, difficulty levels).
Create a bot profile in TrainingBot. Define global bot profile(s) on the TrainingBot side (difficulty, strafe, potion throwing behavior etc.). The EventPractice queue editor lists these profiles automatically from the TrainingBot API (getGlobalProfileNames).
Start the server and verify the hook. You should see this line in console:
TrainingBot found. Hooked into BotDeathListener successfully.
If the message is missing, TrainingBot may have been loaded after EventPractice or the plugin name differs.
Assign bot profiles to match modes. Write the TrainingBot profile name into the mode's bot-profile field in match-modes.yml:
modes:
netheritepot:
bot-profile: "PotBotMedium"
Customize the bot duel menu. Titles, items and layout are edited in menus/bot-duel.yml.
Test it. Open the menu with /botduel or run /botduel <mode>, pick a mode and start the duel. When the bot dies, the BotDeathListener hook closes the match flow cleanly on the EventPractice side.
A mode with bot-profile: null returns the error "No bot profile defined for this mode." when a bot duel starts. Without TrainingBot installed, all bot commands return "Bot duel system is currently unavailable."
Bot system reference commands and behavior
Item
Detail
Command
/botduel
Permission
eventpractice.bot.use (default: everyone)
Menu
menus/bot-duel.yml
Profile source
TrainingBot global profiles (also listed in the queue editor)
Hook
BotDeathListener - the match ends cleanly on the EventPractice side when the bot dies
Players can create their own events from menus; the ticket system gates event creation behind an economy, and the preset system stores repeating settings.
Player permissions are open to everyone by default (eventpractice.player.create/join/start/invite/ban/spectate). Disable them in your permission plugin if you want to restrict them.
Step by step: ticket economy event creation limits
Set the default ticket amount in config.yml:
default-ticket-amount: 10 # set -1 to disable the ticket system completely
Grant the ticket commands to your staff group with permissions:
Command
Description
Permission
/ticket info <player>
Shows remaining tickets
eventpractice.ticket.info
/ticket add <player> <amount>
Adds tickets
eventpractice.ticket.add
/ticket remove <player> <amount>
Removes tickets
eventpractice.ticket.remove
/ticket set <player> <amount>
Sets the ticket amount directly
eventpractice.ticket.set
To attach tickets to VIP/shop packages, run /ticket add from your purchase flow (or console).
Step by step: the player event flow create → start
A player opens the event menu with the lobby's Create Event item or /event create: kit, participant limit (players.min/max/default), winner count (winner-amount), border radius/damage (world-border), damage multiplier, rules, potions.
Tickets are deducted when the event is created; the system picks a free arena and, while pasting, shows "Event is being created. It may take a few seconds...".
Other players join with /event join <player> or the owner invites them with /event invite <player> (chat message with join button; invite-cooldown prevents spam).
Advertise: /event advertise - throttled by advertise-cooldown (default 60s).
The owner starts the countdown with /event start (countdown-seconds, required-players). The countdown is cancelled if there are not enough players.
Spectating: /event spectate <player>. The owner can remove problem players with /event ban <player>.
In-game controls: /event border <radius> <delay> and /event dropdown <targetY> let the event owner manage the border and Y levels.
Event preset system repeating settings
Players store frequently used event settings as presets (kit, damage multiplier, potions, rules, border). Menu: menus/preset.yml. Data is kept in the event-presets storage area and reached from the /settings profile menu.
Preset flow: profile menu → Event Presets → load an existing preset or save the current setup as a new preset. No more re-entering the same settings for every event.
Finished matches can be watched again visually. The module has three layers — recording, storage and playback — and everything is managed from config.yml → visual-replay.
Replay consumes disk and CPU. Size max-stored, max-frames-per-recording and max-duration to match your server capacity.
The world is created automatically; change the world name if you want your own replay world.
Define storage and cleanup policy:
storage:
directory: replays
retention: 15m # how long recordings are kept
max-stored: 250
max-replay-size-mb: 10.0
cleanup:
enabled: false # set true if you want automatic cleanup
With Citizens installed, replay visuals render through NPCs; otherwise Armor Stand rendering is used with fallback-armorstand: true.
Reload. Finish a match and verify the recording exists with /replay latest; /replay status shows system health.
Active recordings/playbacks, stored files and queue state
Access mode
playback.access.mode: OWN_FIGHTS lets players watch only their own matches; it works together with the eventpractice.replay.use permission. Admin access uses eventpractice.replay.admin.
Camera modes
FREE (flight), FOLLOW (tracking) and POV (player view). Default mode is camera.default-mode, HUD format is playback.hud.format.
The blocks below are short excerpts, not full files. Every YAML file has exactly one job.
Validate YAML indentation before restarting. Tab characters break YAML files.
config.yml main runtime settings
License, color format, database, arena world, core event parameters, ELO, FFA, queue ping range, default game rules, lobby/spawn items and the visual-replay configuration.
A command executed for the match winner; use it to attach a winner reward economy.
match-modes.yml PvP profile definitions
Covered in detail in the Match Modes & Queue section. Each mode carries display-name, kit, arena-category, rules, border, potions, bot-profile and icon. Mode ids (keys) are permanent identifiers.
kitroom.yml item pools and categories
Categories (e.g. crystal-pvp), potions and misc sections carry slot → item definitions. Syntax examples are in the Kit Setup section.
Players pick their message and effect from the Kill Cosmetics screen in the profile menu. The file works together with the menus/kill-cosmetics.yml menu.
file responsibility table which setting lives where
prefix: "&7[&eEvents&7] &r"
already-in-event: "&cYou are already in an event!"
no-arena-found: "&cNo available arena was found! ..."
invite-player: "&aYou have invited &e<player>&a."
replay-recordings-line: "&7- &e#<id> &7- &f<duration>s &7- &f<players>"
Messages use <placeholder> variables (<player>, <id>, <category> etc.).
Some fields like the replay HUD use PlaceholderAPI-style %id% placeholders.
Multi-line messages can be defined as YAML lists (see invited-to-event).
The most common problems and fixes. The first step is always checking console logs and the /eventpractice help output.
Before opening a bug report, note the plugin version, server core/version, Java version, storage type, WorldEdit version and the full stack trace from console.
No registered arena exists or every arena in the category is busy. Follow the Arena Setup section, grow the pool with /arena pregen <category> <amount> and verify the mode's arena-category list contains the right category.
The template or spawn points were recorded incompletely. Re-run /arena save for the template, then run setspawn1 and setspawn2 while standing on the real positions inside the template.
Arena paste time is proportional to the schematic size. Shrink the template radius and keep spare arenas ready with /arena pregen. Paste progress is reported to the player via messages.
Cannot watch replay - "cannot watch a replay while in an event"#
Playback combat lock is on (default). Grant staff eventpractice.bypass.replay-combat-lock or set visual-replay.playback.block-while-in-combat: false.
Lower max-stored, retention and max-replay-size-mb under visual-replay.recording.storage and enable cleanup.enabled: true. Manual cleanup: /replay cleanup.
Confirm config.yml → team-glow: true and that packetevents is installed. Without packetevents the NMS fallback adapter takes over; check console logs if the problem persists.
Run /eventpractice reload; jar, license, database.method and arenas-world changes require a full restart (see the Change Workflow table). SnakeYAML scanner errors usually come from tab characters.
At least 2-3 arenas per category is recommended for healthy queue and duel flow; pre-generated arena copies via /arena pregen can match the simultaneous match count.
The arena paste queue runs sequentially; concurrent events are limited by the arena pool size and server RAM. Replay max-participants (default 16) limits the recording side.
Yes - folia-supported: true with the scheduler adapter infrastructure. Bukkit calls requiring a region thread are routed automatically to the right thread.
No. With Citizens installed you get high-fidelity NPC rendering; without it, Armor Stand rendering is used via fallback-armorstand: true.
I deleted a match mode, what happens to ranked points?#
Ratings are stored under player-ratings per mode id; deleting a mode makes the points bound to that id unreachable. This is why disabling a mode with enabled: false is recommended instead of deleting it.
Recent EventPractice updates that affect daily player and admin workflows.
Keep the generated menu files after updating so the queue indicator settings can be merged safely.
The 2.4.0 notes below are historical. The local source checkout is version 2.6.9, uses Java 21 bytecode, references Paper API build 26.3.211 and enforces JDK 25 or later for Maven validation. Verify published-binary compatibility separately.