Skip to content

Fix playerlist icons dedicated#1429

Open
itsRevela wants to merge 3 commits intosmartcmd:mainfrom
itsRevela:fix-playerlist-icons-dedicated
Open

Fix playerlist icons dedicated#1429
itsRevela wants to merge 3 commits intosmartcmd:mainfrom
itsRevela:fix-playerlist-icons-dedicated

Conversation

@itsRevela
Copy link
Copy Markdown
Contributor

Description

  • Fixes the Tab player list not showing all connected players on dedicated servers, and fixes the colored map icon next to each player's name showing incorrect colors

Changes

Previous Behavior

  • On dedicated servers, only the local player was visible in the Tab player list. All other connected players were missing.
  • The colored map icon next to each player's name in the player list and teleport menu did not match the player's actual map marker color.

Root Cause

  • Missing players: Remote players were never registered in the client's IQNet network player tracking when their AddPlayerPacket arrived. Only the host and local player had IQNet entries, so the UI had no knowledge of other players.
  • Wrong icon colors: The icon color was determined by GetPlayerColour(), which searches m_playerColours[] by small ID. On dedicated servers, the small IDs used by the player list UI (client-side IQNet slot IDs) don't match the IDs stored by UpdatePlayerInfo (server-side network IDs), so the lookup always failed and returned the default color. Additionally, the Iggy/SWF UI system (not the XUI system) controls the actual icon rendering, so the original XUI timeline code had no visible effect.

Fix Implementation

  • Missing players: handleAddPlayer now registers remote players in the client's IQNet array so they appear in the Tab player list. The dedicated server's phantom host entry (slot 0, empty gamertag) is filtered from the UI. Player removal uses gamertag matching since XUIDs are not available on dedicated server clients.
  • Icon colors: The map marker icon is now computed client-side using the same hash as the map renderer (getRandomPlayerMapIcon), stored by player name for reliable lookup. The player list and teleport menu UIs (UIScene_InGameInfoMenu, UIScene_TeleportMenu) read the icon via GetPlayerMapIconByName() instead of the broken small-ID lookup. A mapIconToFrame() conversion translates map icon slots (0,1,2,3,8,9,10,11) to the Iggy/SWF frame indices (0-7) that the player list animation expects.

AI Use Disclosure

  • No AI was used to write the code in this PR.

Related Issues

  • None
Screenshot 2026-03-26 221509 Screenshot 2026-03-26 221623

Register remote players in the client's IQNet array when their
AddPlayerPacket arrives, so they appear in the Tab player list.
Previously only the host and local player were registered.

Also filter the dedicated server's phantom host entry (slot 0, empty
gamertag) from the UI, fix tick() to update entries by smallId instead
of sequential index, and fix player removal to use gamertag matching
since XUIDs are 0 on dedicated servers.
The tab player list and teleport menu now show the correct map marker
color for each player. The icon is computed using the same hash as the
map renderer (getRandomPlayerMapIcon) and stored by player name,
bypassing the unreliable small-ID lookup that produced wrong colors
on dedicated servers.
… on disconnect

Players now appear in each other's Tab list immediately on join,
regardless of render distance. Previously, players only appeared when
they entered entity tracking range because AddPlayerPacket was only
sent through the TrackedEntity system.

On disconnect, a RemoveEntitiesPacket is broadcast to all clients so
players added via the join broadcast are properly cleaned up, not just
those within tracking range.
unsigned int seed = static_cast<unsigned int>(entityId);
seed ^= static_cast<unsigned int>(playerIndex * 0x9E3779B9u);
seed ^= (seed >> 16);
seed *= 0x7FEB352Du;
Copy link
Copy Markdown
Collaborator

@sylvessa sylvessa Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where do these magic numbers come from? why is it done like this?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think these magic numbers should be documented

Copy link
Copy Markdown
Contributor Author

@itsRevela itsRevela Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not my code, it is currently being used upstream in y'alls MapItemSavedData.cpp:

static char getRandomPlayerMapIcon(const shared_ptr<Player>& player)
{
    // use seed bit shift random
    unsigned int seed = static_cast<unsigned int>(player->entityId);
    seed ^= static_cast<unsigned int>(player->getPlayerIndex() * 0x9E3779B9u);
    seed ^= (seed >> 16);
    seed *= 0x7FEB352Du;
    seed ^= (seed >> 15);
    seed *= 0x846CA68Bu;
    seed ^= (seed >> 16);

    return PLAYER_MAP_ICON_SLOTS[seed % (sizeof(PLAYER_MAP_ICON_SLOTS) / sizeof(PLAYER_MAP_ICON_SLOTS[0]))];
}

It picks a random color for each player's map icon, but it has to be the same color everytime for the same player. So instead of actual randomness, it scramble the player's ID into a number between 0-7 (8 available colors)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, i never saw this. i just thought it was weird you were using some random seed lol. then again i havent really messed with map stuff

@sylvessa
Copy link
Copy Markdown
Collaborator

players outside of render distance do not show up in the playerlist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants