Signal¶
The object behind every On... member Scribe exposes, such as Server.OnSave or
Client.OnLeaderboard. You never construct one and you never fire one; you
connect to one.
Each handler runs on its own thread, so a handler may yield with task.wait
without holding up the other handlers or the code that fired. A handler that
raises does not stop its siblings and does not break the signal: the error
reaches the output with its traceback, and the next fire behaves normally.
Order is not part of the contract. Never write two handlers where one has to run before the other; put both steps in one handler instead.
The methods below are called with a colon, Data.OnSave:Connect(fn), so the
signatures drop the implicit self. The Session Lifecycle
guide shows the everyday shape.
Methods¶
:Connect¶
Runs handler on every fire, with the arguments the signal fires. Returns a
Connection, which is how you stop listening again.
Connecting during a fire does not join that fire; the new handler starts with the next one. There is no duplicate check, so connecting the same function twice runs it twice.
:Once¶
Runs handler on the next fire only, then detaches it. Returns the same
Connection that Connect does, so you can cancel
before that fire ever arrives.
The detach happens before handler runs, so a handler that raises, or that
somehow causes the signal to fire again, still cannot run a second time.
:Wait¶
Yields the calling thread until the next fire, then returns that fire's arguments. It starts listening at the moment you call it, so a fire that already happened is neither waited for nor replayed.
Call it from a coroutine or a task.spawn, never from the main body of a script
that has to keep going. If nothing ever fires, or the signal is cleared by
DisconnectAll while you wait, the thread stays parked for good.
Prefer Once whenever you have somewhere else to be.
:DisconnectAll¶
Detaches every handler at once and empties the list. Existing
Connection objects report Connected = false afterwards, and
disconnecting one of them again is a no-op.
A fire already in flight is not recalled, so handlers dispatched before the call still run. A thread parked in Wait is left parked, because the fire it was waiting for can no longer reach it.
The signal stays usable. Connect to it again and it fires again.
:Destroy¶
The same function as DisconnectAll, under the name most Roblox objects use. It detaches every handler and does nothing further: no instance is destroyed, nothing beyond the handler list is released, and the signal still works if you connect to it again.
You will rarely need it. The signals Scribe hands you live as long as the server or the client session does, so this is for a signal you made yourself.
Inspecting¶
:HasListeners¶
Whether at least one handler is connected right now. It counts live connections only: one dropped with Disconnect, or by DisconnectAll, stops counting immediately.
Scribe uses it to skip building an argument that nobody would read. In game code it is mostly a teardown check, so that work feeding a signal can stop once the last listener leaves. It cannot tell one listener from four, so never use it to decide whether the connection still attached is yours.