Keeping a require-ed script running even after the require-er was deatroyed

Let’s say theres a ModuleScript with the following code:

return function()
    while true do
        print("running")
        task.wait(0.5)
    end
end

And a script with the following code:

require(path.to.module.above)()

Normally, when you destroy the script, the ModuleScript will stop printing “running”, however in my case I would like to keep it running even after the script is destroyed.

I’ve tried using task.spawn, task.defer, or using coroutine but none of them was able to keep it running after script deletion.

Well, in my case it was different. After I deleted the script, it started printing in a different line though it was the same string.

18:55:24.374  running (x14)  -  Server - ModuleScript:3
18:55:32.014  running (x16)  -  Studio

But, it was still running every 0.5 seconds.

When you return the function from the module like that, the function is actually executing inside the script thread. When you kill the script (and therefore it’s thread), the function stops running. The Module doesn’t have a thread of its own, but you can create one using spawn.

local module = {}
spawn(function()
	while true do
		print("hi")
		task.wait(1)
	end
end)
return module
require(path.to.module.above)

That would run the function in a new thread that wasn’t associated with the script (even though the script started the ball rolling by requiring the module). The script can be destroyed and the function will keep running. You could do this with a coroutine and store the ref to that in the module and then have another command that removes any threads the module spawned. Otherwise, you’d have a never-ending loop in your game and no convenient way to kill it.

Basically, the ModuleScript doesn’t run things in the way a Script does. It doesn’t have a thread associated with it. It’s basically just a table that can serve up functions and data to a script or coroutine. If you need to kill a script but keep something from the module running, then there needs to be another routine that’s still actually running the code.

When you spawn from the script, the spawned thread is still tied to the script (like a child process) and is killed when the script is destroyed. Spawning from the Module creates that thread outside the first script, so it isn’t killed when the script is destroyed, but rather it runs until the whole game is shut down.

1 Like

Well sure but the issue is I really need it inside a function that can be called by another script and continue running despite the script being destroyed

I suppose something like this will work?

local module = {}

local function a()
    while true do
        print("running")
        task.wait(0.5)
    end
end

local bind = Instance.new("BindableEvent")
task.spawn(function()
    print("seperate ms thread running")
    bind.Event:Connect(a)
end)

function module.a(...)
    return bind:Fire(...)
end

return module
4 Likes