Connect Framework
A helpful framework to handle core game functionality, RBXScriptSignal Connections, and help to prevent memory leaks.
This framework is in its very early stages, I will continue to make updates regularly.
https://www.roblox.com/library/13518158092/ConnectFramework
Usage
Handling Connections
local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Connect = require(ReplicatedStorage:WaitForChild("ConnectFramework"))
Connect(CollectionService:GetInstanceAddedSignal("Bread"), function (self, instance: BasePart)
Connect(instance, instance.Touched, function (self, hit)
...
if some_condition then
self:Disconnect()
end
end)
end)
Connections associated with Player.UserId
automatically disconnect when the player leaves the game
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Connect = require(ReplicatedStorage:WaitForChild("ConnectFramework"))
Connect(Players.PlayerAdded, function (self, Player)
Connect(Player.UserId, RunService.Stepped, function (self, runTime, step)
...
end)
end)
Connections associated with an Instance
automatically disconnect when the instance is being destroyed, or when the parent is set to nil
Connect(Player.UserId, Player.CharacterAdded, function (self, Character)
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
Connect(HumanoidRootPart, RunService.Stepped, function (self, runTime, step)
print(HumanoidRootPart.Position)
end)
end)
Error Handling
Available methods on the self
object within callbacks for Connect
, onError
, onRetryError
, and onDisconnect
Disconnect the callback from the event
self:Disconnect(): void
Get the arguments of the function (excluding
self
)self:GetArguments(): Tuple
Boolean of true/false if the function is currently Retrying via a call to
self:ScheduleRetry()
self:IsRetrying(): boolean
The amount of times the function has began
self:CurrentCycle(): number
The amount of times the function has finished
self:CompletedCycles(): number
Boolean of true/false if the function has ever errored
self:HasError(): boolean
The total amount of errors that appeared during execution
self:TotalErrors(): number
The last error that appeared during execution
self:LastError(): string
The average execution time of the function
self:AverageRunTime(): number
Available methods on the self
object within the callback for onError
Schedule the original function to retry with the same arguments
self:ScheduleRetry(delay: number?): voidWarning
Connections to events usingConnect(signal, ...)
will not run within Scheduled Retries to prevent duplicates. This means if the event callback failed to establish the connection on the first attempt, subsequent retries will not connect the event.Note It is possible to bypass this security measure by creating a new thread, although it is not advisable.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Connect = require(ReplicatedStorage:WaitForChild("ConnectFramework"))
local Players = game:GetService("Players")
local PlayerAdded = Connect(Players.PlayerAdded, function (self, Player)
if not self:IsRetrying() then
thisWillError()
end
-- In this scenario, the Player.CharacterAdded connection will never be established
-- as this part of the code will only run in the Scheduled Retry
local CharacterAdded = Connect(Player.UserId, Player.CharacterAdded, function (self, Character)
print("adding character")
end)
print(CharacterAdded) -- output: {}
end)
PlayerAdded:onError(function (self, err)
self:ScheduleRetry()
end)
Instead of the above, you should define all essential connections first
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Connect = require(ReplicatedStorage:WaitForChild("ConnectFramework"))
local Players = game:GetService("Players")
local PlayerAdded = Connect(Players.PlayerAdded, function (self, Player)
-- This will only establish 1 CharacterAdded connection per Player
local CharacterAdded = Connect(Player.UserId, Player.CharacterAdded, function (self, Character)
print("adding character")
end)
print(CharacterAdded) -- output: { ... } or an empty table if in the scheduled retry
if not self:IsRetrying() then
thisWillError()
end
end)
PlayerAdded:onError(function (self, err)
self:ScheduleRetry()
end)
Core Gameplay Loops
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Connect = require(ReplicatedStorage:WaitForChild("ConnectFramework"))
local options = {
-- Default: false
StartInstantly = true;
-- Default: 60
Interval = function ()
local RandomGenerator = Random.new(os.time())
return RandomGenerator:NextInteger(15, 30)
end;
-- Default: No arguments
Arguments = function ()
local RandomGenerator = Random.new(os.time())
return RandomGenerator:NextInteger(5, 10), RandomGenerator:NextInteger(100, 200)
end;
}
Connect:CreateCoreLoop(options, function (random1, random2)
print(random1, random2)
end)
Threads
Connect:Delay()
Automatically cancels any existing thread scheduled with the specified key
if Power == "Double_Speed" then
local PreviousWalkSpeed = Player:GetAttribute("WalkSpeed")
Humanoid.WalkSpeed = PreviousWalkSpeed * 2
Connect:Delay(30, Player.UserId .. "ResetWalkSpeed", function ()
Humanoid.WalkSpeed = PreviousWalkSpeed
end)
end
For more control of how threads get cancelled, you may use the following:
if Power == "Double_Speed" then
local key = Player.UserId .. "ResetWalkSpeed"
local existingThread = Connect:Thread(key)
if existingThread then
task.cancel(existingThread)
end
local PreviousWalkSpeed = Player:GetAttribute("WalkSpeed")
Humanoid.WalkSpeed = PreviousWalkSpeed * 2
local newThread = task.delay(30, function ()
Humanoid.WalkSpeed = PreviousWalkSpeed
end)
Connect:Thread(key, newThread)
end
Debugging
Show warnings relevant to the execution of certain callbacks
Connect:DebugEnabled(true)
Show all warnings and logs, including internal framework info
Connect:DebugEnabled("internal")
Show how many server or client connections you have every 5 seconds depending on the location of the executing script
Connect:Counter()