Skip to content

Feature guide: Sorting players in tablist

NEZNAMY edited this page Jul 28, 2023 · 71 revisions

Content

Enabling

To enable sorting, you must have either Nametags or Layout (or both) enabled.

To verify you enabled sorting, run /tab debug. It will say Sorting type: followed by anything except DISABLED.

Methods of sorting

Below are all of the different methods that you can use to sort players in TAB.

GROUPS

This is the default and recommended method. Players will be sorted by their primary permission group, according to the configured group list.

First, put your players into groups in your permission plugin. All ways to do it can be found at How to assign players into groups.
Verify player's group using /tab debug <player>. It should say Primary permission group: followed by group you configured. If not, you did not assign players into groups correctly.

Second, place all of your groups in to a comma separated list in order of priority.
For example, if you have the groups owner, admin, mod, and default, and want to have groups assigned in that order, you would end up with a configuration like GROUPS:owner,admin,mod,default.
This line should then be placed under sorting-types, which is under scoreboard-teams. This should look something like this:

scoreboard-teams:
  sorting-types:
    - "GROUPS:owner,admin,mod,default"

If you want 2 or more groups with the same priority, separate them with | symbol. Example:

scoreboard-teams:
  sorting-types:
    - "GROUPS:owner,admin,vip1|vip2,default"

Where vip1 and vip2 will be sorted with the same priority (3rd).

PERMISSIONS

This method is not recommended, as many low quality servers give OP to every staff member and don't know how to negate permissions, making this option not function as intended. If you think you can pull it off, and sorting by primary group is not an option, you can give this a try.
This method is, however, handy when trying to sort specific players without assigning them into a group.

This method will sort players based on permission nodes they have.
Place all of your permissions in to a comma separated list in order of priority.
For example, if you have the permissions my.permission.1, my.permission.2, my.permission.3, and want to have players sorted in that order, you would end up with a configuration like PERMISSIONS:my.permission.1,my.permission.2,my.permission.3.
Example:

scoreboard-teams:
  sorting-types:
    - "PERMISSIONS:my.permission.1,my.permission.2,my.permission.3"

PLACEHOLDER

This method sorts players using the output of a placeholder and comparing that to pre-defined values.
To configure this sorting type, write the placeholder that you want to use, followed by a colon (:), followed by a comma separated list of outputs to check against.
For example, if you want to sort players using the output of the %afk% placeholder, depending on whether it is yes or no, you would do that using a configuration such as PLACEHOLDER:%afk%:no,yes, where players who the placeholder outputs no for will be sorted above players who the placeholder outputs yes for in this case, putting AFK players on the bottom.
Example:

scoreboard-teams:
  sorting-types:
    - "PLACEHOLDER:%afk%:no,yes"

PLACEHOLDER_A_TO_Z

This method sorts players alphabetically according to the output of a placeholder.
To configure this sorting type, write the placeholder that you want to use. That's it.
For example, if you want to sort players by their name alphabetically, you would do that using a configuration such as PLACEHOLDER_A_TO_Z:%player%.
Example:

scoreboard-teams:
  sorting-types:
    - "PLACEHOLDER_A_TO_Z:%player%"

PLACEHOLDER_Z_TO_A

This method sorts players reverse alphabetically according to the output of a placeholder.
This is identical to the above A to Z sorting, except that the alphabet is backwards, so Z comes first, and A comes last.
To configure this sorting type, write the placeholder that you want to use. That's it.
For example, if you want to sort players by their name reverse alphabetiically, you would do that using a configuration such as PLACEHOLDER_Z_TO_A:%player%.
Example:

scoreboard-teams:
  sorting-types:
    - "PLACEHOLDER_Z_TO_A:%player%"

PLACEHOLDER_LOW_TO_HIGH

This method sorts players numerically depending on the output of a numeric placeholder from lowest value to highest value.
Only placeholders that output number values will work with this sorting type!
To configure this sorting type, write the placeholder that you want to use. That's it.
For example, if you want to sort players using the output of the %health% placeholder from lowest health to highest, you would do that using a configuration such as PLACEHOLDER_LOW_TO_HIGH:%health%.
Example:

scoreboard-teams:
  sorting-types:
    - "PLACEHOLDER_LOW_TO_HIGH:%health%"

PLACEHOLDER_HIGH_TO_LOW

This method sorts players numerically depending on the output of a numeric placeholder fro highest value to lowest value.
Only placeholders that output number values will work with this sorting type!
To configure this sorting type, write the placeholder that you want to use. That's it.
For example, if you want to sort players using LuckPerms weights, you would do that using a configuration such as PLACEHOLDER_HIGH_TO_LOW:%luckperms_highest_group_weight%.
Example:

scoreboard-teams:
  sorting-types:
    - "PLACEHOLDER_HIGH_TO_LOW:%luckperms_highest_group_weight%"

Combining multiple sorting types

Since sorting-types is a list, you are able to use more than one sorting type. Sorting type priorities go in the same order as defined in the config. Let's take a look at the default config:

  sorting-types:
    - "GROUPS:owner,admin,mod,helper,builder,vip,default"
    - "PLACEHOLDER_A_TO_Z:%player%"

Here, players are sorted by their group first. Owner goes above admin etc. However, if 2 people have the same group (such as admin), next sorting type decides final order. In this case, admin with alphabetically lower username will be higher in the tablist.

A common request is putting AFK players on the bottom of tablist. This can be achieved with the following configuration:

  sorting-types:
    - "PLACEHOLDER:%afk%:no,yes"
    - "GROUPS:owner,admin,mod,helper,builder,vip,default"
    - "PLACEHOLDER_A_TO_Z:%player%"

With AFK status taking the highest priority, AFK players will be always sorted below players which are not AFK. Both player groups (afk and non-afk) then follow the rest of the logic explained above to define the final order. If trying to copypaste this example, keep in mind Placeholder output replacements work here as well, so if you are using a fancier output for %afk%, you will need to use outputs respectively when defining sorting as well.

Although you can theoretically use as many sorting types as you want, there are still strict limits set by mojang. See more about these limits and how to avoid them as much as possible at Additional note 1 - Limitations.

Additional settings

Option name Default value Description
case-sensitive-sorting true When enabled, players will be sorted as A-Z a-z. When disabled, Aa-Zz.

Additional info

Additional note 1 - Limitations

All sorting elements must together build a team name up to 16 characters long. Because of that, cuts in placeholder outputs may be required. TAB is already using the shortest possible values for all sorting types:

  • GROUPS, PERMISSIONS and PLACEHOLDER - 1 character
  • PLACEHOLDER_LOW_TO_HIGH and PLACEHOLDER_HIGH_TO_LOW - 10 characters
  • PLACEHOLDER_A_TO_Z and PLACEHOLDER_Z_TO_A - as many as used

All your sorting types must be within a 15 character limit. Any characters above that will be cut off (TAB reserves 1 character to ensure each player is in a unique team). To get the most out of it, use the 1-character sorting types where possible.

Additional note 2 - per-world sorting

Defining a per-world sorting type is not supported. However, this can be achieved with Conditional placeholders. Simply check for %world% and return one placeholder if it matches, another one if not. This will work with anything, not just worlds (server, regions, etc).

Additional note 3 - Compatibility issues with other plugins

As you already know by now, sorting is managed by scoreboard teams (their names to be exact). Player can only be member of one team. In other words, only one plugin can handle teams at a time. Having multiple plugins handle teams is supposed to end in a disaster.

Fortunately, TAB contains a function that prevents other plugins from assigning players into teams. This can be enabled/disabled by toggling anti-override setting under scoreboard-teams. This is however highly recommended to keep enabled, unless all of your plugins are configured correctly. When a plugin tries to override TAB's teams, this action is logged into anti-override.log file. If your file is empty / does not exist, it means you have no conflicting plugins / settings and can disable this option, slightly boosting performance. If the file exists, most of the time you can guess where the teams come from by their name.
Here are a few common teams and their sources (xxxx means any, usually random character sequence):

  • collideRule-xxxx - this comes from Paper. Not going to explain why as that would be quite long, but the way you can avoid is by setting enable-player-collisions: true in paper config and false in tab config (yes, collisions will be disabled).
  • CMINPxx - CMI, set DisableTeamManagement: true in plugins/CMI/config.yml.
  • CIT-xxxxxxxxxxxx - Citizens NPC with the same name as some online player. Make NPC names not match real players and use holograms to display your desired text (/npc name or something).
  • PVP-xxxxxxxxxxxx - Team coming from PvPManager plugin.

This detection, however, is not 100%. Because of that, you may still be experiencing a compatibility issue even with anti-override enabled. To identify such issue, check if /tab reload fixes your sorting issue. If it does, it's a compatibility issue of some sort. If not, it is most likely a misconfiguration issue.

Common mistakes

Every possible mistake could be called "not reading this wiki page", but that would make this section pointless. For that reason let's call it list of mistakes made when following this page.

The most common mistakes include:

  • Disabling both teams and layout, not realizing it disables sorting as well.

  • Disabling anti-override without disabling teams in other plugins.

  • Mistaking primary-group-finding-list for sorting list, despite that list having nothing to do with sorting and by default even having a comment above it saying it has nothing to do with sorting.

  • Not configuring primary groups correctly. This can have multiple reasons, such as

    • Not configuring group weights in LuckPerms.
    • Accidentally enabling use-bukkit-permission-manager option when on BungeeCord without knowing what it does.
    • Installing TAB on BungeeCord without having any permission plugin on BungeeCord.
    • Enabling assign-groups-by-permissions without giving those permissions.

    Debug command will help you identify if this is your case.

  • Using a plugin that causes TAB to fail to apply teams (such as Tablisknu). This includes installing TAB plugin on both bukkit and bungeecord, causing the installations to conflict.

API

To get started with the API, see Developer API page.

To access this feature, you'll need to obtain SortingManager instance. Get it using TabAPI.getInstance().getSortingManager(). If sorting is disabled, the method will return null.

You can change player's team name using following methods:

  • SortingManager#forceTeamName(TabPlayer, String) - Sets player's team name to specified value (and performs team unregister & register with new name).
  • SortingManager#getForcedTeamName(TabPlayer) - Returns player's forced team name using the method above. Will return null if no value is set.

Unfortunately, there is no simple way of just changing one's position while still accounting for other players. This is because the plugin supports a lot of sorting options, not just groups, so doing amateur stuff like "priority 1, 2" doesn't make sense. If you are really only interested in sorting by groups and changing group which player is sorted as, you can use TabPlayer#setTemporaryGroup(String) and then TabPlayer#resetTemporaryGroup() to reset it back.

Clone this wiki locally