Overview
Run a tier list server without spreadsheets: testers set a tier in game and it shows everywhere
Your testers run /tier set Notch sword HT2. From that moment Notch has an HT2 tag above their head and in the tab list, sits at the right place in /tierlist sword, shows up in PlaceholderAPI placeholders, and lands in a JSON file your website can read.
Ladders (sword, axe, crystal, UHC, SMP, building, anything) and tiers (LT5 to HT1, or bronze to diamond, or your own) are defined in the config. The plugin does not care what they are called.
In short
- One command updates the tag, the tab list, the tier list and the placeholders
- Any ladders and any tier names, all set in the config
- A JSON export your website can read
- PlaceholderAPI support for scoreboards and other plugins
- SQLite built in, nothing else to install
- Latest version
- 1.5.0
- Runs on
- Paper or Purpur 1.21.11 (or newer 1.21.x), Java 21
- BuiltByBit
- TierTags on BuiltByBit
What changed in 1.5.0
- The leaderboard screens are one column now, read top to bottom: one row per player with every tier they hold, each next to its mode's item. Clicking a row still opens that player's tiers, and paging and Back work as before.
- The Search button sits right under the search field instead of at the bottom.
- The tag above the head and in tab now shows the item of the mode the tier is from, for example a sword next to a Sword tier. Turn it off with display.icon: false. The item is drawn from the player's own game textures (1.21.9 or newer); older clients joining through a version bridge may not see it.
- New: every player can pick which tier they see on everyone, for their own screen only: /tier view sword, /tier view best, /tier view off, /tier view default, or "Tags I see" in /tier. The choice is saved and comes back after a relog.
- New settings under display: view (the server's default: best, a mode, or off) and per-viewer (true lets players pick their own view). A player who picks their own view gets their own scoreboard with just the tier tags, so teams from vanilla /team or other plugins on the main scoreboard do not show for them. If another plugin has already given that player their own scoreboard, the tags go into that one.
- /tiertags now works as another name for /tier.
- Existing config.yml files keep working. A format without {icon} gets the icon in front; set display.icon: false if you do not want it.
- Thanks to peterspeeder for the ideas.
Features
01What makes it different
- One command updates the nametag, the tab list, the tier list, the placeholders and the JSON export together, so nothing drifts out of sync
- Ladders and tier names are free text in the config, not a fixed set
- Testers get their own permission (tiertags.tester) without reload or export rights
02What you get
- New in v1.3.0: Overall ranking: /tierlist overall ranks everybody by the sum of their tier points across all ladders
- New in v1.3.0: Leaderboard and rank placeholders: top players per ladder and overall, for holograms and scoreboards, answered from memory so they cost nothing
- New in v1.3.0: Tester role: tiertags.tester can set and remove tiers without reload and export rights
- Any number of ladders, any tier names, each tier with a colour and a point value
- Best tier shown above the head and in tab through scoreboard teams; players sort by tier in tab
- Global points: every ladder's tier points summed, for a "best overall" ranking
- /tierlist per ladder, paged, sorted by tier and then name
- Broadcast when somebody is tiered (switchable), and a private message to the player
- PlaceholderAPI: %tiertags_best%, %tiertags_points%, %tiertags_sword%, and _plain versions without colour
- JSON export on a timer (or /tier export) with every player, their best tier, points and per-ladder tiers, ready for a website
- Offline players supported: set a tier for someone who is not online
- SQLite storage in the plugin folder, nothing to install
- MiniMessage everywhere; tag format, prefix and all messages editable
03The tier screens
- /tier on its own opens a real Minecraft dialog window with your own tiers, your best one and your points
- /tierlist on its own opens the ladder browser: pick a ladder, read the ranked list, page through it with buttons
- Testers get a set screen: type a name, pick the ladder and the tier from drop-downs, then set it, remove it, or look at everything that player holds
- That is three clicks instead of typing /tier set Name sword HT3 with the tier spelled right
menu: falseputs the chat lines back
Installation
Requirements
- Server
- Paper, or a Paper fork such as Purpur. Spigot and CraftBukkit won't work, because it uses Paper-only APIs.
- Minecraft
- 1.21.11 (or newer 1.21.x); plugin.yml api-version 1.21; built against Paper API 1.21.11
- Java
- 21 or newer
- Needs
- No other plugin
- Works with
PlaceholderAPI, when installed- Libraries
org.xerial:sqlite-jdbc:3.53.2.1, downloaded by the server on first start
The listing also says:
- PlaceholderAPI optional
- Works next to other nametag plugins that use teams only if they leave players in no team; if you already use a tab/nametag plugin, set display.enabled to false and use the placeholders in it instead
- No DRM, no licence key and no licence server; the code is not obfuscated
Steps
- Download
TierTags.jarfrom BuiltByBit. There's no licence key to enter. - Stop the server and put the jar in the
pluginsfolder. - Start the server. The plugin writes
plugins/TierTags/config.ymlwith the defaults listed under Configuration. - Change
config.ymlto fit your server. - Run
/tier reload(reload the config) to apply your changes, or restart the server.
Setup guide
- Drop TierTags.jar into /plugins and restart.
- Edit the ladders and tiers to match your server, /tier reload.
- Give your testers tiertags.admin (or a LuckPerms group with it).
- Testers run /tier set <player> <ladder> <tier>. Tags and lists update instantly.
Duel / PvP servers: one ladder per kit. Your tiers show in tab during matches, and %tiertags_best% goes into your scoreboard.
FFA / KitPvP: a single "ffa" ladder is enough, or split by kit. The tag above the head tells everybody who to watch out for.
SMP: ladders do not have to be PvP: "building", "redstone", "farming", "pvp". Testers become your judges and the tier becomes a status people play for.
Websites: point export.file at your web root (for example /var/www/site/tiers.json) and read it with a few lines of JavaScript. The file holds every player with uuid, name, best tier, points and all ladders.
Commands
Straight from plugin.yml. Where the permission column says "not set", plugin.yml puts no permission on the command itself; the nodes the plugin checks are under Permissions.
| Command | Aliases | Usage | What it does | Permission |
|---|---|---|---|---|
/tier | /tiers /tt /tiertags | /tier [player] | /tier set <player> <ladder> <tier> | View or set tiers. | not set |
/tierlist | none | /tierlist <ladder|overall> [page] | The ranked list for one ladder, or overall. | not set |
/leaderboard | /lb | /leaderboard [ladder|overall] [page] | The overall ranking, or one ladder's list. | not set |
Every subcommand
/tier Your own tiers and points.
/tier <player> Somebody else's tiers.
/tier set <player> <ladder> <tier> (admin) Give a tier on a ladder.
/tier remove <player> <ladder> (admin) Take a tier away.
/tier ladders List the ladders.
/tier export (admin) Write the JSON file now.
/tier reload (admin) Reload the config.
/tierlist <ladder> [page] The ranked list for one ladder.
/tierlist overall [page] Everybody ranked by total tier points.Permissions
From plugin.yml.
| Node | Default | What it allows | Includes |
|---|---|---|---|
tiertags.view | everyone | Pick which tier you see on everyone (/tier view). | none |
tiertags.tester | operators | Set and remove tiers, by command or on the set screen. | none |
tiertags.admin | operators | Everything a tester can do, plus reload and export. | tiertags.tester |
Viewing and /tierlist need no permission.
Placeholders
Registered with PlaceholderAPI as tiertags. You need PlaceholderAPI installed for these to work.
| Placeholder | Shows |
|---|---|
%tiertags_best% | best tier held, coloured (or the configured "none") |
%tiertags_best_plain% | the same without colour codes |
%tiertags_points% | global points across every ladder |
%tiertags_rank% | place in the overall ranking (by points) |
%tiertags_<ladder>% | the tier on that ladder, coloured |
%tiertags_<ladder>_plain% | the same without colour |
%tiertags_rank_<ladder>% | place on that ladder |
%tiertags_top_<ladder>_<n>_name% | who is n-th on a ladder |
%tiertags_top_<ladder>_<n>_tier% | their tier, coloured; _tier_plain without colour |
%tiertags_top_<n>_name% | who is n-th overall |
%tiertags_top_<n>_points% | their points; _best and _best_plain their best tier |
%tiertags_count_<ladder>% | how many players hold a tier on a ladder |
%tiertags_count% | how many players hold any tier |
%tiertags_tier% | no description |
%tiertags_tier_plain% | no description |
<ladder> is a ladder key from ladders: in config.yml. The default ladders are sword, axe, mace, crystal, uhc, pot, smp, so for example %tiertags_sword%.
When a player holds no tier, the placeholder shows the text of messages.none in config.yml (default: "<muted>none</muted>").
Configuration
The default files exactly as they ship in the jar, comments included. The plugin writes them to plugins/TierTags/ the first time it starts.
config.yml
| Key | Default | The comment above it |
|---|---|---|
menu | true | Bare /tier and bare /tierlist open the screens instead of printing lines in chat. |
ladders | section, 7 keys | Ladders: key -> label shown to players. Any names you like: kits, game modes, skills. |
ladder-icons | section, 7 keys | The item drawn beside each ladder on the screens: any item id. A ladder missing here gets the general tier icon. You can also write a ladder as sword: { label: "Sword", icon: diamond_sword } |
tiers | section, 10 keys | Tiers, lowest to highest. points feed "best tier" and the global score; colours are MiniMessage. |
display | section, 6 keys | none |
announce | section, 1 key | none |
list | section, 1 key | none |
export | section, 3 keys | none |
theme | section, 11 keys | Every message below is written against these names, not against hex codes: <accent>Open</accent> rather than <#48adf0>Open</#48adf0>. Change a colour here and it changes on every screen at once. Ordinary MiniMessage still works, so <gradient:#a:#b> and... |
messages | section, 84 keys | none |
review-reminder | true | One thank-you line with the BuiltByBit review link: once in the console after install and once in chat for the first operator who joins. It never repeats and sends nothing anywhere. false turns it off. |
plugins/TierTags/config.yml193 lines
# TierTags - tier lists for any server.
#
# Testers set a tier per player per ladder (/tier set <player> <ladder> <tier>). The best tier a
# player holds shows above their head and in the tab list, every ladder has a ranked /tierlist,
# PlaceholderAPI can put tiers anywhere, and a JSON file is written for a website.
# Bare /tier and bare /tierlist open the screens instead of printing lines in chat.
menu: true
# Ladders: key -> label shown to players. Any names you like: kits, game modes, skills.
ladders:
sword: "Sword"
axe: "Axe"
mace: "Mace"
crystal: "Crystal"
uhc: "UHC"
pot: "Pot"
smp: "SMP"
# The item drawn beside each ladder on the screens: any item id. A ladder missing here gets the
# general tier icon. You can also write a ladder as sword: { label: "Sword", icon: diamond_sword }
ladder-icons:
sword: diamond_sword
axe: diamond_axe
mace: mace
crystal: end_crystal
uhc: golden_apple
pot: splash_potion
smp: totem_of_undying
# Tiers, lowest to highest. points feed "best tier" and the global score; colours are MiniMessage.
tiers:
LT5: { color: "<gray>", points: 1 }
HT5: { color: "<gray>", points: 2 }
LT4: { color: "<green>", points: 3 }
HT4: { color: "<green>", points: 4 }
LT3: { color: "<aqua>", points: 6 }
HT3: { color: "<aqua>", points: 8 }
LT2: { color: "<light_purple>", points: 12 }
HT2: { color: "<light_purple>", points: 16 }
LT1: { color: "<gold>", points: 24 }
HT1: { color: "<gold>", points: 32 }
display:
# Tag above the head and in tab, as a team prefix. {tier} is the coloured tier, {icon} the item of
# the ladder that tier is from (the sword for a Sword tier).
enabled: true
format: "{icon}<dark_gray>[</dark_gray>{tier}<dark_gray>]</dark_gray> "
# The ladder's item in the tag. Drawn from the player's own game textures (1.21.9+ clients).
icon: true
# Which tier the tag shows: best (the highest tier on any ladder), a ladder name, or off.
view: best
# Let every player pick a different view for their own screen: /tier view <best|ladder|off|default>.
# A player who picks one gets their own scoreboard holding only the tier teams, so for them teams
# from vanilla /team or other plugins on the main scoreboard are not shown. If another plugin has
# already given that player their own scoreboard, the tier teams go into that one instead.
per-viewer: true
# Also colour the name itself like the tier (only works for named colours like <aqua>).
color-name: false
announce:
# Tell the whole server when a tier is set.
enabled: true
list:
per-page: 10
export:
enabled: true
every-minutes: 5
# Relative to plugins/TierTags/, or an absolute path such as /var/www/site/tiers.json
file: "tiers.json"
# ------------------------------------------------------------------------------------------------
# THEME
# ------------------------------------------------------------------------------------------------
# Every message below is written against these names, not against hex codes: <accent>Open</accent>
# rather than <#48adf0>Open</#48adf0>. Change a colour here and it changes on every screen at
# once. Ordinary MiniMessage still works, so <gradient:#a:#b> and <#ff0000> are fine anywhere.
theme:
accent: "#48adf0" # your colour: headings and anything the player is meant to click
accent2: "#9ad2f7" # a lighter accent, for a second level of emphasis
title: "#f4f7ff" # screen titles
text: "#c2ccdd" # ordinary prose
muted: "#6b7a94" # hints, separators, anything the eye should skip
value: "#ffffff" # the numbers and names the player opened the screen to read
good: "#57e08a"
warn: "#ffc857"
bad: "#ff6b6b"
small-caps: false # ᴇхᴀᴍᴘʟᴇ - a garnish; whole menus in it read badly
# Real Minecraft item pictures beside the buttons and in the chest screens. Drawn from the
# client's own textures, so there is nothing to install and no resource pack: it needs a
# 1.21.9 or newer client, and older ones simply see the buttons as words.
item-icons: true
messages:
prefix: "<accent2><bold>Tiers</bold></accent2> <muted>»</muted> "
none: "<muted>none</muted>"
help: "<text>/tier [player] · /tier set <player> <ladder> <tier> · /tier remove <player> <ladder> · /tierlist <ladder|overall> [page] · /lb [ladder] · /tier view <best|ladder|off> · /tier ladders</text>"
no-permission: "<bad>You cannot do that.</bad>"
usage-set: "<text>/tier set <player> <ladder> <tier></text>"
usage-remove: "<text>/tier remove <player> <ladder></text>"
unknown-ladder: "<bad>Ladders: </bad><value>{list}</value>"
unknown-tier: "<bad>Tiers: </bad><value>{list}</value>"
unknown-player: "<bad>Unknown player: </bad><value>{name}</value>"
set: "<value>{player}</value><text> is now </text>{tier}<text> on </text><value>{ladder}</value><text>.</text>"
you-were-tiered: "<text>You are now </text>{tier}<text> on </text><value>{ladder}</value><text>.</text>"
announce: "<value>{player}</value><text> was tiered </text>{tier}<text> on </text><value>{ladder}</value><text>.</text>"
removed: "<text>Removed </text><value>{player}</value><text>'s tier on </text><value>{ladder}</value><text>.</text>"
nothing-to-remove: "<text>{player} had no tier on {ladder}.</text>"
view-header: "<value>{player}</value><text>: best </text>{best}<text>, </text><value>{points}</value><text> points</text>"
view-row: "<text> - </text><value>{ladder}</value><text>: </text>{tier}"
list-header: "<value>{ladder}</value><text> tier list, page {page}/{pages} ({count} players)</text>"
list-row: "<muted>#{place}</muted> <value>{player}</value> {tier}"
list-empty: "<text>Nobody is tiered here yet.</text>"
# /tierlist overall: everybody ranked by the sum of their tier points across every ladder.
list-overall-header: "<value>Overall</value><text> ranking, page {page}/{pages} ({count} players)</text>"
list-overall-row: "<muted>#{place}</muted> <value>{player}</value> <text>{points} points, best</text> {best}"
# Placeholders: an empty leaderboard slot (%tiertags_top_..%) and a player with no place (%tiertags_rank..%).
placeholder-empty: "-"
placeholder-unranked: "-"
ladders: "<text>Ladders: </text><value>{list}</value>"
reloaded: "<value>Config reloaded.</value>"
exported: "<value>Written to </value><text>{file}</text>"
# The tier screens. Every line here is a screen title, a button label or a tooltip.
menu-title: "<value>Tiers</value>"
menu-close: "<white><icon:close></white><text>Close</text>"
menu-back: "<white><icon:back></white><text>Back</text>"
menu-back-tip: "<text>Back to the screen before.</text>"
menu-home-me: "<value>{player}</value><text>: best </text>{best}<text>, {points} points</text>"
menu-home-untiered: "<text>You hold no tier yet. Ask a tester for a test.</text>"
menu-ladders: "<white><icon:tier></white><accent2>Tier lists</accent2>"
menu-ladders-tip: "<text>The ranked list of every ladder.</text>"
menu-ladders-title: "<value>Tier lists</value>"
menu-ladders-intro: "<text>Pick a ladder to see who is on top.</text>"
# {icon} is the ladder's own item from ladder-icons above.
menu-ladder: "<white>{icon}</white><value>{ladder}</value> <muted>({count})</muted>"
menu-ladder-tip: "<text>The ranked list for {ladder}.</text>"
menu-list-title: "<value>{ladder}</value>"
# The button under the ladders that opens the overall ranking.
menu-overall: "<white><icon:top></white><accent2>Overall</accent2> <muted>({count})</muted>"
menu-overall-tip: "<text>Everybody across every ladder, by tier points.</text>"
menu-overall-title: "<value>Overall ranking</value>"
# Every place on a list is a button that opens that player's tiers; the search field finds a name.
list-hint: "<muted>Search a name, or click one to see all their tiers.</muted>"
# The rows of the list screens. {tiers} is every tier the player holds, each with its ladder's item.
list-overall-entry: "<muted>#{place}</muted> <value>{player}</value> {tiers}"
list-entry: "<muted>#{place}</muted> <value>{player}</value> {tier}"
# /tier view: which tier you see on everyone, in tab and above heads. Only your screen changes.
menu-tags: "<white><icon:spyglass></white><accent2>Tags I see</accent2>"
menu-tags-tip: "<text>Pick which tier you see on everyone. Only your screen changes.</text>"
menu-tags-title: "<value>Tags I see</value>"
menu-tags-intro: "<text>Pick which tier you see next to every player's name, in tab and above heads. Nobody else's screen changes.</text>"
menu-tags-current: "<good>✔</good> {mode}"
menu-tags-pick-tip: "<text>Show this on everyone, for you only.</text>"
view-mode-best: "<value>Best tier</value>"
view-mode-off: "<value>No tags</value>"
view-set: "<text>You now see </text>{mode}<text> on everyone.</text>"
view-unknown: "<bad>Pick one of: </bad><value>{list}</value>"
players-only: "<bad>Only players can do that.</bad>"
list-row-tip: "<text>Every tier {player} holds.</text>"
menu-field-search: "<text>Search a player</text>"
menu-search: "<white><icon:search></white><accent2>Search</accent2>"
menu-search-tip: "<text>Find the name typed above (the start of it is enough).</text>"
search-none: "<text>Nobody tiered is called </text><value>{name}</value><text>.</text>"
menu-prev: "<white><icon:back></white><text>« Page back</text>"
menu-prev-tip: "<text>The page before.</text>"
menu-next: "<white><icon:next></white><text>Page on »</text>"
menu-next-tip: "<text>The next page.</text>"
menu-set: "<white><icon:nick></white><accent2>Set a tier</accent2>"
menu-set-tip: "<text>Testers only: give or take a tier.</text>"
menu-set-title: "<value>Set a tier</value>"
menu-set-intro: "<text>Type the name, pick the ladder and the tier, then set it.</text>"
menu-set-nothing: "<text>There are no ladders or no tiers in config.yml yet.</text>"
menu-field-player: "<text>Player</text>"
menu-field-ladder: "<text>Ladder</text>"
menu-field-tier: "<text>Tier</text>"
menu-set-apply: "<white><icon:yes></white><good>Set this tier</good>"
menu-set-apply-tip: "<text>Give the player the tier above.</text>"
menu-set-remove: "<white><icon:delete></white><bad>Remove from this ladder</bad>"
menu-set-remove-tip: "<text>Take away whatever they hold on that ladder.</text>"
menu-set-view: "<white><icon:yes></white><value>Show their tiers</value>"
menu-set-view-tip: "<text>Every ladder for the player above.</text>"
menu-view-title: "<value>{player}</value>"
menu-export: "<white><icon:save></white><text>Export now</text>"
menu-export-tip: "<text>Write the JSON file for the website.</text>"
menu-reload: "<white><icon:reload></white><text>Reload config</text>"
menu-reload-tip: "<text>Read config.yml again.</text>"
# One thank-you line with the BuiltByBit review link: once in the console after install and once
# in chat for the first operator who joins. It never repeats and sends nothing anywhere. false turns it off.
review-reminder: trueConfig guide
The short annotated version from the listing. If it and the files above disagree, the files are what actually ships.
ladders: key: label. Add or rename freely.
sword: "Sword"
axe: "Axe"
smp: "SMP"
tiers: lowest to highest. Points drive "best tier" and global points.
LT5: { color: "<gray>", points: 1 }
HT3: { color: "<aqua>", points: 8 }
HT1: { color: "<gold>", points: 32 }
display:
enabled: true
format: "<dark_gray>[</dark_gray>{tier}<dark_gray>]</dark_gray> " the tag in tab and above the head
color-name: false also colour the name like the tier
announce:
enabled: true broadcast when a tier is set
list:
per-page: 10
export:
enabled: true
every-minutes: 5
file: "tiers.json" relative to plugins/TierTags, or an absolute path into your web rootWhere this summary and the default files differ (the summary sometimes uses example values):
display.format: the summary shows'<dark_gray>[</dark_gray>{tier}<dark_gray>]</dark_gray> ', the default file has'{icon}<dark_gray>[</dark_gray>{tier}<dark_gray>]</dark_gray> '.
FAQ
Which servers and versions does it run on?
It needs Paper or a Paper fork like Purpur, because it uses Paper-only APIs (the dialog API for its menus, Adventure text components). Spigot and CraftBukkit won't work. The listing says Minecraft 1.21.11 (or newer 1.21.x). plugin.yml declares api-version 1.21, the jar is built against Paper API 1.21.11, and it needs Java 21 or newer.
Does it need other plugins?
No, it runs without any other plugin (plugin.yml has no hard dependencies). Optional: PlaceholderAPI (softdepend), used when it's there. On first start the server downloads org.xerial:sqlite-jdbc:3.53.2.1, so it needs internet access then. The listing adds: Works next to other nametag plugins that use teams only if they leave players in no team; if you already use a tab/nametag plugin, set display.enabled to false and use the placeholders in it instead.
How do I apply config changes?
Edit plugins/TierTags/config.yml and run /tier reload (reload the config). Restarting works too.
Does it run on Folia, or for Bedrock players?
I haven't tested it on Folia, and plugin.yml doesn't declare folia-supported. I haven't tested Bedrock players through Geyser either.
Is there DRM or a licence key?
No. There is nothing to activate and no licence server to reach, and the code is not obfuscated.
How long does setup take?
Drop the jar into /plugins and restart. The setup guide above has 4 short steps.
Can testers set tiers without admin rights?
Yes. Give them tiertags.tester: they can set and remove tiers, nothing else.
Links
- BuiltByBit
- TierTags
- Support
- discord.gg/KG4ubAZEuw
- Everything
- The Complete Collection on BuiltByBit
- More plugins
- All my plugins
- Custom work
- Commissions
Support
Questions, bugs or ideas: the active support Discord or the discussion tab on BuiltByBit. When something breaks, include your server version and the error from the console.











