FiveM Docs
Addons

esx_death

esx_death handles death state, the death screen, respawn timers, penalties and revives in ESX Legacy. Config keys, exports, events and /revive explained.

esx_death is the global death system for ESX Legacy. It shows a branded death screen when a player dies, persists the dead state in the database, runs the early-respawn and bleedout timers, applies respawn penalties and exposes exports to revive players. esx_ambulancejob builds on it for EMS revives and distress calls.

esx_death has no page in the official ESX documentation. This reference is written from the resource source (version 1.0.0).

Overview

FactValue
Resourceesx_death
SideClient + server + NUI
Dependencieses_extended, esx_lib, oxmysql, OneSync (/onesync)
Databaseusers.is_dead, users.death_time
Commands/revive, /reviveall (group admin)
Required byesx_ambulancejob

How it works

  1. es_extended detects the death on the client and triggers esx:onPlayerDeath (client and server) with killer data.
  2. esx_death stores is_dead = 1 and death_time (unix seconds), sets the isDead state bag and opens the death screen.
  3. After Config.EarlyRespawnTimer the player can hold E for Config.HoldDuration ms to respawn at the closest Config.RespawnPoints entry. Respawning before the bleedout ends costs Config.EarlyRespawnFineAmount from the bank when Config.EarlyRespawnFine is enabled.
  4. When the bleedout timer (EarlyRespawnTimer + BleedoutTimer) runs out, the client respawns automatically without a fine.
  5. On respawn the configured penalties remove items, cash, black money and weapons. A revive (EMS, admin, txAdmin) keeps everything.

Death screen controls

KeyAction
E (hold)Respawn when allowed.
GSend a distress signal (cooldown Config.DistressCooldown).
F2Toggle the mouse cursor to click the NUI buttons.

Chat (T) and push-to-talk stay enabled. All other controls are disabled while dead.

Installation

Database

With Config.AutoMigrate = true (default) the server adds the two users columns on start. To migrate manually, run esx_death.sql, which adds them only if missing:

ALTER TABLE `users` ADD COLUMN `is_dead` TINYINT(1) NOT NULL DEFAULT 0;
ALTER TABLE `users` ADD COLUMN `death_time` BIGINT NULL DEFAULT NULL;

The resource runs SELECT is_dead, death_time FROM users LIMIT 0 at start, so it fails loudly if the columns are missing.

server.cfg

OneSync must be enabled. Start esx_death before esx_ambulancejob:

server.cfg
set onesync on
ensure esx_lib
ensure es_extended
ensure esx_death
ensure esx_ambulancejob

Configuration

KeyDefaultDescription
Config.DebugfalsePrint detailed client and server debug logs.
Config.LocaleGetConvar('esx:locale', 'en')Locale for the death screen and commands.
Config.DeathAnim{ enabled = true, dict = 'misslamar1dead_body', name = 'dead_idle', fadeIn = 10.0, fadeOut = 10.0, flags = 1 | 2 | 8, playbackRate = 1.0 }Looping animation while dead.
Config.zoom{ min = 1, max = 6, step = 0.5 }Zoom limits for the death camera.
Config.MedalCliptrueTrigger a Medal.tv clip on death through xLib.medal.triggerClip().
Config.EarlyRespawnTimer60000 * 1Time in ms before respawn becomes available.
Config.BleedoutTimer60000 * 10Additional time in ms until the player bleeds out and respawns automatically.
Config.RemoveWeaponsAfterRPDeathtrueRemove all weapons on respawn (ESX inventory only).
Config.RemoveCashAfterRPDeathtrueRemove all cash and black money on respawn.
Config.RemoveItemsAfterRPDeathtrueClear the inventory on respawn (ox_inventory:ClearInventory with ox_inventory).
Config.EarlyRespawnFinefalseCharge a bank fine when respawning before the bleedout ends.
Config.EarlyRespawnFineAmount5000Amount of that fine. Respawn is refused if the bank balance is too low.
Config.OxInventoryESX.GetConfig('CustomInventory') == 'ox' or GetResourceState('ox_inventory') == 'started'Detected automatically. Switches item and weapon handling to ox_inventory.
Config.RespawnPoints2 points{ coords = vector3, heading = number } list. The closest point is used.
Config.HoldDuration1500Ms to hold E for respawn.
Config.DistressCooldown60000Ms between distress signals.
Config.ShowDeathReasontrueShow "killed by a player" under the buttons for player kills.
Config.ShowKillerNamefalseShow the killer's name instead (requires ShowDeathReason).
Config.CameraEnabledfalseUse the orbit death camera instead of the normal camera.
Config.AutoMigratetrueAdd missing users.is_dead / users.death_time columns on start.

Default respawn points:

config.lua
Config.RespawnPoints = {
    { coords = vector3(341.0, -1397.3, 32.5), heading = 48.5 },     -- Central Los Santos
    { coords = vector3(1836.03, 3670.99, 34.28), heading = 296.06 } -- Sandy Shores
}

Server exports

IsDead

exports.esx_death:IsDead(playerId) --> boolean

Returns true if the cached state of the player is dead. Returns false for players whose state is not loaded yet.

GetDeathState

exports.esx_death:GetDeathState(playerId) --> table | nil

Returns a snapshot or nil when no state is cached:

FieldTypeDescription
deadbooleanCurrent state.
elapsednumberSeconds since death.
earlyRemainingnumberSeconds until respawn is allowed.
remainingnumberSeconds until bleedout.
totalnumberTotal bleedout length in seconds.
distressRemainingnumberSeconds until the next distress signal.
distressSentbooleanA distress signal was sent during this death.
finenumberEarly respawn fine, 0 when disabled.
killedByPlayerbooleanDeath was caused by another player.
killerServerIdnumber?Validated killer server id.
deathCausenumber|string?Weapon hash or cause name.

GetDeadPlayers

exports.esx_death:GetDeadPlayers() --> { [playerId] = 'dead' | 'distress' }

GetDeadPlayerLocations

exports.esx_death:GetDeadPlayerLocations() --> { [playerId] = { x, y, z } }

Revive

exports.esx_death:Revive(playerId, reason?) --> ok, wasDead
NameTypeDescription
playerIdnumberServer id of the player.
reasonstring?Passed to esx_death:stateChanged. Defaults to 'revive'.

Revives in place, keeps the inventory, sets hunger and thirst to 500000 through esx_status:set and clears the dead flag in the database. Returns false, false if the player was not dead.

server/main.lua
local ok = exports.esx_death:Revive(targetId, 'mymedic')

if ok then
    TriggerClientEvent('esx:showNotification', targetId, 'You have been revived.')
end

SetDead

exports.esx_death:SetDead(playerId) --> boolean

Marks a player as dead in the database and syncs the death screen to that client. This does not kill the ped; use it together with your own logic.

Client exports

exports.esx_death:IsDead() --> boolean
exports.esx_death:GetDeathState() --> { dead, earlyRemaining, remaining, distressRemaining }

The server also sets the replicated state bag isDead, so LocalPlayer.state.isDead (client) and Player(src).state.isDead (server) work without exports.

Events

Server events (local)

EventArgumentsWhen
esx_death:stateChangedplayerId, dead, reasonState flips. reason is 'death', 'respawn', 'revive', 'admin', 'txadmin', 'restore', 'logout' or a custom revive reason.
esx_death:distressplayerId, coordsA dead player sent a distress signal. esx_ambulancejob uses it to alert medics.
server/main.lua
AddEventHandler('esx_death:stateChanged', function(playerId, dead, reason)
    if dead then
        print(('Player %s died'):format(playerId))
    elseif reason == 'respawn' then
        print(('Player %s respawned at a hospital'):format(playerId))
    end
end)

Client events (local)

EventArgumentsWhen
esx_death:enterednoneThe death screen opened.
esx_death:recovered'respawn' or 'revive'The player was respawned or revived.
esx_death:requestDistressnoneTrigger it to send a distress signal (same as pressing G).

On recovery esx_death also fires esx:onPlayerSpawn (client and server), playerSpawned and esx_basicneeds:resetStatus.

Net events and callbacks (security)

NameTypeNotes
esx:onPlayerDeathnet eventClient-triggerable. A client can only mark itself dead. Rate limited (3 per 5 s), killer id and cause are sanitized, timestamps and penalties are always set by the server.
esx_ambulancejob:onPlayerDistressnet eventClient-triggerable. Only works while the sender is dead and respects Config.DistressCooldown.
esx_death:respawncallbackRefused if not dead, too early or the fine cannot be paid.
esx_death:distress, esx_death:getStatecallbacksOnly affect the calling player.
esx_death:sync, esx_death:recover, esx_ambulancejob:clsearchclient net eventsThe client ignores them unless they come from the server.

Commands

CommandGroupArgumentsDescription
/reviveadminplayerIdRevive one player. Also works from the server console.
/revivealladminnoneRevive every online player.

The txAdmin "Heal" action (txAdmin:events:healedPlayer) revives the player, or everyone when txAdmin heals all.

Integration tips

  • Block actions while dead (shops, phones, inventories) with LocalPlayer.state.isDead on the client and exports.esx_death:IsDead(source) on the server.
  • Use Revive instead of calling NetworkResurrectLocalPlayer yourself; otherwise the database still says dead and the player is restored as dead on the next login.
  • To change who gets alerted on distress, listen to esx_death:distress in your own dispatch resource.

Common issues

  • SQL error about is_dead on start: the users table lacks is_dead/death_time and Config.AutoMigrate is off. Run esx_death.sql.
  • Two death screens or instant respawn: another death or revive script is still running. Only esx_death should handle death.
  • Weapons not removed with ox_inventory: with ox_inventory, weapons are items. Use Config.RemoveItemsAfterRPDeath instead of the weapons option.
  • Player respawns dead after relog: expected when they logged out while dead. Revive them or let the timer run out.

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