Skip to main content

Director

The game's hand on the group: a tension meter, a difficulty number and a shared blackboard. Exposed as VluxyAI.Director. Make one per game (or per group), raise it from the events that matter, and give every enemy director:Sense() so its brain can read the numbers.

local director = VluxyAI.Director.new({ Fall = 0.05 })
director.Blackboard.Alarm = nil

-- each enemy
:AddSense(director:Sense())

-- the game
agent.Events:Connect(function(name)
	if name == "Kill" then director:Raise(1) end
end)

-- a state
agent:SetSpeed(director:Scale(BASE_SPEED, 0.5)) -- up to 50% faster at full tension
if agent.Blackboard.DirectorTension > 0.8 then return "Retreat" end

Tension is a number in [0, 1] that drains by Fall per second; difficulty is any number the game chooses. Blackboard is a plain table shared by reference: an enemy writes the alarm position into it, the others read it on their next tick.

Functions​

new​

Director.new(options: DirectorOptions?) → Director

Types

​

interface DirectorOptions {
Fall: number?--

Tension drained per second. Default 0.05, so a full meter empties in twenty seconds of quiet.

Difficulty: number?--

The starting difficulty. Default 1.

Tension: number?--

The starting tension. Default 0.

}

Errors

TypeDescription
"unknown option"

GetTension​

Director.GetTension(self: Director) → number--

Tension in [0, 1], drained for the time since it was last touched.

Raise​

Director.Raise(
self: Director,
amount: number--

Added to the tension, clamped to 1. A kill might be 1, a near miss 0.3.

) → ()

Lower​

Director.Lower(
self: Director,
amount: number--

Taken off the tension, clamped to 0.

) → ()

SetTension​

Director.SetTension(
self: Director,
value: number--

The new tension, clamped to [0, 1].

) → ()

GetDifficulty​

Director.GetDifficulty(self: Director) → number

SetDifficulty​

Director.SetDifficulty(
self: Director,
value: number--

Any number the game means by difficulty; 1 is normal.

) → ()

Scale​

Director.Scale(
self: Director,
base: number,--

A speed, a memory, a cooldown.

byTension: number?,--

How much a full meter changes it: 0.5 means base * 1.5 at full tension. Default 0.

byDifficulty: number?--

How much each unit of difficulty above 1 changes it. Default 0.

) → number--

base * (1 + byTension * tension) * (1 + byDifficulty * (difficulty - 1)).

The one line a state needs to scale itself by the game's mood.

Sense​

Director.Sense() → Sense--

Writes DirectorTension, DirectorDifficulty and DirectorShared (the shared blackboard, by reference) each tick.

Types

​

interface DirectorSenseOptions {
Prefix: string?--

Prepended to the three keys. Default "Director", so the keys are DirectorTension, DirectorDifficulty and DirectorShared.

}

One instance serves every agent in the group. Add it before the senses and states that read from it.

Destroy​

Director.Destroy(self: Director) → ()

Clears the shared blackboard. The senses handed out keep working; they read live values.

Show raw api
{
    "functions": [
        {
            "name": "new",
            "desc": "",
            "params": [
                {
                    "name": "options",
                    "desc": "",
                    "lua_type": "DirectorOptions?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Director"
                }
            ],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "\"unknown option\"",
                    "desc": ""
                }
            ],
            "source": {
                "line": 108,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "GetTension",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                }
            ],
            "returns": [
                {
                    "desc": "Tension in `[0, 1]`, drained for the time since it was last touched.",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 139,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "Raise",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                },
                {
                    "name": "amount",
                    "desc": "Added to the tension, clamped to `1`. A kill might be `1`, a near miss `0.3`.",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 148,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "Lower",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                },
                {
                    "name": "amount",
                    "desc": "Taken off the tension, clamped to `0`.",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 157,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "SetTension",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                },
                {
                    "name": "value",
                    "desc": "The new tension, clamped to `[0, 1]`.",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 165,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "GetDifficulty",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 174,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "SetDifficulty",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                },
                {
                    "name": "value",
                    "desc": "Any number the game means by difficulty; `1` is normal.",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 182,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "Scale",
            "desc": "The one line a state needs to scale itself by the game's mood.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                },
                {
                    "name": "base",
                    "desc": "A speed, a memory, a cooldown.",
                    "lua_type": "number"
                },
                {
                    "name": "byTension",
                    "desc": "How much a full meter changes it: `0.5` means `base * 1.5` at full tension. Default `0`.",
                    "lua_type": "number?"
                },
                {
                    "name": "byDifficulty",
                    "desc": "How much each unit of difficulty above `1` changes it. Default `0`.",
                    "lua_type": "number?"
                }
            ],
            "returns": [
                {
                    "desc": "`base * (1 + byTension * tension) * (1 + byDifficulty * (difficulty - 1))`.",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 195,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "Sense",
            "desc": "One instance serves every agent in the group. Add it before the senses and states that read\nfrom it.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                },
                {
                    "name": "options",
                    "desc": "",
                    "lua_type": "DirectorSenseOptions?"
                }
            ],
            "returns": [
                {
                    "desc": "Writes `DirectorTension`, `DirectorDifficulty` and `DirectorShared` (the shared blackboard, by reference) each tick.",
                    "lua_type": "Sense"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 210,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "Destroy",
            "desc": "Clears the shared blackboard. The senses handed out keep working; they read live values.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Director"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 230,
                "path": "lib/Group/Director.luau"
            }
        }
    ],
    "properties": [],
    "types": [
        {
            "name": "DirectorOptions",
            "desc": "",
            "fields": [
                {
                    "name": "Fall",
                    "lua_type": "number?",
                    "desc": "Tension drained per second. Default `0.05`, so a full meter empties in twenty seconds of quiet."
                },
                {
                    "name": "Difficulty",
                    "lua_type": "number?",
                    "desc": "The starting difficulty. Default `1`."
                },
                {
                    "name": "Tension",
                    "lua_type": "number?",
                    "desc": "The starting tension. Default `0`."
                }
            ],
            "source": {
                "line": 33,
                "path": "lib/Group/Director.luau"
            }
        },
        {
            "name": "DirectorSenseOptions",
            "desc": "",
            "fields": [
                {
                    "name": "Prefix",
                    "lua_type": "string?",
                    "desc": "Prepended to the three keys. Default `\"Director\"`, so the keys are `DirectorTension`, `DirectorDifficulty` and `DirectorShared`."
                }
            ],
            "source": {
                "line": 55,
                "path": "lib/Group/Director.luau"
            }
        }
    ],
    "name": "Director",
    "desc": "The game's hand on the group: a tension meter, a difficulty number and a shared blackboard.\nExposed as `VluxyAI.Director`. Make one per game (or per group), raise it from the events\nthat matter, and give every enemy `director:Sense()` so its brain can read the numbers.\n\n```lua\nlocal director = VluxyAI.Director.new({ Fall = 0.05 })\ndirector.Blackboard.Alarm = nil\n\n-- each enemy\n:AddSense(director:Sense())\n\n-- the game\nagent.Events:Connect(function(name)\n\tif name == \"Kill\" then director:Raise(1) end\nend)\n\n-- a state\nagent:SetSpeed(director:Scale(BASE_SPEED, 0.5)) -- up to 50% faster at full tension\nif agent.Blackboard.DirectorTension > 0.8 then return \"Retreat\" end\n```\n\nTension is a number in `[0, 1]` that drains by `Fall` per second; difficulty is any number\nthe game chooses. `Blackboard` is a plain table shared by reference: an enemy writes the\nalarm position into it, the others read it on their next tick.",
    "source": {
        "line": 101,
        "path": "lib/Group/Director.luau"
    }
}