Nexal Leaderboards
Turn any numeric PlaceholderAPI placeholder into a ranked leaderboard. The plugin reads the
placeholder for every online player on a timer, keeps the scores (offline players included), and
shows the rankings through a paginated GUI, chat commands, holograms and its own placeholders such
as %nexalleaderboards_vault_eco_balance_1% for scoreboards, tab lists and signs.
Features
- Any Numeric Placeholder - Rank Vault balances, kills, playtime, levels or any custom stat that PlaceholderAPI can resolve to a number
- Auto-Tracking - The first time
%nexalleaderboards_\<placeholder>_\<pos>%is asked for, the placeholder starts being tracked, but only if it gives a number for someone online; typos and text placeholders are ignored - Validated Manual Tracking -
/lb admin trackstrips%signs and refuses placeholders that do not give a number - Per-Leaderboard Refresh Intervals - Each leaderboard refreshes on its own interval (default 5 minutes, minimum 10 seconds)
- Leaderboard Placeholders - Name, raw value and formatted value (1,234,567) for any rank
- Holograms - Place a hologram showing the top 1 to 20 of a leaderboard; it redraws after every refresh and needs no hologram plugin (native text displays)
- Paginated GUI - Player heads with rank, name and value, auto-refreshing while open
- Chat Rankings -
/lb topfor the top players and/lb playerfor any player's ranks, online or offline - Admin GUI -
/lb adminopens a hub with the settings, every tracked leaderboard (interval, refresh now, remove), the holograms, export and import - Offline Player Retention - Players keep their score after logging off; it updates the next time they are online during a refresh
- Dual Storage - JSON or MySQL/MariaDB, with export/import to move between them; writes run off the main thread
- Customizable Messages - Every message and the hologram text live in
messages.yml
Technologies
- Paper API 1.20.1+ - Minecraft server API (Spigot compatible)
- Utilizer - Configuration, messages, GUIs, tasks, native holograms
- ACF - Command framework
- nexal-core - JSON and SQL persistence (MariaDB/MySQL), help menus
- PlaceholderAPI - Required; the source of every leaderboard
Commands
Aliases: /lb, /leaderboard, /leaderboards.
Player Commands
| Command | Description | Permission |
|---|---|---|
/lb help [page] | Show help | None |
/lb list | List all tracked placeholders | nexalleaderboards.use |
/lb info \<placeholder> | Players, last and next refresh, interval | nexalleaderboards.use |
/lb top \<placeholder> [count] | Top players in chat (count 1-100, default 3) | nexalleaderboards.use |
/lb player \<player> [placeholder] | A player's ranks, online or offline | nexalleaderboards.use |
/lb gui \<placeholder> | Open the paginated leaderboard GUI | nexalleaderboards.use |
Admin Commands
| Command | Description | Permission |
|---|---|---|
/lb admin | Open the admin GUI (the admin help from the console) | nexalleaderboards.admin |
/lb admin help [page] | Admin help as text | nexalleaderboards.admin |
/lb admin track \<placeholder> | Start tracking a placeholder (with or without %) | nexalleaderboards.admin |
/lb admin remove \<placeholder> | Stop tracking and delete its scores and holograms | nexalleaderboards.admin |
/lb admin setinterval \<placeholder> \<seconds> | Set a leaderboard's refresh interval (min 10) | nexalleaderboards.admin |
/lb admin refresh \<placeholder> | Refresh now and report the result | nexalleaderboards.admin |
/lb admin hologram list | List the holograms | nexalleaderboards.admin |
/lb admin hologram create \<name> \<placeholder> [lines] | Place a hologram of the top 1-20 (default 10) where you stand | nexalleaderboards.admin |
/lb admin hologram movehere \<name> | Move a hologram to you | nexalleaderboards.admin |
/lb admin hologram delete \<name> | Delete a hologram | nexalleaderboards.admin |
/lb admin reload | Reload config.yml and messages.yml; switches storage when storage.type changed | nexalleaderboards.admin |
/lb admin export | Export all data to export/ | nexalleaderboards.admin |
/lb admin import | Import the files in export/ | nexalleaderboards.admin |
Permissions
| Permission | Description | Default |
|---|---|---|
nexalleaderboards.use | Basic leaderboard commands | true |
nexalleaderboards.admin | Admin commands and GUI (includes use) | op |
Placeholders
Requires PlaceholderAPI. \<placeholder> is the tracked placeholder without % signs, \<pos> a rank starting at 1.
| Placeholder | Description |
|---|---|
%nexalleaderboards_\<placeholder>_\<pos>% | Player name at that rank |
%nexalleaderboards_\<placeholder>_\<pos>_name% | Player name at that rank |
%nexalleaderboards_\<placeholder>_\<pos>_value% | Raw value (1500000.5) |
%nexalleaderboards_\<placeholder>_\<pos>_formatted% | Formatted value (1,500,000.5) |
An empty rank returns - for the name and 0 for the values.
%nexalleaderboards_vault_eco_balance_1% → Steve
%nexalleaderboards_vault_eco_balance_1_formatted% → 1,500,000.5
%nexalleaderboards_statistic_player_kills_3_value% → 150.0
Scoreboard example:
lines:
- "&6Top Balances:"
- "#1 %nexalleaderboards_vault_eco_balance_1% - $%nexalleaderboards_vault_eco_balance_1_formatted%"
- "#2 %nexalleaderboards_vault_eco_balance_2% - $%nexalleaderboards_vault_eco_balance_2_formatted%"
- "#3 %nexalleaderboards_vault_eco_balance_3% - $%nexalleaderboards_vault_eco_balance_3_formatted%"
How tracking works
- A placeholder starts being tracked with
/lb admin track, or automatically the first time a%nexalleaderboards_...%placeholder asks for it (auto-track-on-query: true). Either way it must give a number for at least one online player; an unknown or text placeholder is refused (auto-tracking tries such a placeholder again after a minute at most). - On every refresh the placeholder is read for each online player and the scores are stored.
- Offline players keep their last score.
- A value counts as its first number. Colour codes, thousands separators and spaces are removed
first, so a gold
1,500is 1500 andLevel 5is 5; a value without digits reads as 0.
Holograms
Stand where the hologram should be and run /lb admin hologram create \<name> \<placeholder> [lines].
Holograms are drawn with native text displays (armor stands before 1.19.4), so no hologram plugin
is needed. They redraw after every refresh of their leaderboard and whenever messages.yml
changes. Removing a leaderboard deletes its holograms too. The text comes from the hologram
section of messages.yml:
hologram:
header:
- "<gradient:#9B59B6:#A569BD>\<bold>TOP %lines%\</bold>\</gradient>"
- "<gradient:#B983CE:#C99DDA>%placeholder%\</gradient>"
line: "\<white>#%rank%\</white> <gradient:#9B59B6:#A569BD>%player%\</gradient> \<gray>-\</gray> <gradient:#B983CE:#C99DDA>%value%\</gradient>"
empty-line: "\<gray>#%rank% -\</gray>"
footer: []
Configuration
config.yml
# Storage settings
storage:
# Storage type: json or sql
# To move your data: /lb admin export, change the type, /lb admin reload, /lb admin import
type: json
sql:
host: localhost
port: 3306
database: minecraft
username: root
password: ""
# Default refresh interval in seconds (minimum 10), used for newly tracked placeholders
default-refresh-interval: 300
# Start tracking a placeholder the first time %nexalleaderboards_...% asks for it,
# if it gives a number for someone online
auto-track-on-query: true
# Maximum players ranked per leaderboard (-1 for unlimited)
max-tracked-per-leaderboard: 1000
gui:
# How often an open leaderboard GUI redraws, in ticks (20 ticks = 1 second)
auto-refresh-ticks: 100
The four plugin-wide settings can also be changed in-game under /lb admin → Configuration.
Changes to config.yml apply without a restart, except storage.type, which needs /lb admin reload.
messages.yml
All messages, the /lb gui texts (leaderboard-gui section) and the hologram text are
customizable with MiniMessage gradients, sounds and titles, and every message
maps %prefix%. Messages added in an update fall back to the bundled text when an older
messages.yml does not have them.
Database Schema
With SQL storage the plugin creates these tables (with JSON storage the same records live in
data.json, one key per table):
leaderboards_tracked
| Column | Type | Key | Description |
|---|---|---|---|
id | VARCHAR(255) | PK | Placeholder name |
lastRefresh | BIGINT | Last refresh (epoch ms) | |
refreshInterval | BIGINT | Refresh interval (seconds) | |
playerCount | INT | Players ranked at the last refresh | |
createdAt | BIGINT | When tracking started (epoch ms) |
leaderboards_entries
| Column | Type | Key | Description |
|---|---|---|---|
id | VARCHAR(320) | PK | \<placeholder>:\<player uuid> |
placeholder | VARCHAR(255) | Placeholder name | |
playerId | VARCHAR(36) | Player UUID | |
playerName | VARCHAR(16) | Player name at the last change | |
value | DOUBLE | Score | |
lastUpdated | BIGINT | Last change of the score (epoch ms) |
leaderboards_holograms
| Column | Type | Key | Description |
|---|---|---|---|
id | VARCHAR(64) | PK | Hologram name |
placeholder | VARCHAR(255) | Leaderboard shown | |
lines | INT | Ranks shown | |
world | VARCHAR(64) | World name | |
x, y, z | DOUBLE | Position |
Key Legend: PK = Primary Key
Installation
- Install PlaceholderAPI and the expansions for the stats you want to rank (e.g.
/papi ecloud download Vault) - Place the plugin JAR in
/plugins - Start or restart the server
- Track a placeholder:
/lb admin track vault_eco_balance - Show it:
/lb gui vault_eco_balance, a hologram, or the placeholders above
Storage Migration
/lb admin export- Set
storage.type(and thesqlsection) in config.yml /lb admin reloadswitches to the new storage; if it cannot be opened, the old one stays/lb admin import
Troubleshooting
"does not give a number for anyone online"
- Check the placeholder with
/papi parse me %\<placeholder>%; it must print a number - Install its expansion (
/papi ecloud download \<name>) and/papi reload
Leaderboard shows all zeros
- The placeholder returns text without digits for those players
Placeholder not auto-tracking
- Check
auto-track-on-query: truein config.yml - It must give a number for someone online; track it with
/lb admin track \<placeholder>otherwise
High CPU usage
- Raise the refresh intervals (
/lb admin setintervalor the admin GUI) - Lower
max-tracked-per-leaderboard