Skip to main content

Project 03: Bodyguard

In Project 02, you spawned a static pedestrian. In Project 03, you transform a spawned pedestrian into an intelligent, active ally: an individual bodyguard who walks alongside you, detects when you are under attack, targets the specific hostile threat, and returns to your side once the danger has passed.


The mission

Build an individual bodyguard script satisfying six core operational criteria:

  1. Spawn an armed companion pedestrian who walks in an offset follow posture beside the player.
  2. Establish a mutual companion relationship group to prevent friendly fire and enforce faction loyalty.
  3. Detect when the player is engaged in combat and direct the bodyguard specifically at a known aggressor.
  4. Allow native combat AI to manage tactical shooting without interrupting or resetting tasks every frame.
  5. Automatically resume peaceful offset following once the hostile threat is eliminated.
  6. Cleanly delete both bodyguard and test actors when reloading the script.

Specifications, constraints

  • Individual companion focus: Keep the architecture focused on a single bodyguard rather than multi-npc squad formations.
  • Explicit target requirement: Recognize that player.IsInCombat is a binary boolean that provides no entity handle; you must supply a concrete target entity to Task.Combat.
  • Task priority hierarchy: Organize OnTick so that ongoing combat, new engagement, and peaceful following never conflict or overwrite each other on the same frame.
  • Zero orphan entities: Guarantee that all spawned actors are checked and deleted inside OnAborted.

Implementation steps

  1. Declare entity handles: Define private fields private Ped _guard; and private Ped _testAggressor;.
  2. Configure diplomatic relations: In the constructor, create a companion relationship group (COMPANION_GUARD) and establish mutual Relationship.Companion with the player's group.
  3. Implement bodyguard spawning: In a dedicated helper, stream PedHash.Security01SMM, spawn the ped 2 meters to the right, equip them with a weapon, assign BlockPermanentEvents = true, and associate the companion relationship group.
  4. Build the decision hierarchy in OnTick:
    • If the player is invalid, abort early.
    • If the guard is missing or dead, trigger spawning.
    • If the guard is already fighting (_guard.IsInCombat), return immediately to give the game's tactical AI full control.
    • If both the player and the aggressor are engaged in combat, issue _guard.Task.Combat(_testAggressor, ...).
    • Otherwise, maintain peaceful movement via _guard.Task.FollowToOffsetFromEntity(player, ...).
  5. Enforce clean teardown: In OnAborted, verify that both _guard and _testAggressor exist, and delete them cleanly.

APIs, tools to explore

  • GTA.RelationshipGroup: Struct representing faction loyalty and diplomatic rules between entities.
  • RelationshipGroup.SetRelationshipBetweenGroups(RelationshipGroup other, Relationship relation, bool bidirectional): Configures mutual alignment between two groups.
  • Ped.Task.FollowToOffsetFromEntity(Entity target, Vector3 offset, float speed, int timeout, float stoppingRange, bool persist): Commands an entity to match the movement of a target while maintaining a local coordinate offset.
  • Ped.Task.Combat(Ped target, TaskCombatFlags combatFlags, TaskThreatResponseFlags threatResponseFlags): Commands an entity to engage in an armed or unarmed assault against an explicit target.
  • Ped.IsInCombat: Native engine boolean indicating whether a pedestrian is actively fighting.
  • Ped.BlockPermanentEvents: Disables default ambient panic, stopping NPCs from fleeing gunshots so your script retains full behavioral control.

Validation checklist

Your mod is validated when:

  • The bodyguard spawns reliably and walks in formation on your left flank as you navigate through Los Santos.
  • When an aggressor attacks the player, the bodyguard draws their weapon and engages that specific target.
  • During the firefight, the bodyguard uses native tactical cover and shooting without stuttering or task resetting.
  • Once the hostile target dies, the bodyguard holsters their weapon and returns to follow formation.
  • Reloading the script with Insert cleanly deletes both bodyguard and aggressor.

Solution, explanations

Partner
Verified solution and code explanations

The mission, specifications, and guided steps remain 100% free and open for everyone. The complete verified reference code and production explanations are reserved for Partner members.