UI Visibility Configuration

Configuration system for controlling visibility of UI elements that can be displayed separately for the current player versus other players and NPCs.

Toggling UI elements

Every visibility switch is a row of the config, so the life bars and the player names are shown or hidden from the administration panel without touching any file.

  1. Log in to the administration panel at /reldens-admin (the path can be changed with the RELDENS_ADMIN_ROUTE_PATH environment variable).
  2. Open Settings > Config (/reldens-admin/config).
  3. Type ui/ in the search box and click Filter to list all the client UI rows. Use ui/lifeBar or ui/players to go straight to the life bars or the player names rows. The search is kept until you click Clear Filters.
  4. Click the edit icon of the row, set the Value to 1 to show the element or 0 to hide it, and click Save.
  5. The rows ui/lifeBar/showCurrentPlayer, ui/players/showCurrentPlayerName and ui/players/showNamesLimit are not created by the installation. Click Create New and fill Scope client, the Path, the Value and the Type (boolean for the switches, float for the names limit).
  6. Restart the server and reload the game: the config is loaded when the server starts and sent to the players when they join.
Admin Panel - Config list filtered by ui/ with the client UI visibility rows

Configuration reference

All the rows use the scope client:

  • ui/lifeBar/showCurrentPlayer (boolean, not installed, hidden when missing) - life bar of the current player.
  • ui/lifeBar/showAllPlayers (boolean, 0) - life bars of the other players, always visible when enabled.
  • ui/lifeBar/showEnemies (boolean, 1) - life bars of the NPCs and enemies, never shown when disabled.
  • ui/lifeBar/showOnClick (boolean, 1) - show the life bar of the clicked target only.
  • ui/lifeBar/enabled (boolean, 1) - turns the whole life bars system on or off.
  • ui/players/showCurrentPlayerName (boolean, not installed, hidden when missing) - name of the current player.
  • ui/players/showNames (boolean, 1) - names of the other players.
  • ui/players/showNamesLimit (float, not installed, 10 when missing) - maximum name length before it is cut with an ellipsis.

The combinations of these switches are explained in each section below, and the life bar colors, size and position are in Stat Bars Configuration.

Code integration (advanced)

Life Bar Visibility

Controls the display of health bars above player and NPC sprites. Allows independent configuration for the current player, other players and NPCs / enemies.

Configuration paths

  • Scope: client
  • Base path: ui/lifeBar
  • Type: boolean (type 3)

Visibility properties

  • showCurrentPlayer
    • Path: client/ui/lifeBar/showCurrentPlayer (not seeded by the migrations, must be added manually).
    • Default: disabled (with no config row the value resolves to undefined).
    • Controls: the current player's lifebar visibility.
    • Use case: disable when using alternative UI systems like the stat bars in the player info panel.
  • showAllPlayers
    • Path: client/ui/lifeBar/showAllPlayers.
    • Default: 0 (disabled).
    • Controls: the other players' lifebars visibility.
    • Use case: enable for PvP-focused games where seeing the other players' health is important.
  • showEnemies
    • Path: client/ui/lifeBar/showEnemies.
    • Default: 1 (enabled).
    • Controls: the NPCs and enemies lifebars visibility. When disabled their bars are never shown (not even on click).
    • Use case: disable for a less cluttered visual experience.
  • showOnClick
    • Path: client/ui/lifeBar/showOnClick.
    • Default: 1 (enabled).
    • Controls: whether the lifebars show only when the target is clicked.
    • Other players: applies when showAllPlayers is disabled, the clicked player bar is shown.
    • NPCs / enemies: requires showEnemies enabled, and restricts their bars to the clicked target (ObjectsHandler.isValidMessage() and ObjectsHandler.isValidToDraw() in lib/users/client/objects-handler.js).

Implementation flow

lib/users/client/lifebar-ui.js, method canShowPlayerLifeBar(playerId):

  1. Check if the player is the current player by comparing playerId with gameManager.getCurrentPlayer().playerId.
  2. If current player: hide the bar and return false when the player is dead or disabled, otherwise return the value of barConfig.showCurrentPlayer.
  3. If other player: check barConfig.showAllPlayers first, then, if false, barConfig.showOnClick and whether the player is the current target.
  4. Draw the lifebar only if the check returns true.

The NPCs and enemies bars are handled by lib/users/client/objects-handler.js: the lifebar messages for objects are only processed when showEnemies is enabled, and with showOnClick enabled only the clicked target bar is drawn.

Customizable fields:

  • showCurrentPlayer - boolean - stored in this.barConfig.showCurrentPlayer
  • showAllPlayers - boolean - stored in this.barConfig.showAllPlayers
  • showEnemies - boolean - stored in this.barConfig.showEnemies
  • showOnClick - boolean - stored in this.barConfig.showOnClick

Examples

The showCurrentPlayer, showCurrentPlayerName and showNamesLimit rows are not seeded, so an UPDATE on them changes 0 rows. The examples use INSERT ... ON DUPLICATE KEY UPDATE for those paths (the config table has the scope_path unique key).

Hide the current player lifebar:

INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES ('client', 'ui/lifeBar/showCurrentPlayer', '0', 3)
ON DUPLICATE KEY UPDATE `value` = '0';

Show all the players' lifebars always:

UPDATE `config` SET `value` = '1' WHERE `scope` = 'client' AND `path` = 'ui/lifeBar/showAllPlayers';
UPDATE `config` SET `value` = '0' WHERE `scope` = 'client' AND `path` = 'ui/lifeBar/showOnClick';

Hide all the lifebars (disables the whole lifebar system, LifebarUi.createLifeBarUi() returns false when it is off):

UPDATE `config` SET `value` = '0' WHERE `scope` = 'client' AND `path` = 'ui/lifeBar/enabled';

Setting only showCurrentPlayer, showAllPlayers and showEnemies to 0 is not enough, the other players' bars would still show on click while showOnClick is 1.

Player Names Visibility

Controls the display of character names above player sprites. Allows independent configuration for the current player versus the other players.

Configuration paths

  • Scope: client
  • Base path: ui/players
  • Type: boolean (type 3)

Visibility properties

  • showCurrentPlayerName
    • Path: client/ui/players/showCurrentPlayerName (not seeded by the migrations, must be added manually).
    • Default: disabled (with no config row the value resolves to false).
    • Controls: the current player's name visibility.
    • Use case: disable for a cleaner visual experience when the player info is shown in a UI panel.
  • showNames
    • Path: client/ui/players/showNames.
    • Default: 1 (enabled).
    • Controls: the other players' names visibility.
    • Use case: disable for a less cluttered multiplayer experience.
  • showNamesLimit
    • Path: client/ui/players/showNamesLimit (not seeded by the migrations, must be added manually).
    • Default: 10 (code fallback).
    • Controls: the maximum name length before truncation with an ellipsis.
    • Use case: prevent long names from cluttering the screen.

Implementation flow

lib/users/client/player-engine.js, method showPlayerName(id):

  1. Determine which config to check using a ternary: id === this.playerId ? showCurrentPlayerName : showNames.
  2. Return false if the config value is false.
  3. Validate the player exists and has a name property.
  4. Apply the name length limit if configured.
  5. Attach the text sprite to the player using SpriteTextFactory.

Method updateNamePosition(playerSprite):

  1. Determine which config to check: playerId === this.playerId ? showCurrentPlayerName : showNames.
  2. Return false if the config is disabled or the nameSprite does not exist.
  3. Calculate the relative position and update the sprite coordinates.

Customizable fields:

  • globalConfigShowCurrentPlayerName - boolean - loaded from client/ui/players/showCurrentPlayerName
  • globalConfigShowNames - boolean - loaded from client/ui/players/showNames
  • globalConfigShowNamesLimit - number - loaded from client/ui/players/showNamesLimit
  • globalConfigNameText - object - loaded from client/ui/players/nameText with the style properties

Examples

Hide the current player name:

INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES ('client', 'ui/players/showCurrentPlayerName', '0', 3)
ON DUPLICATE KEY UPDATE `value` = '0';

Hide all the other players' names:

UPDATE `config` SET `value` = '0' WHERE `scope` = 'client' AND `path` = 'ui/players/showNames';

Show both the current and the other players' names:

INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES ('client', 'ui/players/showCurrentPlayerName', '1', 3)
ON DUPLICATE KEY UPDATE `value` = '1';
UPDATE `config` SET `value` = '1' WHERE `scope` = 'client' AND `path` = 'ui/players/showNames';

Increase the name length limit:

INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES ('client', 'ui/players/showNamesLimit', '20', 2)
ON DUPLICATE KEY UPDATE `value` = '20';

Common Patterns

Clean current player display

When using custom UI panels for the current player information:

INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES ('client', 'ui/lifeBar/showCurrentPlayer', '0', 3)
ON DUPLICATE KEY UPDATE `value` = '0';
INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES ('client', 'ui/players/showCurrentPlayerName', '0', 3)
ON DUPLICATE KEY UPDATE `value` = '0';

Result: the current player has no floating UI elements, all the info is shown in panels.

Minimal multiplayer display

For focused gameplay with minimal distractions:

UPDATE `config` SET `value` = '0' WHERE `scope` = 'client' AND `path` = 'ui/lifeBar/showAllPlayers';
UPDATE `config` SET `value` = '0' WHERE `scope` = 'client' AND `path` = 'ui/players/showNames';
UPDATE `config` SET `value` = '1' WHERE `scope` = 'client' AND `path` = 'ui/lifeBar/showOnClick';

Result: the other players show their info only when clicked.

Full visibility

For PvP or cooperative multiplayer:

INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES ('client', 'ui/lifeBar/showCurrentPlayer', '1', 3)
ON DUPLICATE KEY UPDATE `value` = '1';
UPDATE `config` SET `value` = '1' WHERE `scope` = 'client' AND `path` = 'ui/lifeBar/showAllPlayers';
INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES ('client', 'ui/players/showCurrentPlayerName', '1', 3)
ON DUPLICATE KEY UPDATE `value` = '1';
UPDATE `config` SET `value` = '1' WHERE `scope` = 'client' AND `path` = 'ui/players/showNames';
UPDATE `config` SET `value` = '0' WHERE `scope` = 'client' AND `path` = 'ui/lifeBar/showOnClick';

Result: all the players always show their names and health bars.

Implementation Details

Code organization

Both systems follow the same architectural pattern:

  1. Configuration loaded from gameManager.config: PlayerEngine loads it in its constructor, LifebarUi loads it in createLifeBarUi() (not in the constructor).
  2. A single method determines the visibility based on the player type (current vs other).
  3. The player type selects the appropriate config property.
  4. Early return if the visibility check fails.
  5. Render or update the UI element if the check passes.

Property access pattern

Properties are stored as class instance variables for performance.

LifebarUi.createLifeBarUi():

this.barConfig = gameManager.config.get('client/ui/lifeBar');

PlayerEngine constructor:

this.globalConfigShowNames = Boolean(this.config.get('client/ui/players/showNames'));
/** @type {boolean} */
this.globalConfigShowCurrentPlayerName = Boolean(this.config.getWithoutLogs('client/ui/players/showCurrentPlayerName'));

Conditional logic pattern

PlayerEngine.showPlayerName() uses a ternary:

let shouldShow = id === this.playerId
    ? this.globalConfigShowCurrentPlayerName
    : this.globalConfigShowNames;
if(!shouldShow){
    return false;
}

LifebarUi.canShowPlayerLifeBar() uses early returns:

if(isCurrentPlayer){
    return this.barConfig.showCurrentPlayer;
}
if(this.barConfig.showAllPlayers){
    return true;
}
return this.barConfig.showOnClick && playerId === this.getCurrentTargetId();

Integration points

Life bars:

  • Created in lib/users/client/plugin.js during the reldens.beforeCreateEngine event.
  • Updated on reldens.playerStatsUpdateAfter, reldens.runPlayerAnimation, reldens.updateGameSizeBefore.
  • Removed on reldens.playersOnRemove.

Player names:

  • Created in lib/users/client/player-engine.js during the addPlayer() call.
  • Updated on every animation frame during updatePlayerState().
  • Removed on the removePlayer() call, which destroys the name sprite when the player has one and always destroys the player sprite, so players without names (for example with showNames set to 0) are removed too.

Migration Notes

No migration seeds ui/lifeBar/showCurrentPlayer or ui/players/showCurrentPlayerName. Without the rows both resolve to a falsy value, so the current player lifebar and name are hidden.

To manage them from the config table, add the rows manually:

INSERT INTO `config` (`scope`, `path`, `value`, `type`) VALUES
('client', 'ui/lifeBar/showCurrentPlayer', '0', 3),
('client', 'ui/players/showCurrentPlayerName', '0', 3);

Then set them to 1 to enable these features if desired.

Related Documentation

Go Up