So I’ve been scripting on Roblox for a couple of years now and thought I had a pretty good grasp of how scripts/modules work etc…
However, I noticed when destroying a script, any connections made in the script to other instances are disconnected even when stored in a module script and are still visible to other scripts. Which to me seems counter-intuitive, so I just wondered if someone could explain this behaviour?
--Testing script - part touches work until script2 is destroyed but script 1 can still print the connection
--script 1
print("hello world script 1")
local script2 = script.Parent.Script2
local module = require(script.Parent.ModuleScript)
task.wait(5)
script2:Destroy()
task.wait(5)
print(module.conn, typeof(module.conn), module.conn.Connected)
--script 2
print("hello world script 2")
local module = require(script.Parent.ModuleScript)
module.connectpart()
--module script
print("module required")
local module = {}
module.conn = nil
module.touchfunc = function(otherPart: BasePart)
local character = otherPart.Parent
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
print(character.Name .. " touched the part!")
end
module.connectpart = function()
module.conn = workspace.Part.Touched:Connect(module.touchfunc)
end
return module
Currently I assume it is something to do with how script threads have memory allocated, so when they are destroyed effectively anything they did gets GC’d?
This is exactly what I thought might be the case, that the script held the only references to the function so of course once the function fell out of scope it couldn’t be called…
But this isn’t what seems to happen… The script that calls the connect method for an instance also seems to disconnect it when that script instance is destroyed, even though the instance, connection, and functions are all still in scope.
I think you could maybe get around that by making a script.Destroying event that checks if the script is destroyed. When it does, all the events that were connected by that script get connected again, or just recreated.
It’s courtesy for the engine to perform those disconnections. In most cases, people expect destroyed scripts to die off ASAP. Developers can’t reasonably manage every connection manually and retaining the connection anyway is at best a memory leak and at worst game breaking.
If you want a connection to stay alive, make sure the script isn’t destroyed. Setting the parent to nil is an alternative if you’d like the script to be detached from the game hierarchy.
Thanks, this is mush closer to the answer I was looking for (basically, it’s not a bug but a feature). It just surprised me that I could deliberately intend to store connections outside the script thread but still have them disconnected anyway.