Follower
Based on game build 722832 | Last updated: 2026-04-28
Overview
Follower manages the relationship between an entity and its leader, handling following behavior, loyalty timers, and automatic leashing when the follower falls too far behind. It integrates with the leader component to maintain bidirectional tracking, supports item-based ownership through inventoryitem, and caches player leader state for reconnection after disconnects. The component pushes events for leader changes and loyalty state, and listens to entity lifecycle events to manage cleanup.
Usage example
local inst = CreateEntity()
inst:AddComponent("follower")
inst:AddComponent("leader")
-- Set a leader entity
inst.components.follower:SetLeader(player)
-- Add loyalty time (in seconds)
inst.components.follower:AddLoyaltyTime(120)
-- Check loyalty percentage
local loyalty = inst.components.follower:GetLoyaltyPercent()
-- Enable automatic leashing when far from leader
inst.components.follower:StartLeashing()
Dependencies & tags
External dependencies:
TUNING.FOLLOWER_REFOLLOW_DIST_SQ-- distance threshold for player reconnectionFindWalkableOffset-- finds valid teleport positions on landFindSwimmableOffset-- finds valid teleport positions on waterMakeComponentAnInventoryItemSource-- links follower to inventory item ownerRemoveComponentInventoryItemSource-- unlinks follower from inventory item owner
Components used:
combat-- drops target when leader changes if target is an ally; clears target during teleportfollowermemory-- callsOnChangedLeaderwhen leader changeshitchable-- checkscanbehitchedbefore allowing teleportinventoryitem-- checked on leader to enable item-based ownershipleader-- adds/removes follower from leader's tracking; checksloyaltyeffectivenessandforceleashleaderrollcall-- checksIsEnabledfor roll call eligibilitylocomotor-- checksCanPathfindOnLandandCanPathfindOnWaterfor teleport positioning
Tags:
pocketdimension_container-- checked to prevent teleporting to leaders in pocket dimensionsplayer-- checked to enable leashing for player leaders
Properties
| Property | Type | Default Value | Description |
|---|---|---|---|
leader | entity | nil | Current leader entity. Assignment fires onleader property watcher to sync replica. |
itemowner | entity | nil | Owner when follower is an inventory item. Assignment fires onitemowner property watcher to sync replica. |
targettime | number | nil | Timestamp when loyalty expires. Used with maxfollowtime for loyalty percentage. |
maxfollowtime | number | nil | Maximum loyalty duration in seconds. Caps loyalty time additions. |
canaccepttarget | boolean | true | Whether follower can accept combat targets independently. |
noleashing | boolean | nil | When truthy, disables automatic leashing behavior. |
keepleaderonattacked | boolean | nil | When truthy, prevents leader loss when attacked by leader. |
neverexpire | boolean | nil | When truthy, loyalty timer never expires (immune to StopFollowing). |
hasitemsource | boolean | nil | Internal flag tracking if follower is linked as inventory item source. |
canberollcalledfn | function | nil | Custom callback for roll call eligibility. Signature: fn(inst, leader) → boolean. |
OnChangedLeader | function | nil | External hook called when leader changes. Signature: fn(inst, new_leader, prev_leader). |
task | task | nil | Scheduled loyalty expiry task. Cancelled on leader change or cleanup. |
porttask | task | nil | Scheduled teleport retry task for leashing. Cancelled on sleep/wake. |
cached_player_leader_userid | string | nil | Cached player user ID for reconnection after disconnect. |
cached_player_leader_timeleft | number | nil | Cached remaining loyalty time for reconnection. |
cached_player_leader_task | task | nil | Task to clear cached player leader on expiry. |
_onleaderwake | function | nil | Internal listener for leader wake events during leashing. |
Main functions
GetDebugString()
- Description: Returns a debug string showing current leader, item owner, and loyalty timer status.
- Parameters: None
- Returns: String with follower state information.
- Error states: None
GetLeader()
- Description: Returns the effective leader, prioritizing
itemowneroverleader. Used for inventory item followers. - Parameters: None
- Returns: Entity instance or
nilif no leader. - Error states: None
StartLeashing()
- Description: Enables automatic teleport when follower is too far from leader. Registers entity sleep/wake listeners on leader.
- Parameters: None
- Returns: None
- Error states: None. Returns early if
noleashingis truthy or leader is nil.
StopLeashing()
- Description: Disables automatic teleport and cancels pending port tasks. Removes sleep/wake event listeners.
- Parameters: None
- Returns: None
- Error states: None
DisableLeashing()
- Description: Permanently disables leashing by setting
noleashingto true. CallsStopLeashing()to cleanup. - Parameters: None
- Returns: None
- Error states: None
EnableLeashing()
- Description: Re-enables leashing by clearing
noleashing. Restarts leashing if leader is a player or inventory item. - Parameters: None
- Returns: None
- Error states: None. Returns early if
noleashingis already nil.
SetCanBeRollCalledFn(fn)
- Description: Sets custom callback for roll call eligibility checks.
- Parameters:
fn-- function with signaturefn(inst, leader) → boolean - Returns: None
- Error states: None
CanBeRollCalled(leader)
- Description: Checks if follower can be roll called by leader. Checks
leaderrollcallcomponent and custom callback. - Parameters:
leader-- entity instance to check against - Returns:
trueif roll call is allowed,falseotherwise. - Error states: None
CachePlayerLeader(userid, timeleft)
- Description: Caches player leader information for reconnection after disconnect. Registers world event listeners for player join/spawn.
- Parameters:
userid-- string player user ID, or nil to use current leader's useridtimeleft-- number seconds of loyalty remaining, or nil to calculate fromtargettime
- Returns: None
- Error states: None
ClearCachedPlayerLeader()
- Description: Clears cached player leader data and removes world event listeners. Called on leader change or cache expiry.
- Parameters: None
- Returns: None
- Error states: None
OnItemSourceNewOwner(owner)
- Description: Called when inventory item source gets a new owner. Updates
itemownerand registers with owner'sleadercomponent. - Parameters:
owner-- entity instance of new owner - Returns: None
- Error states: None
OnItemSourceRemoved(owner)
- Description: Called when inventory item source is removed. Clears
itemownerand unregisters from owner'sleadercomponent. - Parameters:
owner-- entity instance of previous owner - Returns: None
- Error states: None
SetLeader(new_leader)
- Description: Sets the follower's leader. Handles cleanup of previous leader, registers with new leader's
leadercomponent, and enables leashing for player/inventory leaders. - Parameters:
new_leader-- entity instance ornilto clear leader - Returns: None
- Error states: None
GetLoyaltyPercent()
- Description: Returns loyalty as a percentage (0-1). Calculated from remaining time vs
maxfollowtime. - Parameters: None
- Returns: Number between 0 and 1, or 0 if no loyalty timer active.
- Error states: None
AddLoyaltyTime(time)
- Description: Adds time to the loyalty timer. Applies
loyaltyeffectivenessmultiplier from leader'sleadercomponent. Caps atmaxfollowtime. - Parameters:
time-- number seconds to add - Returns: None
- Error states: None. Returns early if
neverexpireis truthy.
CancelLoyaltyTask()
- Description: Cancels the loyalty expiry task and clears
targettime. Called on leader change. - Parameters: None
- Returns: None
- Error states: None
StopFollowing()
- Description: Ends following behavior by clearing loyalty timer and calling
SetLeader(nil). Pushesloseloyaltyevent. - Parameters: None
- Returns: None
- Error states: None. Returns early if
neverexpireis truthy.
IsNearLeader(dist)
- Description: Checks if follower is within
distunits of leader. - Parameters:
dist-- number distance threshold - Returns:
trueif within range and leader exists,falseotherwise. - Error states: None
OnSave()
- Description: Serializes loyalty timer and cached player leader data for world save.
- Parameters: None
- Returns: Table with
time,cached_player_leader_userid,cached_player_leader_timeleftornilif no data to save. - Error states: None
OnLoad(data)
- Description: Restores loyalty timer and cached player leader data from world save.
- Parameters:
data-- table fromOnSave() - Returns: None
- Error states: None
IsLeaderSame(guy)
- Description: Checks if another entity shares the same leader as this follower.
- Parameters:
guy-- entity instance to compare - Returns:
trueif both have same leader,falseotherwise. - Error states: Errors if
guyhas nofollowercomponent (nil dereference onguy.components.follower— no guard present).
KeepLeaderOnAttacked()
- Description: Enables flag to prevent leader loss when attacked by leader. Removes the "attacked" event listener.
- Parameters: None
- Returns: None
- Error states: None
LoseLeaderOnAttacked()
- Description: Re-enables leader loss on attack. Restores the "attacked" event listener.
- Parameters: None
- Returns: None
- Error states: None
LongUpdate(dt)
- Description: Updates loyalty timers during long update cycles. Adjusts remaining time based on
dtand reschedules expiry tasks. - Parameters:
dt-- number delta time since last update - Returns: None
- Error states: None
OnRemoveFromEntity()
- Description: Cleanup called when component is removed from entity. Cancels all tasks and removes all event listeners.
- Parameters: None
- Returns: None
- Error states: None
OnRemoveEntity()
- Description: Cleanup called when entity is removed. Clears inventory item source linkage.
- Parameters: None
- Returns: None
- Error states: None
onattacked(inst, data) (local)
- Description: Event listener for "attacked". Removes leader if attacker is the current leader (unless
keepleaderonattackedis set). - Parameters:
inst-- entity instancedata-- table withattackerfield
- Returns: None
- Error states: None
onleader(self, leader) (local)
- Description: Property watcher callback fired when
self.leaderis assigned. Syncs state to replica component. - Parameters:
self-- component instanceleader-- new leader entity or nil
- Returns: None
- Error states: None
onitemowner(self, owner) (local)
- Description: Property watcher callback fired when
self.itemowneris assigned. Syncs state to replica component. - Parameters:
self-- component instanceowner-- new item owner entity or nil
- Returns: None
- Error states: None
OnPlayerJoined(self, player) (local)
- Description: Event listener for "ms_playerjoined". Reconnects cached player leader if within refollow distance and loyalty time remains.
- Parameters:
self-- component instanceplayer-- player entity that joined
- Returns: None
- Error states: None
OnNewPlayerSpawned(self, player) (local)
- Description: Event listener for "ms_newplayerspawned". Clears cached player leader if spawning player matches cached userid.
- Parameters:
self-- component instanceplayer-- player entity that spawned
- Returns: None
- Error states: None
clear_cached_player_leader(inst, self) (local)
- Description: Task callback to clear cached player leader on expiry.
- Parameters:
inst-- entity instanceself-- component instance
- Returns: None
- Error states: None
stopfollow(inst, self) (local)
- Description: Task callback to stop following when loyalty timer expires. Calls
StopFollowing(). - Parameters:
inst-- entity instanceself-- component instance
- Returns: None
- Error states: None
TryPorting(inst, self) (local)
- Description: Task callback for leashing teleport. Finds valid position near leader and teleports follower. Retries after 3 seconds if teleport fails.
- Parameters:
inst-- entity instanceself-- component instance
- Returns: None
- Error states: None
OnEntitySleep(inst) (local)
- Description: Event listener for "entitysleep". Cancels port task and schedules retry after 0 seconds.
- Parameters:
inst-- entity instance - Returns: None
- Error states: None
Events & listeners
Listens to:
attacked-- triggersonattacked; removes leader if attacker is the leaderentitywake-- triggers leashing restart when leader wakes (registered on leader entity)entitysleep-- triggersOnEntitySleep; schedules teleport retryonremove-- triggersOnLeaderRemoved; clears leader when leader entity is removed (registered on leader entity)ms_playerjoined-- triggersOnPlayerJoined; reconnects cached player leaderms_newplayerspawned-- triggersOnNewPlayerSpawned; clears cached player leader on spawn
Pushes:
startleashing-- fired when leashing is enabled. Data:nonestopleashing-- fired when leashing is disabled. Data:noneleaderchanged-- fired when leader changes. Data:{ new = entity, old = entity }gainloyalty-- fired when loyalty time is added. Data:{ leader = entity }loseloyalty-- fired when loyalty is lost. Data:{ leader = entity }