players
Read player snapshots and safely handle changes to player slots.
Player reference
players.capacity
Maximum session slot count.
text
players.capacityReturns: Integer 32
players.get
id is a slot in 0..31; an out-of-range value throws. A disconnected slot returns nil.
text
players.get(id)Returns: Player snapshot or nil
players.local_player
Current local player.
text
players.local_player()Returns: Player snapshot or nil
players.selected
Current valid selection from Harmony's Network → Players UI.
text
players.selected()Returns: Player snapshot or nil
players.list
Dense one-based sequence; includes the local player by default.
text
players.list([include_local])Returns: Player snapshot array
players.valid
Whether that slot still resolves to the same player generation.
text
players.valid(id, generation)Returns: Boolean
Player IDs are zero-based session slots, whereas the array returned by players.list() is one-based. A slot can be reused after a player leaves. Keep its generation with its ID when identifying a player across callbacks.
Player snapshot fields
| Field | Type | Meaning |
|---|---|---|
id | Integer | Session slot, 0..31. |
generation | Integer | Harmony identity generation used for revalidation. |
name | String | Copied player name. |
rid | Decimal string | Rockstar ID; "0" when unavailable. |
local_player | Boolean | Whether this is the local player. |
ped | Integer handle | Player ped; can be 0 when unavailable. |
vehicle | Integer handle | Associated vehicle; can be 0. |
horse | Integer handle | Associated horse; can be 0. |
entity | Integer handle | Harmony's resolved entity for this player; can be 0. |
position | vec3 | Copied position at the time of the snapshot. |
session_host | Boolean | Harmony's current session-host flag. |
script_host | Boolean | Harmony's current script-host flag. |
modder | Boolean | Harmony's detection flag; not proof that a particular incident was malicious. |
The table is an owned snapshot, not a live player object. Re-fetch it when fresh data is needed. Entity handles can become stale even when the player identity remains valid.
These Lua fields expose the underlying identity data. Streaming display settings do not automatically anonymize a script's own players output. A script that draws names or IDs should explicitly choose its display policy; logging a real field records that real value.
Anonymous roster example
lua
local page = menu.root("Session overview")
page:button("Log anonymous roster", function()
local roster = players.list()
util.log("Connected players: " .. tostring(#roster))
for _, player in ipairs(roster) do
local label = string.format("player_%d", player.id)
local suffix = player.local_player and " (you)" or ""
util.log(label .. suffix)
end
end)To retain a selection, save only the needed snapshot fields and check players.valid(saved.id, saved.generation) before using it later. Do not assume that the same slot means the same person after a session change.