Combatintermediate13 min readupdated 19 Sept 2026

Tuning NPC accuracy and combat behaviour in FiveM

The short answer

Set how well a ped shoots with SetPedAccuracy(ped, 0-100), how often with SetPedShootRate(ped, 0-1000) and how with SetPedFiringPattern. Scale all NPC weapon damage on a client with SetAiWeaponDamageModifier. Shape behaviour with SetPedCombatAbility, SetPedCombatMovement, SetPedCombatRange and SetPedCombatAttributes, and decide who a ped fights with relationship groups (AddRelationshipGroup, SetRelationshipBetweenGroups, value 5 = hate). Apply everything on the client that owns the ped.

Every server that spawns armed NPCs, whether bank guards, gang lookouts or a PvE mission, runs into the same complaint: the NPCs shoot like aimbots. A guard at forty metres lands every round, a gang member wins a draw against a player who already had his weapon out. GTA's AI has a long list of knobs, and the defaults are tuned for a single-player game where the player has a health bar and auto-aim.

Tuning NPC accuracy and combat behaviour in FiveM — illustrated with a FiveM-compatible minimap render

#The levers, from most to least impact

NativeRangeWhat it changes
SetPedAccuracy(ped, n)0 to 100How often shots hit
SetPedShootRate(ped, n)0 to 1000How often the ped fires
SetPedFiringPattern(ped, hash)pattern hashSingle shots, bursts or full auto
SetAiWeaponDamageModifier(f)float, 1.0 normalDamage NPC weapons deal (client-wide)
SetPedCombatAbility(ped, n)0 to 2Poor, average, professional
SetPedCombatMovement(ped, n)0 to 3Stationary, defensive, offensive, suicidal
SetPedCombatRange(ped, n)0 to 3Near, medium, far, very far
SetPedCombatAttributes(ped, id, on)attribute idIndividual behaviour flags

NPC combat natives

Start with accuracy and damage. Most "aimbot NPC" complaints disappear with those two alone, and the rest is about making fights look intelligent rather than making them easier.

#Accuracy, shoot rate and firing patterns

Accuracy is a 0 to 100 value per ped. A ped at 100 almost never misses; one at 10 sprays. For roleplay guards, 20 to 40 makes a firefight dangerous without being a coin flip the player cannot influence. For PvE missions where players come in groups, 40 to 60 is reasonable.

client.lua
local function tuneShooter(ped, accuracy)
    SetPedAccuracy(ped, accuracy)
    SetPedShootRate(ped, 300)
    SetPedFiringPattern(ped, `FIRING_PATTERN_BURST_FIRE`)
end

Shoot rate reduces how often the ped pulls the trigger, which helps with automatic weapons. Firing patterns make the rhythm believable; the reference lists patterns such as FIRING_PATTERN_SINGLE_SHOT, FIRING_PATTERN_BURST_FIRE and FIRING_PATTERN_FULL_AUTO. A guard firing controlled bursts reads as a professional; one on full auto reads as a video game.

#Lowering the damage NPCs deal

Accuracy decides whether a shot lands; damage decides what it costs. SetAiWeaponDamageModifier(value) scales damage from all NPC weapons, and SetAiMeleeWeaponDamageModifier(value) does the same for melee. Both are set on the client and affect that client's game, so run them in every client's startup.

client.lua
CreateThread(function()
    SetAiWeaponDamageModifier(0.5)
    SetAiMeleeWeaponDamageModifier(0.6)
end)

Halving NPC gun damage is a common starting point on roleplay servers. It keeps shootouts with NPCs survivable without touching weapon damage between players, which you tune separately; see damage modifiers and headshot settings.

Headshots are the other source of instant deaths. The weapons.meta fields that control AI headshots (HeadShotDamageModifierAI, MinHeadShotDistanceAI, MaxHeadShotDistanceAI) are separate from the player ones, which is why NPCs can one-tap players even when players cannot one-tap each other.

#Combat ability, movement and attributes

How a ped fights matters as much as how well it aims. Three natives set the broad style:

  • SetPedCombatAbility: the reference lists 0 poor, 1 average, 2 professional, matching the combat behaviour data. Some testers report little visible difference, so treat it as a hint rather than a dial.
  • SetPedCombatMovement: 0 stands still, 1 is defensive and uses cover, 2 is offensive and advances while using cover, 3 charges and flanks recklessly.
  • SetPedCombatRange: 0 keeps within about 5 to 15 metres, 1 within 7 to 30, 2 within 15 to 40, 3 within 22 to 45.

Attributes are individual switches. The ones worth knowing for armed guards:

IdNameUse
0CA_USE_COVERPed uses cover
5CA_ALWAYS_FIGHTFights instead of fleeing when threatened
13CA_AGGRESSIVEMay advance on the target
17CA_ALWAYS_FLEEAlways runs away; for civilians
27CA_PERFECT_ACCURACYNever set this
46CA_CAN_FIGHT_ARMED_PEDS_WHEN_NOT_ARMEDUnarmed ped still engages
58CA_DISABLE_FLEE_FROM_COMBATStops released peds running off

Useful combat attributes

A guard that should hold a door uses movement 1, cover on and always-fight on. A gang lookout that should chase uses movement 2 with aggressive on. A shopkeeper who should run uses always-flee.

#Relationship groups: who fights whom

NPCs decide who is an enemy through relationship groups. Players are in PLAYER; ambient peds belong to groups such as COP, SECURITY_GUARD, AMBIENT_GANG_BALLAS, AMBIENT_GANG_FAMILY or AMBIENT_GANG_LOST. Relationship values run from 0 (companion) through 3 (neutral) to 5 (hate).

Create a group for your own peds so they do not inherit ambient behaviour, and set the relationship in both directions, because the native reference says it has to be called once for each group.

client.lua
local _, GUARDS = AddRelationshipGroup('BANK_GUARDS')

SetRelationshipBetweenGroups(5, GUARDS, `PLAYER`)
SetRelationshipBetweenGroups(5, `PLAYER`, GUARDS)
SetRelationshipBetweenGroups(0, GUARDS, `COP`)
SetRelationshipBetweenGroups(0, `COP`, GUARDS)

In Lua, AddRelationshipGroup returns the new group's hash as its second value because the native writes it to an output parameter. Hating PLAYER makes guards attack any player on sight, which suits a PvE mission; for a bank that should only react to robbers, use neutral (3) and switch the relationship when the alarm goes off.

The same native calms ambient gangs down. Setting the ambient gang groups to neutral towards PLAYER stops Grove Street opening fire on every passing player, which many roleplay servers want outside of scripted gang territory.

#A complete armed guard

Putting it together: spawn a guard, arm it, tune its combat and put it in the GUARDS group created in the previous section. This runs on a client, so the ped is created and owned by that client.

client.lua
local function spawnGuard(coords, heading)
    local model = `s_m_m_security_01`
    RequestModel(model)
    while not HasModelLoaded(model) do Wait(0) end

    local ped = CreatePed(4, model, coords.x, coords.y, coords.z, heading, true, false)
    SetModelAsNoLongerNeeded(model)

    GiveWeaponToPed(ped, `WEAPON_PISTOL`, 120, false, true)
    SetPedDropsWeaponsWhenDead(ped, false)
    SetPedArmour(ped, 50)

    SetPedAccuracy(ped, 30)
    SetPedShootRate(ped, 300)
    SetPedFiringPattern(ped, `FIRING_PATTERN_BURST_FIRE`)
    SetPedCombatAbility(ped, 1)
    SetPedCombatMovement(ped, 1)
    SetPedCombatRange(ped, 1)
    SetPedCombatAttributes(ped, 0, true)
    SetPedCombatAttributes(ped, 5, true)
    SetPedSeeingRange(ped, 40.0)
    SetPedHearingRange(ped, 40.0)

    SetPedRelationshipGroupHash(ped, GUARDS)
    TaskGuardCurrentPosition(ped, 15.0, 15.0, true)
    return ped
end

Seeing and hearing ranges stop guards across the street joining a fight they could not know about. SetPedDropsWeaponsWhenDead(ped, false) keeps a dead guard's pistol off the market; ambient drops are handled in disabling NPC weapon drops.

#Server-spawned peds and ownership

With OneSync you can spawn peds on the server with CreatePed, which is the better choice for persistent guards because they do not disappear when the player who spawned them leaves. The catch is that accuracy, combat attributes and relationship groups are set through client natives, and a networked ped's AI runs on whichever client owns it at the moment.

The usual pattern is: the server creates the ped and sends its network id to clients; the client that owns the ped (check NetworkGetEntityOwner against your own player) applies the combat settings. Re-apply them if ownership moves to another client, for example when the original owner walks away. The relationship group itself must also exist on every client, so run the AddRelationshipGroup code in every client's startup, not only on the owner.

#Tuning by playtest, not by numbers

The values in this guide are starting points. The right ones depend on your weapons, your player health and armour, and what a fight with NPCs is supposed to feel like. A short tuning loop works better than guessing:

  1. Put two or three players against a group of guards with the weapons players will realistically carry.
  2. Time the fights. A roleplay robbery shootout that ends in under ten seconds either way is usually too lethal; one that lasts minutes with nobody hurt is too soft.
  3. Change one lever at a time, accuracy first, then SetAiWeaponDamageModifier, then behaviour.
  4. Watch where players died from. Deaths from long range mean accuracy is too high; deaths from being flanked mean the behaviour is doing its job.
ProblemLikely causeFix
NPCs never missAttribute 27 set, or accuracy near 100Remove the attribute, set accuracy 20 to 40
NPCs one-tap playersAI headshot damageLower AI damage or add armour to players
Guards ignore robbersNeutral relationshipSwitch to hate (5) when the alarm triggers
Guards attack policeRelationship with COP not setSet companion or like both ways
Settings lost after a whileOwnership migrated to another clientRe-apply on the new owner

Common NPC combat problems

#Tuning ambient peds globally

For the whole ambient population, loop the ped pool as you would for drops and apply a lower accuracy once per ped. Skip players and mission entities so your scripted guards keep their own settings.

client.lua
local tuned = {}

CreateThread(function()
    while true do
        for _, ped in ipairs(GetGamePool('CPed')) do
            if not tuned[ped] and not IsPedAPlayer(ped) and not IsEntityAMissionEntity(ped) then
                SetPedAccuracy(ped, 15)
                tuned[ped] = true
            end
        end
        Wait(2000)
    end
end)

Prune the table occasionally, as in the drop script, so handles of deleted peds do not pile up.

Share this guideXRedditFacebook

Questions

How do I stop NPCs having aimbot in FiveM?
Lower their accuracy with SetPedAccuracy(ped, 20) to 40, reduce NPC damage with SetAiWeaponDamageModifier(0.5) and make sure nothing enables combat attribute 27, CA_PERFECT_ACCURACY.
What is a good NPC accuracy for roleplay?
20 to 40 for guards and gang members. It keeps fights dangerous but gives players a chance to win through cover and positioning.
How do I stop gang NPCs attacking players?
Set the relationship between the ambient gang groups, such as AMBIENT_GANG_BALLAS, and PLAYER to neutral (3) in both directions with SetRelationshipBetweenGroups.
Why do my NPC settings reset?
Combat settings are applied on a client. If the ped's network ownership moves to another client, or the ped is recreated, apply them again.
Does SetAiWeaponDamageModifier affect players shooting each other?
No. It scales damage from NPC weapons; player damage is tuned with the weapon and player damage modifiers.

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.

  • All 860 ped model namesEvery model GetHashKey resolves, with its hash and how many clothing components and props it carries.