Lua functions

FormationFollow

Registered in this checkout as EQ2Emu_lua_FormationFollow; implementation found at WorldServer/Lua/LuaFunctions.cpp:1370.

Historical signature: FormationFollow(…) via current binding

Parameter and behavior details in the historical explanation are under review against the current implementation.

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.

Checked example

Active call in a local runtime Lua script. Argument count matches current fixed C++ readers. The binding also handles arguments dynamically. This is a contextual call pattern, not a tested standalone script.

FormationFollow(NPC, 407787, "inverse_v", 4.0, 2.0, 0, 8.0, 5.0, 0, "location_id")

Evidence: server/SpawnScripts/SouthFreeport/GuardCaesonia.lua:14; binding EQ2Emu_lua_FormationFollow.

Current registration: WorldServer/Lua/LuaInterface.cpp.