Skip to main content

Sight

A Types.Sense that writes what the agent can see. A target is seen when it is within Range, inside the FieldOfView cone around the entity's look direction, and a ray from the eye to it hits nothing but the target's own model.

Writes SeenTargets, SeenTarget, SeenDistance, SeenVisibility, SeenPosition and SeenAt. The last two are memory: they outlive the sighting by Memory seconds so a state can head to where the target was. Distances are math.huge when there is nothing to measure.

For a horror game: Visibility scales the range per target, so darkness and a lit flashlight are one function (Perception.LightAt is the ready-made one); SeeThrough lets the ray pass glass (Perception.Transparent); and a player hidden with VLUXYAI_HIDDEN is not a target at all.

A position remembered inside an enabled SafeAreas area is forgotten at once, and a prediction never carries into one, so no chase follows a player into a safe room.

NoticeRadius is the close-range sense every enemy wants: a player that close is seen whichever way the agent faces and however dark it is, so sneaking right behind an enemy does not work.

Types​

SightOptions​

interface SightOptions {
Range: number?--

Studs the agent can see. Default 40.

FieldOfView: number?--

The full angle of the view cone, in degrees. Default 120.

EyeOffset: Vector3?--

Added to the entity's pivot to get the eye. Default Vector3.zero.

Memory: number?--

Seconds SeenPosition and SeenAt outlive the last sighting. Default 3.

Targets: ((agent: Agent) → {BasePart})?--

What to look for. Default Perception.AliveRoots, every alive player's root.

Ignore: ((agent: Agent) → {Instance})?--

What the sight ray passes through. Default Perception.IgnoreList, the agent's entity.

Visibility: ((
agent: Agent,
target: BasePart
) → number)?--

How visible a target is, 0 to 1 (or more): the range is multiplied by it, so 0 is invisible and 0.5 is seen at half the distance. Pass function(_, root) return VluxyAI.Perception.LightAt(root.Position) end for darkness. Default: everything 1.

SeeThrough: ((part: BasePart) → boolean)?--

Parts the sight ray looks past, such as Perception.Transparent. Default: everything blocks.

PerTarget: boolean?--

Also write SeenMemory, the last position and time of every target seen within Memory seconds, so an enemy remembers where each of several players went. Default false.

Predict: number?--

Seconds of the target's last velocity to carry PredictedPosition forward after losing sight, capped. 0 turns prediction off. Default 2.

PredictMax: number?--

Studs the prediction may run past the last sighting at most. It also stops short of the first wall. Default 16.

NoticeRadius: number?--

Studs within which a target is noticed even outside the cone or in the dark, like someone brushing past. It still needs a clear line unless NoticeThroughWalls; a player hidden with VLUXYAI_HIDDEN stays hidden. 0 turns it off. Default 0.

NoticeThroughWalls: boolean?--

Let NoticeRadius work through walls too, for a creature that senses rather than sees. Default false.

Prefix: string?--

Prepended to every key this sense writes, so two instances can coexist. Default "".

}

Functions​

new​

Sight.new(options: SightOptions?) → Sight

Errors

TypeDescription
"unknown option"A key not in `SightOptions`.
"Range must be zero or more"

Tick​

Sight.Tick(
self: Sight,
agent: Agent,
deltaTime: number
) → ()

Looks, and writes the keys listed above to agent.Blackboard.

Forget​

Sight.Forget(
blackboard: Blackboard,--

The agent's blackboard.

prefix: string?--

The sense's Prefix. Default "".

) → ()

Forgets the last sighting at once: SeenPosition, SeenAt, PredictedPosition, SeenVelocity and SeenMemory. For a state or another sense that knows the chase is over (the target reached a safe room, got away through a door that locked) and wants nothing left to follow. The next sighting writes them again.

Predict​

Sight.Predict(
position: Vector3,--

Where the target was last seen.

velocity: Vector3,--

How it was moving, flat.

elapsed: number,--

Seconds since then.

options: SightOptions,--

Predict and PredictMax are read.

agent: Agent?--

For the wall ray's ignore list; without it no ray is cast.

) → Vector3--

Where the target probably is: carried along velocity for up to Predict seconds and PredictMax studs, stopped 2 studs short of the first wall in the way, and never inside a safe area.

A prediction that ran through walls would send a chase to a point the target never went near, and often one no path reaches, so the agent would walk at it again and again.

Destroy​

Sight.Destroy(self: Sight) → ()

Nothing to release; present so the sense satisfies Types.Sense and any cleanup helper.

Configure​

Sight.Configure(
self: Sight,
patch: SightOptions--

The options to change; the rest keep their values.

) → ()

Changes options after construction, for difficulty and pacing: a director widening the cone or shortening the memory mid-round. The same rules as new apply.

Errors

TypeDescription
"unknown option"
Show raw api
{
    "functions": [
        {
            "name": "new",
            "desc": "",
            "params": [
                {
                    "name": "options",
                    "desc": "",
                    "lua_type": "SightOptions?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Sight"
                }
            ],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "\"unknown option\"",
                    "desc": "A key not in `SightOptions`."
                },
                {
                    "lua_type": "\"Range must be zero or more\"",
                    "desc": ""
                }
            ],
            "source": {
                "line": 153,
                "path": "lib/Senses/Sight.luau"
            }
        },
        {
            "name": "Tick",
            "desc": "Looks, and writes the keys listed above to `agent.Blackboard`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Sight"
                },
                {
                    "name": "agent",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "deltaTime",
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 184,
                "path": "lib/Senses/Sight.luau"
            }
        },
        {
            "name": "Forget",
            "desc": "Forgets the last sighting at once: `SeenPosition`, `SeenAt`, `PredictedPosition`,\n`SeenVelocity` and `SeenMemory`. For a state or another sense that knows the chase is over (the\ntarget reached a safe room, got away through a door that locked) and wants nothing left to\nfollow. The next sighting writes them again.",
            "params": [
                {
                    "name": "blackboard",
                    "desc": "The agent's blackboard.",
                    "lua_type": "Blackboard"
                },
                {
                    "name": "prefix",
                    "desc": "The sense's `Prefix`. Default `\"\"`.",
                    "lua_type": "string?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 305,
                "path": "lib/Senses/Sight.luau"
            }
        },
        {
            "name": "Predict",
            "desc": "A prediction that ran through walls would send a chase to a point the target never went\nnear, and often one no path reaches, so the agent would walk at it again and again.",
            "params": [
                {
                    "name": "position",
                    "desc": "Where the target was last seen.",
                    "lua_type": "Vector3"
                },
                {
                    "name": "velocity",
                    "desc": "How it was moving, flat.",
                    "lua_type": "Vector3"
                },
                {
                    "name": "elapsed",
                    "desc": "Seconds since then.",
                    "lua_type": "number"
                },
                {
                    "name": "options",
                    "desc": "`Predict` and `PredictMax` are read.",
                    "lua_type": "SightOptions"
                },
                {
                    "name": "agent",
                    "desc": "For the wall ray's ignore list; without it no ray is cast.",
                    "lua_type": "Agent?"
                }
            ],
            "returns": [
                {
                    "desc": "Where the target probably is: carried along `velocity` for up to `Predict` seconds and `PredictMax` studs, stopped `2` studs short of the first wall in the way, and never inside a safe area.",
                    "lua_type": "Vector3"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 329,
                "path": "lib/Senses/Sight.luau"
            }
        },
        {
            "name": "Destroy",
            "desc": "Nothing to release; present so the sense satisfies [Types.Sense] and any cleanup helper.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Sight"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 372,
                "path": "lib/Senses/Sight.luau"
            }
        },
        {
            "name": "Configure",
            "desc": "Changes options after construction, for difficulty and pacing: a director widening the cone\nor shortening the memory mid-round. The same rules as `new` apply.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Sight"
                },
                {
                    "name": "patch",
                    "desc": "The options to change; the rest keep their values.",
                    "lua_type": "SightOptions"
                }
            ],
            "returns": [],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "\"unknown option\"",
                    "desc": ""
                }
            ],
            "source": {
                "line": 384,
                "path": "lib/Senses/Sight.luau"
            }
        }
    ],
    "properties": [],
    "types": [
        {
            "name": "SightOptions",
            "desc": "",
            "fields": [
                {
                    "name": "Range",
                    "lua_type": "number?",
                    "desc": "Studs the agent can see. Default `40`."
                },
                {
                    "name": "FieldOfView",
                    "lua_type": "number?",
                    "desc": "The full angle of the view cone, in degrees. Default `120`."
                },
                {
                    "name": "EyeOffset",
                    "lua_type": "Vector3?",
                    "desc": "Added to the entity's pivot to get the eye. Default `Vector3.zero`."
                },
                {
                    "name": "Memory",
                    "lua_type": "number?",
                    "desc": "Seconds `SeenPosition` and `SeenAt` outlive the last sighting. Default `3`."
                },
                {
                    "name": "Targets",
                    "lua_type": "((agent: Agent) -> { BasePart })?",
                    "desc": "What to look for. Default [Perception.AliveRoots], every alive player's root."
                },
                {
                    "name": "Ignore",
                    "lua_type": "((agent: Agent) -> { Instance })?",
                    "desc": "What the sight ray passes through. Default [Perception.IgnoreList], the agent's entity."
                },
                {
                    "name": "Visibility",
                    "lua_type": "((agent: Agent, target: BasePart) -> number)?",
                    "desc": "How visible a target is, `0` to `1` (or more): the range is multiplied by it, so `0` is invisible and `0.5` is seen at half the distance. Pass `function(_, root) return VluxyAI.Perception.LightAt(root.Position) end` for darkness. Default: everything `1`."
                },
                {
                    "name": "SeeThrough",
                    "lua_type": "((part: BasePart) -> boolean)?",
                    "desc": "Parts the sight ray looks past, such as [Perception.Transparent]. Default: everything blocks."
                },
                {
                    "name": "PerTarget",
                    "lua_type": "boolean?",
                    "desc": "Also write `SeenMemory`, the last position and time of every target seen within `Memory` seconds, so an enemy remembers where each of several players went. Default `false`."
                },
                {
                    "name": "Predict",
                    "lua_type": "number?",
                    "desc": "Seconds of the target's last velocity to carry `PredictedPosition` forward after losing sight, capped. `0` turns prediction off. Default `2`."
                },
                {
                    "name": "PredictMax",
                    "lua_type": "number?",
                    "desc": "Studs the prediction may run past the last sighting at most. It also stops short of the first wall. Default `16`."
                },
                {
                    "name": "NoticeRadius",
                    "lua_type": "number?",
                    "desc": "Studs within which a target is noticed even outside the cone or in the dark, like someone brushing past. It still needs a clear line unless `NoticeThroughWalls`; a player hidden with `VLUXYAI_HIDDEN` stays hidden. `0` turns it off. Default `0`."
                },
                {
                    "name": "NoticeThroughWalls",
                    "lua_type": "boolean?",
                    "desc": "Let `NoticeRadius` work through walls too, for a creature that senses rather than sees. Default `false`."
                },
                {
                    "name": "Prefix",
                    "lua_type": "string?",
                    "desc": "Prepended to every key this sense writes, so two instances can coexist. Default `\"\"`."
                }
            ],
            "source": {
                "line": 78,
                "path": "lib/Senses/Sight.luau"
            }
        }
    ],
    "name": "Sight",
    "desc": "A [Types.Sense] that writes what the agent can see. A target is seen when it is within `Range`,\ninside the `FieldOfView` cone around the entity's look direction, and a ray from the eye to it\nhits nothing but the target's own model.\n\nWrites `SeenTargets`, `SeenTarget`, `SeenDistance`, `SeenVisibility`, `SeenPosition` and\n`SeenAt`. The last two are memory: they outlive the sighting by `Memory` seconds so a state\ncan head to where the target was. Distances are `math.huge` when there is nothing to measure.\n\nFor a horror game: `Visibility` scales the range per target, so darkness and a lit flashlight\nare one function ([Perception.LightAt] is the ready-made one); `SeeThrough` lets the ray pass\nglass ([Perception.Transparent]); and a player hidden with `VLUXYAI_HIDDEN` is not a target at all.\n\nA position remembered inside an enabled [SafeAreas] area is forgotten at once, and a\nprediction never carries into one, so no chase follows a player into a safe room.\n\n`NoticeRadius` is the close-range sense every enemy wants: a player that close is seen\nwhichever way the agent faces and however dark it is, so sneaking right behind an enemy\ndoes not work.",
    "source": {
        "line": 145,
        "path": "lib/Senses/Sight.luau"
    }
}