Scriptingintermediate8 min readupdated 11 Sept 2026

How weapon hashes work in FiveM scripts

The short answer

A hash is the Jenkins one-at-a-time hash of the lowercase name. In FiveM Lua, write `WEAPON_PISTOL` (computed at compile time, fastest) or call GetHashKey('WEAPON_PISTOL') / joaat(...) at runtime. Names are case-insensitive. Natives return hashes as signed 32-bit integers, so WEAPON_UNARMED appears as -1569615261 even though its hex is 0xA2719263 (2725352035 unsigned). Convert before comparing with unsigned values from websites.

GTA V identifies weapons, models and components by 32-bit hashes of their names. Scripts compare them constantly — “is the player holding a pistol?” — and most hash bugs come from mixing the three ways to get a hash, or from signed and unsigned versions of the same number.

How weapon hashes work in FiveM scripts — illustrated with a FiveM-compatible minimap render

#Three ways to get a hash

client.lua
local a = `WEAPON_PISTOL`               -- compile time
local b = GetHashKey('WEAPON_PISTOL')  -- runtime native
local c = joaat('weapon_pistol')       -- runtime, FiveM Lua helper
print(a == b, b == c)                  -- true  true

if GetSelectedPedWeapon(PlayerPedId()) == `WEAPON_PISTOL` then
    print('holding a pistol')
end

Backticks only work with literal names. Use GetHashKey or joaat when the name comes from a config or database. Cfx.re measured backtick comparisons at less than half the cost of calling GetHashKey in a hot loop.

#Signed vs unsigned

NameHexUnsignedSigned (what natives return)
WEAPON_UNARMED0xA27192632725352035-1569615261
WEAPON_PISTOL0x1B06D571453432689453432689
WEAPON_PISTOL_MK20xBFE256D43219281620-1075685676
WEAPON_CARBINERIFLE0x83BF02782210333304-2084633992
COMPONENT_PISTOL_CLIP_010xFED0FD714275109233-19858063

Computed with the joaat algorithm.

Converting
local function toSigned(h)
    if h > 0x7FFFFFFF then return h - 0x100000000 end
    return h
end

local function toUnsigned(h)
    if h < 0 then return h + 0x100000000 end
    return h
end

Hashes below 0x80000000 are identical in both forms, which is why some weapons “work” and others silently fail when a table stores unsigned numbers. The complete list with both values: weapon names and hashes.

#JavaScript and C#

In JavaScript use GetHashKey('WEAPON_PISTOL'); in C# (uint)API.GetHashKey("WEAPON_PISTOL") or the WeaponHash enum. When moving hashes between languages or storing them as JSON, keep one convention (signed or name strings) for the whole project. If you only need the number for one name, FAM Tools has a joaat calculator that also searches backwards from a hash you already have.

#Debugging hash mismatches

  1. Print both values: print(GetSelectedPedWeapon(ped), WEAPON_X).
  2. If they differ by exactly 4294967296, it is a signed/unsigned mix.
  3. If they are unrelated, check spelling (WEAPON_CARBINERIFLE, not WEAPON_CARBINE_RIFLE).
  4. For add-on weapons, make sure the weapon is actually streamed and loaded.
Share this guideXRedditFacebook

Questions

What is joaat in FiveM?
The Jenkins one-at-a-time hash GTA V uses for names; FiveM Lua exposes it as joaat() and backtick literals.
Why is WEAPON_UNARMED negative?
Natives return signed 32-bit integers. 0xA2719263 is 2725352035 unsigned and -1569615261 signed.
Is GetHashKey case-sensitive?
No. The name is lowercased before hashing.
Should I use backticks or GetHashKey?
Backticks for fixed names (faster), GetHashKey/joaat for names from config or data.

Ready to pick a map?

Twelve themes on three base map styles, $8 each, instant download.

Relevant to what you just read

Look it up while you work

The reference tables this guide leans on, free and without an account.