Configuration File
ArenaPvP's main configuration lives in mods/HaporeLab_ArenaPvP/config.json. It's created automatically on first launch with sensible defaults.
Reloading Configuration
You can reload the configuration without restarting the server:
/arena reload
This reloads config.json and applies changes to language, rating settings, and other global options. Arena templates (from templates/) and inventory presets (from presets/) are also refreshed — new templates and presets become available for the next match.
Global Settings
| Key | Type | Default | Description |
|---|---|---|---|
Version | string | "17" | Config format version (managed automatically, do not edit) |
Language | string | "en" | Plugin language: "en" or "es" |
DebugMode | boolean | false | Enable debug mode (allows single-player arena testing) |
InstancesLimit | integer | 0 | Max concurrent arena instances (0 = unlimited) |
ArenaWorldPrefix | string | "arena_" | Prefix for arena world names |
Visual Effects
| Key | Type | Default | Description |
|---|---|---|---|
ParticleOnDeath | boolean | true | Show particles when a player dies in the arena |
ParticleIds | string[] | ["Teleport", "Lightning:1.5", "MemoryUnlock:1.5"] | Particle effect IDs for death effect (format: "ParticleId" or "ParticleId:scale") |
ActiveRaycast | boolean | true | Show colored particles when looking at another player |
ParticleIdRaycastEnemy | string | "Arena_Raycast_Enemy" | Particle when aiming at an enemy |
ParticleIdRaycastAlly | string | "Arena_Raycast_Ally" | Particle when aiming at an ally |
FriendlyFireOutsideArena | boolean | true | Enable or disable friendly fire outside the arena |
Rating & Matchmaking
| Key | Type | Default | Description |
|---|---|---|---|
MaxRatingDifference | integer | 50 | Max rating gap for matchmaking (0 = no limit) |
MaxRatingDifferenceOverrides | object | {} | Per-category overrides for MaxRatingDifference (see below) |
RatingGainOnWin | integer | 25 | Rating earned per victory |
RatingLossOnDefeat | integer | 15 | Rating lost per defeat |
AbandonPenaltyEnabled | boolean | true | Penalize players who leave or disconnect mid-match |
AbandonPenaltyRating | integer | 25 | Rating deducted for abandoning or disconnecting |
MinRatingAfterPenalty | integer | 0 | Minimum rating floor (rating cannot go below this) |
OpenSkillEnabled | boolean | false | Enable the OpenSkill (Weng-Lin) skill-based rating system |
OpenSkillRatingScale | integer | 40 | Multiplier for the ordinal value (μ − 3σ) when deriving visible rating |
OpenSkillRatingOffset | integer | 1000 | Base offset added after scaling, so new players start at this rating |
RatingTiersEnabled | boolean | true | When enabled, UIs (leaderboard, etc.) display tier names instead of numeric rating. PlaceholderAPI placeholders are always available regardless of this setting |
RatingPerTier | integer | 300 | Rating points per tier bracket. Controls tier width: with 300 each tier covers 300 points (0–299, 300–599, etc.). The number of tiers equals the length of RatingTierNames |
RatingTierNames | string[] | (see below) | Array of tier names mapped to brackets of RatingPerTier points each. Fewer names is OK — the last name absorbs all higher ratings |
MaxRatingDifferenceOverrides
By default, all categories use the global MaxRatingDifference value. You can override the rating gap per category by specifying category codes as keys:
{
"MaxRatingDifference": 50,
"MaxRatingDifferenceOverrides": {
"2-FFA": 100,
"4-T": 30,
"4-TCTO": 75
}
}
In this example:
2-FFAallows a rating gap up to 100 (more relaxed matchmaking for 1v1)4-Trestricts the gap to 30 (tighter matchmaking for 2v2 teams)4-TCTOallows up to 75- All other categories use the global default of 50
This is useful when you want more relaxed matchmaking for less competitive modes (like FFA duels) and stricter matchmaking for competitive team modes.
Reconnection
| Key | Type | Default | Description |
|---|---|---|---|
EnableReconnectionSystem | boolean | true | Enable the reconnection system (allows players to rejoin after disconnect) |
Broadcast
| Key | Type | Default | Description |
|---|---|---|---|
BroadcastQueue | boolean | true | Send a server-wide message when a player joins a queue |
BroadcastBlacklistWorlds | string[] | [] | Worlds excluded from receiving the broadcast (supports wildcards) |
When BroadcastQueue is enabled, every time a player joins a queue, all other online players receive a notification like:
Steve has joined the 1v1 FFA queue.
The player who joined does not receive the broadcast — only the rest of the server. Category codes are automatically formatted into a readable name:
| Code | Display |
|---|---|
2-FFA | 1v1 FFA |
2-T | 1v1 Team |
4-T | 2v2 Team |
4-TDM | 2v2 Team Deathmatch |
6-TCTO | 3v3 Capture the Orb |
4-FFADM | 4-player FFA Deathmatch |
Worlds whose name starts with the configured ArenaWorldPrefix (e.g. arena_) are always excluded — you don't need to add them manually.
BroadcastBlacklistWorlds
Use BroadcastBlacklistWorlds to exclude additional worlds from the broadcast. Two formats are supported:
| Format | Behaviour | Example |
|---|---|---|
"lobby_vip" | Exact match — excludes only the world with that exact name | Only lobby_vip is excluded |
"dungeon_*" | Wildcard prefix — excludes every world whose name starts with the prefix before * | dungeon_forest, dungeon_cave, etc. |
{
"BroadcastQueue": true,
"BroadcastBlacklistWorlds": [
"lobby_staff",
"dungeon_*",
"minigame_*"
]
}
In this example:
lobby_staffis excluded by exact name- Any world starting with
dungeon_is excluded (e.g.dungeon_forest,dungeon_ice) - Any world starting with
minigame_is excluded - All
arena_*worlds are excluded automatically
This is useful to avoid spamming players who are in unrelated activities like dungeons or mini-games.
Combat Logger
| Key | Type | Default | Description |
|---|---|---|---|
CombatLogEnabled | boolean | true | Enable the combat logger (penalizes disconnecting during PvP combat) |
CombatLogTimeSeconds | integer | 5 | Time window in seconds after PvP damage to consider a player "in combat" |
CombatLogTimeSecondsOverrides | object | {} | Per-category overrides for CombatLogTimeSeconds (see below) |
CombatLogTimeSecondsOverrides
By default, all categories use the global CombatLogTimeSeconds value. You can override the combat timer per category by specifying category codes as keys:
{
"CombatLogTimeSeconds": 5,
"CombatLogTimeSecondsOverrides": {
"2-FFA": 180,
"4-T": 180,
"2-T": 180
}
}
In this example:
2-FFA(1v1 duels) uses 180 seconds — effectively the entire match duration4-T(2v2 team) uses 180 seconds — once combat starts, there’s no escape- All other categories use the global default of 5 seconds
In classic modes (FFA, Team) where there are no respawns, a player who disconnects during combat is marked as dead. If the combat timer is too short (e.g. 5 seconds), a player in a Team match could disconnect just after combat ends, reconnect with full health, and gain an unfair advantage.
By setting the combat timer equal to or greater than the match’s TimeLimit, you ensure that once a player enters combat, disconnecting at any point during the match will count as a combat log — no loopholes.
Category Sorting
| Key | Type | Default | Description |
|---|---|---|---|
SortCategoryOverrides | object | {} | Custom display order for arena categories across all UIs |
By default, categories are sorted alphabetically. You can override the display order by assigning a numeric priority to each category code — lower numbers appear first.
{
"SortCategoryOverrides": {
"2-FFA": 0,
"4-T": 1,
"4-TDM": 2,
"4-FFA": 3,
"6-TCTO": 4
}
}
In this example:
2-FFAappears first,4-Tsecond,4-TDMthird, and so on- Any category not listed will appear after all overridden categories, in alphabetical order
You don't need to list every category — only the ones you want to prioritize:
{
"SortCategoryOverrides": {
"2-FFA": 0
}
}
This puts 2-FFA first; everything else keeps its default alphabetical order.
The sort order is applied everywhere categories are listed:
- Arena UI (queue selector)
- Leaderboard (category picker)
- HyTv (match browser)
- Map Preferences (template blacklist per category)
Keybinds
| Key | Type | Default | Description |
|---|---|---|---|
GameModeKeyOpensArenaUI | boolean | true | When the gamemode key (O) is pressed outside an arena, open the Arena UI (/arena) instead of changing gamemode |
Blocked Commands
| Key | Type | Default | Description |
|---|---|---|---|
BlockedCommandsInArena | string[] | ["tp", "home", "spawn", "tpa", "warp", "back"] | Command prefixes to block while a player is inside an arena (OP players are exempt) |
Each entry is a command prefix (without /). For example, "tp" blocks /tp, /tp player1, etc. Players with OP permissions bypass this restriction.
Permissions
| Key | Type | Default | Description |
|---|---|---|---|
DisableGroupPermission | string[] | [] | Permission groups to disable inside arena (list of group names) |
This is useful for disabling certain permission groups' abilities (like creative mode or fly) while players are inside an arena match.
Integrations
Optional mod integrations are grouped under the Integrations key. Each integration only takes effect if the corresponding mod is installed — otherwise, the settings are ignored.
{
"Integrations": {
"MMOSkillTree": {
"FairPlayMode": true
},
"RPGLeveling": {
"ShareExp": true,
"SharePercentage": 50,
"ShareDistance": 1000,
"ShowLvlGroup": true,
"FormatLvlGroup": "Lvl. {0}",
"FairPlayMode": true
}
}
}
MMO Skill Tree
| Key | Type | Default | Description |
|---|---|---|---|
FairPlayMode | boolean | true | Save and reset skills on arena entry, restore on exit — ensures all players compete on equal footing. See MMO Skill Tree |
RPG Leveling
| Key | Type | Default | Description |
|---|---|---|---|
ShareExp | boolean | true | Share XP between group members outside arenas |
SharePercentage | integer | 50 | Percentage of earned XP shared with nearby group members |
ShareDistance | integer | 1000 | Max distance (blocks) for XP sharing |
ShowLvlGroup | boolean | true | Show player level in the group HUD |
FormatLvlGroup | string | "Lvl. {0}" | Level display format ({0} = level number) |
FairPlayMode | boolean | true | Save and reset level on arena entry, restore on exit — ensures all players compete on equal footing. See RPG Leveling |
Complete Example
{
"Version": "18",
"DebugMode": false,
"InstancesLimit": 0,
"Language": "en-US",
"GameModeKeyOpensArenaUI": true,
"ArenaWorldPrefix": "arena_",
"MaxRatingDifference": 50,
"MaxRatingDifferenceOverrides": {},
"RatingGainOnWin": 25,
"RatingLossOnDefeat": 15,
"AbandonPenaltyEnabled": true,
"AbandonPenaltyRating": 25,
"MinRatingAfterPenalty": 0,
"OpenSkillEnabled": false,
"OpenSkillRatingScale": 40,
"OpenSkillRatingOffset": 1000,
"RatingTiersEnabled": true,
"RatingPerTier": 300,
"RatingTierNames": [
"Iron", "Bronze", "Silver", "Gold", "Platinum",
"Diamond", "Master", "Grandmaster", "Challenger", "Challenger+"
],
"MatchHistoryEnabled": true,
"MatchHistoryLimit": 100,
"AssistWindowSeconds": 10,
"EnableReconnectionSystem": true,
"FriendlyFireOutsideArena": false,
"CombatLogEnabled": true,
"CombatLogTimeSeconds": 5,
"CombatLogTimeSecondsOverrides": {},
"ActiveRaycast": true,
"ParticleIdRaycastEnemy": "Arena_Raycast_Enemy",
"ParticleIdRaycastAlly": "Arena_Raycast_Ally",
"ParticleOnDeath": true,
"ParticleIds": [
"Teleport",
"Lightning:1.5",
"MemoryUnlock:1.5"
],
"SortCategoryOverrides": {},
"BroadcastQueue": true,
"BroadcastBlacklistWorlds": [],
"BlockedCommandsInArena": [
"tp",
"home",
"spawn",
"tpa",
"warp",
"back"
],
"DisableGroupPermission": [],
"Integrations": {
"MMOSkillTree": {
"FairPlayMode": true
},
"RPGLeveling": {
"ShareExp": true,
"SharePercentage": 50,
"ShareDistance": 1000,
"ShowLvlGroup": true,
"ShowExpBarGroup": true,
"FormatLvlGroup": "Lvl. {0}",
"FairPlayMode": true
}
}
}
Arena templates now managed as individual files:
- Arena Templates — see Arena Templates (
mods/arenapvp/templates/) - Inventory Presets — see Inventory Presets (
mods/arenapvp/presets/)