Module Scripts Don't keep running after death?

So, I’ve read this post: Do modules keep running after death? - #4 by reteach

And I am working with a modular structure, here is how it’s setup currently:
image

I will be focusing on the client side instead of the server side because I feel like that’s where I should be focusing most in this post. Inside of the ClientMain Script, I require the Boilerplate Module in the “Shared” folder like so:

--ClientMain Script
local Boilerplate = require(game:GetService("ReplicatedStorage"):WaitForChild("Modules").Shared.Boilerplate)
Boilerplate.Main()

local Modules = Boilerplate.Modules
local SharedModules = Boilerplate.SharedModules

local Test = Modules.Test
Test.Main()

The Boilerplate module handles the variables the server and client will access, it also handles the Client variables, like Player, UserInputService, Character, and etc. It also has a table called “Modules”, the current module I’m working with is called “Test”, as you can see in the Client folder I have a ModuleScript called “Test”. Inside of the Test Modulescript, there is a main function like so:

--Test ModuleScript
local Test = {}
	local Boilerplate = require(game:GetService("ReplicatedStorage"):WaitForChild("Modules").Shared.Boilerplate)
	local Modules = Boilerplate.Modules

	function Test.Main()
		Boilerplate.UserInputService.InputBegan:Connect(function(Input, gameProcessed)
			if not gameProcessed then
				if Input.KeyCode == Enum.KeyCode.F then
					print("F Key!")
				end
			end
		end)
	end
return Test

Inside of this Main function I make a new event, a InputBegan event and I listen for the “F” Key to be pressed. To get to the main point, whenever I Destroy the ClientMain localscript inside of the Character, the InputBegan event doesn’t fire anymore. Whenever I press “F”, it doesn’t print “F Key!” anymore. (Which works entirely in my favor, I’m just wondering why this actually happens, hence why I’m making this post) This makes me wonder, if ModuleScripts actually don’t keep running after death, or is the Event being garbage collected when the Script that required it is nil or destroyed? (If I didn’t explain things well or you need me to elaborate on a few things, please let me know).

Edit: Also, here is my Boilerplate Module Code:

local Boilerplate = {}
	function Boilerplate.Main()
		--[[Setup Boilerplate Variables]]--
		Boilerplate.Players = game:GetService("Players")
		Boilerplate.RunService = game:GetService("RunService")
		Boilerplate.RepStorage = game:GetService("ReplicatedStorage")
		Boilerplate.RepModules = Boilerplate.RepStorage:WaitForChild("Modules")
		
		--[[Setup Module Tables]]--
		Boilerplate.Modules = {}
		Boilerplate.SharedModules = {}
		Boilerplate.ModuleDirectory = {}
		
		--[[Setup Client/Server Module Directory]]--
		if Boilerplate.RunService:IsServer() then
			Boilerplate.ServerStorage = game:GetService("ServerStorage")
			Boilerplate.ModuleDirectory = Boilerplate.ServerStorage:WaitForChild("Modules")
		elseif Boilerplate.RunService:IsClient() then
			Boilerplate.ModuleDirectory = Boilerplate.RepModules.Client
			
			--[[Setup the Client's Variables]]--
			Boilerplate.Player = Boilerplate.Players.LocalPlayer
			Boilerplate.Character = Boilerplate.Player.Character or Boilerplate.Player.CharacterAdded:Wait()
			Boilerplate.UserInputService = game:GetService("UserInputService")
		end
		
		--[[Insert Respective Modules of either Client/Server & Shared into Modules Table]]--
		
		--Client/Server Insertion
		for i,v in pairs(Boilerplate.ModuleDirectory:GetChildren()) do
			if v:IsA("ModuleScript") then
				local State, Error = pcall(function()
					Boilerplate.Modules[v.Name] = require(v)
				end)
				
				if not State then
					warn("[!] "..Error)
				end
			end
		end
		
		--Shared Insertion
		for i,v in pairs(Boilerplate.RepModules.Shared:GetChildren()) do
			if v:IsA("ModuleScript") then
				local State, Error = pcall(function()
					Boilerplate.SharedModules[v.Name] = require(v)
				end)
				
				if not State then
					warn("[!] "..Error)
				end
			end
		end
	end
return Boilerplate

(This is the same Setup as this post’s solution, however with some little changes)

Just out of curiosity would moving ClientMain to StarterPlayerScripts vs StarterCharacterScripts fix this?

It’s not really a asking for a solution question, it’s more of a “Why is this behavior happening” question. However, if I were to parent the ClientMain to the StarterPlayerScripts location, run the game, then delete the script inside of the PlayerScripts folder, then the behavior would still occur.

Ah, I gotcha. Well, I don’t think the module script would be garbage collected if a script that required it is destroyed because it’s entirely independent. I’m stumped as to why this would occur.

Yeah it’s weird. The ClientMain script that calls the “Main” function inside of the TestModule Script when deleted stops all loops, and events aswell inside of the TestModule Script even though they’re not being broke or the events aren’t being disconnected.

If you destroy a script that is running imported code from a module script, the imported code will effectively stop running also. That is why you are having this issue. Simply move it to StarterPlayerScripts @Shinjaa

2 Likes

So basically, whenever you call a function from a ModuleScript inside of a Script, it acts as if the Function is imported into the Script itself, and then upon deletion of the Script, the function will stop running? Not sure if I understood this quite right lol. Also, it’s not really an issue as I’ve described in my reply to MastahProdigy. I will not be moving it to StarterPlayerScripts btw, mainly because this is the behavior that I actually want, I just asked why this behavior was occuring.

I don’t think that’s the correct wording but yes. ModuleScripts are just code containers, they don’t act independently afaik.

1 Like

Gotcha, I think I understand now. Thank you for your help!

1 Like

Yea I don’t know why I said independent earlier. You still have to include a module in a script for it to run, but what I meant was even though he destroys ClientMain the code within the module should still be usable if you called the module in another script correct?

I would guess so. I don’t know all the details. If you want to know more it might be easier if you just tested it out yourself in a baseplate