Problems with ModuleScripts

Hello.

I have some ModuleScripts in my game, and they are causing me some problems.
One problem i am having is where when a character spawns in, they have a script that requires a ModuleScript to do some stuff with it, But when the character is destroyed, everything in the ModuleScript keeps running (like loops and stuff) and I’m not sure why.
I have tested taking the loop that is in the ModuleScript, and placing it in the server script itself, and it does stop when the script is destroyed, But when the loop is in the ModuleScript, it keeps going.
My main concern isn’t really that the loop keeps going, I’m more worried because if the ModuleScript keeps going, then doesn’t that mean that the required ModuleScripts just keep piling up? (Could this possibly cause a memory leak and/or lag?) Since you can respawn a lot in this game.
Is there a way to stop ModuleScripts from piling up like this? (if they do, because I’m not 100% sure)

Another problem I’m having is mostly just me not being sure what to do.
I have a server script that is located in ServerScriptService, And sometimes it needs to require ModuleScripts from different objects to make them do something and then never use them again.
Would this possibly cause a memory leak or something like that? Since it keeps requiring ModuleScripts and then not using them.
If it could cause memory leaks, then what should i do to fix this? Otherwise, I think it’s fine.

Any help is appreciated!
(Also, I’m unsure if there is already a post about this, because I’m not sure what to search up to find someone having the same exact issues)

1 Like

ModuleScript’s work like normal Script’s, but they only start working once they are first required, after they are required once the result is cached, so every other time you require them the ModuleScript does not run again and instead you get the cached result of it. So if you are running any loops or connections within a ModuleScript, they will run only once.
When Script that required the ModuleScript is destroyed, the code within the ModuleScript will keep running as its not connected to the destroyed Script. However if you call a function that the ModuleScript returns, from a Script that required it and then destroy the Script, the code within the function will stop as when called, the functions run within the Script’s enviroment rather than the ModuleScript.

3 Likes

You can visualise the results that @realmile explained through the use of prints.

StarterCharacterScripts:

LocalScript

print("Test - RequireScript has started")
require(script.Parent:WaitForChild("TestModule")).startLoop()

Module

local TestModule = {}

local a = 0
function TestModule.startLoop()
	spawn(function()
		while true do
			a += 1
			print("Test - Loop from TestModule is running", a)
			wait(1)
		end
	end)
end

print("Test - TestModule has been required")

return TestModule

Results:

18:01:40.983 Test - RequireScript has started - Client - TestScript:1
18:01:41.086 Test - TestModule has been required - Client - TestModule:14
18:01:41.248 Test - Loop from TestModule is running 1 - Client - TestModule:8
18:01:42.260 Test - Loop from TestModule is running 2 - Client - TestModule:8
18:01:43.276 Test - Loop from TestModule is running 3 - Client - TestModule:8
18:01:44.277 Test - Loop from TestModule is running 4 - Client - TestModule:8
18:01:45.289 Test - Loop from TestModule is running 5 - Client - TestModule:8
18:01:46.290 Test - Loop from TestModule is running 6 - Client - TestModule:8
18:01:47.376 Test - RequireScript has started - Client - TestScript:1
18:01:47.392 Test - TestModule has been required - Client - TestModule:14
18:01:47.428 Test - Loop from TestModule is running 1 - Client - TestModule:8
18:01:48.440 Test - Loop from TestModule is running 2 - Client - TestModule:8
18:01:49.459 Test - Loop from TestModule is running 3 - Client - TestModule:8
18:01:50.460 Test - Loop from TestModule is running 4 - Client - TestModule:8
18:01:51.474 Test - Loop from TestModule is running 5 - Client - TestModule:8
18:01:51.637 Test - RequireScript has started - Client - TestScript:1
18:01:51.655 Test - TestModule has been required - Client - TestModule:14
18:01:51.686 Test - Loop from TestModule is running 1 - Client - TestModule:8
18:01:52.689 Test - Loop from TestModule is running 2 - Client - TestModule:8
18:01:53.705 Test - Loop from TestModule is running 3 - Client - TestModule:8
18:01:54.721 Test - Loop from TestModule is running 4 - Client - TestModule:8

1 Like

So there isn’t anything i should worry about? Unless i misunderstood your response.

1 Like

You should be worried about your first issue. If you have a loop that runs inside of a module script and continues to run when a player respawns, these running threads will compound as players continue to respawn. This is, by definition, a memory leak. You should add an exit condition in your loop. For example. pass the character object to the loop, and ensure that the passed character (which would be passed by value, not reference), matches the current player.Character. This ensure that each loop only runs when its specific character still exists. When roblox replaces the player.character with a new character after a respawn, the loop for that character would break.

From what I understand, your second question is not a problem. Once a variable has no application within a scope roblox garbage collection should take care of it for you.

1 Like

Correct. Though if you have scripts that constantly need to require a module it would be best to try changing that so same scripts don’t require modules constantly for other reasons.

1 Like

This is just incorrect information… He described a memory leak- go back up and reread. Reference my last response.

1 Like

His concern was piling up the loops every time he requires a module (which wouldn’t happen), he specifically said he doesn’t mind the loop continuing (though if he needs it to stop he shouldn’t be calling it on require and rather with a function). He never mentioned what the loop does, so there isn’t enough information to classify it as a memory leak.

1 Like

That was his second concern, if you would read the first paragraph he wrote:

This is literally a memory leak. Assuming characters can die and respawn (which is nearly bound to happen in any roblox experience), this will accumulate memory. Even if the loop does nothing, it still runs and is still a memory leak.

1 Like

As I explained in my first post, simply requiring modules wont run them again (so there wont be more loops created). We don’t know exactly what happens when the module is required, but if we assume that there is a loop that goes through every player and connects a CharacterAdded, that alone wouldn’t cause a memory leak. Now if the CharacterAdded creates a loop, that would be a problem, however we don’t know what the module does, and as he said he is concerned that a “loop” will get created every time he requires a module (which wouldn’t happen).

1 Like

I should’ve been a bit more specific about what the loop is.
It’s not a constant “while true do” loop, it only lasts for a bit.
The reason why i am not concerned about the loop continuing after the ModuleScript is destroyed is because the loop itself is not the problem, i am only worried about memory leaks, and how i can prevent them.
What i mean is that if a ModuleScript is required when you spawn in, and you respawn, would that required ModuleScript kind of get “deleted” or is it just going to stay? if it stays, then i have no clue of how i could remove it (not the ModuleScript itself, i mean like the required version of the ModuleScript)

Still haven’t figured it out yet.
All i want to know is if requiring a module script in a script keeps that required version forever since the module script stuff seems to continue working even after the script that required it is destroyed.
For example, if i make so in the module script, it creates a part with a proximity prompt, and when that prompt is triggered, it prints something, and the script requiring the module script is destroyed, it still prints when you trigger the prompt.

I figured out a way to make so that the things in the script do not continue after the script is deleted.
It turns out that i was making connections to remote events within the module script itself, if i make the connections through the script requiring it and then use the module functions there, it doesn’t continue after the script is destroyed (which kind of makes sense)
(Also, I’m wondering if i should do this or not)

But i still haven’t figured out the answer to my question, Which is if requiring modules every time a character respawns (through a script in StarterCharacterScripts) is fine to do or if its bad