Skip to content

Repository files navigation

MyRank

繁體中文 | English

A server-side Fabric mod that shows a ranked leaderboard in the scoreboard sidebar, with the player's own rank appended at the bottom.

Built on fabric-mod-template, using a preprocessor for multi-version support. The core version is Minecraft 1.17.

Supported versions

Minecraft Status
1.17.x ✅ core
1.18.x
1.19.x
1.20 – 1.20.1
1.20.2
1.20.3/4
1.20.5/6
1.21 – 1.21.1

Features

  • Driven entirely by vanilla commands: set the leaderboard with /scoreboard objectives setdisplay sidebar <objective>, clear the sidebar to disable it; sidebar.team.<color> slots are supported — players on a colored team see their team's board first (matching the vanilla client logic)
  • Server side only (environment: "*", installing on both sides is fine too; the integrated server in singleplayer works as well)
  • No Fabric API dependency, pure mixin implementation
  • Every player sees a personalized sidebar (the objective is faked via packets and never touches the real server scoreboard):
    • shows the top N entries of the objective (default 10; ranks 1/2/3 get distinct colors, your own name is highlighted in green)
    • if you are below the top list, an extra #rank yourname line with your score is appended
  • Event-driven updates: scoreboard changes are reflected within the same tick (≤50ms), with snapshot short-circuiting and per-line diffing so high-frequency changes stay cheap; the display slot is re-claimed once per second, self-healing against vanilla sidebar broadcasts
  • Persistent settings: the ranking mode and each player's top count are stored in myrank.json in the world directory and restored on restart (which objective is displayed already lives in the vanilla scoreboard data)
  • Localized messages: translated on the server using each player's reported client language (works for vanilla clients too), with built-in en_us / zh_tw / zh_cn and automatic fallback to en_us; language files live in src/main/resources/assets/myrank/lang/*.yml (yamlang format) — add a file to add a language
  • Pinned rows: /myrank pin add <name> pins a score holder (e.g. a datapack-maintained fake player like "Total") to the top of the sidebar — no #rank prefix, excluded from ranking and player counts; pairs seamlessly with datapacks that sum totals every tick (see "Pinned rows & datapack totals" below)
  • Permission nodes: with a fabric-permissions-api provider installed (e.g. LuckPerms), the OP commands check permission nodes; without one, vanilla OP levels are used

Commands

The leaderboard itself is toggled with vanilla commands:

/scoreboard objectives setdisplay sidebar <objective>        enable / switch the leaderboard
/scoreboard objectives setdisplay sidebar.team.aqua <obj>    a board only the aqua team sees
/scoreboard objectives setdisplay sidebar                    disable
Command Permission Description
/myrank display <slot> on|off OP (2) whether MyRank takes over that slot (off = show the vanilla scoreboard; all slots default on, persisted)
/myrank mode competition OP (2) ranks skip after ties: 1, 2, 2, 4 (default)
/myrank mode dense OP (2) ranks stay consecutive after ties: 1, 2, 2, 3
/myrank pin add <name> OP (2) pin a score holder to the top of the sidebar (no rank, excluded from ranking)
/myrank pin remove <name> OP (2) unpin a score holder
/myrank pin list OP (2) list all pinned names
/myrank top <1-15> everyone how many top entries your own sidebar shows (persisted)
/myrank query everyone your current rank, score and the number of ranked players
/myrank query <name> everyone query any ranked player (with tab completion)
/myrank list [page] everyone the full leaderboard in chat, paginated (10 per page)
/myrank everyone which leaderboard you are shown and the current ranking mode

query/list operate on the board the command sender currently sees (team-color slot first, same as the sidebar).

Tied players always share a rank; mode only decides how ranks continue after a tie group.

Permission nodes

With a fabric-permissions-api provider (e.g. LuckPerms) installed, the OP commands map to the nodes below, defaulting to vanilla OP level 2; without a provider, OP levels are checked directly:

Node Command
myrank.command.display /myrank display
myrank.command.mode /myrank mode
myrank.command.pin /myrank pin

Pinned rows & datapack totals

Leaderboard data keeps accumulating in real time via scoreboard criteria (e.g. minecraft.mined:minecraft.deepslate), while a datapack sums the server-wide total into a fake player (e.g. "Total") every tick. Pin that fake player with /myrank pin add, and it:

  • shows at the very top of the sidebar, in gold, without a #rank prefix
  • takes no part in ranking, and is excluded from /myrank query / /myrank list counts

Datapack example (an mcfunction hooked into minecraft:tick; mine_count is a criteria objective):

scoreboard players set Total mine_count 0
execute as @a run scoreboard players operation Total mine_count += @s mine_count
/myrank pin add Total
/scoreboard objectives setdisplay sidebar mine_count

The sidebar sorts by score (determined by the client). On 1.20.3+, pinned rows' sorting scores are automatically bumped above every ranked line, and a number format makes the display always show the real value — guaranteeing they stay on top. On 1.20.2 and earlier, pinned rows use their real score directly, so the displayed value is always correct, but they may not render on top when tied with a ranked entry (as the client then uses alphabetical order). Names containing non-ASCII or special characters must be double-quoted in commands. Pinned names are stored in the world's myrank.json and apply to holders with that name in every objective.

Quick test

/scoreboard objectives add test dummy "xxx"
/scoreboard players set Alice test 100
/scoreboard players set Bob test 80
/scoreboard objectives setdisplay sidebar test

Building

.\gradlew buildAndGather

The jars of every version are gathered into build/libs/; for a single version use .\gradlew :1.17.1:build, whose output lands in versions/1.17.1/build/libs/.

Adding a supported version

  1. Add the new version to versions in settings.json
  2. Copy versions/<closest version>/gradle.properties to versions/<new version>/ and adjust it (see the template repo's counterpart and https://fallen-breath.github.io/fabric-versions/)
  3. Add a createNode in the preprocess block of build.gradle and connect it with link
  4. Handle version differences in code with preprocessor comments like //#if MC >= 11900 (e.g. MyRankTexts.literal wraps the 1.19 TextComponentComponent.literal change)

Where version differences live: text building in MyRankTexts, the sendSuccess wrapper at the end of MyRankCommand, and all scoreboard/packet APIs in the "Version-specific scoreboard access" section at the top of MyRankManager. Extending to 1.21.2+ should only require touching these.

About

A server-side Fabric mod that shows a ranked leaderboard in the scoreboard sidebar, with the player's own rank appended at the bottom.

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages