Skip to main content

AccessPolicyService

Registers AccessPolicy objects and runs the enabled ones against each player.

Policies register disabled unless they asked not to. A policy that is off is still listed, still autocompletes, and still names what it reads -- it simply is not running. That is what makes a consequence as blunt as kicking safe to ship in the box: turning it on is a deliberate act you can see in a readout, and turning it off again is one command rather than a deploy.

A policy built with isEnabledByDefault = true runs from the moment it is registered, for the case where the consequence is the whole reason it exists. It says so in the readout, so nobody goes looking for the command that turned it on.

Shared, and registration happens in both realms, so a console on either side can name and autocomplete every policy. Where a policy's consequence actually runs is its AccessPolicyRealm -- kicking on the server, presentation on the client -- and this service simply skips the ones that are not for here.

Functions

SetReplicatedPolicyEnabled

AccessPolicyService.SetReplicatedPolicyEnabled(
payload{[string]boolean}
) → ()

Applies what the server says each policy's switch is set to. The entry point the client's replication arrives through, and the seam a test drives directly.

A policy the server never registered is left alone.

RegisterPolicy

AccessPolicyService.RegisterPolicy() → () → ()--

Removes the policy

Registers a policy. Disabled, unless the policy was built with isEnabledByDefault = true -- see AccessPolicy.IsEnabledByDefault for when that is the right call.

Registering does not take ownership. A policy has a lifetime of its own, so give it to a maid at the point you make it and the disposer to a maid too.

SetPolicyEnabled

AccessPolicyService.SetPolicyEnabled(
policyNamestring,
enabledboolean
) → ()

Turns a policy on or off for every player at once. Enabling applies it to everyone already here; disabling tears it back down.

IsPolicyEnabled

AccessPolicyService.IsPolicyEnabled(
policyNamestring
) → boolean

GetPolicy

AccessPolicyService.GetPolicy(
policyNamestring
) → AccessPolicy?

GetPolicyNames

AccessPolicyService.GetPolicyNames(selfAccessPolicyService) → {string}

ObserveIsPolicyEnabled

AccessPolicyService.ObserveIsPolicyEnabled(
policyNamestring
) → Observable<boolean>

Whether a policy is running, live. The registry changes at runtime -- a console command flips one, a game registers another -- so anything rendering policy state wants this rather than a snapshot it has to remember to refresh.

ObservePolicyNames

AccessPolicyService.ObservePolicyNames(selfAccessPolicyService) → Observable<{string}>

Every registered policy name, live.

GetPolicyNamesReadingFact

AccessPolicyService.GetPolicyNamesReadingFact(
factNamestring
) → {string}

Which policies read this fact.

The reverse of AccessPolicy.GetFactNames, and the question you actually have in a bug report: somebody's fact just flipped, so what acts on it? Declared inputs are what make this answerable at all -- a policy that read facts without declaring them would be invisible here.

GetPolicyNamesReadingFeature

AccessPolicyService.GetPolicyNamesReadingFeature() → {string}

Which policies read this feature.

IsPolicyActiveForPlayer

AccessPolicyService.IsPolicyActiveForPlayer(
playerPlayer,
policyNamestring
) → boolean

Whether a policy is actually running against this player right now.

Three things have to be true and each fails differently, which is why asking AccessPolicyService.IsPolicyEnabled alone misleads: the policy is enabled, this realm is the one it runs in, and the player is being tracked at all.

ObserveIsPolicyActiveForPlayer

AccessPolicyService.ObserveIsPolicyActiveForPlayer(
playerPlayer,
policyNamestring
) → Observable<boolean>

Whether a policy is active for this player, live.

The naming across this service is deliberate and worth knowing: enabled is the global switch, and active is enabled and the right realm and this player being tracked. Everything scoped to one player says ForPlayer, so which of the two a method means is readable at the call site rather than something you have to remember.

PromiseIsPolicyActiveForPlayer

AccessPolicyService.PromiseIsPolicyActiveForPlayer(
playerPlayer,
policyNamestring
) → Promise<boolean>

Settles once the policy is active for this player. Never resolves false -- a caller waiting on a policy wants to know when it starts, and "not yet" is not an outcome worth settling on.

AddPlayer

AccessPolicyService.AddPlayer() → () → ()--

Stops running policies for this player

Starts running the enabled policies for a player.

Called by AccessService as players join, and callable directly by a test holding a mock. Idempotent.

RemovePlayer

AccessPolicyService.RemovePlayer() → ()

GetDebugState

AccessPolicyService.GetDebugState(selfAccessPolicyService) → {[string]{
policyNamestring,
realmstring,
enabledboolean,
facts{string},
features{string}
}}

Every policy, whether it is running, and what it reads. A disabled policy is included -- knowing a consequence exists but is switched off is most of the answer to "why did nothing happen".

Show raw api
{
    "functions": [
        {
            "name": "SetReplicatedPolicyEnabled",
            "desc": "Applies what the server says each policy's switch is set to. The entry point the client's replication\narrives through, and the seam a test drives directly.\n\nA policy the server never registered is left alone.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "payload",
                    "desc": "",
                    "lua_type": "{ [string]: boolean }"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 189,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "RegisterPolicy",
            "desc": "Registers a policy. Disabled, unless the policy was built with `isEnabledByDefault = true` -- see\n[AccessPolicy.IsEnabledByDefault] for when that is the right call.\n\nRegistering does not take ownership. A policy has a lifetime of its own, so give it to a maid at the\npoint you make it and the disposer to a maid too.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "policy",
                    "desc": "",
                    "lua_type": "AccessPolicy"
                }
            ],
            "returns": [
                {
                    "desc": "Removes the policy",
                    "lua_type": "() -> ()"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 214,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "SetPolicyEnabled",
            "desc": "Turns a policy on or off for every player at once. Enabling applies it to everyone already here;\ndisabling tears it back down.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "policyName",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "enabled",
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 268,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "IsPolicyEnabled",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "policyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 291,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "GetPolicy",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "policyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "AccessPolicy?"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 301,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "GetPolicyNames",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "{ string }"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 310,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "ObserveIsPolicyEnabled",
            "desc": "Whether a policy is running, live. The registry changes at runtime -- a console command flips one,\na game registers another -- so anything rendering policy state wants this rather than a snapshot it\nhas to remember to refresh.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "policyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Observable<boolean>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 325,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "ObservePolicyNames",
            "desc": "Every registered policy name, live.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Observable<{ string }>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 344,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "GetPolicyNamesReadingFact",
            "desc": "Which policies read this fact.\n\nThe reverse of [AccessPolicy.GetFactNames], and the question you actually have in a bug report:\nsomebody's fact just flipped, so what acts on it? Declared inputs are what make this answerable at\nall -- a policy that read facts without declaring them would be invisible here.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "factName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "{ string }"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 358,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "GetPolicyNamesReadingFeature",
            "desc": "Which policies read this feature.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "feature",
                    "desc": "",
                    "lua_type": "AccessFeature"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "{ string }"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 378,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "IsPolicyActiveForPlayer",
            "desc": "Whether a policy is actually running against this player right now.\n\nThree things have to be true and each fails differently, which is why asking\n[AccessPolicyService.IsPolicyEnabled] alone misleads: the policy is enabled, this realm is the one it\nruns in, and the player is being tracked at all.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "player",
                    "desc": "",
                    "lua_type": "Player"
                },
                {
                    "name": "policyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 406,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "ObserveIsPolicyActiveForPlayer",
            "desc": "Whether a policy is *active* for this player, live.\n\nThe naming across this service is deliberate and worth knowing: **enabled** is the global switch, and\n**active** is enabled *and* the right realm *and* this player being tracked. Everything scoped to one\nplayer says `ForPlayer`, so which of the two a method means is readable at the call site rather than\nsomething you have to remember.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "player",
                    "desc": "",
                    "lua_type": "Player"
                },
                {
                    "name": "policyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Observable<boolean>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 444,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "PromiseIsPolicyActiveForPlayer",
            "desc": "Settles once the policy is active for this player. Never resolves false -- a caller waiting on a policy\nwants to know when it starts, and \"not yet\" is not an outcome worth settling on.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "player",
                    "desc": "",
                    "lua_type": "Player"
                },
                {
                    "name": "policyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<boolean>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 467,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "AddPlayer",
            "desc": "Starts running the enabled policies for a player.\n\nCalled by [AccessService] as players join, and callable directly by a test holding a mock. Idempotent.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "player",
                    "desc": "",
                    "lua_type": "Player"
                }
            ],
            "returns": [
                {
                    "desc": "Stops running policies for this player",
                    "lua_type": "() -> ()"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 487,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "RemovePlayer",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                },
                {
                    "name": "player",
                    "desc": "",
                    "lua_type": "Player"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 507,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        },
        {
            "name": "GetDebugState",
            "desc": "Every policy, whether it is running, and what it reads. A disabled policy is included -- knowing a\nconsequence exists but is switched off is most of the answer to \"why did nothing happen\".",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "AccessPolicyService"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "{ [string]: { policyName: string, realm: string, enabled: boolean, facts: { string }, features: { string } } }"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 523,
                "path": "src/access/src/Shared/AccessPolicyService.lua"
            }
        }
    ],
    "properties": [],
    "types": [],
    "name": "AccessPolicyService",
    "desc": "Registers [AccessPolicy] objects and runs the enabled ones against each player.\n\nPolicies register **disabled** unless they asked not to. A policy that is off is still listed, still\nautocompletes, and still names what it reads -- it simply is not running. That is what makes a\nconsequence as blunt as kicking safe to ship in the box: turning it on is a deliberate act you can see\nin a readout, and turning it off again is one command rather than a deploy.\n\nA policy built with `isEnabledByDefault = true` runs from the moment it is registered, for the case where the\nconsequence is the whole reason it exists. It says so in the readout, so nobody goes looking for the\ncommand that turned it on.\n\nShared, and registration happens in both realms, so a console on either side can name and autocomplete\nevery policy. Where a policy's consequence actually runs is its [AccessPolicyRealm] -- kicking on the\nserver, presentation on the client -- and this service simply skips the ones that are not for here.",
    "source": {
        "line": 20,
        "path": "src/access/src/Shared/AccessPolicyService.lua"
    }
}