Lua Formation Follow
This documents the native formation-follow Lua helper for spawn scripts.
FormationFollow(...) lets one NPC follow another NPC's movement path in a configured formation. The function keeps the existing Lua script simple: pass the follower NPC, identify the leader, choose a formation pattern, then tune spacing and catch-up behavior.
Formation follow rebuilds are queued asynchronously at the zone level. The follower stores its configuration, resolves the leader when available, and applies the movement loop when the rebuild completes.
Completing the zone's initial spawn indexes preserves the active actors' scene identities, so formation requests made by their spawn scripts can finish after the zone loads. Removing or replacing an actor still invalidates work captured for its old scene.
Numeric spawn_id, location_id, and runtime_id references bind to the selected leader's allocation and zone publication after lookup, including while waiting for its movement path. A leader that has not loaded yet can resolve during the queued retry window. Once selected, a retired leader is not silently replaced by another spawn that reuses its ID; call FormationFollow again to select a new leader. The leader needs an authored or generated movement loop for the initial formation build.
After the initial build, behind uses the same live leader/trail tracking as the other formations. Its target is BackDistance * Slot along the leader's recent trail while moving. It slows or holds when ahead of its slot, suppresses catch-up when too close to an earlier behind follower, and stops when it reaches its slot behind a stopped leader. Spacing is a moving target with tolerance, not an exact fixed separation on every tick.
Automatic slots and column predecessor checks are separate for each leader/pattern. flank_left and flank_right followers can share the leader with behind followers without taking their column slots or becoming their column predecessors. Speed is the normal movement speed; live catch-up and spacing checks may temporarily raise, reduce, or stop movement.
FormationFollow
FormationFollow(NPC, Leader, Pattern, BackDistance, SideDistance[, Speed[, CatchupDistance[, MaxCatchupSpeed[, Slot[, LeaderRefType]]]]])
Return value: none. The call queues configuration/build work; it does not synchronously report that the follower is already moving.
| Parameter | Required | Default | Description |
|---|---|---|---|
NPC |
Yes | - | The follower NPC/spawn. Use the script's NPC; do not pass a separate Spawn parameter. |
Leader |
Yes | - | Either a leader spawn object or a numeric leader reference. Numeric references use LeaderRefType. |
Pattern |
Yes | behind if empty/unknown |
Formation pattern name or numeric pattern id. See pattern table below. |
BackDistance |
Yes | - | Distance behind the leader or behind the previous rank, depending on pattern. |
SideDistance |
Yes | - | Lateral spacing for flank/V/echelon patterns. Use 0 for direct behind/column behavior. |
Speed |
No | 0 |
Normal formation movement speed. 0 uses the default walking speed, currently 2.0. |
CatchupDistance |
No | 0 |
Distance before the follower starts catch-up behavior. 0 uses the code default based on formation spacing. |
MaxCatchupSpeed |
No | 0 |
Speed used during short catch-up bursts. 0 uses the code default based on normal speed. |
Slot |
No | 0 |
Formation slot. 0 auto-assigns a slot among followers of the same leader/pattern. |
LeaderRefType |
No | spawn_id for numeric leaders |
Only used when Leader is numeric. Valid values are listed below. |
Patterns
| Name | Aliases | Numeric id | Description |
|---|---|---|---|
behind |
follow, column |
0 |
Follow directly behind the leader. Multiple slots form a column. |
flank_left |
left |
1 |
Follow behind and to the leader's left. |
flank_right |
right |
2 |
Follow behind and to the leader's right. |
inverse_v |
wedge, v |
3 |
Alternates followers left/right behind the leader in a V/wedge shape. |
staggered_column |
staggered |
4 |
Column with slight alternating side offsets. |
echelon_left |
- | 5 |
Diagonal line behind and left of the leader. |
echelon_right |
- | 6 |
Diagonal line behind and right of the leader. |
LeaderRefType
LeaderRefType is only needed when Leader is numeric.
| Value | Aliases | Description |
|---|---|---|
runtime_id |
id, entity_id |
The active runtime spawn id. |
spawn_id |
- | The database spawn id. This is the default for numeric leaders. |
location_id |
spawn_location_id, location |
The spawn location id. Useful when followers spawn at the same time as the leader. |
When Leader is an actual spawn object, the function uses that spawn's runtime id and ignores LeaderRefType.
Examples
Follow A Leader Spawn Object
function spawn(NPC)
local Leader = GetSpawn(NPC, 123456)
if Leader ~= nil then
FormationFollow(NPC, Leader, "behind", 4.0, 0.0, 2.0, 8.0, 5.0)
end
end
Follow By Spawn Location Id
function spawn(NPC)
FormationFollow(NPC, 430688, "inverse_v", 4.0, 2.0, 0, 8.0, 5.0, 0, "location_id")
end
This uses:
| Argument | Value |
|---|---|
Leader |
430688 |
Pattern |
inverse_v |
BackDistance |
4.0 |
SideDistance |
2.0 |
Speed |
0, so default walk speed |
CatchupDistance |
8.0 |
MaxCatchupSpeed |
5.0 |
Slot |
0, so auto-assign |
LeaderRefType |
location_id |
Explicit Slots
function spawn(NPC)
FormationFollow(NPC, 430688, "behind", 3.0, 0.0, 2.0, 6.0, 5.0, 1, "location_id")
end
Use explicit slots when a script needs a predictable position. For behind, slot 1 is closest to the leader, slot 2 is behind slot 1, and so on. For inverse_v, odd slots go to one side and even slots go to the other side.
Mixed Behind And Flank Followers
Call each line for its own follower spawn. All three can auto-assign slot 1 because their patterns differ:
FormationFollow(BehindNPC, 133802494, "behind", 4.0, 0.0, 2.5, 8.0, 5.0, 0, "location_id")
FormationFollow(LeftNPC, 133802494, "flank_left", 4.0, 2.0, 2.5, 8.0, 5.0, 0, "location_id")
FormationFollow(RightNPC, 133802494, "flank_right", 4.0, 2.0, 2.5, 8.0, 5.0, 0, "location_id")
A second behind follower using automatic assignment takes the next column slot; the left and right followers do not change that assignment. The example uses normal speed 2.5 and catch-up speed 5.0; the live controller prevents an in-position follower from independently running ahead around the copied patrol loop.