xPlayer
Complete ESX Legacy xPlayer reference. Every server-side player method for money, accounts, inventory, jobs, weapons, metadata and notifications, verified against 1.16.4.
xPlayer is the server-side object that represents one loaded ESX character. You get it with ESX.GetPlayerFromId(source) and use its methods to change money, items, job, group, weapons and metadata. Every change goes through these methods so that es_extended can sync the client, fire events and save the data to the database.
Overview
| Fact | Value |
|---|---|
| Side | Server only |
| Defined in | es_extended/server/classes/player.lua and server/classes/player/*.lua |
| Created by | es_extended when a character loads (CreateExtendedPlayer) |
| Stored in | ESX.Players[source], also indexed by identifier |
| Saved | Every 10 minutes, on /save and /saveall, and when the player drops |
| Version | ESX Legacy 1.16.4 |
ox_inventory changes some methods
When the ox_inventory resource exists, es_extended sets Config.CustomInventory = "ox" and replaces the inventory, weapon and some account methods with versions that forward to ox_inventory. Each affected method below has an "ox_inventory" note. See the ox_inventory guide.
Getting an xPlayer
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then
return -- player is not loaded (still connecting, in character selection, or gone)
end
print(xPlayer.getName(), xPlayer.getJob().name)Other ways to get a player object:
| Function | Returns |
|---|---|
ESX.GetPlayerFromId(source) | xPlayer or nil |
ESX.GetPlayerFromIdentifier(identifier) | xPlayer or nil |
ESX.GetExtendedPlayers(key, value) | array of xPlayer, optionally filtered |
ESX.Player(source) | a static proxy (see below) |
Static players (ESX.Player)
ESX.Player(src) and ESX.ExtendedPlayers() exist only in resources that load @es_extended/imports.lua. They return a lightweight proxy instead of the real object. Every key you index on the proxy becomes a function that calls the method through the RunStaticPlayerMethod export:
local player = ESX.Player(source)
if player then
player.addAccountMoney("bank", 500, "Quest reward")
local job = player.getJob() -- returns a copy, not a live reference
endOnly methods work on static players
player.job, player.name and other fields do not exist on the proxy. Indexing any key returns a function. Use the getters (getJob(), getName()) instead. Tables returned through the export are copies, so changing them has no effect on the player.
Properties
The object also exposes raw fields. Read them if you like, but change state only through methods, otherwise the client is not updated and nothing is saved.
| Field | Type | Description |
|---|---|---|
source / playerId | number | Server ID of the player. |
identifier | string | Database identifier. With multicharacter it looks like char1:abc123.... |
license | string | Full identifier with prefix, for example license:abc123.... Used for ACE principals. |
ssn | string | Social security number in XXX-XX-XXXX format, generated on character creation. |
name | string | Character name ("First Last") or the FiveM name when no identity exists. |
group | string | Permission group, for example user or admin. |
accounts | table[] | Array of accounts: { name, money, label, round, index }. |
inventory | table[] | Items with a count above 0, sorted by label (default inventory). |
loadout | table[] | Weapons: { name, label, ammo, components, tintIndex }. Empty with ox_inventory. |
job | table | Current job, see getJob. |
weight / maxWeight | number | Carried weight and limit. maxWeight starts at Config.MaxWeight. |
coords | table | Last known { x, y, z, heading }. |
metadata | table | Persistent custom data, see Metadata. |
variables | table | Non-persistent custom data set with set. |
lastPlaytime | number | Saved playtime in seconds when the character loaded. |
paycheckEnabled | boolean | Whether the player receives paychecks. |
admin | boolean | Admin state when the object was created. Use isAdmin() for the live value. |
spawned | boolean | Set to true once the client reports its first spawn. Players are not saved before that. |
Character identity data (firstName, lastName, dateofbirth, sex, height) is not a field on the server object. It is stored as variables, so read it with xPlayer.get("firstName"). See PlayerData.
Identity and session
getIdentifier
xPlayer.getIdentifier()Returns the database identifier of the character (the identifier column in users).
Returns: string
local identifier = xPlayer.getIdentifier()
MySQL.update("UPDATE users SET phone_number = ? WHERE identifier = ?", { number, identifier })getSSN
xPlayer.getSSN()Returns the character's social security number, for example "482-17-3390". ESX generates a unique SSN when the character is created.
Returns: string
getSource
xPlayer.getSource()Returns the player's server ID. xPlayer.getPlayerId() is an alias.
Returns: number
getPlayerId
xPlayer.getPlayerId()Alias of getSource.
Returns: number
getName
xPlayer.getName()Returns the character name. With esx_identity or multicharacter this is "Firstname Lastname", otherwise the FiveM player name.
Returns: string
setName
xPlayer.setName(newName)| Name | Type | Description |
|---|---|---|
newName | string | The new display name. |
Changes the name on the object and in the name state bag. It does not update firstname / lastname in the database, so the change is lost on reconnect.
xPlayer.setName("John Doe")getPlayTime
xPlayer.getPlayTime()Returns the total playtime of the character in seconds: the saved playtime plus the time online in this session. The value is persisted in metadata.lastPlaytime.
Returns: number
local hours = math.floor(xPlayer.getPlayTime() / 3600)
xPlayer.showNotification(("You have played %d hours"):format(hours))isCurrent
xPlayer.isCurrent()Returns true while this object is still the active entry in ESX.Players. Use it after a Wait or an awaited database query to make sure the player has not dropped or switched characters in the meantime.
Returns: boolean
local result = MySQL.single.await("SELECT * FROM my_table WHERE owner = ?", { xPlayer.identifier })
if not xPlayer.isCurrent() then
return -- player left while we were waiting
endisAdmin
xPlayer.isAdmin()Returns true if the player is allowed the ACE command, if sv_lan is "true", or if the player's group is listed in Config.AdminGroups.
Returns: boolean
Config.AdminGroups is deprecated in favor of Config.CommandPermissions. For your own permission checks, prefer ACE (IsPlayerAceAllowed) or getGroup. See admin permissions.
kick
xPlayer.kick(reason)| Name | Type | Description |
|---|---|---|
reason | string | Message shown to the player. |
Drops the player from the server. ESX saves the character in the playerDropped handler.
xPlayer.kick("You have been kicked for exploiting.")triggerEvent
xPlayer.triggerEvent(eventName, ...)| Name | Type | Description |
|---|---|---|
eventName | string | Client event name. Must be a string, otherwise the call asserts. |
... | any | Arguments passed to the client handler. |
Shortcut for TriggerClientEvent(eventName, xPlayer.source, ...).
xPlayer.triggerEvent("myjob:client:startShift", { route = 3 })executeCommand
xPlayer.executeCommand(command)| Name | Type | Description |
|---|---|---|
command | string | The command line to run, without the leading /. |
Makes the player's client run ExecuteCommand(command). The command runs with the player's own permissions. Throws an error if command is not a string.
xPlayer.executeCommand("e sit")Position
getCoords
xPlayer.getCoords(vector, heading)| Name | Type | Description |
|---|---|---|
vector | boolean? | true returns a vector3 (or vector4 with heading). Otherwise a plain table. |
heading | boolean? | Include the heading (w in a vector4, heading in a table). |
Reads the live ped position when the ped exists, otherwise the last cached position. Falls back to a random Config.DefaultSpawns entry if nothing valid is known.
Returns: vector3, vector4 or { x, y, z, heading? }
local coords = xPlayer.getCoords(true)
if #(coords - vector3(441.8, -982.0, 30.7)) < 10.0 then
print("Player is at Mission Row PD")
endsetCoords
xPlayer.setCoords(coordinates)| Name | Type | Description |
|---|---|---|
coordinates | vector3, vector4 or table | Target position. Tables need x, y, z and may have heading or w. |
Teleports the ped on the server side. Returns false if the coordinates are invalid (non-finite or beyond Config.PlayerCoordinateLimit) or the ped does not exist. Returns nothing on success.
xPlayer.setCoords(vector4(-269.4, -955.3, 31.2, 205.0))Permission group
getGroup
xPlayer.getGroup()Returns the player's permission group, for example "user", "admin" or "owner".
Returns: string
if xPlayer.getGroup() ~= "user" then
print(xPlayer.getName() .. " is staff")
endsetGroup
xPlayer.setGroup(newGroup)| Name | Type | Description |
|---|---|---|
newGroup | string | The new group name. |
Replaces the ACE principal identifier.<license> → group.<old> with group.<new>, updates the group state bag and fires esx:setGroup on the server (source, group, lastGroup) and on the client (group, lastGroup). The group is saved to the users table.
xPlayer.setGroup("admin")Variables
Variables are temporary key/value pairs on the player. They are not saved to the database. ESX itself uses them for identity data (firstName, lastName, dateofbirth, sex, height).
set
xPlayer.set(key, value, replicate)| Name | Type | Description |
|---|---|---|
key | string | Variable name. |
value | any | Value to store. |
replicate | boolean? | Defaults to true. When not false, the whole variables table is sent to the client as ESX.PlayerData.variables. |
xPlayer.set("lastRobbery", os.time(), false) -- server-only flagget
xPlayer.get(key)| Name | Type | Description |
|---|---|---|
key | string | Variable name. |
Returns: any (the stored value or nil)
local first, last = xPlayer.get("firstName"), xPlayer.get("lastName")updatePlayerData
Removed
xPlayer.updatePlayerData no longer exists in ESX Legacy 1.16.4. set, setMeta and clearMeta send esx:updatePlayerData to the client themselves. To push other data, use xPlayer.triggerEvent("esx:updatePlayerData", key, value).
Money and accounts
Every character has the accounts defined in Config.Accounts. By default these are money (cash), bank and black_money. Account names are case-insensitive in getAccount. See the money and accounts guide.
Invalid amounts throw errors
With the default inventory, setAccountMoney, addAccountMoney and removeAccountMoney call Lua error() for unknown accounts and for amounts that are not valid numbers. add and remove also throw for amounts of 0 or below. Always validate user input (for example from NUI or events) before you pass it on. The ox_inventory versions return false instead.
getAccounts
xPlayer.getAccounts(minimal)| Name | Type | Description |
|---|---|---|
minimal | boolean? | true returns { [accountName] = money } instead of the full array. |
Returns: table[] of { name, money, label, round, index }, or a name → money map.
local balances = xPlayer.getAccounts(true)
print(balances.bank, balances.money, balances.black_money)getAccount
xPlayer.getAccount(account)| Name | Type | Description |
|---|---|---|
account | string | Account name, for example "bank". |
Returns: { name, money, label, round, index } or nil if the account does not exist.
local bank = xPlayer.getAccount("bank")
if bank and bank.money >= 2500 then
-- player can afford it
endgetMoney
xPlayer.getMoney()Returns the balance of the money (cash) account, or 0.
Returns: number
setMoney
xPlayer.setMoney(money)| Name | Type | Description |
|---|---|---|
money | number | New cash balance. Asserts that it is a number, then rounds it. |
Shortcut for setAccountMoney("money", money).
Returns: true on success.
addMoney
xPlayer.addMoney(money, reason)| Name | Type | Description |
|---|---|---|
money | number | Amount of cash to add. Rounded before use. |
reason | string? | Reason passed to the esx:addAccountMoney event, useful for logs. |
Shortcut for addAccountMoney("money", money, reason).
Returns: true on success, false on overflow.
xPlayer.addMoney(150, "Sold fish")removeMoney
xPlayer.removeMoney(money, reason)| Name | Type | Description |
|---|---|---|
money | number | Amount of cash to remove. Rounded before use. |
reason | string? | Reason passed to the esx:removeAccountMoney event. |
Shortcut for removeAccountMoney("money", money, reason).
Returns: true on success, false if the player does not have enough cash.
setAccountMoney
xPlayer.setAccountMoney(accountName, money, reason)| Name | Type | Description |
|---|---|---|
accountName | string | Account name. |
money | number | New balance, 0 or higher. Rounded if the account has round = true. |
reason | string? | Defaults to "unknown". |
Sets the balance to an exact value. Fires esx:setAccountMoney on the server (source, accountName, money, reason) and on the client (the updated account table).
Returns: true on success. Throws for negative or invalid amounts and unknown accounts.
xPlayer.setAccountMoney("black_money", 0, "Money laundered")addAccountMoney
xPlayer.addAccountMoney(accountName, money, reason)| Name | Type | Description |
|---|---|---|
accountName | string | Account name. |
money | number | Amount to add, greater than 0. |
reason | string? | Defaults to "Unknown". |
Fires esx:addAccountMoney on the server (source, accountName, money, reason) and syncs the account to the client.
Returns: true on success, false if the new balance would overflow. Throws for amounts of 0 or below.
local reward = 1200
if reward > 0 then
xPlayer.addAccountMoney("bank", reward, "Delivery job")
endremoveAccountMoney
xPlayer.removeAccountMoney(accountName, money, reason)| Name | Type | Description |
|---|---|---|
accountName | string | Account name. |
money | number | Amount to remove, greater than 0. Converted with tonumber. |
reason | string? | Defaults to "Unknown". |
Balances never go negative. Fires esx:removeAccountMoney on the server.
Returns: true on success, false if the balance is too low or rounding turned the amount into 0. Throws for amounts of 0 or below.
local price = 500
if xPlayer.removeAccountMoney("bank", price, "Bought a phone") then
xPlayer.addInventoryItem("phone", 1)
else
xPlayer.showNotification("Not enough money in your bank account", "error")
endox_inventory
Accounts listed in the inventory:accounts convar (default ["money", "black_money"], black_money is always included) are stored as ox_inventory items. For those, the account methods call exports.ox_inventory SetItem / AddItem / RemoveItem. All three return false instead of throwing for invalid input. Amounts below 1 are rejected.
Paycheck
togglePaycheck
xPlayer.togglePaycheck(toggle)| Name | Type | Description |
|---|---|---|
toggle | boolean | false stops paychecks for this player until set back to true. |
Not saved. Every new session starts with paychecks enabled.
xPlayer.togglePaycheck(false) -- e.g. while the player is in jailisPaycheckEnabled
xPlayer.isPaycheckEnabled()Returns: boolean
Job
getJob
xPlayer.getJob()Returns the live job table.
| Field | Type | Description |
|---|---|---|
id | number? | Copied from an id column in jobs. The default schema has none, so this is usually nil. |
name | string | Job name, for example "police". |
label | string | Display label. |
type | string | Job type from the jobs.type column (default "civ"). |
onDuty | boolean | Duty state. |
grade | number | Grade number. |
grade_name | string | Grade name, for example "boss". |
grade_label | string | Grade label. |
grade_salary | number | Salary per paycheck for this grade. |
skin_male | table | Male outfit for the grade. |
skin_female | table | Female outfit for the grade. |
local job = xPlayer.getJob()
if job.name == "police" and job.onDuty then
-- allow cuffing
endsetJob
xPlayer.setJob(newJob, grade, onDuty)| Name | Type | Description |
|---|---|---|
newJob | string | Job name. Must exist in ESX.Jobs. |
grade | number or string | Grade number. Converted with tostring. |
onDuty | boolean? | Duty state. Defaults to Config.DefaultJobDuty. Always false for unemployed. |
If the job or grade does not exist, ESX prints a warning and does nothing. On success it stores the duty state in metadata.jobDuty, updates the job state bag and fires esx:setJob on the server (source, job, lastJob) and the client (job, lastJob).
if ESX.DoesJobExist("mechanic", 0) then
xPlayer.setJob("mechanic", 0)
end
-- Toggle duty without changing the job
local job = xPlayer.getJob()
xPlayer.setJob(job.name, job.grade, not job.onDuty)refreshJob
xPlayer.refreshJob()Reloads label, grade name, salary and outfits from ESX.Jobs while keeping the grade and duty state. Fires esx:jobDataRefreshed. ESX.RefreshJob(jobName) calls this for every player in that job, so you rarely need it directly.
Returns: true, or false if the grade no longer exists. In that case the player is set to unemployed grade 0.
Inventory
These methods describe the default es_extended inventory. Items must exist in the items table (or be added with ESX.AddItems). See adding items.
getInventory
xPlayer.getInventory(minimal)| Name | Type | Description |
|---|---|---|
minimal | boolean? | true returns { [itemName] = count }. |
Returns: an array of items the player owns (count above 0), sorted by label. Each item is { name, count, label, weight, usable, rare, canRemove }.
for _, item in ipairs(xPlayer.getInventory()) do
print(item.label, item.count)
endox_inventory
getInventory() returns ox_inventory's slot table. getInventory(true) returns an array of { name, count, slot, metadata }.
getInventoryItem
xPlayer.getInventoryItem(itemName)| Name | Type | Description |
|---|---|---|
itemName | string | Item name. |
Returns: the item table. For known items the player does not own, a new entry with count = 0. nil for items that do not exist.
local bread = xPlayer.getInventoryItem("bread")
if bread and bread.count >= 2 then
-- player has at least 2 bread
endox_inventory
Signature becomes getInventoryItem(name, metadata) and returns exports.ox_inventory:GetItem(source, name, metadata).
hasItem
xPlayer.hasItem(itemName)| Name | Type | Description |
|---|---|---|
itemName | string | Item name. |
Returns: item, count if the player has at least one, otherwise false.
local item, count = xPlayer.hasItem("lockpick")
if item then
print(("Player has %d lockpicks"):format(count))
endWith ox_inventory the signature is hasItem(name, metadata).
addInventoryItem
xPlayer.addInventoryItem(itemName, count)| Name | Type | Description |
|---|---|---|
itemName | string | Item name. |
count | number | Amount to add. Rounded; values of 0 or below are ignored. |
Fires esx:onAddInventoryItem on the server (source, itemName, newCount) and esx:addInventoryItem on the client.
Returns: true on success, false for invalid counts or unknown items.
if xPlayer.canCarryItem("water", 3) then
xPlayer.addInventoryItem("water", 3)
else
xPlayer.showNotification("You cannot carry that much", "error")
endThe default inventory does not check weight here. Call canCarryItem first.
With ox_inventory the signature is addInventoryItem(name, count, metadata, slot); count defaults to 1.
removeInventoryItem
xPlayer.removeInventoryItem(itemName, count)| Name | Type | Description |
|---|---|---|
itemName | string | Item name. |
count | number | Amount to remove. Rounded. Must be greater than 0. |
Fires esx:onRemoveInventoryItem on the server (source, itemName, newCount).
Returns: true on success, false if the player does not have the item or not enough of it. Throws for counts of 0 or below.
if xPlayer.removeInventoryItem("lockpick", 1) then
TriggerClientEvent("myscript:client:pickLock", xPlayer.source)
endWith ox_inventory the signature is removeInventoryItem(name, count, metadata, slot).
setInventoryItem
xPlayer.setInventoryItem(itemName, count)| Name | Type | Description |
|---|---|---|
itemName | string | Item name. |
count | number | The exact count the player should end up with, 0 or higher. |
Adds or removes the difference using the methods above.
Returns: the result of addInventoryItem / removeInventoryItem, nil if the count is already correct, false for unknown items or negative counts.
xPlayer.setInventoryItem("bandage", 0) -- remove all bandagesWith ox_inventory the signature is setInventoryItem(name, count, metadata).
canCarryItem
xPlayer.canCarryItem(itemName, count)| Name | Type | Description |
|---|---|---|
itemName | string | Item name. |
count | number | Amount to test. |
Returns: true if weight + itemWeight * count stays within maxWeight. false for unknown items.
With ox_inventory the signature is canCarryItem(name, count, metadata).
canSwapItem
xPlayer.canSwapItem(firstItem, firstItemCount, testItem, testItemCount)| Name | Type | Description |
|---|---|---|
firstItem | string | Item the player gives away. |
firstItemCount | number | Amount given away. |
testItem | string | Item the player receives. |
testItemCount | number | Amount received. |
Returns: true if the player owns enough of firstItem and the weight after the swap fits.
if xPlayer.canSwapItem("fish", 10, "packaged_fish", 5) then
xPlayer.removeInventoryItem("fish", 10)
xPlayer.addInventoryItem("packaged_fish", 5)
endgetWeight
xPlayer.getWeight()Returns: number, the current inventory weight.
getMaxWeight
xPlayer.getMaxWeight()Returns: number, the weight limit (starts at Config.MaxWeight).
setMaxWeight
xPlayer.setMaxWeight(newWeight)| Name | Type | Description |
|---|---|---|
newWeight | number | New limit. Must be a finite number, 0 or higher. |
Not saved; resets to Config.MaxWeight on the next load. Returns false for invalid values. With ox_inventory, the value is also forwarded to SetMaxWeight.
-- backpack equipped
xPlayer.setMaxWeight(xPlayer.getMaxWeight() + 20)syncInventory
xPlayer.syncInventory(weight, maxWeight, items, money)Only exists with ox_inventory. ox_inventory calls it to copy its weight, items and account balances into the xPlayer. Do not call it yourself.
Weapons
Weapon methods only work with the default inventory. With ox_inventory, weapons are items: these methods do nothing, getLoadout() returns {}, and hasWeapon / hasWeaponComponent return false.
Weapon names are the upper-case names from Config.Weapons, for example "WEAPON_PISTOL". Component names are the short ESX names from that config, for example "clip_extended" or "suppressor".
getLoadout
xPlayer.getLoadout(minimal)| Name | Type | Description |
|---|---|---|
minimal | boolean? | true returns { [weaponName] = { ammo, tintIndex?, components? } }. Default clips are left out. |
Returns: array of { name, label, ammo, components, tintIndex } or the minimal map.
for _, weapon in ipairs(xPlayer.getLoadout()) do
print(weapon.label, weapon.ammo)
endgetWeapon
xPlayer.getWeapon(weaponName)| Name | Type | Description |
|---|---|---|
weaponName | string | Weapon name. |
Returns: loadoutIndex, weapon (the live loadout entry) or nil, nil.
local _, weapon = xPlayer.getWeapon("WEAPON_PISTOL")
if weapon then
print("Pistol ammo: " .. weapon.ammo)
endhasWeapon
xPlayer.hasWeapon(weaponName)Returns: boolean
addWeapon
xPlayer.addWeapon(weaponName, ammo)| Name | Type | Description |
|---|---|---|
weaponName | string | Weapon name. Must exist in Config.Weapons, otherwise the label lookup asserts. |
ammo | number | Starting ammo. |
Gives the weapon to the ped and shows an inventory notification.
Returns: true, or false if the player already has the weapon.
if not xPlayer.hasWeapon("WEAPON_STUNGUN") then
xPlayer.addWeapon("WEAPON_STUNGUN", 0)
endremoveWeapon
xPlayer.removeWeapon(weaponName)Removes the weapon, its components and its ammo from the ped.
Returns: true, or false if the player did not have it.
addWeaponAmmo
xPlayer.addWeaponAmmo(weaponName, ammoCount)| Name | Type | Description |
|---|---|---|
weaponName | string | Weapon name. |
ammoCount | number | Ammo to add. |
Returns: true, or false if the player does not have the weapon.
removeWeaponAmmo
xPlayer.removeWeaponAmmo(weaponName, ammoCount)Subtracts ammo. There is no lower bound, so check the current ammo first if it matters.
Returns: true, or false if the player does not have the weapon.
updateWeaponAmmo
xPlayer.updateWeaponAmmo(weaponName, ammoCount)Sets the stored ammo to an exact value without touching the ped (ESX uses it to sync ammo reported by the client). Throwable weapons (throwable = true in the config) are removed when the ammo reaches 0.
Returns: true, or false if the player does not have the weapon.
addWeaponComponent
xPlayer.addWeaponComponent(weaponName, weaponComponent)| Name | Type | Description |
|---|---|---|
weaponName | string | Weapon name. |
weaponComponent | string | Component name from Config.Weapons, for example "suppressor". |
Returns: true, or false if the player lacks the weapon, the component does not exist for it, or it is already attached.
xPlayer.addWeaponComponent("WEAPON_PISTOL", "flashlight")removeWeaponComponent
xPlayer.removeWeaponComponent(weaponName, weaponComponent)Returns: true, or false if nothing was removed.
hasWeaponComponent
xPlayer.hasWeaponComponent(weaponName, weaponComponent)Returns: boolean
setWeaponTint
xPlayer.setWeaponTint(weaponName, weaponTintIndex)| Name | Type | Description |
|---|---|---|
weaponName | string | Weapon name. |
weaponTintIndex | number | Tint index. Must exist in the weapon's tints table. |
Returns: true, or false if the player lacks the weapon or the tint is invalid.
xPlayer.setWeaponTint("WEAPON_PISTOL", 2) -- goldgetWeaponTint
xPlayer.getWeaponTint(weaponName)Returns: number, the tint index, or 0 if the player does not have the weapon.
Metadata
Metadata is a persistent table saved in the metadata column of users. Changes are synced to ESX.PlayerData.metadata on the client.
Keys used by ESX
ESX writes health, armor, lastPlaytime and jobDuty into metadata. Do not overwrite them with unrelated data.
getMeta
xPlayer.getMeta(index, subIndex)| Name | Type | Description |
|---|---|---|
index | string? | Top-level key. Omit it to get the whole metadata table. |
subIndex | string or string[] | Key (or list of keys) inside a table value. |
Returns: the value, a { [key] = value } table when subIndex is a list, or nil if the key does not exist (an error when Config.EnableDebug is on).
local stress = xPlayer.getMeta("stress") or 0
local licenses = xPlayer.getMeta("licenses", { "driver", "weapon" })setMeta
xPlayer.setMeta(index, value, subValue)| Name | Type | Description |
|---|---|---|
index | string | Top-level key. |
value | number, string or table | Value to store. When subValue is given, this is the key inside the table instead. |
subValue | any | Optional. Stores metadata[index][value] = subValue, creating the table if needed. |
xPlayer.setMeta("stress", 35)
xPlayer.setMeta("licenses", "driver", true) -- metadata.licenses.driver = trueBooleans are rejected as a top-level value, and false as subValue is treated as "no subValue". To store a false flag, use clearMeta or a number.
clearMeta
xPlayer.clearMeta(index, subValues)| Name | Type | Description |
|---|---|---|
index | string | Top-level key. |
subValues | string or string[] | Optional. Only remove these keys inside the table. |
xPlayer.clearMeta("stress")
xPlayer.clearMeta("licenses", { "weapon", "pilot" })Notifications
These methods trigger client events, so the notification shows on the player's screen.
showNotification
xPlayer.showNotification(msg, notifyType, length, title, position)| Name | Type | Description |
|---|---|---|
msg | string | Message text. |
notifyType | string? | "info" (default), "success", "error" or "warning" with esx_notify. |
length | number? | Duration in ms. Default 5000. |
title | string? | Optional title. |
position | string? | esx_notify position, for example "top-right". |
xPlayer.showNotification("Vehicle stored", "success", 3000)showAdvancedNotification
xPlayer.showAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex)| Name | Type | Description |
|---|---|---|
sender | string | Title line. |
subject | string | Subtitle line. |
msg | string | Message text. |
textureDict | string | Picture, for example "CHAR_BANK_MAZE". |
iconType | number | GTA feed icon type. |
flash | boolean | Flash the notification. |
saveToBrief | boolean? | Keep it in the pause-menu brief. Default true. |
hudColorIndex | number? | Background color index. |
xPlayer.showAdvancedNotification("Maze Bank", "Transfer", "You received $500", "CHAR_BANK_MAZE", 9, false)showHelpNotification
xPlayer.showHelpNotification(msg, thisFrame, beep, duration)| Name | Type | Description |
|---|---|---|
msg | string | Help text. Supports input tokens like ~INPUT_CONTEXT~. |
thisFrame | boolean? | Show for one frame only (not useful from the server). |
beep | boolean? | Play a sound. Default true. |
duration | number? | Duration in ms. Default -1. |
Internal methods
beginAccountOperation, endAccountOperation, beginAccountShutdown and getPendingAccountOperations exist on every xPlayer. es_extended uses them to finish pending money operations before the final save when a player drops. They are not meant for resource code.
Common issues
attempt to index a nil value (local 'xPlayer'): the player is not loaded yet or has left. Always check the result ofESX.GetPlayerFromId.- Money "disappears" after a restart: you changed
xPlayer.accounts[i].moneydirectly. Use the account methods. - Items over the weight limit:
addInventoryItemdoes not check weight with the default inventory. UsecanCarryItem. - Weapon methods do nothing: you run ox_inventory. Give weapons as items with
exports.ox_inventory:AddItem. - Trusting client input: never pass amounts from a client event straight into
addAccountMoney. Validate type, range and the player's distance on the server.
Related
Frequently asked questions
Independent documentation
Last updated on
Server Functions
Every ESX.* server function in ESX Legacy 1.16.4 with signatures, parameters, return values and examples. Players, callbacks, commands, jobs, items and vehicles.
OneSync Functions
ESX.OneSync server functions for ESX Legacy. Find nearby players, peds, objects and vehicles and spawn server-owned entities with SpawnVehicle and SpawnPed.