Skip to content

players ​

Read player snapshots and safely handle changes to player slots.

Player reference ​

players.capacity ​

Maximum session slot count.

text
players.capacity

Returns: 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 ​

FieldTypeMeaning
idIntegerSession slot, 0..31.
generationIntegerHarmony identity generation used for revalidation.
nameStringCopied player name.
ridDecimal stringRockstar ID; "0" when unavailable.
local_playerBooleanWhether this is the local player.
pedInteger handlePlayer ped; can be 0 when unavailable.
vehicleInteger handleAssociated vehicle; can be 0.
horseInteger handleAssociated horse; can be 0.
entityInteger handleHarmony's resolved entity for this player; can be 0.
positionvec3Copied position at the time of the snapshot.
session_hostBooleanHarmony's current session-host flag.
script_hostBooleanHarmony's current script-host flag.
modderBooleanHarmony'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.