Game Damage Events
The CEventNetworkEntityDamage payload from gameEventTriggered explained index by index, plus generated clean kill, death and vehicle events for your resource.
Ta dokumentacja jest na razie po angielsku.
Game Damage Events documents the raw CEventNetworkEntityDamage payload FiveM hands to scripts, and generates a small resource that turns it into named events like damage:onPlayerDied and damage:onPlayerKilled. It is for anyone building a kill feed, death screen, bounty system or vehicle damage logic.
What it is for
FiveM forwards low-level game events to client scripts through gameEventTriggered. When a networked entity takes damage, you get CEventNetworkEntityDamage with an array of integers and no names. The layout also changed between game builds, which is why many old snippets read the wrong index and silently break. This page tells you which index is which today, and writes the parsing once so every other script can listen to clean events.
Quick start
- Open Raw args to see the payload layout, or Event explorer to see the events the generated code emits.
- Tick Include on the events you want (five are selected by default).
- Open Code builder, set the Event prefix and options.
- Copy each file tab (
client.lua,server.lua,fxmanifest.lua) into a new resource, and useexamples.luaas a starting point for your listeners.
The raw payload
On game build 2189 and newer, the args are:
| Index | Lua | Name | Type | Status |
|---|---|---|---|---|
| 0 | args[1] |
victim | entity | Reliable |
| 1 | args[2] |
attacker | entity (-1 or 0 when none) | Reliable |
| 2 | args[3] |
unknown, likely the damage amount as a raw float | int | Reported |
| 3 | args[4] |
unknown, added in b2060 | int | Reported |
| 4 | args[5] |
unknown, added in b2189 | int | Reported |
| 5 | args[6] |
fatal (1 when it killed or destroyed the victim) | int 0/1 | Reliable |
| 6 | args[7] |
weaponHash (weapon or cause, such as WEAPON_RUN_OVER_BY_CAR, WEAPON_FALL) |
hash | Reliable |
| 7 | args[8] |
unknown, non-zero on vehicle collisions | int | Reported |
| 8 | args[9] |
unknown, non-zero on vehicle collisions | int | Reported |
| 9 | args[10] |
unknown, 1 on some headshots or collisions | int 0/1 | Varies by build |
| 10 | args[11] |
read as isMelee or isHeadshot depending on build | int 0/1 | Varies by build |
| 11 | args[12] |
isMelee or vehicle damage flags (93 tyres, 116 body, 120 windows) | int | Varies by build |
| 12 | args[13] |
vehicle damage type or hit material | int | Varies by build |
Only victim, attacker, fatal and weapon are safe to rely on. The attacker can be a vehicle when someone was run over.
Before b2060 the layout was two slots shorter: fatal at index 3 and weaponHash at index 4. Older resources still read those and get wrong values on current builds. The Old layout (before b2060) panel lists it.
The minimal handler:
AddEventHandler("gameEventTriggered", function(name, args)
if name ~= "CEventNetworkEntityDamage" then return end
local victim, attacker = args[1], args[2]
local fatal = args[6] == 1
local weaponHash = args[7]
print(json.encode(args)) -- dump the rest on your build
end)Warning
The event fires on every client that knows the victim, not only on the victim and the attacker. If ten players are near a fight, all ten get it. Filter on PlayerPedId() before you reward a kill.
Events the generated code emits
All are client events named <prefix>:<event>, for example damage:onPlayerDied.
| Event | When | Arguments |
|---|---|---|
onPlayerDied |
Local player died, any cause. Once per death. | cause, killerServerId, weaponHash, killerEntity |
onPlayerKilledByPlayer |
Local player killed by another player (also run over by a player’s car). | killerServerId, weaponHash, isMelee, isHeadshot, distance |
onPlayerKilledByPed |
Local player killed by an NPC. | killerPed, weaponHash, isMelee |
onPlayerKilledByVehicle |
Run over by a vehicle with no player driver. | vehicle, weaponHash |
onPlayerKilled |
Local player killed another player (killer side). | victimServerId, weaponHash, isMelee, isHeadshot, distance |
onPlayerDamaged |
Local player took damage and survived. Frequent. | attacker, weaponHash, isMelee, attackerServerId |
onPedKilledByPlayer |
Local player killed an NPC. | ped, weaponHash, isMelee, isHeadshot |
onPedDied |
An NPC died and the local player was not the killer. Every client. | ped, attacker, weaponHash |
onVehicleDestroyed |
A vehicle blew up or was wrecked. Every client. | vehicle, attacker, weaponHash, byLocalPlayer |
onVehicleDamaged |
A vehicle took damage but survived. Every client, frequent. | vehicle, attacker, weaponHash |
onEntityDamaged |
Every raw damage event, untouched, for debugging. | victim, attacker, weaponHash, fatal, args |
cause is one of "player", "ped", "vehicle", "suicide" or "environment". Selected by default: onPlayerDied, onPlayerKilledByPlayer, onPlayerKilled, onPedKilledByPlayer, onVehicleDestroyed. The Event explorer search matches event names, descriptions, groups and argument names, and each card has a ready listener.
In the generated code, melee comes from the weapon group and headshots from GetPedLastDamageBone (bone 31086, the head), not from the unstable slots. Deaths are reported once: shooting a body again does not fire a second death, and deaths that never raised a damage event (fall damage on some builds, SetEntityHealth(ped, 0)) are still caught.
Code builder options
| Option | What it does | Default |
|---|---|---|
| Events | Which events to generate. All and None buttons at the top. | 5 selected |
| Event prefix | Prefix for every event name. | damage |
| Debug prints | Prints every emitted event to the F8 console. | off |
| Server relay | Adds server.lua: the victim reports its own death, the server checks it and fires <prefix>:server:playerDied and <prefix>:server:playerKilled. |
on |
| Max kill distance (m) | Server relay drops kill reports where the killer is further away than this (OneSync). | 1000 |
The server relay checks the payload type and cause, allows one report per player every 3 seconds, makes sure the killer is another connected player, and checks the distance between the two peds.
Examples
Client side, a kill feed line:
AddEventHandler("damage:onPlayerKilled", function(victimServerId, weaponHash, isMelee, isHeadshot, distance)
local msg = ("You killed %s (%.0fm)%s"):format(GetPlayerName(GetPlayerFromServerId(victimServerId)), distance, isHeadshot and ", headshot" or "")
print(msg)
end)Server side, with the relay on:
AddEventHandler("damage:server:playerDied", function(victim, killer, info)
print(GetPlayerName(victim), "died", info.cause, killer and GetPlayerName(killer))
end)The manifest the tool writes:
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
client_script 'client.lua'
server_script 'server.lua'Limitations
- The server never receives
CEventNetworkEntityDamageitself. The relay trusts the victim’s own report, which is the least abusable direction (a cheater can only lie about their own death), but treat it as a kill feed source, not as proof for bans. - The unknown slots differ between builds. If you need one, turn on
onEntityDamagedwith Debug prints and log the raw table on your server’s build.
The idea of named damage events comes from Vespura’s DamageEvents resource. The Lua here is a separate implementation for current game builds.
