Skip to main content

Neighbours

A Types.Sense for enemies that share a map: who else from the group is near, which way is away from them, and, when asked, an eased speed and a sideways nudge so they do not pile up. One instance is one group; make it once and add it to every enemy that should know about the others. Exposed as VluxyAI.Senses.Neighbours.

local crowd = VluxyAI.Senses.Neighbours.new({
	Range = 10,
	Slow = { Distance = 5, Min = 0.5 },  -- half speed when shoulder to shoulder
	Avoid = { Radius = 4 },              -- step aside within four studs
})
-- every enemy in the group
:AddSense(crowd)

Enemies that should crowd (a swarm) take the sense without Slow and Avoid, or with Distance = 0 and Radius = 0, or leave it out. One enemy in a shared group opts out for itself with agent.Data.Neighbours = { Slow = false } or { Avoid = false } (the Key option renames it). An enemy that must ignore one kind gives Filter; Configure turns either behaviour on or off for the whole group later.

Types​

NeighboursSlow​

interface NeighboursSlow {
Distance: number--

Studs from the nearest neighbour at which the ease begins. Further away the speed is untouched. 0 turns the ease off.

Min: number?--

The speed scale when the neighbour is on top of the agent. Default 0.5.

Curve: Curve?--

Shape of the ease over [0, 1] (distance over Distance). Default linear.

}

NeighboursAvoid​

interface NeighboursAvoid {
Radius: number--

Studs within which a neighbour pushes the agent sideways. 0 turns the nudge off.

Strength: number?--

How hard: the nudge is up to Strength * Radius studs. Default 1.

Deadband: number?--

Studs the nudge must change by before the mover is told again, against jitter when neighbours keep moving. Default 0.

}

NeighboursOptions​

interface NeighboursOptions {
Range: number?--

Studs within which another agent counts as nearby. Default 10.

Slow: NeighboursSlow?--

Ease the agent's speed as its nearest neighbour gets close. Off by default, and off with Distance = 0.

Avoid: NeighboursAvoid?--

Nudge the mover away from neighbours while walking. Off by default, off with Radius = 0; needs a mover with SetNudge (both built-ins have it).

Others: ((agent: Agent) → {Agent})?--

Who counts, instead of the agents sharing this instance.

Filter: ((
agent: Agent,
other: Agent
) → boolean)?--

Return false to ignore other for agent: same kind only, say.

Prefix: string?--

Prepended to every key this sense writes. Default "".

Key: string?--

The agent.Data key an enemy may set to opt out for itself: agent.Data.Neighbours = { Slow = false, Avoid = false }. Default "Neighbours".

}

Functions​

new​

Neighbours.new(options: NeighboursOptions?) → Neighbours

Errors

TypeDescription
"unknown option"
string`Slow.Distance` or `Avoid.Radius` missing or below `0`.

Tick​

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

Joins the agent to the group on its first tick, measures the others, writes the keys listed above, and applies Slow and Avoid when they are set.

Configure​

Neighbours.Configure() → ()

Changes options after construction. The same rules as new apply.

Errors

TypeDescription
"unknown option"

Destroy​

Neighbours.Destroy(
self: Neighbours,
agent: Agent?
) → ()

Removes the agent from the group and undoes its ease and nudge; with no agent, empties the group.

Show raw api
{
    "functions": [
        {
            "name": "new",
            "desc": "",
            "params": [
                {
                    "name": "options",
                    "desc": "",
                    "lua_type": "NeighboursOptions?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Neighbours"
                }
            ],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "\"unknown option\"",
                    "desc": ""
                },
                {
                    "lua_type": "string",
                    "desc": "`Slow.Distance` or `Avoid.Radius` missing or below `0`."
                }
            ],
            "source": {
                "line": 144,
                "path": "lib/Senses/Neighbours.luau"
            }
        },
        {
            "name": "Tick",
            "desc": "Joins the agent to the group on its first tick, measures the others, writes the keys listed\nabove, and applies `Slow` and `Avoid` when they are set.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Neighbours"
                },
                {
                    "name": "agent",
                    "desc": "",
                    "lua_type": "Agent"
                },
                {
                    "name": "deltaTime",
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 221,
                "path": "lib/Senses/Neighbours.luau"
            }
        },
        {
            "name": "Configure",
            "desc": "Changes options after construction. The same rules as `new` apply.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Neighbours"
                },
                {
                    "name": "patch",
                    "desc": "",
                    "lua_type": "NeighboursOptions"
                }
            ],
            "returns": [],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "\"unknown option\"",
                    "desc": ""
                }
            ],
            "source": {
                "line": 333,
                "path": "lib/Senses/Neighbours.luau"
            }
        },
        {
            "name": "Destroy",
            "desc": "Removes the agent from the group and undoes its ease and nudge; with no agent, empties the\ngroup.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Neighbours"
                },
                {
                    "name": "agent",
                    "desc": "",
                    "lua_type": "Agent?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 346,
                "path": "lib/Senses/Neighbours.luau"
            }
        }
    ],
    "properties": [],
    "types": [
        {
            "name": "NeighboursSlow",
            "desc": "",
            "fields": [
                {
                    "name": "Distance",
                    "lua_type": "number",
                    "desc": "Studs from the nearest neighbour at which the ease begins. Further away the speed is untouched. `0` turns the ease off."
                },
                {
                    "name": "Min",
                    "lua_type": "number?",
                    "desc": "The speed scale when the neighbour is on top of the agent. Default `0.5`."
                },
                {
                    "name": "Curve",
                    "lua_type": "Curve?",
                    "desc": "Shape of the ease over `[0, 1]` (distance over `Distance`). Default linear."
                }
            ],
            "source": {
                "line": 49,
                "path": "lib/Senses/Neighbours.luau"
            }
        },
        {
            "name": "NeighboursAvoid",
            "desc": "",
            "fields": [
                {
                    "name": "Radius",
                    "lua_type": "number",
                    "desc": "Studs within which a neighbour pushes the agent sideways. `0` turns the nudge off."
                },
                {
                    "name": "Strength",
                    "lua_type": "number?",
                    "desc": "How hard: the nudge is up to `Strength * Radius` studs. Default `1`."
                },
                {
                    "name": "Deadband",
                    "lua_type": "number?",
                    "desc": "Studs the nudge must change by before the mover is told again, against jitter when neighbours keep moving. Default `0`."
                }
            ],
            "source": {
                "line": 63,
                "path": "lib/Senses/Neighbours.luau"
            }
        },
        {
            "name": "NeighboursOptions",
            "desc": "",
            "fields": [
                {
                    "name": "Range",
                    "lua_type": "number?",
                    "desc": "Studs within which another agent counts as nearby. Default `10`."
                },
                {
                    "name": "Slow",
                    "lua_type": "NeighboursSlow?",
                    "desc": "Ease the agent's speed as its nearest neighbour gets close. Off by default, and off with `Distance = 0`."
                },
                {
                    "name": "Avoid",
                    "lua_type": "NeighboursAvoid?",
                    "desc": "Nudge the mover away from neighbours while walking. Off by default, off with `Radius = 0`; needs a mover with `SetNudge` (both built-ins have it)."
                },
                {
                    "name": "Others",
                    "lua_type": "((agent: Agent) -> { Agent })?",
                    "desc": "Who counts, instead of the agents sharing this instance."
                },
                {
                    "name": "Filter",
                    "lua_type": "((agent: Agent, other: Agent) -> boolean)?",
                    "desc": "Return `false` to ignore `other` for `agent`: same kind only, say."
                },
                {
                    "name": "Prefix",
                    "lua_type": "string?",
                    "desc": "Prepended to every key this sense writes. Default `\"\"`."
                },
                {
                    "name": "Key",
                    "lua_type": "string?",
                    "desc": "The `agent.Data` key an enemy may set to opt out for itself: `agent.Data.Neighbours = { Slow = false, Avoid = false }`. Default `\"Neighbours\"`."
                }
            ],
            "source": {
                "line": 81,
                "path": "lib/Senses/Neighbours.luau"
            }
        }
    ],
    "name": "Neighbours",
    "desc": "A [Types.Sense] for enemies that share a map: who else from the group is near, which way is\naway from them, and, when asked, an eased speed and a sideways nudge so they do not pile up.\nOne instance is one group; make it once and add it to every enemy that should know about\nthe others. Exposed as `VluxyAI.Senses.Neighbours`.\n\n```lua\nlocal crowd = VluxyAI.Senses.Neighbours.new({\n\tRange = 10,\n\tSlow = { Distance = 5, Min = 0.5 },  -- half speed when shoulder to shoulder\n\tAvoid = { Radius = 4 },              -- step aside within four studs\n})\n-- every enemy in the group\n:AddSense(crowd)\n```\n\nEnemies that should crowd (a swarm) take the sense without `Slow` and `Avoid`, or with\n`Distance = 0` and `Radius = 0`, or leave it out. One enemy in a shared group opts out for\nitself with `agent.Data.Neighbours = { Slow = false }` or `{ Avoid = false }` (the `Key`\noption renames it). An enemy that must ignore one kind gives `Filter`; `Configure` turns\neither behaviour on or off for the whole group later.",
    "source": {
        "line": 136,
        "path": "lib/Senses/Neighbours.luau"
    }
}