Full technical reference for server admins and developers.
Table of contents
Quick setup walkthrough
Detailed setup (per arena)
config.yml reference
kits.yml format
maps.yml internals
Permissions reference
Adding or translating a language
Top NPCs deep dive
Map regeneration (FAWE vs in-memory)
Storage backends and migration
BungeeCord / Velocity setup
Developer API reference
Frequently asked questions and troubleshooting
Update / migration notes
1. Quick setup walkthrough
Drop the jar into plugins/, start the server, stop it again so all default files generate.
Pick your architecture in config.yml: MULTI_ARENA (default, multiple arenas in parallel) or SINGLE_GAME (one match per server).
Start the server.
In your lobby world, run /ufk config, open the Maps editor, click your map (or first create it with /ufk createmap <name> inside the arena world), set global lobby spawn, border MIN/MAX (FAWE WAND), spectator spawn, team spawns, nexus, mines, bases for each team.
/ufk maps should now show ✓ Playable.
/ufk start (or let auto-start handle it).
2. Detailed setup (per arena)
2.1 Create the arena world
Build your arena in a dedicated world (e.g. ufk_arena1). Recommended size: 100x100 to 300x300 blocks. Bigger arenas = longer matches, more travel time.
Build the 4 team bases roughly equidistant from a central point. The center is where Deathmatch usually concentrates the action.
Place a "Nexus block" inside each base. Any block works (default visual is wool of the team color), the plugin will pin its location.
Stand inside the world and run /ufk createmap <name>. The plugin records the world reference.
2.2 Configure via /ufk config The configuration GUI is the
single source of truth for map setup. The CLI commands
/ufk setspawn,
/ufk setobjective,
/ufk setborder,
/ufk mine do not exist; everything is GUI-driven.
In the Maps editor, click your map, then:
Border MIN / MAX: stand at the corner you want to set, click the corresponding slot. The border is a closed cuboid (floor + ceiling enforced).
Spectator spawn: where dead/spectator players are teleported. Pick a safe vantage point above the arena.
Team spawn: per-team starting position, typically inside that team's base.
Team objective (Nexus): aim a block, click the slot. The block becomes that team's nexus.
Mines: cuboid resource zone. Set pos1 + pos2 in the team's mine menu, click "Add a mine". You can stack several mines per team.
Bases: same workflow, defines the build/protect cuboid where original blocks are protected and enemies are blocked during preparation.
2.3 Per-arena waiting lobby (optional) Each arena can have its
own waiting lobby spawn. If unset, players wait at the global lobby spawn instead. Useful when you want themed lobbies per arena or when arenas are in different worlds.
2.4 Visualization mode In the map editor, toggle "Mine particles" / "Base particles" to display live particles around the configured cuboids. Great for verifying overlap or alignment without leaving creative.
2.5 Verify and start
/ufk maps shows the playable / incomplete status, with a ✓/✗ checklist of what's missing.
/ufk start starts a match immediately (admin override).
Auto-start triggers when game.min_players is reached in a WAITING game.
3. config.yml reference
The config has
23 top-level sections across ~944 lines, with inline comments explaining the
why behind every option. Below is a summary of the sections and their purpose. Open the actual file for the per-key documentation.
Section
Purpose
debug
Verbose console logging for the plugin
world
force_difficulty (NORMAL recommended for hostile mob spawns)
game
Architecture, countdowns, sounds, min players, auto-start, reconnection
phases
Duration of preparation, PvP, deathmatch phases
pvp
Friendly fire, drops on death, healing rules
death
Death messages, respawn behavior
teams
Team count, max per team, balance, auto-balance, max size diff
objective
Nexus HP, regen, hologram, sounds, particles
base
Build outside enforcement, original-block protection, mob spawn block in bases
tnt
TNT enable, prime ticks, fuse delay
creepers
Wave spawning, max alive, charged percent, banned ground, TNT drops
mobs
Block mob spawns outside arenas, purge on player join
Reset mode (FAWE / IN_MEMORY), snapshot strategy, world cleanup on game end
config_mode
Visualization particles for /ufk config
display
Boss bar, hologram view range, scoreboard intervals
chat
Scoping (team-only / arena / global), label format
scoreboard
Lobby and in-game scoreboard refresh, footer
tablist
Header / footer refresh interval, lobby vs in-game
stats
Lobby stats item slot, GUI options
top
Real NPCs (ProtocolLib), max NPCs per category, refresh interval
language
Default language, allow_player_change
bungeecord
Bungee mode, server name, restart-on-end
storage
Backend selection, MySQL credentials, Hikari pool size
4. kits.yml format
Kits are defined as a flat map of identifier → kit. Each kit has a
display_name and a list of items. Items are written as
<MATERIAL> or
<MATERIAL>:<amount>.
Material names follow the Bukkit Material enum (uppercase, underscores).
Amount defaults to 1 if not specified.
After editing, run /ufk reload. New kits appear in the kit selector GUI immediately.
Kit display names are also translatable through the kit.display.<id> keys in lang/.
5. maps.yml internals
maps.yml is the persistent storage for every map: world reference, border corners, spawn points, nexuses, mines, bases. It is written by the GUI editor (or by
/ufk createmap) and can be hand-edited if you really want to, but
the GUI is the recommended workflow.
Do not hand-edit
maps.yml while the server is running. The plugin caches the file in memory; any external edit is overwritten on the next save.
If you need to wipe a map's setup and start fresh, the cleanest way is
/ufk config → click the map → "Delete map" (shift-click confirm). It removes the entry from
maps.yml safely.
6. Permissions reference
The base command is
/ufk (aliases:
/fallenkingdoms,
/fk).
Permission groups
Permission
Default
Effect
ufk.*
op
Grants both ufk.admin and ufk.play
ufk.admin
op
Bundles every admin subcommand
ufk.play
true
Bundles every player subcommand
Per-subcommand permissions
Subcommand
Permission
Default
/ufk help
ufk.command.help
true
/ufk join
ufk.command.join
true
/ufk leave
ufk.command.leave
true
/ufk lang
ufk.command.lang
true
/ufk guide
ufk.command.guide
op
/ufk config
ufk.command.config
op
/ufk maps
ufk.command.maps
op
/ufk createmap
ufk.command.createmap
op
/ufk start
ufk.command.start
op
/ufk stop
ufk.command.stop
op
/ufk bypass
ufk.command.bypass
op
/ufk reload
ufk.command.reload
op
/leave
none required
Spectators only
7. Adding or translating a language
The plugin ships 10 bundled languages:
en_US,
fr_FR,
de_DE,
es_ES,
zh_CN,
ru_RU,
pt_BR,
pl_PL,
tr_TR,
ja_JP. Each file lives in
plugins/UltimateFallenKingdoms/lang/<code>.yml.
7.1 Translate an existing language Open the corresponding
.yml and edit the value side of each entry. Keep the YAML structure and the
%placeholder% tokens intact (
%player%,
%team%,
%map%,
%hp%, etc.). Run
/ufk reload when done.
7.2 Add a new language
Copy en_US.yml to lang/<code>.yml (e.g. nl_NL.yml for Dutch). The code follows the xx_YY convention.
Translate every value, preserving placeholders and MiniMessage tags (<gradient>, <color>, <bold>, <click>, <hover>, <newline>).
Run /ufk reload. Players can now select your new code with /ufk lang <code>.
8.1 Categories The Top system supports
5 categories: Kills, Wins, K/D, Nexus (destroyed), Games (played). Each can be enabled / disabled independently and has its own per-rank locations.
8.2 Real NPCs vs ArmorStands
If ProtocolLib is installed and top.use_real_npcs: true (default), the plugin spawns packet-based fake players with the real player's skin loaded from Mojang sessionserver, the right per-rank armor, and a separate ArmorStand floating above for the gradient nameplate.
If ProtocolLib is missing, the plugin gracefully falls back to ArmorStands with rendered name + score. Functional but visually inferior.
8.3 Per-rank armor
Rank
Armor
#1
Full diamond
#2
Full gold
#3
Full iron
#4 and below
Full leather
[/TR]
8.4 Configure NPCs in-game
/ufk config → Top.
Pick a category, toggle it ON.
Set the Max NPCs for this category (1 to N).
Stand at the desired NPC location and click a rank slot to assign your current position. Click again with right-click to clear.
NPCs spawn instantly. Skin / armor / nameplate update on the next top.refresh_interval_seconds tick.
8.5 Skin cache Skins are fetched once from
sessionserver.mojang.com and cached for 24h. Cache is in-memory only, not persisted across restarts. After a server restart, the first load of each NPC takes ~500ms while skins resolve.
9. Map regeneration (FAWE vs in-memory)
When a game ends or stops, the plugin restores the arena to its pre-game state. Two strategies are supported, controlled by
map.reset_mode:
9.1 FAWE (recommended for big arenas) Uses FastAsyncWorldEdit to:
Save a schematic of the arena border before each game start.
Paste it back on game end / stop.
Pros: extremely fast (~1-3s for 200x200x80 arenas), handles every block change including tile entities. Cons: requires FAWE installed.
9.2 IN_MEMORY (fallback) Uses an internal block-state recorder that:
Listens to every block change inside the arena border.
Reverts each one in reverse order on reset.
Pros: zero external dependency. Cons: holds the change list in memory (RAM scales with player griefing intensity), slower for very destructive matches. Fully covers TNT, creepers, fire spread, fluid flow, etc.
10. Storage backends and migration
Three storage backends are supported, configured under
storage: in
config.yml:
Type
File / target
Use case
sqlite (default)
plugins/UltimateFallenKingdoms/ufk.db
Single-server installs, dev environments
mysql
Remote MySQL / MariaDB host
Multi-server networks, BungeeCord, dedicated DB
flat
One YAML file per player
Tiny servers, manual editing, no DB tooling
10.1 SQLite → MySQL migration
Backupufk.db before doing anything.
Set storage.type: mysql and fill the credentials. Restart the server: the plugin creates the schema on the MySQL host.
Stop the server, dump the SQLite tables (players, stats, any plugin-specific table) using a tool like sqlite3 CLI, DBeaver, or sqlitebrowser.
Import the dumped rows into the MySQL DB.
Restart the server. Stats now load from MySQL.
10.2 HikariCP pool tuning (MySQL) The plugin uses HikariCP. Defaults are conservative (
pool_size: 6,
connection_timeout: 5000). For very large networks (50+ servers sharing the same DB), bump pool size and lower
idle_timeout.
11. BungeeCord / Velocity setup
The plugin supports proxy networks under
bungeecord: in
config.yml:
bungeecord.server_name: this server's identifier inside the proxy.
bungeecord.send_back_on_end: where to send players after a match ends (typically your hub).
11.1 Recommended topology
One Hub server running your usual hub plugins (no UFK installed).
N Game servers each running UFK + one or more arenas. Use SINGLE_GAME for one-match-per-server, or MULTI_ARENA if you want multiple arenas per server.
Shared MySQL backend so stats follow the player across the network.
11.2 Bungee + signs Sign-based connectors (BungeeSigns, ServerListPlus, etc.) work natively. Ping data (
online,
max) reflects the per-arena values driven by the plugin.
12. Developer API reference
12.1 Add as a soft dependency In your
plugin.yml:
Code (Text):
softdepend: [UltimateFallenKingdoms]
This guarantees UFK loads first if present, while keeping your plugin functional if it isn't.
12.2 Maven / Gradle (local jar) There is no public Maven repo for the plugin yet. Add the jar as a
system-scoped or local dependency:
12.3 Access the API The
UFKApi instance is registered with Bukkit's
ServicesManager. Recommended pattern:
Code (Text):
RegisteredServiceProvider<UFKApi> rsp =
Bukkit.getServicesManager().getRegistration(UFKApi.class);
if (rsp == null) return;
UFKApi api = rsp.getProvider();
Or, equivalently:
Code (Text):
UltimateFallenKingdoms ufk =
(UltimateFallenKingdoms) Bukkit.getPluginManager().getPlugin("UltimateFallenKingdoms");
UFKApi api = ufk.getApi();
12.4 Methods
Method
Returns
Use case
api.games()
GameManager
Inspect / control all games
api.maps()
MapManager
Read configured maps
api.teams()
TeamManager
Resolve team metadata, colors, members
api.players()
PlayerManager
Per-player game state
api.lang()
LangManager
Send localized MiniMessage strings
api.storage()
Storage
Read player stats, write custom records
api.gameOf(player)
@Nullable Game
Find a player's game
api.activeGames()
Collection<Game>
Iterate all live games
12.5 Events All events live in
fr.ultimateplugins.ufk.api.events and extend
UFKEvent. Register them like any standard Bukkit event.
Event
Fired when
Notable
GameStartEvent
Game transitions to RUNNING
GameEndEvent
Game transitions to ENDING
getWinner() (nullable on draw)
PhaseChangeEvent
Phase moves between PREPARATION/PVP/DEATHMATCH
getFrom(), getTo()
ObjectiveDestroyedEvent
A nexus is broken
getOwner(), getBreaker() (nullable)
PlayerEliminatedEvent
Player loses last life
PlayerJoinTeamEvent
Player picks a team
Cancellable
TeamEliminatedEvent
Team has lost its nexus and all its players
12.6 Example: Vault rewards on win
Code (Text):
public class WinReward implements Listener {
private final Economy econ;
public WinReward(Economy econ) { this.econ = econ; }
@EventHandler
public void onGameEnd(GameEndEvent event) {
Team winner = event.getWinner();
if (winner == null) return;
for (UUID uuid : winner.getMembers()) {
Player p = Bukkit.getPlayer(uuid);
if (p != null) econ.depositPlayer(p, 100.0);
}
}
}
12.8 Enums Available in
fr.ultimateplugins.ufk.api.enums:
ArchitectureMode,
DeathMode,
GamePhase,
GameState,
LobbyMode,
MapResetMode,
ObjectiveType,
PlayerState,
StorageType.
13. Frequently asked questions
Q. The Top NPCs show names like ufk_wins_2 above their head. ProtocolLib isn't installed (or failed to load). Install ProtocolLib 5.x for your MC version, restart. The fake-player NPCs require packet support.
Q. Map regeneration takes 30+ seconds. You're using the
IN_MEMORY fallback on a very destructive arena. Install FastAsyncWorldEdit (FAWE) to switch to schematic-based regen which finishes in 1 to 3 seconds for typical arenas.
Q. Players see English even though I set language.default: fr_FR. Players have a per-player language preference. To force everyone to the server default, set
language.allow_player_change: false. To remove existing per-player choices, wipe the relevant rows in your storage backend (or
ufk.db for SQLite).
Q. SQLite "database is locked" errors on a busy server. SQLite is single-writer. Migrate to MySQL (
storage.type: mysql) for multi-server or high-throughput setups.
Q. No creepers spawn during my game. Check that
world.force_difficulty is at least
NORMAL (PEACEFUL disables hostile mob spawn). Check that
creepers.enabled: true. Check console for "spawn attempts failed" messages: the
creepers.banned_ground_blocks list might be too restrictive for your arena's terrain.
Q. Mobs are spawning in my lobby. Set
mobs.block_outside_arenas: true (default): the plugin cancels every mob spawn outside running arenas. Also enable
mobs.purge_on_player_join: true to clear leftover mobs whenever a player joins the server.
Q. Players in a base can break the original walls. Set
base.protect_original_blocks: true (default). Inside the base, only blocks placed
during the game by players can be broken; the original terrain is locked.
Q. Friendly fire is on / off and I can't change it. pvp.friendly_fire in
config.yml controls it. Default is
false. Run
/ufk reload after editing.
Q. The game won't auto-start even with enough players. Verify
game.auto_start.enabled: true. Verify
game.min_players is reached. Players must be in
LOBBY state (not spectating). Check that the map is ✓ Playable in
/ufk maps.
Q. /ufk dev is mentioned somewhere. Does it exist? No. It was a developer-only command removed before the public release.
Q. How do I disable Bungee mode entirely? Set
bungeecord.enabled: false and restart. Default is
false, so a fresh install is single-server out of the box.
14. Update / migration notes
This section will track breaking changes between versions.
v1.0.0 · initial release
Public release on Spigot.
No migrations needed.
Need help?
Use the
Discussion tab on the resource page with your
server.log, plugin version, MC version, and a description of the issue.
Star the resource if it saved you time. ⭐