FiveM Docs
Addons

esx_scoreboard

esx_scoreboard is the ESX Legacy player list with job counts, search and live activities like robberies. Config keys and the AddActivity export API.

esx_scoreboard is a player list for ESX Legacy that players open with a key (default Z). It shows every online player with server id, character name, job, grade and ping, a counter per job, a search bar, and a list of ongoing activities such as robberies or races that other resources push in through server exports.

Overview

Resourceesx_scoreboard (version 1.0.0, added with ESX Legacy 1.16.0)
SideServer data cache, client NUI (Svelte)
Dependenciesesx_lib, es_extended
DatabaseNone
Used byesx_pausemenu (online players button)

The server keeps an in-memory cache of players and job counts. It updates it on esx:playerLoaded, esx:setJob, esx:jobDataRefreshed and playerDropped, and runs a full reconcile every minute as a safety net. Data is only sent to players who currently have the scoreboard open, and the list is paged, so it scales to large servers.

Installation

server.cfg
ensure esx_lib
ensure es_extended
ensure esx_scoreboard

The UI ships prebuilt in web/dist. To change the Svelte source, run npm install and npm run build in web (Node.js 18 or newer).

Usage

  • Press Z or run /scoreboard to toggle it. Press ESC to close it.
  • Search filters by player name, job label or server id.
  • While it is open, camera look and attack controls are disabled.

Configuration

All keys are in config/main.lua.

Display

KeyDefaultDescription
Config.OpenKey"Z"Default key for the scoreboard key mapping
Config.ServerName"ESX Server"Name in the header
Config.MaxPlayersnilSlots shown in the header; nil reads sv_maxclients
Config.LogoUrl""HTTPS logo URL; empty shows the ESX placeholder
Config.Jobs7 jobsBadge color per job, see below
Config.ActivityTypes6 typesLabel and icon per activity type
Config.DebugfalseDebug logging
config/main.lua
Config.Jobs = {
  police = { label = "Police", color = "#3B82F6" },
  ambulance = { label = "EMS", color = "#EF4444" },
  -- mechanic, taxi, realtor, cardealer, banker ...
}

Config.ActivityTypes = {
  robbery = { label = "Robbery", icon = "💰" },
  -- heist, drug, race, hostage, shootout
}

Jobs that are not listed in Config.Jobs are still counted; they just use the default color.

Performance and limits

KeyDefaultDescription
Config.SummaryInterval10000ms between summary broadcasts (counts, jobs, activities) to open scoreboards
Config.PageRefreshInterval15000ms between refreshes of the visible player page
Config.PageRefreshBatchSize25Open scoreboards refreshed before the server thread yields
Config.PageRefreshBatchDelay50ms between refresh batches
Config.PingRefreshInterval30000ms between ping updates
Config.FullReconcileInterval60000ms between full rebuilds of the player cache
Config.OpenCooldown2000Minimum ms between open requests per player
Config.PageRequestCooldown1500Minimum ms between page, search or sort requests per player
Config.ActivityDebounce1000Debounce for activity broadcasts
Config.DefaultPageSize50Rows per page
Config.MaxPageSize100Hard cap for rows per page
Config.MaxPageCacheEntries256Cached page payloads
Config.MaxPlayerQueryCacheEntries64Cached search or sort results
Config.MaxSearchLength48Max search text length accepted
Config.MaxActivities64Activities kept; the oldest is dropped first
Config.MaxActivityPlayers16Player entries stored per activity
Config.UpdateIntervalConfig.SummaryIntervalLegacy alias for older configs

Server exports

Use these from your own server scripts (robberies, heists, races) to show what is going on in the city.

AddActivity

local id = exports.esx_scoreboard:AddActivity(activityType, label, location, players)
NameTypeDescription
activityTypestringKey such as robbery; only letters, digits, _ and - are kept
labelstring?Display text; defaults to the label from Config.ActivityTypes
locationstring?Location text
playerstable?Array of server ids or strings, capped at MaxActivityPlayers

Returns the numeric activity id, or -1 if the type is invalid.

UpdateActivity

local ok = exports.esx_scoreboard:UpdateActivity(id, { label = '...', location = '...', players = { ... } })

Only the fields you pass are changed. Returns true when the activity was found.

RemoveActivity

local ok = exports.esx_scoreboard:RemoveActivity(id)

Returns true when the activity was found and removed.

GetActiveActivities

local list = exports.esx_scoreboard:GetActiveActivities()

Returns a copy of all activities. Each entry has id, type, label, location, startTime (os.time()) and players.

Example: store robbery

server/robbery.lua
local activeRobberies = {}

RegisterNetEvent('myrobbery:start', function(storeName)
    local src = source
    -- validate distance, cooldown and police count here
    activeRobberies[src] = exports.esx_scoreboard:AddActivity('robbery', storeName, 'Grove Street', { src })
end)

local function endRobbery(src)
    local id = activeRobberies[src]
    if id then
        exports.esx_scoreboard:RemoveActivity(id)
        activeRobberies[src] = nil
    end
end

AddEventHandler('playerDropped', function()
    endRobbery(source)
end)

Activities are not removed automatically. Always remove them when the event ends, including when the player disconnects.

Network events

EventDirectionNotes
esx_scoreboard:server:openclient to serverOpen and register as active viewer; rate limited by OpenCooldown
esx_scoreboard:server:requestDataclient to serverSame as open
esx_scoreboard:server:requestPageclient to server{ page, pageSize, search, sortBy, sortAsc }; only for active viewers, rate limited
esx_scoreboard:server:closeclient to serverStop receiving updates
esx_scoreboard:client:receiveSummaryserver to clientCounts, jobs, activities, server info
esx_scoreboard:client:receivePageserver to clientOne page of players
esx_scoreboard:client:receiveActivitiesserver to clientActivity list

The client-triggerable events only return public data (names, jobs, ping) and are rate limited, so they cannot be abused for more than reading the player list.

Common issues

  • "ESX.GetJobs() unavailable after 10 attempts": es_extended was not ready. Make sure it starts before esx_scoreboard.
  • Changing OpenKey has no effect: FiveM saves key mappings per player. Existing players must rebind it themselves.
  • Players missing right after restart: the cache is rebuilt from GetPlayers() once ESX jobs are available; wait for the first reconcile or reopen the list.
  • Old robberies stay on the board: your script never called RemoveActivity.

Frequently asked questions

Independent documentation

esx-fivem.com is a community project and is not affiliated with the ESX Framework team. Facts on this page were checked against the upstream source. Official resources: docs.esx-framework.org and github.com/esx-framework.
Edit on GitHub

Last updated on

On this page