-
Notifications
You must be signed in to change notification settings - Fork 288
Placeholders
- About
- Internal placeholders
- PlaceholderAPI
- Relational placeholders
- Refreshing
- Placeholder is not working
- API
TAB offers various placeholders to display the most common information. It also supports PlaceholderAPI placeholders.
Basic placeholders provided by the plugin. Most of these placeholders were added because they were requested by people who don't want to install another plugin just to show username. Some of them have configurable output in config.yml in Placeholders section. Unused placeholders do not affect performance in any way.
Placeholders must be refreshed.
All internal placeholders have a manually defined refresh interval,
which I found the most optimal. You can override the refresh intervals if you want to.
Time is in milliseconds.
-1 is used for placeholders which are in fact constants (such as %player%),
or fire an event each time they change, which can be listened to (such as %world%) and value updated.
Refresh interval for conditions is set to be equal to the fastest refreshing placeholder used inside each condition.
These placeholders are available on all platforms.
| Identifier | Refresh interval | Description |
|---|---|---|
| %online% | 1000 | Total online player count on server where plugin is installed (excluding vanished players). If the plugin is installed on a proxy, it will show total player count on the whole network. |
| %world% | -1 | Name of world where player is |
| %worldonline% | 1000 | Amount of players in the same world (excluding vanished players) as the player |
| %ping% | 500 | Player's ping to the server where TAB is installed. Note: This value is measured by the server and TAB is only retrieving that value. If it's wrong, it's not a TAB issue. |
| %player% | -1 | Player's name |
| %uuid% | -1 | Player's UUID |
| %time% | 500 | Current real time, output is configurable in config.yml in time-format option |
| %date% | 60000 | Current date, output is configurable in config.yml in date-format option |
| %staffonline% | 2000 | Amount of online players with tab.staff permission |
| %nonstaffonline% | 2000 | Amount of online players without tab.staff permission |
| %memory-used% | 200 | Used RAM of server in MB |
| %memory-max% | -1 | Total RAM of server in MB |
| %memory-used-gb% | 200 | Used RAM of server in GB |
| %memory-max-gb% | -1 | Total RAM of server in GB |
| %player-version% | -1 | User-friendly version of player, such as 1.14.4. For versions that share the same protocol version number, the higher one is returned (for example 1.20 & 1.20.1 -> 1.20.1 is returned) |
| %player-version-id% | -1 | Network ID of player's version. You can see the full version list in TAB's source code. Useful for conditions to create per-version results using numeric operations since version names cannot be effectively compared. |
| %luckperms-prefix% | 1000 | Prefix from LuckPerms from the server where TAB is installed |
| %luckperms-suffix% | 1000 | Suffix from LuckPerms from the server where TAB is installed |
| %luckperms-prefixes% | 1000 | All prefixes combined from LuckPerms from the server where TAB is installed |
| %luckperms-suffixes% | 1000 | All suffixes combined from LuckPerms from the server where TAB is installed |
| %displayname% | 500 | Display name variable set by permission plugin, typically prefix + name + suffix |
| %group% | 1000 | Returns player's primary group name. Created for internal functionality, but can be used as a display placeholder as well. |
| %vanished% | 1000 | Returns true/false based on player's vanish status. Created for internal functionality, but can be used as a display placeholder as well. |
| %bedrock% | -1 | Returns true/false based on whether player is using Bedrock edition or not (Java) |
| %bossbar_announce_time_total_<bossbar>% | -1 | Total time (inputted value) of an announced bossbar. |
| %bossbar_announce_time_left_<bossbar>% | 100 | Remaining time of an announced bossbar. |
| %online_<server name>% | 1000 | Amount of online players on specified server (excluding vanished players) |
| %% | -1 | Returns the % symbol. Useful to display % symbol without breaking all placeholders after it |
These placeholders only work when TAB is installed on a backend server, they don't work when TAB is on a proxy. If you have TAB installed on proxy and wish to use these, use their PlaceholderAPI alternative with Bridge plugin installed for PlaceholderAPI support on proxy.
| Identifier | Refresh interval | Description | PlaceholderAPI alternative |
|---|---|---|---|
| %health% | 100 | Player's health, rounded up to match Minecraft's heart display. | %player_health_rounded% |
| %displayname% | 500 | Player's display name value set by permission plugin. | %player_displayname% |
| %tps% | 1000 | TPS of server from the last minute. Measured by the server. Not directly available on modded platforms - primitive approximation using MSPT (TPS = 1000/MSPT, max 20) is used there. | %server_tps_1% |
| %mspt% | 1000 | Server's current milliseconds per tick (not available on Spigot) | - |
| %deaths% | 1000 | Player's death count | %statistic_deaths% |
| Identifier | Refresh interval | Description |
|---|---|---|
| %server% | -1 | Name of server where player is, defined in proxy's config. |
| %serveronline% | 1000 | Amount of online players on server where the player is (excluding vanished players) |
| %playerlist-group_<group>% | 1000 | Amount of online players in specified global playerlist group (therefore the feature must be enabled) |
PlaceholderAPI is supported and relational placeholders are supported too. When parsing relational placeholders, TAB puts viewer as the first player argument and target player as the second argument.
You can find most of the placeholders that PlaceholderAPI offers on PlaceholderAPI wiki. Some plugins are not listed there, for those you'll need to check their own wiki for placeholders.
TAB also offers its own placeholders into PlaceholderAPI. To enable TAB's expansion, set
placeholders:
register-tab-expansion: true
in config.yml.
Full list of placeholders (general + feature specific):
General:
| Identifier | Description |
|---|---|
%tab_replace_<placeholder>% |
Applies Placeholder output replacements to a PlaceholderAPI placeholder (for example %tab_replace_essentials_vanished%) |
%tab_placeholder_<placeholder>% |
returns value of tab's internal placeholder (such as %tab_placeholder_animation:name% for %animation:name%) (this also applies Placeholder output replacements to them if configured) |
BossBar:
| Identifier | Description |
|---|---|
%tab_bossbar_visible% |
"Enabled" if visible, "Disabled" if not |
NameTags:
| Identifier | Description |
|---|---|
%tab_tagprefix% |
Player's current tagprefix with placeholders parsed. |
%tab_tagsuffix% |
Player's current tagprefix with placeholders parsed. |
%tab_tagprefix_raw% |
Player's current raw tagprefix with placeholder identifiers. |
%tab_tagsuffix_raw% |
Player's current raw tagsuffix with placeholder identifiers. |
%tab_nametag_visibility% |
"Enabled" if player can see nametags, "Disabled" if disabled using /tab nametag toggleview
|
Scoreboard:
| Identifier | Description |
|---|---|
%tab_scoreboard_name% |
Returns name of player's currently displayed scoreboard or empty string if none is displayed due to no display condition being met. |
%tab_scoreboard_visible% |
"Enabled" if visible, "Disabled" if not (toggled with a command) |
Tablist name formatting:
| Identifier | Description |
|---|---|
%tab_tabprefix% |
Player's current tabprefix with placeholders parsed. |
%tab_customtabname% |
Player's current customtabname with placeholders parsed. |
%tab_tabsuffix% |
Player's current tabprefix with placeholders parsed. |
%tab_tabprefix_raw% |
Player's current raw tabprefix with placeholder identifiers. |
%tab_customtabname_raw% |
Player's current raw customtabname with placeholder identifiers. |
%tab_tabsuffix_raw% |
Player's current raw tabsuffix with placeholder identifiers. |
Unlike classic placeholders which take either 0 (placeholders with the same output for all players) or 1 (per-player placeholders) players, relational placeholders take in 2 players. The first usage was to display relation between two players, specifically enemies / allies (red / green) for factions, allowing players to see faction names of other players colored based on relation. While the usage is not limited to this, the name of the 2-player placeholder type has been established as "relational" and will be called that everywhere.
TAB does not offer any internal relational placeholders. However, it has full support for PlaceholderAPI placeholders. You can also register your own relational placeholders using the API. In PlaceholderAPI, all relational placeholder identifiers must start with %rel_. This rule is adopted and used in TAB as well (including those registered via API).
When passing players into the function, first player is the player viewing the text, second player is the one text is being displayed on.
Code wise, the PlaceholderAPI request function becomes
public String onPlaceholderRequest(Player viewer, Player target, String identifier)
where viewer is the player looking and target is the player the value is being displayed on.
When trying to use placeholders from other plugins, you will need to check their documentation and search for relational placeholders. If your plugin does not appear to offer any, you ran out of luck and TAB cannot do anything about it.
To properly distinguish viewer/target (if needed), your relational placeholder expansion must follow the same order as TAB does. Since PlaceholderAPI never created any convention regarding this, and instead it calls the players one and two, I had to decide and this is the decision.
TAB is refreshing placeholders in intervals. For internal placeholders it's using values I found the most optimal and set directly in the plugin. Refresh intervals for PlaceholderAPI placeholders can be configured.
By default, all placeholders are refreshed asynchronously,
so they don't slow down the server, since reading should be a thread-safe operation.
Some placeholders, however, require to be refreshed in the main thread,
causing problems or throwing errors when refreshed asynchronously.
For these, replace them with %sync:<original placeholder>% and they will be refreshed in the main thread,
for example %server_total_entities% -> %sync:server_total_entities%.
Keep in mind that now you should configure a reasonable refresh interval for these placeholders to not cause TPS drops
(with async placeholders it doesn't really matter).
Configured refresh intervals and CPU usage of placeholders can be checked using /tab cpu.
When using a placeholder, you should know if it's a TAB's internal placeholder or a PlaceholderAPI placeholder. If you don't, that's the problem.
Caution
Remember that using % symbol will mess up placeholder starts and ends, breaking all placeholders after it.
To make the symbol display correctly without messing up placeholders, use %% to display the symbol.
Example: Sale 100% OFF! %some_placeholder% -> Sale 100%% OFF! %some_placeholder%.
Here are few possible reasons:
- You attempted to use a proxy-only placeholder on backend, or backend-only placeholder on proxy
- You used the
%symbol before the placeholder, breaking placeholder starts and ends (see above).
Here are few possible reasons:
- The placeholder is not working in PlaceholderAPI. You can check this using
/papi parse me <placeholder>. If it isn't working there, it's not a TAB issue. If the placeholder you used is advertised somewhere, make sure you have the adequate expansion downloaded. - If you have TAB installed on a proxy, make sure TAB-Bridge is installed on backend servers to forward support to the proxy.
- You used the
%symbol before the placeholder, breaking placeholder starts and ends (see above).
To get started with the API, see Developer API page.
For working with placeholders, you will need the PlaceholderManager. Get it using TabAPI.getInstance().getPlaceholderManager().
Placeholders have two attributes:
- An identifier, which is used to uniquely identify the placeholder. This is also what's usually used for replacement. For example, in
%uptime%, the identifier is%uptime%. - A refresh rate in milliseconds, which is how often the placeholder's refresh function will be called, to get a new value to display. Use
-1to make the placeholder never refresh periodically. This can be used for either constants or placeholders that update on events, and you wish to update their value manually using functions in the respective placeholder interface.
Server placeholders are global to the entire plugin. Their values are not dependent on player.
Examples of server placeholders would be uptime and TPS placeholders.
To register a new server placeholder, use PlaceholderManager#registerServerPlaceholder(String, int, Supplier<Object>). The first two parameters are explained above, and the last parameter is a function that will be called to refresh the value of the placeholder.
Example
TabAPI.getInstance().getPlaceholderManager().registerServerPlaceholder("%system-time%", 50, () -> System.currentTimeMillis());
This placeholder will show current system time and update every 50 milliseconds.
Player placeholders are calculated on a per-player basis. These depend on the player that we want to get the value for.
Examples of player placeholders would be username and prefix.
To register a new player placeholder, use PlaceholderManager#registerPlayerPlaceholder(String, int, Function<TabPlayer, Object>). The first two parameters are explained above, and the last parameter is a function that will be called to refresh the value of the placeholder.
Example
TabAPI.getInstance().getPlaceholderManager().registerPlayerPlaceholder("%player-uuid%", -1, player -> player.getUniqueId());
This placeholder will show player's UUID and never refreshes, since UUID doesn't change at runtime.
Relational placeholders are calculated using a pair of players, instead of a single one. These depend on the player pair that we want to get the value for. Their identifier must start with rel_.
To register a new relational placeholder, use PlaceholderManager#registerRelationalPlaceholder(String, int, BiFunction<TabPlayer, TabPlayer, Object>). The first two parameters are explained above, and the last parameter is a function that will be called to refresh the value of the placeholder.
Example
TabAPI.getInstance().getPlaceholderManager().registerRelationalPlaceholder("%rel_staff_version%", 1000, (viewer, target) -> {
if (viewer.hasPermission("tab.staff")) {
return target.getVersion().getFriendlyName();
} else {
return "";
}
});
This placeholder will show the version of players, but only to those, who have tab.staff permission.
The first player in the method is viewer, the second player is target.
The same order is applied when hooking into PlaceholderAPI as well.
- Why TAB?
- Installation
- Commands & Permissions
- Frequently Asked Questions
- Compatibility
- How to assign players into groups
- Known issues
- TAB-Bridge plugin
- Belowname
- Bossbar
- Global playerlist
- Header/Footer
- Layout
- Multi server support
- Nametags
- Per world playerlist
- Ping spoof
- Playerlist objective
- Scoreboard
- Sorting in tablist
- Spectator fix
- Tablist name formatting