Configuring Squads, Formations, and Slots

GAIS_Cover
YuewuDev

Author

YuewuDev

Created: Oct 12, 2026Updated: Oct 12, 2026

Table of contents

Configuring Squads, Formations, and Slots

This guide does more than describe which components and fields to configure. It completes two verifiable scenarios: spawning a fixed formation from a template and regrouping units that already exist in the level. When finished, you should be able to observe runtime convergence of members, roles, formation slots, navigation-adapted positions, and Movement Intent.

Related documentation: see Squad System, Formation System, Squad, Role, and Unit Parameters, and Formation, Slot, and Navigation Parameters.

Prerequisites

  1. The squad-host Actor class implements IGAIS_SquadActorInterface and has UGAIS_SquadComponent, UGAIS_FormationComponent, and the components required by commands and AI.
  2. Every Actor that can join a squad has UGAIS_UnitComponent. If it must also receive commands, it must be a Pawn/Character with UGAIS_CommandSystemComponent on the Pawn.
  3. The project defines role and slot tags, such as GAIS.Role.Frontline, GAIS.Role.Ranged, GAIS.Formation.Slot.Front, and GAIS.Formation.Slot.Backline.
  4. The level has a usable NavMesh. To verify navigation adaptation, prepare a slope, stairs, or edge terrain.

Scenario 1: Spawn a Fixed Formation from a Template

Create a UGAIS_FormationDefinition subclass or Blueprint asset and configure a formation with clear spatial semantics. Every slot needs a stable SlotId; do not use the array index as identity. Give important positions a higher Weight and add SlotTags, such as GAIS.Formation.Slot.Front for front-line slots and GAIS.Formation.Slot.Backline for rear slots.

If the formation should follow the squad's overall facing, such as a shield wall or advancing line, keep bHasDirection enabled. For circular, scattered, or encirclement formations, per-slot rotation is more important and the overall direction semantic can be disabled.

Then create a UGAIS_SquadDefinition:

  1. Set SquadActorClass to the squad-host class.
  2. Add the formation to AvailableFormations.
  3. Configure role capacity, qualification tags, required status, and role StateTree in AvailableRoles.
  4. Configure unit types to spawn and their DesiredRole in DefaultUnits.
  5. Configure DefaultSquadStateTree, DefaultUnitStateTree, or role StateTree so the squad and units receive an explicit behavior layer after joining.
  6. Tune SlotAssignmentSettings so role tags and SlotTags match correctly.
  7. Tune DefaultMovementIntentResponseSettings and DefaultMovementIntentTags to control start/stop distance, response speed, and the project semantics carried by final Intent.

At runtime, create the squad with UGAIS_SquadSubsystem::CreateSquad and allow default units to spawn. The squad initializes its Definition, FormationComponent selects an available formation, SquadComponent waits for Formation Ready, then assigns slots and generates Movement Intent.

Scenario 2: Regroup Existing Units into a Squad

If units already exist in the level, do not respawn them just to use the squad system. Use CreateSquadFromActors to create the squad host and add the existing Actors. Every Actor must have UGAIS_UnitComponent, must not already belong to another squad, and must satisfy Unit/StateTree runtime contracts. If any Actor cannot be accepted, the entire transaction returns null and does not leave a partial squad.

For independent units that are recruited only after a gameplay condition, ensure they are automatically registered with UGAIS_SquadSubsystem by UGAIS_UnitComponent, then use CreateSquadFromNearbyUnits to recruit a specified number of unassigned units near the squad's spawn location. This entry point requires authority, a search radius greater than 0, and a recruitment count greater than 0. If enough valid candidates cannot be found or all candidates cannot be added atomically, it also returns null. Use TryReorganizeSquad to recruit nearby auto-recruitable units and fill missing roles during combat. Use MergeSquads to combine two squads; the primary squad retains identity and high-level command semantics.

After regrouping, validate more than member count. Confirm role-container recalculation, required-role gaps, slot reassignment, and Movement Intent refresh. When a unit leaves, its Squad-layer StateTree should clear and fall back to its own behavior layer.

Adjusting a Squad from a Client in Multiplayer

  1. Confirm that members, roles, TeamId, formation, and commands are maintained by the server.
  2. Server AI, Subsystems, or authoritative scripts call AddUnit, AssignRoleToUnit, SetCurrentFormation, and other authority entry points directly.
  3. A client that owns the squad host uses Server Add/Remove Unit, Server Assign/Revoke Role, Server Set Current Formation, or Server Issue Squad Command.
  4. If the client does not own the squad host, send a project RPC through its PlayerController. The server validates permissions and invokes the GAIS authority entry point.
  5. Verify that server and client UnitsContainer, RoleContainer, CurrentFormation, and Unit mirrors eventually agree.

Configure Navigation Adaptation

Inspect Navigation Adaptation on the squad host's UGAIS_FormationComponent:

Setting

Recommendation

bEnabled

Enable for most projects with real movement. When disabled, slots use geometric positions only.

NavigationQueryFilterClass

Configure a project QueryFilter when different unit types or squads have different traversable areas.

ProjectionQueryExtent

Increase Z when slots may be on slopes, stairs, or terrain with height variation.

ReprojectionDistanceThreshold / ReprojectionYawThresholdDegrees

Increase for large, frequently moving squads to reduce repeated projection.

bUseFallbackProjection / FallbackSearchRadius

Enable near terrain edges, bridges, or obstacles so failed slots contract toward the formation root.

Move the squad host onto a slope or near a NavMesh edge and verify that slot world positions land on navigable areas. If slot preview Actors are enabled, they should follow formation movement and show navigation offsets.

Validation

  • GetInitializationState() is Active, and IsSquadActive() is true. If still waiting, verify that Formation is Ready.
  • Each role in RoleContainer has the expected current count, MaxNum, and bRequired state.
  • FormationComponent has a current formation, IsFormationReady is true, and slot count matches the asset definition.
  • QuerySlots or FindSlotRuntimeView shows stable SlotId, SlotTags, and world transforms. Do not infer availability from legacy state fields or array indices.
  • Every Unit participating in formation has a reasonable AssignedSlotId.
  • Movement Intent exposes RawDesiredLocation, DesiredLocation, DesiredOrientation, DesiredSpeed, bShouldMove, and MovementIntentTags.
  • GameplayDebugger Squad / Formation sections show members, roles, current formation, slots, and slot-score explanations.

Common Failures

Symptom

Check first

Squad initialization stalls

Does FormationComponent exist, can AvailableFormations load, and is the current formation Ready?

Unit joins but has no role

Does AvailableRoles contain it, and do IsQualifiedOfRole, AllowedClasses, RequiredTags, or BlockTags reject it?

Unit has no slot

Are there enough slots, is the SlotTags policy too strict, or do distance/stability weights overpower semantic matching?

Slot position is not walkable

Is Navigation Adaptation enabled, do QueryFilter/ProjectionQueryExtent fit the NavMesh, and is fallback radius large enough?

Movement Intent exists but the unit does not move

Is MovementIntentDriver configured, or does the project movement system consume Intent mirrored on UnitComponent?

Client formation click has no effect

Was an authority-only API called? If using Server..., does the client own the squad host or Owner chain?