Skip to Content
ReferenceGame Event Payload Diagnosis

Diagnose FiveM game-event payloads

Log the smallest useful, bounded observation before writing policy. A game event can represent an incoming request, a client-side observation or a completed server transition. These are not interchangeable. Never convert “I saw this event” into an automatic ban, payment or inventory grant without corroborating server state.

Use client contracts and server contracts to choose the listener. Low-level gameEventTriggered arrays and the structured server events are different APIs: a numeric slot in one is not a property of the other.

Fields worth distinguishing

EventDocumented fields used for diagnosisWhat they do not establish
weaponDamageEvent(sender, data)weaponType, hitGlobalId, hitGlobalIds, overrideDefaultDamage, weaponDamage, willKillA network ID is not a server handle; willKill is not confirmed death; weaponDamage is not always the damage used.
startProjectileEvent(sender, data)projectileHash, weaponHash, ownerId, fire/initial position fields, targetEntityA projectile request is not proof of impact, ownership entitlement or a player’s final aim.
ptFxEvent(sender, data)assetHash, effectHash, isOnEntity, entityNetId, position/offset/rotation fieldsAn attached effect’s offsets are not a world-space position.
removeAllWeaponsEvent(sender, data)pedIdThe target ped ID is not the sender’s persistent account identity.
vehicleComponentControlEvent(sender, data)vehicleGlobalId, pedGlobalId, componentIndex, componentIsSeat, pedInSeat, requestUpstream explicitly leaves the meaning of request uncertain; it is not a safe “accepted” boolean for policy.
respawnPlayerPedEvent(player, content)posX, posY, posZA respawn notification is not permission to grant a loadout again.

The generated server reference  lists the full structured payloads. Retain unknown f*/unk* names as unknown instead of inventing meanings. vehicleComponentControlEvent  and respawnPlayerPedEvent  are separately documented.

A bounded server-side damage observation

Add this as server.lua in a temporary resource with server_script 'server.lua'. It is disabled unless the server owner explicitly enables its convar. It prints a count, not player identifiers, arbitrary strings, coordinates or an entire payload.

local observed, selectedWeapon = 0, nil RegisterCommand('fd_damage_watch', function(source, args) if source ~= 0 then return end -- Server console only. selectedWeapon = args[1] and joaat(args[1]) or nil observed = 0 print('[Damage lab] Observation counter reset; no requests will be cancelled.') end, true) AddEventHandler('weaponDamageEvent', function(sender, data) if GetConvarInt('fd_damage_observe', 0) ~= 1 then return end if type(data) ~= 'table' or type(data.weaponType) ~= 'number' then return end if selectedWeapon and data.weaponType ~= selectedWeapon then return end observed = observed + 1 if observed <= 5 then print(('[Damage lab] sample=%d target-id-present=%s override=%s'):format( observed, tostring(type(data.hitGlobalId) == 'number'), tostring(data.overrideDefaultDamage == true))) end end)

In the server console, run set fd_damage_observe 1, then optionally fd_damage_watch WEAPON_PISTOL. Trigger one controlled hit against a remotely owned test entity. After five observations, the handler keeps only the count. Finish with set fd_damage_observe 0 and stop the resource. It neither blocks damage nor broadcasts evidence to clients.

Do not use this diagnostic flag on a public server indefinitely. For a bug report, record the artifact, Legacy/Enhanced track, game build, which client owned the target, the action taken and whether server-observed health changed. This makes a reproduction more useful than a large unlabelled JSON dump.

Handle network IDs without confusing them with handles

A server-native operation needs an entity handle. For a named payload field documented as a network ID, resolve it with NetworkGetEntityFromNetworkId, check it is nonzero, and verify the entity still exists before reading state. Recheck after an asynchronous boundary. A target that vanished between dispatch and inspection is an expected race, not evidence of cheating.

Conversely, the handle given to entityCreating is already a server entity handle. Passing it through a network-ID conversion changes its meaning. For player references, distinguish server session IDs, client player indices and permanent identifiers; see network and local IDs.

Cancellation must have a documented effect

The server contract explicitly permits rejecting weaponDamageEvent. It does not follow that every event in the table has the same supported veto. A server-side gameplay rule should first be stated independently of the transport, validated against current state, and tested for false positives on normal resources.

For low-level client arrays, preserve a build-specific decoder behind a version check and a fixture captured from that exact build. An unrecognized shape should disable that diagnostic feature rather than guess an index. Prefer named native queries or a structured documented event when available. These reference pages intentionally do not publish speculative offset lists.

Secure custom events, OneSync and ownership, profiler captures, and client diagnostics cover the surrounding workflow. These examples have not been used to certify FiveM engine behavior; they are scoped diagnostic recipes, not an anti-cheat product.