Configuration Files
Detailed specifications of variables and settings inside the plugin configuration files.
Main Configuration File (config.yml)
Located at plugins/ShyamDuels/config.yml. This file manages module toggles, world structures, command limitations, and party and duel matchmaking metrics.
Module Toggles
Disable specific sub-modules server-wide:
yamlLicense: "" # BuiltByBit license key (injected at build time)
debug: false # Verbose display/logging output
server:
name: Practice Server # Shown in messages and display configs
modules:
queue: true
ffa: true
party: true
spectate: true
friends: true
duels: true
custom-kits: true
killstreaks: true
auto-gg: true
action-bar: true
tab-list: true
scoreboard: true
practice-kit-editor: true
practice-duel-command: true
practice-right-click-duel: true
practice-death-messages: true
practice-golden-head: true
practice-totem-practice: true
armor-trimmer: true
enchant-table: true
shield-customizer: true
kit-editor-armor-trimmer: true
kit-room-shulker-editor: true
See Practice Features Country Flags for practice module details.
World and Arena Configurations
yamlarenas:
world: Arenas # Base void world; clone worlds become Arenas1, Arenas2, …
difficulty: HARD # Applied to base + clone worlds (HARD for crystal/anchor damage)
cloning: 0 # Extra world copies for duel capacity (0 = off; FFA never cloned)
reset-clones-on-startup: true # Delete and re-clone Arenas1/2/… from base world each boot
reset-on-startup: true # Sanitize the base arena world and FAWE-reset template arenas on boot
build-height-limit-offset: 2 # Height allowance above the arena top where placing blocks is still allowed
reset-queue:
max-concurrent: 3 # Max simultaneous FAWE arena restorations
ffa-one-at-a-time: true # Only one FFA reset at a time (duel resets unaffected)
clear-entities-on-startup: true # Remove dropped items/non-player entities in loaded worlds
sanitize-clone-worlds: true # Strip entity data from copied world folders
gamerules: # Applied to base + clone worlds on startup/load (all optional)
daylight-cycle: false # freeze the time of day
weather-cycle: false # freeze the weather
mob-spawning: false # doMobSpawning (passive)
monster-spawning: false # hostile monsters
mob-griefing: false # mobGriefing
show-advancement-messages: false
locator-bar: false # player locator HUD
show-death-messages: false
natural-regeneration: true
spawn-phantoms: false
spawn-patrols: false
spawn-wandering-traders: false
spawn-wardens: false
raids: false # false = raids disabled
random-tick-speed: 0 # stop block/crop ticking
fire-spread: 0 # no fire spread
See the Arena Setup: Arena Cloning guide for how cloning works. Build template arenas only in the base Arenas world, not in Arenas1, Arenas2, or other auto-generated clone worlds.
Lobby World Protection
The lobby location and optional world protection are configured under lobby:. When
protect-world is enabled, the plugin disables PvP, mob spawning, mob griefing, and
freezes time/weather in the lobby world via gamerules, applied on startup and whenever the
lobby world loads. adventure-mode puts players into Adventure mode whenever they are
sent to spawn (admins with shyamduels.admin.bypass and Creative/Spectator players are
left untouched).
yamllobby:
world: spawn
x: 0.0
# ... y, z, yaw, pitch ...
adventure-mode: true # Force Adventure mode in the lobby
protect-world: true # Apply the protective gamerules below to the lobby world
gamerules: # Each value is optional and falls back to the shown default
mob-spawning: false # doMobSpawning (passive)
monster-spawning: false # hostile monsters
mob-griefing: false # mobGriefing
daylight-cycle: false # freeze the time of day
weather-cycle: false # freeze the weather
show-death-messages: false
random-tick-speed: 0 # stop block/crop ticking
Enabled Worlds
Restrict certain features to specific lobby/world names:
yamlenabled-worlds:
kit-editor:
- spawn # Worlds where /kiteditor is allowed
right-click-duel:
- spawn # Worlds where right-click player interaction is active
Command Restrictions
Configure command rules inside matches to block cheating or bypass attempts:
yamlcommand-restrictions:
allowed: # Always permitted (plus admin bypass)
- leave
- leavefight
- spawn
- spectate
in-party: # Blocked while in a party lobby
- kiteditor
- duel
- ffa
- spectate
in-match-global: # Blocked during any active match
- kiteditor
- duel
- queue
- play
- ffa
- party
in-duel:
mode: block-all
commands: []
in-ffa:
mode: block-all
commands: []
in-spectate:
mode: block-all
commands: []
Queue and Duels
yamlqueue:
multiple-kits: true # Allow queuing multiple kits at once
max-multiple-kits: 3 # Max kits queued at once (minimum 1; values <1 clamp to 1; needs multiple-kits)
random-queue-enabled: true # Random kit queue option
override-conflicting-commands: true # Reroute /queue to ShyamDuels over other plugins
modes: # Disable individual queue sizes
1v1: true
2v2: true
3v3: true
4v4: true
match-found-animation:
enabled: true
blindness: true # Apply blindness for the duration of the match-found animation
blindness-duration-ticks: 200 # Safety cap (removed early by animation callback; should exceed animation length)
totem-pop: true # Client totem-pop on match start (bundles item overlay + particles + sound)
totem-sound: false # false suppresses the local vanilla pop sound; custom sound below can replace it
sound: "" # Optional extra sound key; empty = no sound
sound-volume: 1.0
sound-pitch: 1.2
fallback-item: DIAMOND_SWORD # Item model shown in the pop when a kit has no icon (totem-pop only)
indicator:
enabled: true
height-offset: 1.15 # Vertical offset above nametag passenger mount
scale: 0.60 # ItemDisplay scale (0.60 balanced with nametag)
rotation-speed-ticks: 5 # Ticks per 45° step (5 = 2s per full rotation)
billboard: FIXED # FIXED (world-space), VERTICAL, or CENTER
show-to-self: false # Show indicator to the queued player in F5
duels:
invite-expiration: 60 # Seconds before duel invites expire
invite-resend-cooldown: 10 # Seconds before the same sender can re-invite the same player (0 disables)
start-countdown: 5 # Countdown before round starts
round-system: BEST_OF # BEST_OF (majority of rounds) or FIRST_TO (exact win count)
end-commands: [] # Console commands run when a duel ends
leavefight:
delay: 1 # Teleport delay in seconds after /leavefight (0 disables the delay)
spawn:
delay: 1 # Teleport delay for /spawn (falls back to leavefight.delay)
Arena World Borders
Per-player, client-side red borders drawn around arenas during duels, FFA, and spectating. They are sent as packets and never modify the real server world border. See Arena Setup: Fake World Borders for the full explanation.
yamlworld-border:
enabled: true # Master switch; false sends no arena borders at all
padding: 0.0 # Extra blocks on every side (0.0 hugs the corner blocks exactly)
warning-blocks: 0 # Red "approaching border" overlay distance in blocks (0 = off)
warning-time: 0 # Red warning overlay duration in seconds (0 = off)
world-border-shrink:
enabled: false # Timed per-duel border shrink (PacketWorldBorderManager + MatchBorderShrinkSession)
kits: ["*"] # Kit filter ("*" = all kits)
interval: 1m # Shrink step interval (ms/s/m/h/d/t units, bare number = seconds)
shrink:
blocks-per-interval: 10.0
duration: null # Optional lerp duration (same units); null = instant step
minimum-distance-from-center: 5.0 # Minimum radius; minimum diameter = 2x this value
damage:
enabled: true
amount: 2.0
interval: 1s
buffer-blocks: 0.0
Advancements
Challenge/achievement subsystem (AdvancementManager, 36 trigger types). Full key reference lives in advancement.yml - settings, defaults, per-category tabs, per-advancement triggers/conditions/rewards. See the Advancements guide for every key, all trigger and condition types, and a step-by-step example. Key commands: /advancements (aliases /adv, /achievements, /sdadv), admin grant/revoke/reset/resetall/reload (shyamduels.advancements.admin). Event: AdvancementGrantEvent (see Events Reference). Persistence: player_advancements table.
GUI Mode (Normal vs Dialog)
Menu routing is controlled by gui.mode in config.yml (NORMAL = FastInv inventories, DIALOG = Paper 1.21.7+ dialogs from dialog-menus/*.yml, 57 files). Dialog clicks are debounced (150ms) with single-use 5-minute callbacks.
Friends
yamlfriends:
# How long a pending friend request stays valid before it is auto-removed, in seconds.
# Set to 0 (or negative) to disable expiry and keep requests forever.
request-expiry-seconds: 300
Expired requests are cleaned up by a background task and also pruned whenever a player's
requests are read, so a request disappears once request-expiry-seconds has passed.
Party, FFA, and Match Start
yamlparty:
default-max-size: 8
create-permission: shyamduels.party.create # Permission required to run /party create
public-permission: shyamduels.party.public # Permission required to switch a party to public
min-member-limit: 2
broadcast-cooldown:
enabled: true
seconds: 30
member-limit-input: sign # chat, sign, or auto
size-permission-prefix: shyamduels.party.size.
size-permissions:
shyamduels.vip: 16
shyamduels.vipplus: 32
invite-expiration: 60
transfer-ownership-on-leave: true # Present but currently unused; ownership always transfers
announce-format: "<#FF780C>[Party Announcement]#FF780C> {owner} : <#FFFA45>{message}#FFFA45>"
external-commands: # Route /party queue|ffa to other commands
enabled: true
subcommands:
queue:
require-in-party: true
require-owner: true
commands:
- "player:queue"
ffa:
require-in-party: false
commands:
- "player:ffa"
party-chat:
format: "7FFFF[Party] FFFFFF{player}: AAAAAA{message}"
party-ffa:
spawn-circle-radius: 4.0
ffa:
reset-interval-seconds: 1800
use-match-start-options: true
skip-countdown: false
countdown-seconds: [5, 4, 3, 2, 1]
random-spawn:
enabled: false
max-attempts: 40 # Columns to test before falling back to configured spawn
match-chat:
default-enabled: true # Default state of the Global Chat in Matches player setting
isolate-match-chat: false # Force match chat to duel/FFA participants and spectators
kill-regen:
enabled: true # Global master toggle
duels: true # 1v1 duels
team-battle: true # Team queue duels
party-vs-party: true
party-split: true
party-ffa: true
ffa: true # Global FFA arenas
match-start:
countdown-seconds: [5, 4, 3, 2, 1]
match-start-potions:
enabled: true
delay_seconds: 1
take-from-inventory: false
blocked-effects: [poison, slowness, weakness, ...]
Configure match-start potion scanning per kit with /kit matchstartpots. When take-from-inventory is false, buffs are splashed without consuming items from player inventories (MMC/MCPVP style). See Kit Setup.
Killstreaks, Messages, and Practice Items
yamlkillstreaks:
enabled: true
broadcast: true
tiers:
- kills: 5
name: "Killing Spree"
- kills: 10
name: "Rampage"
- kills: 15
name: "Dominating"
- kills: 20
name: "Unstoppable"
- kills: 25
name: "Godlike"
death-messages:
enabled: true
customizable: true
kill-commands: # Run commands on kills (rank-based rewards)
enabled: false
attacker: []
victim: []
ranks: {}
auto-gg:
enabled: true
delay-seconds: 2
default-enabled: true # Default Auto GG state before a player changes it
combat:
anti-death-drops: true # Prevent item drops on death inside matches
cosmetics:
strip-without-permission:
enabled: true
permission: "shyamduels.cosmetics"
armor-trims: true
banner-patterns: true
action-bar:
enabled: true
interval-ticks: 20
message: "" # MiniMessage; empty = use built-in state message
first-join-commands:
enabled: false
commands: [] # Run once on a player's first join
every-join-commands:
enabled: false
commands: [] # Run on every join
item-names:
kit-selector: "7FFFFSelect a Kit"
arena-selector: "7FFFFSelect an Arena"
golden-head:
cooldown: 3
item:
id: "minecraft:honey_bottle"
texture-url: "https://textures.minecraft.net/texture/..."
texture-value: "<base64 texture value>"
display-name: "..."
lore: [...]
effects:
- "ABSORPTION:120:1:true:false"
- "REGENERATION:8:2:true:false"
- "SPEED:15:1:true:false"
particles:
enabled: true
consume-particles: [...]
advanced:
drop-if-full: true
remove-existing-effects: true
action-bar-countdown: true
consume-duration: 1.6
max-stack-size: 16
prevent-stacking: false
totem-practice:
command: "totempractice" # Root command name registered by practice module
gui: { title, size }
practice: { score_reset_duration, max_misses }
titles: { exit: { fadeIn, stay, fadeOut } }
door-animation:
enabled: true
animation_ticks: 20
fence_material: "OAK_FENCE"
kits: [] # Empty = all duel kits use gates when they have them
gate:
close_delay_seconds: 3
eject_check_radius: 10
open_speed_ticks: 20
close_speed_ticks: 20
debug: false
ready_up:
enabled: true
prompt: "FF780C&l⚡ FFFA45Hit the gate to ready up!"
player_ready: "%F699✔ %F699{player} is ready!"
all_ready: "7FFFF&l⚡ 7FFFFAll players ready! Opening gates!"
large_party_threshold: 10
large_party_actionbar: "%F699✔ &f{player} &7is ready &8({ready}/{total})"
large_party_bar: "%F699✔ Ready: &f{ready}&7/&f{total}"
bedfight:
enabled: true
kits: [bedfight, bedwars] # On enable these kits get their kits.db bedwars_enabled flag set
bed-break-commands: [] # Console commands run on bed break (%player%, %team%, %enemyTeam%)
void-buffer: 5.0
void-fallback-offset: 10
void-fallback-y: 0
respawn-countdown-time: 3
fireball:
velocity: 1.0
lifetime-seconds: 5
cooldown-seconds: 2
knockback: { radius: {x: 6, y: 4, z: 6}, multiplier: 2.09, y-force: 0.805 }
tnt:
auto-ignite: true
fuse-ticks: 80
knockback: { radius: {x: 7, y: 4, z: 7}, multiplier: 1.87, y-force: 0.69 }
bridge:
enabled: true
void-buffer: 2.0
respawn-countdown-time: 3
lock-to-spawn-during-countdown: true
spawn-cage: true
instant-golden-apples: false # Reserved flag (no reader outside BridgeConfig; verify wiring before relying on it)
bow-cooldown-seconds: 4.0
# Note: unlike bedfight, Bridge has no bridge.kits list. A duel becomes a Bridge
# duel only when the kit has Bridge mode enabled (Kit.bridgeEnabled).
Shulker Lore Previews
Packet-based shulker-box content previews (sprite lore on hover). Requires PacketEvents, Minecraft 1.21.9+ (protocol 773+), and non-Bedrock clients. Players toggle it with /shulkerlore or the SHULKER_LORE setting in /settings (see Player Settings).
yamlshulker-lore:
enabled: true # Master switch for the preview system
default-enabled: true # Default per-player toggle state
line-format: "<sprites>" # Line template (<sprites> is replaced by the item row)
separator: " " # Separator between sprites on one line
max-sprites-per-line: 9 # Sprites per lore line (1-9, 27 slots total over 3 rows)
lore-position: BOTTOM # BOTTOM or TOP (where preview lines are inserted)
header: "" # Optional line above the preview
footer: "" # Optional line below the preview
white-sprite: true # Use white sprite variant
empty-slot: "<dark_gray>?</dark_gray>" # Placeholder for empty slots
sprite-overrides: {} # Per-material sprite replacements
potion-colors: {} # Per-potion color overrides (default water: #385DC6)
custom-kits:
enabled: true
base-kit-name: custom
default-unlocked-kits: 3
hide-from-public-menus: false
play-others-gui:
enabled: true
show-when-hosted-at-least: 1
auto-join-when-single: false
right-click:
enabled: true
# What right-clicking another player does:
# profile -> open the player profile GUI (stats, public kits, send duel) [default]
# command -> run the commands listed below (legacy behaviour)
action: profile
commands:
- "duel %clicked_player%"
# Kit sharing & player profiles
kit-sharing:
# Default value of each player's "Share Edited Kits" setting before they change it
default-enabled: false
# Strip rank-gated cosmetics (trims, banners) from imported kits when the importer lacks the
# cosmetics.strip-without-permission.permission, so sharing can't hand out paid cosmetics
strip-cosmetics-on-import: true
# Cooldown (seconds) between successful kit imports per player (0 = off; anti shift-click spam)
import-cooldown-seconds: 30
When action: profile, right-clicking opens the configurable Player Profile GUI
(menus/profile.yml) instead of running a command. Worlds are controlled by
enabled-worlds.right-click-duel. See
Kit Sharing & Profiles for the full system.
golden-head.item.id set to minecraft:honey_bottle to retain the intended consumable behaviour. The Golden Head appearance is supplied by item.texture-value; item.texture-url is optional reference data.
Golden head, totem practice, and door animation are toggled via modules.*, not separate enabled keys on those sections.
Tab List and Scoreboard
Tab headers/footers and scoreboard layouts are configured in separate files:
plugins/ShyamDuels/tab/display.yml- tab list header, footer, and name formatsplugins/ShyamDuels/tab/scoreboard.yml- in-match and lobby scoreboardsplugins/ShyamDuels/tab/animations.yml- scrolling tab animations
Reload tab config with /tab reload. Players toggle tab/scoreboard visibility in /settings.
In tab/scoreboard.yml, scoreboard.async-placeholders: true (default) resolves PlaceholderAPI off the main thread for performance. Set it to false only if a PlaceholderAPI expansion you use is not thread-safe and errors on the scoreboard.
Other tab/scoreboard.yml keys: scoreboard.update-time, scoreboard.lobby-update-time, scoreboard.max-updates-per-tick, scoreboard.title, scoreboard.disabled-worlds, scoreboard.teleport-update, scoreboard.party-addition, scoreboard.enderpearl-cooldown-*. Add a <mode> section in tab/scoreboard.yml for custom scoreboard modes. Tab keys: tablist.ping-source, tablist.player-sorting, sort-ranks.*, default-player-format, golden-head.item.id, titles.* (title animations), heads.* (head cache).
Tab sort ranks in tab/display.yml use LuckPerms permissions for prefix priority: group.owner, shyamduels.tab.admin, shyamduels.tab.staff, shyamduels.tab.vip.
Nametags and Below-Name Health System
Nametags and above-head health displays are configured in tab/display.yml under nametags: and belowname-objective:.
ShyamDuels v2.0+ supports both modern background-free TextDisplay entities (1.19.4+) and legacy vanilla scoreboard teams:
yaml# tab/display.yml
nametags:
enabled: true
# Display mode:
# text-display -> Modern (1.19.4+), background-free nametags with crisp text drop shadows (Recommended)
# scoreboard -> Classic vanilla scoreboard teams (has client-side dark translucent background)
mode: text-display
# Settings for text-display mode:
# background-color: 'transparent' (no background box), or hex '#RRGGBB' / '#AARRGGBB', or 'default'
background-color: transparent
# Enables crisp text drop shadows for contrast against all blocks and skies
text-shadow: true
# Vertical offset above player's head (default: 0.25)
height-offset: 0.25
# Whether nametag is visible through solid blocks
see-through: false
# Text before player name above head
tagprefix: '%luckperms_prefix%'
tagsuffix: ''
collision: never
respect-npcs: true
belowname-objective:
enabled: true
# In text-display mode, this is automatically merged as Line 2 of the background-free display
fancy-value: '<#FFFA45>%shyamduels_rank% &r» <#FF780C>%shyamduels_elo% ELO'
per-world:
Arenas:
fancy-value: '<#FF1D54>❤ %player_health_rounded% | <#FFFA45>❤ %player_golden_health%'
value: '%player_health_rounded%'
In arena worlds the red heart is real HP. After a golden apple or golden head, absorption is shown as a gold heart (for example ❤ 18.0 | ❤ 4.0). Both values are shown to one decimal place. The gold half is omitted when absorption is 0. %player_health_rounded% is HP only; %player_golden_health% is the absorption number.
Highlights of TextDisplay Mode:
- Background-Free: Removes the dark rectangular background box rendered by vanilla Minecraft clients.
- Multi-line Integration: Combines player rank/prefix/name and below-name health (
❤ 21.8) in a single unified display. - Client-Side Interpolation: Passenger mounting ensures 0-jitter, 100% smooth positioning matching client FPS.
- First-Person Protection: Automatically hidden from the player themselves to keep the 1st-person screen clear during combat.
GUI Menus and Item Configs
All player-facing menus live under plugins/ShyamDuels/menus/:
duel.yml,queue-kit.yml,ffa.yml,spectate.yml(note: there is nomenus/queue.yml- the/queuepicker runs onGuiConfigLoaderfallbacks;queue.ymlonly exists underdialog-menus/)profile.yml,public-kits.yml,kit-preview.yml(player profile & kit sharing; note: there is nomenus/profile-stats.yml- that file only exists underdialog-menus/)kiteditor.yml,kitroom.yml,kitroom_items.ymlparty-gui.yml,party-manage.yml,party-settings.yml,party-signgui.ymlplayer-settings.ymlarmor_trimmer.yml,shield_customizer.yml,shulker_editor.yml,enchant_table.ymlcustomkits-*.yml(selector, editor, category, settings, armor selection, enchantment, signgui)
Lobby hotbar items and the post-duel rematch button: items/spawn-items.yml. Party and queue hotbar items: items/party-items.yml, items/queue-items.yml.
yaml# items/spawn-items.yml
rematch:
enabled: true # Allow rematch after duels
duration-seconds: 5 # How long the rematch item stays in hotbar
slot: 5 # Hotbar slot (0-8)
material: EMERALD
name: "&a&lREMATCH"
lore:
- " &fQuick rematch vs &e{opponent}"
- " &7Kit: &b{kit}"
items:
queue:
slot: 0
material: DIAMOND_SWORD
name: "&b&lRANKED QUEUE"
commands: ["player:queue"]
Rematch lore supports {opponent} and {kit} placeholders. Reload item configs with /shyamduels reload-items.
Kit and FFA GUI order/icons: data/order.yml. Kit categories: categories/<id>.yml (per-category files, legacy categories.yml supported). Custom kit editor categories: data/customkits/categories.json (runtime, managed by CategoryDataManager).
Custom Item Icons (Custom Model Data & Nexo)
Every item entry in a menu or item config supports two optional fields for swapping the vanilla
icon for a resource-pack model or a Nexo custom item. Both sit alongside the normal
material, name and lore keys:
yamlsome-item:
slot: 11
material: DIAMOND_SWORD
# Optional custom icon (pick one):
custom-model-data: 1001 # Applies a CustomModelData value to the vanilla material
# nexo: my_custom_icon # OR pull the icon (and its model) from a Nexo item id
name: "&b&lRANKED QUEUE"
lore:
- "&7Click to queue"
Custom Model Data
custom-model-data: <int> stamps a CustomModelData value onto the configured
material, so a resource pack can render a custom texture/model for that slot. It is only
applied when the value is greater than 0; leave it out (or set 0) to keep
the default look. The material must still be a valid Minecraft item.
Item Model
On modern Paper versions, item-model: <namespace:key> applies Minecraft's Item Model component to a vanilla material. This is useful when a resource pack supplies a model without relying on CustomModelData:
yamlsome-item:
material: HONEY_BOTTLE
item-model: "minecraft:player_head"
The item remains the configured material; the model changes only its appearance.
Nexo Items
Nexo is an optional soft-dependency. When it is installed, you can render any Nexo custom item as a menu icon using either form:
yaml# Explicit field:
nexo: my_custom_icon
# Or as a material shorthand:
material: "nexo:my_custom_icon"
The Nexo item id (with its own model) takes priority. If Nexo is not installed, or
the id does not exist, ShyamDuels falls back to the vanilla material plus any
custom-model-data, so menus never break on servers without Nexo. On startup the console
logs Nexo hook: enabled when the integration is active.
nexo: field or a nexo: material) is resolved first.
Only when no Nexo item is found does the vanilla material + custom-model-data
apply. You don't need Nexo installed to use custom-model-data.
Runtime Data Files
data/arenas.db,data/kits.db,data/stats.db- SQLite databases (paths configurable indatabase.yml)data/complex-door-data/<arena>.yml- Gate definitions per arenadata/customkits/- Saved player custom kit profilesdata/playerdata/- Per-player custom kit slot unlock dataschematics/<ArenaName>.schem- FAWE arena snapshots
Messages (lang/messages.yml)
All in-game chat strings, GUI titles, duel titles, party messages, and help text live in plugins/ShyamDuels/lang/messages.yml. Reload with /shyamduels reload-messages.
Database Connection Settings (database.yml)
Database settings are stored in plugins/ShyamDuels/database.yml as a separate editable file. On startup and when you run /shyamduels reload-config, the plugin merges this file into the runtime config under the database.* prefix (e.g. database.type, database.performance.io-threads). Edit database.yml on disk; you do not need a database: block inside config.yml.
yaml# ==============================================================================
# Database Configuration (plugins/ShyamDuels/database.yml)
# ==============================================================================
type: "SQLITE" # SQLITE or MYSQL
# Performance settings (tuned for big servers: 300+ players)
sqlite:
directory: data
arenas-file: arenas.db # Local SQLite database files
kits-file: kits.db
stats-file: stats.db
mysql:
host: localhost
port: 3306
database: shyamduels
username: root
password: ""
use-ssl: false
maximum-pool-size: 30 # HikariCP max connections (30 with 10 idle recommended for 400-500 CCU)
minimum-idle: 10 # Minimum idle connections kept ready
connection-timeout-ms: 5000 # Max wait for a connection from the pool
max-lifetime-ms: 1800000 # Max lifetime of a pooled connection (30m)
idle-timeout-ms: 600000 # Time an idle connection stays in pool (10m)
# Performance settings (tuned for high CCU servers: 400-500+ players)
performance:
compute-threads: 4 # Scoreboard/Tab diffing & MiniMessage parsing workers (auto: clamp(2,16,cores/2))
io-threads: 8 # DB queries, GeoIP & file I/O workers (auto: clamp(4,32,cores))
auto-detect-threads: true # Auto-detect CPU cores (Pterodactyl/Docker aware) and adjust both pools
autosave-minutes: 5 # Batch-save all online players' stats every N minutes (0 = off).
# Saves everyone in one transaction; limits crash loss to a few minutes.
maximum-pool-size / minimum-idle and
performance.io-threads together so concurrent queries have both connections and worker
threads available. The performance block lives in database.yml and is read under the
database. prefix internally. When auto-detect-threads is true, thread counts are derived from detected cores.
ELO and Ranks Database (ranks.yml)
Manages matchmaking ranges and calculations:
yamlelo:
rank-system: true # Enable rank progressions
enabled: true
custom-kits: false # Award Win/Loss (and ELO) for custom-kit-system fights.
# Official kits (Crystal Sea, Anchor Sea, ...) always count.
match-types: # When false, that match type records neither ELO nor Win/Loss.
duel: true # Kill/Death still update for every finished match.
queue: true
party: false
party-vs-party: false
party-split: false
team-battle: false
party-ffa: false
ffa: false
rematch: false
starting-elo: 1000 # Base ELO rating for new players
min-elo: 0 # Floor a player's ELO can drop to
base-gain: 25 # ELO added on an even-matchup win (default 25 in EloSettings.java)
base-loss: 20 # ELO deducted on an even-matchup loss
kill-gain: 5 # Bonus ELO added per kill
# Opponent-relative (true Elo) scaling. Beating a much weaker opponent gives almost nothing;
# beating a stronger one gives more. Set false for flat base-gain / base-loss.
opponent-based: true
min-gain: 1 # Floor for a win (token amount vs far-weaker players)
max-gain: 40 # Cap for a win (vs far-stronger players)
min-loss: 1 # Floor for a loss
max-loss: 40 # Cap for a loss (vs far-weaker players / prevents extreme swings)
anti-farm:
enabled: true # Block ELO farming exploits
cooldown-hours: 2 # Cooldown before the same opponent yields ELO again
max-wins-per-opponent: 5 # Max wins against the same player in cooldown period
block-same-ip: true # Block ELO gains between matching IP addresses
progress-bar: # %shyamduels_elo_bar% / %shyamduels_elo_progressbar%
length: 10
completed-symbol: "|"
uncompleted-symbol: "|"
completed-color: "<#00FF88>"
uncompleted-color: "<#555555>"
Each rank under elo.ranks.* defines name, a colored display
tag, an ELO range (min-elo/max-elo) and a loss-multiplier.
See ELO & Ranks for the full ladder.
Country Flags & Player Heads Cache
Country display powers /countryflags, tab/nametag flag prefixes, and the
%shyamduels_country* placeholders (see the Country Flags guide for
the full list of supported countries). It resolves player countries from a MaxMind
GeoLite2-Country database:
yamlcountry:
enabled: true # Master toggle for the country feature
update-on-join: true # Re-check MaxMind on join; persists only when the ISO code changed.
# Manual /country flag selections are never overwritten.
maxmind:
database: "GeoLite2-Country.mmdb" # Local file (plugin data folder unless absolute)
auto-download: true # Download the database automatically when missing/expired
download-url: "https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb"
The player's real client IP is taken from Paper's connection address (works behind Velocity/Bungee
when Velocity modern forwarding is configured correctly); otherwise it falls back to
Player#getAddress(). Without correct proxy forwarding, MaxMind may resolve the proxy
host's country instead of the player's.
Player head textures (used by tab lists, scoreboards, and bracket GUIs) are cached with optional Mojang refresh:
yamlheads:
mojang-enabled: true # Query Mojang for skin textures
mojang-interval-ms: 1400 # Rate limit between Mojang requests
http-timeout-ms: 1500
positive-ttl-ms: 2592000000 # Successful lookups cached for ~30 days
failure-ttl-ms: 900000 # Failed lookups retried after ~15 minutes
max-entries: 20000 # In-memory cache ceiling
disk-save-debounce-ms: 5000 # Debounce for flushing the disk cache
External Plugin Compatibility
Settings for compatibility with third-party external plugins (such as cosmetic or kill effects plugins):
yamlcompatibility:
# If enabled, ShyamDuels will fire a fake PlayerDeathEvent during virtual deaths.
# This allows third-party cosmetic/kill-effects plugins that only listen to the
# vanilla death event to work seamlessly during virtual duel eliminations.
fire-fake-death-event: true
Sound Effects Library (sounds.yml)
Maps custom sounds to events, grouped by category (e.g. match-start, duel,
queue, party, gui, kiteditor, custom-kits).
Each entry has an enabled toggle plus a sound, volume and
pitch. Supports standard Minecraft sound keys (e.g. BLOCK_NOTE_BLOCK_PLING):
yamlmatch-start:
countdown:
enabled: true
sound: "BLOCK_NOTE_BLOCK_PLING"
volume: 1.0
pitch: 1.0
fight:
enabled: true
sound: "ENTITY_ENDER_DRAGON_GROWL"
volume: 1.0
pitch: 1.5
duel:
invite:
enabled: true
sound: "ENTITY_EXPERIENCE_ORB_PICKUP"
volume: 0.8
pitch: 1.2
match-result:
match-win:
enabled: true
sound: "UI_TOAST_CHALLENGE_COMPLETE"
volume: 1.0
pitch: 1.0
Set enabled: false on any entry to mute just that event.
Kit Categories Configuration (categories/*.yml)
Categories are organized in dedicated files inside plugins/ShyamDuels/categories/<id>.yml (e.g. potpvp.yml, sword.yml). Starts empty by default:
yaml# ==============================================================================
# Category Configuration: potpvp.yml (plugins/ShyamDuels/categories/potpvp.yml)
# ==============================================================================
id: "potpvp"
display-name: "<gradient:#FF1D54:#FF7B00><b>PotPvP Modes</b></gradient>"
slot: 11 # Slot in parent selection GUI (-1 for auto)
icon:
material: SPLASH_POTION
custom-model-data: 1001
# nexo: "potpvp_icon"
# item-model: "minecraft:custom_potion"
lore:
- "&7Competitive potion fighting modes."
- ""
- "&fKits Included: &e<kits_count>"
- "&fQueued: &a<queued> &7| &fPlaying: &b<playing>"
- ""
- "&eClick to browse category kits!"
kits:
- "NoDebuff"
- "Debuff"
- "Gapple"
# Optional Sub-Menu Layout Overrides:
sub-menu:
title: "<gradient:#FF1D54:#FF7B00>PotPvP Queue</gradient> &8| &7<mode>"
size: 54
border: RED_STAINED_GLASS_PANE
kit-slots:
- 10
- 11
- 12
- 13
- 14
- 15
- 16
Tournament Configuration (tournament.yml)
Located at plugins/ShyamDuels/tournament.yml. Controls automated bracket tournaments, match timers, scheduler persistence across restarts, non-strict wave arena scheduling, custom spectator rules, and prize distributions.
yaml# Master toggle (shipped default: 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"
kit:
default-kit: "Nethpot"
random-kit: false
kit-pool:
- "axe"
- "crystal"
- "BuildUHC"
match:
time-limit: "5m"
timeout-behavior: "DISQUALIFY_BOTH" # "DISQUALIFY_BOTH", "HIGHEST_HEALTH", "RANDOM_WINNER"
rounds: 1
round-system: "BEST_OF"
affect-elo: false
record-stats: false
arenas:
reserve-before: "5m"
strict-mode: false
force-reserve: true
minimum-required: 1
spectator:
enabled: true
auto-spectate-on-elimination: false
auto-spectate-waiting-players: false
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"