Tournament System
Comprehensive automated tournament system featuring single-elimination brackets, persistent countdown timers across reboots, wave arena scheduling, live visual bracket GUIs with auto-pagination, Nexo custom items, and spectator integrations.
The entire tournament feature can be enabled or disabled in tournament.yml via enabled: true/false.
Feature Highlights
- Automatic Periodic Scheduling: Configure tournaments to run every X hours or days (e.g.
interval: "24h"). - Persistent Schedule Across Restarts: If the server reboots with 45 minutes remaining on the countdown, it resumes at 45 minutes rather than resetting.
- Interactive Live Visual Bracket: Dynamic GUI rendering round matchups, player heads, fight statuses, and winners.
- Auto-Pagination: Brackets exceeding 16 players automatically split across pages with previous/next controls.
- Non-Strict Wave Execution: Tournaments can run smoothly even when fewer arenas exist than concurrent matches. Waiting players receive interactive 1-click spectator prompts.
- Full Nexo & CustomModelData Support: Borders, navigation buttons, and overview menu items fully support CustomModelData and Nexo custom items.
- Automated Prize Distribution: Execute custom console commands, send titles, and give rewards to 1st, 2nd, and 3rd place winners.
Commands Reference
| Command | Permission | Description |
|---|---|---|
/tournament or /tourney, /t |
None | Opens the main interactive Tournament Overview GUI (console shows a text summary). |
/tournament join |
None | Joins an open tournament registration. |
/tournament leave |
None | Leaves an open tournament registration. |
/tournament bracket |
None | Opens the visual live bracket viewer. |
/tournament info |
None | Displays current tournament status, kit, round, and remaining players in chat. |
/tournament list |
None | Lists all registered tournament participants. |
/tournament spectate [player] |
None | Spectates a running tournament fight or opens the bracket. |
/tournament start [kit] |
shyamduels.tournament.admin |
Starts registration for a tournament with the specified kit. |
/tournament forcestart |
shyamduels.tournament.admin |
Force starts an active registration immediately without waiting for timer. |
/tournament stop |
shyamduels.tournament.admin |
Cancels the currently active or registering tournament. |
/tournament setkit <kit> |
shyamduels.tournament.admin |
Changes the default or current registration tournament kit. |
/tournament setmin <amount> |
shyamduels.tournament.admin |
Sets the minimum required participants. |
/tournament setmax <amount> |
shyamduels.tournament.admin |
Sets the maximum tournament player capacity. |
/tournament nextmatch |
shyamduels.tournament.admin |
Forces wave execution to launch pending matches into available arenas. |
/tournament skipround |
shyamduels.tournament.admin |
Resolves all pending matches in the active round and advances the bracket. |
/tournament add <player> |
shyamduels.tournament.admin |
Manually adds a player into the tournament. |
/tournament remove <player> |
shyamduels.tournament.admin |
Manually eliminates or removes a player from the tournament. |
/tournament reload |
shyamduels.tournament.admin |
Reloads tournament.yml into memory and restarts schedulers. |
/tournament debug |
shyamduels.tournament.admin |
Outputs internal tournament engine and bracket state diagnostics. |
All tournament admin subcommands accept either shyamduels.tournament.admin or the global shyamduels.admin permission. /tournament stop is aliased as /tournament cancel, and /tournament forcestart as /tournament force-start.
Configuration Overview (tournament.yml)
yaml# Master toggle: disables all tournaments, commands, and schedulers when false
enabled: false
schedule:
enabled: true
interval: "24h"
initial-delay: "30m"
persist-schedule-across-restarts: true
players:
minimum: 4
maximum: 16
require-even: true
odd-player-handling: "BYE" # "BYE", "WAIT", or "CANCEL"
wait-extension-seconds: 60 # Used when odd-player-handling is "WAIT"
kit:
default-kit: "Nethpot"
random-kit: false
kit-pool:
- "axe"
- "cartpvp"
- "crystal"
- "BuildUHC"
match:
time-limit: "5m"
timeout-behavior: "DISQUALIFY_BOTH" # "DISQUALIFY_BOTH" (default/fallback), "HIGHEST_HEALTH", or "RANDOM_WINNER". Any other value falls back to double disqualification.
rounds: 1
round-system: "BEST_OF" # "BEST_OF" (win majority e.g. Best of 3) or "FIRST_TO" (e.g. First to 3 wins)
affect-elo: false
record-stats: false
countdown:
registration-seconds: 120 # Registration countdown when a tournament is announced
match-start-seconds: 5 # Countdown before players can move/fight
round-transition-seconds: 10 # Pause between rounds
broadcast-intervals: [120, 60, 30, 15, 10, 5, 3, 2, 1]
arenas:
reserve-before: "5m"
strict-mode: false
force-reserve: true
minimum-required: 1
rules:
allow-join: true
allow-leave: true
block-parties: true # Players must leave their party to join
block-queues: true # Participants cannot join normal queues or FFA
broadcast-replacements: true # Announce open slots when someone leaves during registration
return-to-previous-location: true
spectator:
enabled: true
# Automatically spectate when eliminated
auto-spectate-on-elimination: false
# Auto-teleport waiting players to spectate the active match (non-strict mode)
# They exit spectator automatically when their own match is ready
auto-spectate-waiting-players: false
# When auto-spectate is false, send a 1-click [CLICK TO SPECTATE] chat prompt
notify-waiting-players: true
rewards:
first-place:
enabled: true
title: "<gradient:#37F699:#55FFFF><bold>CHAMPION!</bold></gradient>"
subtitle: "<gray>You won the <aqua>%kit%</aqua> tournament!</gray>"
commands:
- "eco give %player% 10000"
- "give %player% diamond 10"
# second-place / third-place / participation blocks follow the same layout
# (participation has no title/subtitle, only enabled + commands)
Bracket GUI: Navigation & Pagination
The live bracket viewer GUI supports full Nexo / CustomModelData items and auto-paginates brackets with more than 16 players.
| Key | Default | Description |
|---|---|---|
gui.bracket.back-button.slot |
45 |
Inventory slot for the back button (bottom-left of a 6-row chest). |
gui.bracket.back-button.custom-model-data |
0 |
CustomModelData int applied to the back button item. Set 0 to disable. |
gui.bracket.back-button.nexo |
"" |
Nexo item ID for the back button. Takes priority over material when set. |
gui.bracket.back-button.item-model |
"" |
Vanilla minecraft:item_model component key for the back button (1.21.4+). |
gui.bracket.pagination.previous.slot |
48 |
Slot for the "previous page" arrow (only shown when multiple pages exist). |
gui.bracket.pagination.next.slot |
50 |
Slot for the "next page" arrow. |
gui.bracket.pagination.info.slot |
49 |
Centre slot showing current page / total pages. Supports {page} and {total_pages}. |
For any bracket GUI button: if nexo is non-empty it takes priority; otherwise item-model is applied if set; otherwise the plain material is used. custom-model-data is always applied on top of whichever item is chosen.
Messages: Waiting Player Notification
When spectator.notify-waiting-players is true, waiting participants receive a clickable chat prompt. Customise the text in tournament.yml under messages.waiting-match-running.
| Placeholder | Description |
|---|---|
{player1} |
Name of the first fighter currently in the arena. |
{player2} |
Name of the second fighter currently in the arena. |
{arena} |
Arena name where the current match is taking place. |
PlaceholderAPI Placeholders
| Placeholder | Description | Example Output |
|---|---|---|
%shyamduels_in_tournament% |
Whether the viewer is a participant | true / false |
%shyamduels_tournament_status% |
Current tournament lifecycle state | Waiting, In Progress, Disabled |
%shyamduels_tournament_status_formatted% |
Colored variant of the state | MiniMessage string |
%shyamduels_tournament_kit% |
Selected kit for the tournament | Nethpot |
%shyamduels_tournament_players% |
Current participant count | 8 |
%shyamduels_tournament_min_players% / %shyamduels_tournament_max_players% |
Minimum required / maximum capacity | 4, 16 |
%shyamduels_tournament_round% |
Active round number | 2 |
%shyamduels_tournament_total_rounds% |
Total expected bracket rounds | 4 |
%shyamduels_tournament_remaining_players% |
Non-eliminated players remaining | 5 |
%shyamduels_tournament_participants% |
Comma-separated participant list | Steve, Alex, ... |
%shyamduels_tournament_countdown% |
Registration countdown remaining | 1m 30s |
%shyamduels_tournament_match_time% |
Configured per-match time limit | 5m 00s |
%shyamduels_tournament_champion% |
Crowned tournament champion | Steve |
%shyamduels_tournament_next_auto% |
Time remaining until next automated tournament (Disabled when scheduling off) |
12h 30m 00s |
%shyamduels_tournament_player_status% |
Viewer's participation status | Alive, Fighting, Eliminated, Not Joined |
%shyamduels_tournament_player_wins% / %shyamduels_tournament_player_losses% |
Matches won / lost by the viewing player this tournament | 3, 0 |
%shyamduels_tournament_player_round% |
Rounds survived by the viewer | 2 |
%shyamduels_tournament_arena% / %shyamduels_tournament_match_status% / %shyamduels_tournament_player_opponent% |
Viewer's current match arena / match status / opponent | Arena1, Fighting, Alex |