Benefit of using Signal / Custom Signal

Hello, I’m just a new guy who wanna try to use GoodSignal or similar to that, can you tell me what’s the benefit of using that custom Signal? Thank you.

GoodSignal claims to be nearly the same as roblox’s RBXScriptSignal. the bonus is it might help with debugging by giving a couple more steps on a stack frame, The downside is that roblox can implement their signals in C/C++ and will have very good performance that no signal plugin can match.

Excerpt from GoodSignal github

--               Batched Yield-Safe Signal Implementation                     --
-- This is a Signal class which has effectively identical behavior to a       --
-- normal RBXScriptSignal, with the only difference being a couple extra      --
-- stack frames at the bottom of the stack trace when an error is thrown.     --
-- This implementation caches runner coroutines, so the ability to yield in   --
-- the signal handlers comes at minimal extra cost over a naive signal        --
-- implementation that either always or never spawns a thread.                --
1 Like

if you want to make your own event system you can also do something like this

local module = {}
module.__index = module

module.New = function()
    local self = setmetatable({}, module)
    self.callbacks = {}
end

module.Bind = function(self, callback)
    local callbacks = {} -- if we are looping the old callbacks we don't want to break the order so instead of adding the callback directly we make brand new table
    callbacks[callback] = true
    for callback, value in pairs(self.callbacks) do
        callbacks[callback] = true
    end
    self.callbacks = callbacks
end

module.UnBind = function(self, callback)
    self.callbacks[callback] = nil -- its safe the remove callbacks directly so we don't need to make a new table like Bind
end

module.UnBindAll = function(self, function)
    self.callbacks = {}
end

module.Call = function(self, ...)
    for callback, value in pairs(self.callbacks) do
        callback(...) -- if you don't want the callback to block the next callbacks you might want to task.spawn the function
    end
end

return module

-- require the module above
local eventsModule = require(game.ReplicatedStorage.ModuleScript)

-- create a new event
local myCoolEvent = eventsModule.New()

-- bind a function to the event
myCoolEvent:Bind(function(value1, value2)
    print("Bind1", value1, value2)
end)

-- bind a second function to the event
myCoolEvent:Bind(function(value1, value2)
    print("Bind2", value1, value2)
end)

-- every 2 seconds call the event
while true do
    task.wait(2)
    myCoolEvent:Call("String Value", math.random(100))
end

or you could just use a BindableEvent

-- create a new event
local myCoolEvent = Instance.new("BindableEvent")

-- bind a function to the event
myCoolEvent.Event:Connect(function(value1, value2)
    print("Bind1", value1, value2)
end)

-- bind a second function to the event
myCoolEvent.Event:Connect(function(value1, value2)
    print("Bind2", value1, value2)
end)

-- every 2 seconds call the event
while true do
    task.wait(2)
    myCoolEvent:Fire("String Value", math.random(100))
end
1 Like

Maybe people who just start scripting especially in Roblox will ask, what’s the difference using event connection compared to just writing a function, if it’s only used in the same script

The difference can depend on how you tell the roblox workspace to handle events, the differed events beta can be a helpful mental mapping as well as speed up events execution (Article here). If not differing events then it should behave largely the same as a function until a yeilding function call is reached, then execution should (hopefully) resume after the bindable event’s :Fire call.

Gotta make sure the return self is before the end and it will work