Scope
local Scope = require("@game/ReplicatedStorage/Twill").Scope
Scope.Player(player):Connect(someSignal, onSomething)Scope.Alive(character):Connect(humanoid.Died, onDeath)Ask for the bag matching how long a thing should live, put what was made into
it, and disconnect nothing by hand. Every bag is a Bag, so
Connect, Add, Extend and the rest work on it.
The four lifetimes
Section titled “The four lifetimes”| Scope | Closes when |
|---|---|
Player | That player leaves. |
Character | The character is removed, which is at respawn rather than at death. |
Alive | The humanoid dies, or the character is removed. |
Framework | The server stops. Holds Twill’s own connections. |
Character and Alive differ by one death. A healthbar belongs in Character,
because it should survive the death that fills it in. A sprint loop belongs in
Alive, because it should stop the moment the humanoid does.
Asking twice for the same scope returns the same bag. Two systems share one without knowing about each other.
Bags that clean up after themselves
Section titled “Bags that clean up after themselves”A character bag attaches itself to the character. An instance destroyed without
the bag being closed takes the bag with it, and the bag removes its own entry, so
nothing here holds a dead Instance.
A character created outside game is not attached, since there is nothing to
watch. Closing it is then the caller’s job.
Taking over player closing
Section titled “Taking over player closing”By default a player’s bag closes on PlayerRemoving. A system that must unwind
first, such as saving data, calls OwnPlayerClosing and then closes the bag
itself when it is done.
Scope.OwnPlayerClosing()
Players.PlayerRemoving:Connect(function(player) saveEverything(player) Scope.Close(player)end)This is a one way switch, and it applies to every player from that point on.
Lifecycle calls it when a player gate is set.
Scope.Player
Section titled “Scope.Player”[Server] | [Client]
Returns the bag that closes when this player leaves.
function Scope.Player(player: Player): BagCreated on the first ask. For a player who has already left, answers a bag that
closes a moment later instead, so nothing put in it outlives them. Throws when
given anything but a Player.
Scope.Character
Section titled “Scope.Character”[Server] | [Client]
Returns the bag that closes when this character is removed.
function Scope.Character(character: Model): BagAttaches itself to the character when the character is in game. Throws when
given anything but a Model.
Scope.Alive
Section titled “Scope.Alive”[Server] | [Client]
Returns the bag that closes the instant this character dies.
function Scope.Alive(character: Model): BagWaits for the humanoid when the character has none yet. Also closes when the character bag closes, so a character removed without dying does not leave this one open.
Throws when given anything but a Model.
Scope.Framework
Section titled “Scope.Framework”[Server] | [Client]
Returns the bag Twill’s own modules keep their connections in.
function Scope.Framework(): BagThe same bag every time. Game code can use it for connections that live as long as the server, but a shorter scope is almost always the right one.
Scope.Close
Section titled “Scope.Close”[Server] | [Client]
Closes a player’s bag now.
function Scope.Close(player: Player)Does nothing when there is no bag to close. Throws when given anything but a
Player.
Scope.CloseCharacter
Section titled “Scope.CloseCharacter”[Server] | [Client]
Closes a character’s bag now.
function Scope.CloseCharacter(character: Model)Scope.CloseAlive
Section titled “Scope.CloseAlive”[Server] | [Client]
Closes a character’s alive bag now, without waiting for a death.
function Scope.CloseAlive(character: Model)Scope.CloseAll
Section titled “Scope.CloseAll”[Server] | [Client]
Closes every bag held here, shortest lifetime first.
function Scope.CloseAll()Alive bags, then character bags, then player bags, then the framework bag. This is a shutdown rather than a reset: the framework bag is destroyed, not emptied.
Scope.OwnPlayerClosing
Section titled “Scope.OwnPlayerClosing”[Server] | [Client]
Hands closing of every player bag to the caller, from this point on.
function Scope.OwnPlayerClosing()There is no way back. Once called, nothing closes a player bag until the caller does.