Skip to main content

Agent

The running AI: what every Enter, Update, Exit, When and Input function receives. Made by Builder:Build or VluxyAI.NewAgent, started with Agent:Start, and taken apart with Agent:Destroy. See Types.Agent for the fields.

Functions​

new​

Agent.new(definition: AgentDefinition) → Agent

Builds an agent from a definition. Blackboard and Data initial values are deep-copied, so one definition can make many agents. The agent is not running until Agent:Start.

Errors

TypeDescription
stringThe definition failed [Validate.Definition].

StrictBlackboard​

Agent.StrictBlackboard(
blackboard: Blackboard,--

The real table; initial keys count as known.

name: string--

For the warning.

) → Blackboard--

A view that warns once per key that reads as a misspelling of a known one.

What StrictBlackboard on the definition installs. Writes go through and make the key known; a read of an unknown key whose spelling is within two edits (or a case change) of a known key warns, naming both. Any other unknown read is an ordinary nil, since memory keys are nil most of the time by design.

GetState​

Agent.GetState(self: Agent) → string?--

nil before Start and after Destroy.

SetState​

Agent.SetState(
self: Agent,
name: string
) → ()

Forces a transition, running Exit and Enter even when name is already current. An unknown name warns and does nothing. Does nothing before Start.

StartTimer​

Agent.StartTimer(
self: Agent,
name: string,--

Any name; "Attack", "Look".

seconds: number
) → ()

Starts (or restarts) a named timer that Agent:TimerDone reports on. Timers are the usual way a state waits: start one in Enter, transition when it is done.

TimerDone​

Agent.TimerDone(
self: Agent,
name: string
) → boolean--

true when the timer has run out, or was never started.

TimerLeft​

Agent.TimerLeft(
self: Agent,
name: string
) → number--

Seconds left, 0 when done or never started.

TimeInState​

Agent.TimeInState(self: Agent) → number--

Seconds since the current state was entered, not counting time paused. 0 before Start.

Pause​

Agent.Pause(self: Agent) → ()

Freezes the agent: ticks stop, so senses, navigator and brain stand still; the mover halts; timers and TimeInState hold. For a cutscene, a jumpscare, or a director backing an enemy off. The navigator keeps its target and re-plans on the first tick after Agent:Resume. Does nothing when not running or already paused.

Resume​

Agent.Resume(self: Agent) → ()

Undoes Agent:Pause. Every running timer and TimeInState are pushed forward by the time spent paused, so a timer with two seconds left still has two seconds left.

IsPaused​

Agent.IsPaused(self: Agent) → boolean

LookAt​

Agent.LookAt(
self: Agent,
position: Vector3?--

Where to face; nil to stop facing anything.

) → ()

Turns the body toward position while it stands still, so an enemy can stare at a player without walking. Calls the mover's optional Face; a mover without one ignores this.

Teleport​

Agent.Teleport(
self: Agent,
position: Vector3--

Where the body goes: the root or pivot position, not a floor position.

) → ()

Puts the agent somewhere else at once and forgets the current target, so the next MoveTo plans from the new place. Uses the mover's optional Teleport, else pivots the entity. For a stalker that vanishes and reappears out of sight; pair it with Perception.SeenByAnyone.

IsNew​

Agent.IsNew(
self: Agent,
key: string--

A blackboard key, usually a memory such as HeardAt or HeardSoundAt.

) → boolean--

true while Blackboard[key] is non-nil and differs from the value last acknowledged.

"Is there something here I have not dealt with yet?" A transition that investigates every new noise reads agent:IsNew("HeardAt") and calls Agent:Acknowledge when it acts, so the same noise is not investigated twice. When.New does both in one predicate.

Acknowledge​

Agent.Acknowledge(
self: Agent,
key: string
) → ()

Records the current Blackboard[key] as dealt with. Agent:IsNew is false for it until the value changes.

MoveTo​

Agent.MoveTo(
self: Agent,
target: Vector3
) → ()

Shorthand for agent.Navigator:MoveTo(target).

Errors

TypeDescription
stringThe agent has no navigator.

Stop​

Agent.Stop(self: Agent) → ()

Shorthand for agent.Navigator:Stop(). Does nothing without a navigator.

GetPosition​

Agent.GetPosition(self: Agent) → Vector3--

The mover's position, or the entity's pivot without one.

GetPivot​

Agent.GetPivot(self: Agent) → CFrame--

Where the body is and which way it faces.

The entity's pivot; on a headless agent, the mover's GetPivot, or its position facing -Z when the mover has no GetPivot. Senses, the Broadcaster and doors read this rather than agent.Entity, so they work with or without a Model.

Errors

TypeDescription
stringThe agent has neither an Entity nor a mover.

HasArrived​

Agent.HasArrived(self: Agent) → boolean--

true while the navigator reports Arrived.

GetPathStatus​

Agent.GetPathStatus(self: Agent) → PathStatus--

The navigator's status, or Idle without a navigator.

SetSpeed​

Agent.SetSpeed(
self: Agent,
speed: number,--

Studs per second, before the speed scale.

seconds: number?--

Ramp to it over this long instead of at once, so a lunge builds and a stop settles.

) → ()

The agent's base speed: what a state asks for. The mover gets speed times the speed scale (Agent:SetSpeedScale), so a crowd ease or a slow-motion effect layered on top survives a state changing its own speed. With seconds the base speed moves there over the agent's ticks; a new SetSpeed replaces the ramp. Does nothing without a mover.

SetSpeedScale​

Agent.SetSpeedScale(
self: Agent,
scale: number--

A multiplier on the base speed; 1 is none, 0.5 half speed.

) → ()

Layered on top of whatever Agent:SetSpeed asked for, and kept across state changes. The Neighbours sense eases through this; a director or a stun can too.

GetSpeedScale​

Agent.GetSpeedScale(self: Agent) → number--

The current speed scale, 1 unless something set it.

GetSpeed​

Agent.GetSpeed(self: Agent) → number--

The base speed the last SetSpeed asked for, before the scale.

Step​

Agent.Step(
self: Agent,
deltaTime: number
) → ()

One tick: every sense, then the navigator, then the brain. Does nothing unless running. The Heartbeat loop calls this; a test or a custom scheduler calls it directly.

Start​

Agent.Start(
self: Agent,
manual: boolean?--

Skip the Heartbeat loop; you call Agent:Step yourself.

) → Agent

Enters the brain's initial state and starts ticking. Calling it again does nothing.

Errors

TypeDescription
stringThe agent was destroyed.

IsRunning​

Agent.IsRunning(self: Agent) → boolean

IsDestroyed​

Agent.IsDestroyed(self: Agent) → boolean--

true once Destroy has run.

For code that yields inside a state and needs to know whether the agent is still there when it wakes up.

Emit​

Agent.Emit(
self: Agent,
name: string,--

"Scream", "Kill", "DoorOpened": whatever your client understands.

payload: any?--

Anything a remote can carry.

) → ()

Announces something for clients. Fires Events; a Broadcaster relays it, a Replica dispatches it to On(name, ...) handlers. Does nothing after Destroy.

Destroy​

Agent.Destroy(self: Agent) → ()

Exits the current state, stops moving, and destroys the navigator, every sense, the mover and the pathfinder that have a Destroy, then fires Destroyed. Safe to call twice. The entity model is left alone; it is yours.

Show raw api
{
    "functions": [
        {
            "name": "new",
            "desc": "Builds an agent from a definition. Blackboard and Data initial values are deep-copied, so one\ndefinition can make many agents. The agent is not running until [Agent:Start].",
            "params": [
                {
                    "name": "definition",
                    "desc": "",
                    "lua_type": "AgentDefinition"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "string",
                    "desc": "The definition failed [Validate.Definition]."
                }
            ],
            "source": {
                "line": 84,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "StrictBlackboard",
            "desc": "What `StrictBlackboard` on the definition installs. Writes go through and make the key\nknown; a read of an unknown key whose spelling is within two edits (or a case change) of a\nknown key warns, naming both. Any other unknown read is an ordinary `nil`, since memory keys\nare `nil` most of the time by design.",
            "params": [
                {
                    "name": "blackboard",
                    "desc": "The real table; initial keys count as known.",
                    "lua_type": "Blackboard"
                },
                {
                    "name": "name",
                    "desc": "For the warning.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "A view that warns once per key that reads as a misspelling of a known one.",
                    "lua_type": "Blackboard"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 166,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "GetState",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "`nil` before `Start` and after `Destroy`.",
                    "lua_type": "string?"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 208,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "SetState",
            "desc": "Forces a transition, running `Exit` and `Enter` even when `name` is already current. An unknown\nname warns and does nothing. Does nothing before `Start`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 219,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "StartTimer",
            "desc": "Starts (or restarts) a named timer that [Agent:TimerDone] reports on. Timers are the usual\nway a state waits: start one in `Enter`, transition when it is done.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "name",
                    "desc": "Any name; `\"Attack\"`, `\"Look\"`.",
                    "lua_type": "string"
                },
                {
                    "name": "seconds",
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 248,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "TimerDone",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "`true` when the timer has run out, or was never started.",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 257,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "TimerLeft",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "Seconds left, `0` when done or never started.",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 267,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "TimeInState",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "Seconds since the current state was entered, not counting time paused. `0` before `Start`.",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 280,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Pause",
            "desc": "Freezes the agent: ticks stop, so senses, navigator and brain stand still; the mover halts;\ntimers and `TimeInState` hold. For a cutscene, a jumpscare, or a director backing an enemy\noff. The navigator keeps its target and re-plans on the first tick after [Agent:Resume]. Does\nnothing when not running or already paused.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 296,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Resume",
            "desc": "Undoes [Agent:Pause]. Every running timer and `TimeInState` are pushed forward by the time\nspent paused, so a timer with two seconds left still has two seconds left.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 318,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "IsPaused",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 338,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "LookAt",
            "desc": "Turns the body toward `position` while it stands still, so an enemy can stare at a player\nwithout walking. Calls the mover's optional `Face`; a mover without one ignores this.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "position",
                    "desc": "Where to face; `nil` to stop facing anything.",
                    "lua_type": "Vector3?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 349,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Teleport",
            "desc": "Puts the agent somewhere else at once and forgets the current target, so the next `MoveTo`\nplans from the new place. Uses the mover's optional `Teleport`, else pivots the entity. For a\nstalker that vanishes and reappears out of sight; pair it with [Perception.SeenByAnyone].",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "position",
                    "desc": "Where the body goes: the root or pivot position, not a floor position.",
                    "lua_type": "Vector3"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 365,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "IsNew",
            "desc": "\"Is there something here I have not dealt with yet?\" A transition that investigates every\nnew noise reads `agent:IsNew(\"HeardAt\")` and calls [Agent:Acknowledge] when it acts, so the\nsame noise is not investigated twice. [When.New] does both in one predicate.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "key",
                    "desc": "A blackboard key, usually a memory such as `HeardAt` or `HeardSoundAt`.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "`true` while `Blackboard[key]` is non-nil and differs from the value last acknowledged.",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 394,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Acknowledge",
            "desc": "Records the current `Blackboard[key]` as dealt with. [Agent:IsNew] is `false` for it until\nthe value changes.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 406,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "MoveTo",
            "desc": "Shorthand for `agent.Navigator:MoveTo(target)`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "target",
                    "desc": "",
                    "lua_type": "Vector3"
                }
            ],
            "returns": [],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "string",
                    "desc": "The agent has no navigator."
                }
            ],
            "source": {
                "line": 417,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Stop",
            "desc": "Shorthand for `agent.Navigator:Stop()`. Does nothing without a navigator.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 436,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "GetPosition",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "The mover's position, or the entity's pivot without one.",
                    "lua_type": "Vector3"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 446,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "GetPivot",
            "desc": "The entity's pivot; on a headless agent, the mover's `GetPivot`, or its position facing -Z\nwhen the mover has no `GetPivot`. Senses, the [Broadcaster] and doors read this rather than\n`agent.Entity`, so they work with or without a Model.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "Where the body is and which way it faces.",
                    "lua_type": "CFrame"
                }
            ],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "string",
                    "desc": "The agent has neither an Entity nor a mover."
                }
            ],
            "source": {
                "line": 463,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "HasArrived",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "`true` while the navigator reports `Arrived`.",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 484,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "GetPathStatus",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "The navigator's status, or `Idle` without a navigator.",
                    "lua_type": "PathStatus"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 492,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "SetSpeed",
            "desc": "The agent's base speed: what a state asks for. The mover gets `speed` times the speed scale\n([Agent:SetSpeedScale]), so a crowd ease or a slow-motion effect layered on top survives a\nstate changing its own speed. With `seconds` the base speed moves there over the agent's\nticks; a new `SetSpeed` replaces the ramp. Does nothing without a mover.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "speed",
                    "desc": "Studs per second, before the speed scale.",
                    "lua_type": "number"
                },
                {
                    "name": "seconds",
                    "desc": "Ramp to it over this long instead of at once, so a lunge builds and a stop settles.",
                    "lua_type": "number?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 510,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "SetSpeedScale",
            "desc": "Layered on top of whatever [Agent:SetSpeed] asked for, and kept across state changes. The\n[Neighbours] sense eases through this; a director or a stun can too.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "scale",
                    "desc": "A multiplier on the base speed; `1` is none, `0.5` half speed.",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 554,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "GetSpeedScale",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "The current speed scale, `1` unless something set it.",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 568,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "GetSpeed",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "The base speed the last `SetSpeed` asked for, before the scale.",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 576,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Step",
            "desc": "One tick: every sense, then the navigator, then the brain. Does nothing unless running. The\nHeartbeat loop calls this; a test or a custom scheduler calls it directly.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "deltaTime",
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 587,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Start",
            "desc": "Enters the brain's initial state and starts ticking. Calling it again does nothing.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "manual",
                    "desc": "Skip the Heartbeat loop; you call [Agent:Step] yourself.",
                    "lua_type": "boolean?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "string",
                    "desc": "The agent was destroyed."
                }
            ],
            "source": {
                "line": 656,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "IsRunning",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 682,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "IsDestroyed",
            "desc": "For code that yields inside a state and needs to know whether the agent is still there when\nit wakes up.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [
                {
                    "desc": "`true` once `Destroy` has run.",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 693,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Emit",
            "desc": "Announces something for clients. Fires `Events`; a [Broadcaster] relays it, a [Replica]\ndispatches it to `On(name, ...)` handlers. Does nothing after `Destroy`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "name",
                    "desc": "`\"Scream\"`, `\"Kill\"`, `\"DoorOpened\"`: whatever your client understands.",
                    "lua_type": "string"
                },
                {
                    "name": "payload",
                    "desc": "Anything a remote can carry.",
                    "lua_type": "any?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 705,
                "path": "lib/Agent.luau"
            }
        },
        {
            "name": "Destroy",
            "desc": "Exits the current state, stops moving, and destroys the navigator, every sense, the mover and\nthe pathfinder that have a `Destroy`, then fires `Destroyed`. Safe to call twice. The entity\nmodel is left alone; it is yours.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Agent"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 721,
                "path": "lib/Agent.luau"
            }
        }
    ],
    "properties": [],
    "types": [],
    "name": "Agent",
    "desc": "The running AI: what every `Enter`, `Update`, `Exit`, `When` and `Input` function receives.\nMade by [Builder:Build] or `VluxyAI.NewAgent`, started with [Agent:Start], and taken apart with\n[Agent:Destroy]. See [Types.Agent] for the fields.",
    "source": {
        "line": 74,
        "path": "lib/Agent.luau"
    }
}