Skip to content

Leaderboards and Podium NPCs

Create: Hydraulics edited this page Aug 17, 2026 · 1 revision

Leaderboards and Podium NPCs

GenRaid Setup includes a live leaderboard system built on ajLeaderboards, PlaceholderAPI, and FancyNpcs. The top ranked player's actual skin and name are shown on an in-game podium NPC, and every player who looks at it also sees their own personal rank and balance.

This page covers how the system works and walks through the most common issue you are likely to run into, along with the exact fix.

How It Works

  1. GenSteal tracks each player's stats through PlaceholderAPI.
  2. ajLeaderboards reads those stats and caches a ranked list.
  3. FancyNpcs reads specific ajLeaderboards placeholders and uses them to set an NPC's skin and name.

Because this chains three separate plugins together, most issues come from one link in that chain silently failing rather than the whole system being broken.

The Most Common Issue: Leaderboard Shows "---"

If a leaderboard placeholder like %ajlb_lb_<board>_1_alltime_value% shows --- instead of a real number, do not assume the plugin is broken or that PlaceholderAPI is misconfigured.

--- is ajLeaderboards' built in default for "no cached data exists for this player on this board." It is not a formatting error. It means the cache was never written, not that it was written wrong.

Step 1: Confirm the base placeholder actually works

/papi parse me %gensteal_tokens_raw%

If this returns a real number, GenSteal and PlaceholderAPI are working correctly, and the problem is somewhere between ajLeaderboards and the cache.

Step 2: Check if the player is being blocked from updates

This is, by far, the most common cause of this entire issue.

/ajlb checkupdate <board> <player>

If you see a warning that the player has the dontupdate permission, that is your answer. ajLeaderboards has a built in permission, ajleaderboards.dontupdate.<board> (or the wildcard ajleaderboards.dontupdate.*), which blocks a specific player from ever being automatically updated on a board.

This is almost always caused by testing as OP or with a wildcard rank. OP status and ranks carrying LuckPerms' * wildcard, such as Owner or Manager on this setup, silently include this permission along with everything else. If your own test account never updates no matter what you try, this is why.

To check directly:

/lp user <yourname> permission check ajleaderboards.dontupdate.<board>

If that comes back true, remove or negate it:

/lp user <yourname> permission set ajleaderboards.dontupdate.<board> false

Then test again with /ajlb checkupdate.

If you would rather disable this feature server wide instead of managing it per player, set the following in ajLeaderboards' config.yml:

enable-dontupdate-permission: false

Step 3: Understand what checkupdate actually tells you

/ajlb checkupdate only confirms that a player is eligible to be updated. It does not mean an update has actually happened yet. If it says the player should be updated but the leaderboard still shows ---, force the write directly:

/ajlb updateplayer <board> <player>

Then confirm it landed in the cache:

/ajlb list <board>

Your player should now appear with their actual value.

Step 4: If the value still will not appear after all of the above

Check require-zero-validation in ajLeaderboards' config.yml. If a player's very first cached read happened to be zero, for example before they had earned anything, ajLeaderboards may hold that value as unconfirmed and require one more non-zero read before it trusts and displays it. Run /ajlb updateplayer a second time to rule this out.

Setting Up the Podium NPC's Skin

The podium NPC uses FancyNpcs' placeholder skin support to display whoever is currently ranked first. This works differently from a normal placeholder, because the NPC is not tied to any specific viewing player.

Use the dedicated skin placeholder, not the name placeholder

ajLeaderboards provides a placeholder built specifically for this use case:

%ajlb_lb_<board>_<number>_<type>_skin%

Use this one for the NPC's skin field, not %ajlb_lb_<board>_<number>_<type>_name%. The _skin% variant is designed to resolve safely even when a position has no player yet. The _name% variant can return an empty string in that case, which will cause FancyNpcs to throw an error trying to apply it as a skin.

Test without player context before applying it

Since the NPC is not shown from one specific player's point of view, test the placeholder the same way FancyNpcs will actually read it:

/papi parse --null %ajlb_lb_<board>_1_alltime_skin%

Do not test with /papi parse me, that resolves in a different context than the one FancyNpcs actually uses, and can appear to work in testing while still failing for real.

Positions with no player yet

ajLeaderboards only tracks players who joined the server after the board was created with /ajlb add. If you are testing with only one account, or with alts that existed before the board was added, positions 2 and 3 will show as empty. This is expected, not a bug. Either wait for real players to join after the board exists, or have your test alts log in again after the board has been created.

Personalized Viewer Stats

Every player sees their own live rank and balance, using a different placeholder family than the podium:

%ajlb_position_<board>_<type>%
%ajlb_value_<board>_<type>%

These require actual player context, since they are answering "what is my rank," not "who is in first place." Test these with /papi parse me, not --null.

Skin Refresh Behavior

FancyNpcs automatically re-checks and refreshes placeholder driven skins on its own over time. You do not need to build or run anything extra to keep the podium updated as rankings change.

One thing worth knowing: skin fetches go through Mojang's skin servers, which are rate limited. If you notice skins occasionally failing to update or falling back to a default skin under heavy server load, this is a rate limiting symptom, not a sign that anything is misconfigured.

Clone this wiki locally