esx_identity
esx_identity lets ESX Legacy players register first name, last name, date of birth, sex and height. Config, events, commands and validation rules.
esx_identity is the ESX Legacy resource that asks a new player for their character's first name, last name, date of birth, sex and height, validates the input on the server and stores it in the users table. Use it on every ESX server; both the single-character flow and esx_multicharacter depend on it.
Overview
| Resource | esx_identity |
| Version | 1.16.3 (fxmanifest, ships with ESX Legacy 1.16.4) |
| Side | Client + server, NUI form built with Vue |
| Dependencies | es_extended, esx_lib, oxmysql, esx_skin (opened after registration) |
| Database | Adds firstname, lastname, dateofbirth, sex, height to users |
Installation
Run the bundled SQL once if your users table does not have the identity columns yet (the official txAdmin recipe already includes them):
ALTER TABLE `users`
ADD COLUMN `firstname` VARCHAR(16) NULL DEFAULT NULL,
ADD COLUMN `lastname` VARCHAR(16) NULL DEFAULT NULL,
ADD COLUMN `dateofbirth` VARCHAR(10) NULL DEFAULT NULL,
ADD COLUMN `sex` VARCHAR(1) NULL DEFAULT NULL,
ADD COLUMN `height` INT NULL DEFAULT NULL;Then ensure it after es_extended and esx_lib:
ensure esx_lib
ensure es_extended
ensure esx_identityHow it works
Player connects
Without multicharacter, the server reads the identity columns during playerConnecting. With multicharacter, esx_multicharacter triggers the form when the player picks an empty slot.
Form or restore
If firstname is empty, the client receives esx_identity:showRegisterIdentity and opens the form. Otherwise the stored identity is applied to the xPlayer and the client gets esx_identity:alreadyRegistered.
Server-side validation
The esx_identity:registerIdentity callback re-checks every field (see Validation rules), formats the names (jOHN becomes John), saves the row and pushes the data to the client.
Skin creation
Without multicharacter, the client fires esx_skin:playerRegistered, which opens the esx_skin creator for players without a saved skin.
Configuration
All keys live in config.lua.
| Key | Default | Description |
|---|---|---|
Config.Locale | ESX.GetConfig().Locale | Language of notifications and the form. |
Config.EnableCommands | ESX.GetConfig().EnableDebug | Registers /char and /chardel. |
Config.DateFormat | "DD/MM/YYYY" | Display and storage format. Choices: DD/MM/YYYY, MM/DD/YYYY, YYYY/MM/DD. See Common issues. |
Config.MaxNameLength | 20 | Names must be shorter than this (byte length). |
Config.MinHeight | 120 | Minimum height in centimeters. |
Config.MaxHeight | 220 | Maximum height in centimeters. |
Config.MaxAge | 100 | Oldest allowed age. The youngest allowed age is fixed at 18. |
Config.FullCharDelete | true | /chardel also resets bank_savings and caution addon accounts and the user_ears, user_glasses, user_helmet, user_mask datastores. |
Config.EnableDebugging | ESX.GetConfig().EnableDebug | Registers the xPlayerGet* debug commands. |
Validation rules
The server never trusts the NUI. A registration is rejected with an error notification when:
| Field | Rule |
|---|---|
firstname, lastname | String, valid locale characters, length between 1 and MaxNameLength - 1. |
sex | m, M, f or F (stored lowercase). |
dateofbirth | Matches DD/MM/YYYY, is a real calendar date, year between currentYear - MaxAge and currentYear - 18. |
height | Number between MinHeight and MaxHeight. |
A player that is already registered cannot register again (already_registered).
Reading identity data
After loading, the identity is stored on the xPlayer and replicated to the player's state bag.
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return end
local fullName = xPlayer.getName() -- "John Doe"
local firstName = xPlayer.get('firstName')
local lastName = xPlayer.get('lastName')
local dob = xPlayer.get('dateofbirth') -- "24/12/1995"
local sex = xPlayer.get('sex') -- "m" or "f"
local height = xPlayer.get('height') -- 180
-- also available to any resource via state bags
local state = Player(source).state
print(state.firstName, state.lastName)Events
esx_identity:completedRegistration
Server event fired by esx_identity when a player finishes the form in multicharacter mode only. esx_multicharacter listens to it to create the new character. In single-character mode the identity is saved directly and this event is not fired.
AddEventHandler('esx_identity:completedRegistration', function(source, data) end)| Name | Type | Description |
|---|---|---|
source | number | Player server ID. |
data.firstname | string | Formatted first name. |
data.lastname | string | Formatted last name. |
data.dateofbirth | string | Date in Config.DateFormat. |
data.sex | string | "m" or "f". |
data.height | number | Height in centimeters. |
AddEventHandler('esx_identity:completedRegistration', function(source, data)
print(('Player %s registered as %s %s'):format(source, data.firstname, data.lastname))
end)esx_identity:showRegisterIdentity
Client event that opens the registration form. It waits for the NUI and the loading screen, then opens the form unless the player is dead. It also triggers esx_skin:resetFirstSpawn. It is registered as a net event, so the server can send it:
TriggerClientEvent('esx_identity:showRegisterIdentity', playerId)Opening the form for a player that is already registered does nothing useful: the server rejects the submission with "You have already registered." Clear the identity first (for example with /chardel).
Internal events
| Event | Side | Description |
|---|---|---|
esx_identity:setPlayerData | Client (secure net event) | Server pushes firstName, lastName, dateOfBirth, sex, height into ESX.PlayerData. |
esx_identity:alreadyRegistered | Client (secure net event) | Sent to registered players; fires esx_skin:playerRegistered once the loading screen is gone. |
esx_identity:registerIdentity | Server callback | Receives the form payload. Do not call it from other resources. |
Commands
| Command | Permission | Enabled by | Description |
|---|---|---|---|
/char | user | Config.EnableCommands | Shows your active character name. |
/chardel | admin | Config.EnableCommands | Wipes your identity and skin and reopens the form. |
/xPlayerGetFirstName | user | Config.EnableDebugging | Prints xPlayer.get('firstName'). |
/xPlayerGetLastName | user | Config.EnableDebugging | Prints xPlayer.get('lastName'). |
/xPlayerGetFullName | user | Config.EnableDebugging | Prints xPlayer.getName(). |
/xPlayerGetSex | user | Config.EnableDebugging | Prints xPlayer.get('sex'). |
/xPlayerGetDOB | user | Config.EnableDebugging | Prints xPlayer.get('dateofbirth'). |
/xPlayerGetHeight | user | Config.EnableDebugging | Prints xPlayer.get('height'). |
Common issues
- Registration always fails with "Invalid Format (DOB)". The form sends the date in
Config.DateFormat, but the server validator only parsesDD/MM/YYYY. WithYYYY/MM/DDevery submission fails, and withMM/DD/YYYYdates with a day above 12 fail. Keep the default format. - Long names get cut or the query errors.
MaxNameLengthis 20, but the SQL columns areVARCHAR(16). Either lowerConfig.MaxNameLengthto17or widen the columns. - Form never opens. The client waits for both the NUI
readymessage andesx:loadingScreenOff. A custom loading screen that never shuts down blocks the form. Check the F8 console for "Waiting for esx_identity NUI..". - "identifier-missing" on connect. The player has no license identifier (for example
sv_lan). Fix the identifier setup ines_extended. - Height notification says inches. The English debug string reads "Inches", but the value is stored in centimeters.
Related
Frequently asked questions
Independent documentation
Last updated on
esx_context
esx_context reference for ESX Legacy. Open mouse-driven context menus and small forms with ESX.OpenContext, element fields, exports, keybind and pitfalls.
esx_inventory
esx_inventory is the default ESX Legacy NUI inventory. Learn its config, keybinds, the server storage API exports and how it relates to ox_inventory.