How do I know which script "owns" an event connection?

So after doing some experimenting I figured out that script signals a.k.a events have “owners”.

If the following code is executed inside a ModuleScript:

local module = {}

module.event = workspace.ChildAdded:Connect(function(obj)

 print(obj.Name " was added!")
end)


return module

When the module executes for the first time, the module “owns” the event, meaning that even if the script that initiated the module is Destroy()'d, this event connection along with it’s connected function will continue to exist and function as usual.

However

If we now do this instead:

ModuleScript

local module = {}


function module.object_added(obj)
 print(obj.Name " was added!")
end


function module.make_event()
 module.event = workspace.ChildAdded:Connect(module.object_added)
end


return module

Script

local module = require(game.ReplicatedStorage.MyModule)

module.make_event()

This function will still execute when things are being added to workspace, that is, until we Destroy() this script.

After destroying it, doing print( module.event.Connected ) prints false.

This implies or sorta indicates that the script that called the function actually owns the event connection.

Despite the function still existing in the ModuleScript, the event is disconnected when the script that “owns” that event is destroyed.

On to the question

Is there actually a way in Roblox to know which script definitively owns an event connection?
And if so, are there ways to pass that connection around?

I figured this entire thing kinda functions like how pointers/references do.

Some things I have not tested yet is whether event connections can be passed through BindableEvents or -Functions.

This behavior is also not clearly documented in the Roblox documentations and it makes it hard to figure out how precisely it works.
My intend is to utilize this behavior and structure projects in a way such that they are safe from any potential memory leaks or lingering events.

I may have most of my code in ModuleScripts (where event connections are often also being made) and I would like to know or find a way to track which currently running script owns an event connection.

1 Like

I ran some tests and here are the results:

  • Sending a connection using a BindableEvent or BindableFunction worked, and I was able to disconnect the connection successfully from within the second script
  • Sending a connection using a RemoteEvent or RemoteFunction didn’t work, the result was nil, so connections do not replicate from server to client or vice versa
1 Like

The last one I expected, I did not expect BindableEvents to work though.
I suppose RBXScriptSignals must be some kind of data type that acts as an “object” or similar to tables but doesn’t have a location/parent of any kind.

I still have yet to find a tool or window in Studio or a function that let’s me see which script actually “owns” the event connection.

I was at least pleased to know that making connections inside a ModuleScript should technically be safe, Roblox engineers have designed events in a clever way that prevents easy memory leaks.

I used to think that only destroying the object the event is connected to disconnects it.
But services such as Workspace or UserInputService cannot be destroyed, so I was glad that destroying the script that “created” the connection also disconnects it, even if done through a ModuleScript.

I have yet to find any edge-case scenarios where making an event actually does not cause it to disconnect post-script-destruction.

2 Likes

Behind the scenes, each script has a unique memory address even if it has the same name as another script, but as far as I know, there isn’t a method available that one can use to view it (although, one can see the memory address of a table value by using tostring, but this method doesn’t work on Instances)

I have all beta features enabled on Studio, and Roblox seems to be experimenting with a UniqueId property that all Instances seem to have. Currently it doesn’t seem to be able to be used, but once it’s available, it can provide a way to identify the script that owns the connection if you send its value with the connection


@C_Corpze From further research, the reason why the UniqueId property is currently unable to be used is due to a bug:

1 Like