I couldn’t be confident on a specific category where this type of post would fit. Notify me if it should go somewhere else.
The Dilemma
Some of you may have run into an issue or question in your trials and tribulations with ModuleScripts where a piece of your code still executes, despite the Script that required it being missing.
ModuleScripts do in-fact keep running after death, death specifically being through means of :Destroy()
Script
require(workspace.ModuleScript)
ModuleScript
local module = {}
while task.wait(0.5) do
print("e")
end
return module
Example1.rbxl (54.6 KB)
Running this code, will print “e” into the Output log as expected, and deleting both the Script AND the ModuleScript, still prints “e”, from a nil source.
If this behaviour benefits you, enjoy the rest of your day!
But if you were looking for an answer on how to avoid this from happening, I have an answer for this as well.
The Solution
All you need is to turn your code snippet into a module function!
Script
require(workspace.ModuleScript).setup()
ModuleScript
local module = {}
function module.setup()
while task.wait(0.5) do
print("e")
end
end
return module
Example2.rbxl (54.6 KB)
Upon running it, simply deleting the Server Script is enough to cease the entire process.
I hope this article of knowledge has made someone’s day a little bit easier!
3 Likes
So I guess the lesson here is to not put any code that could run for an indeterminate amount of time in the module’s initialization part and to instead make it a function.
2 Likes
Because ModuleScript
s are not Script
s. They do not run code unless required, and when required the module is initialized for the entirety of the environment context. This means the module code is only run once, and the result is cached across all of the scripts in that context. (Server, Client, or Plugin)
This is why the script continues to run in the first case.
In the second case, the returned value from the module is now in the Script
’s environment. Not ModuleScript
’s. The function does not run in the module, it runs from the Script
, therefore when you :Destroy()
the Script
instance, the execution is halted.
2 Likes
couldnt you make a client sided anti cheat with this?
put a module in ReplicatedFirst, require it and immediately destroy both the module and the script requiring it, and the cheater wont be able to stop the script from running by destroying it and maybe even not be able to view it. im probably overlooking something obvious here because this seems stupid, maybe someone can experiment with this
1 Like
Ohh! That could actually be a pretty good use-case! I have yet to find a way to cease the e’s after deleting the scripts, so it could be possible, I suppose the hope is that the software doesn’t delete the script before it can require the modulescript.
This is correct, but do note that I deleted both the Script and the ModuleScript.
Edit: I prob misread your post, disregard my reply
Pretty much! Just generally any case that involves code undesirably firing, in my case I was working with a tool that still read my inputs despite it being deleted.