How to cancel previous required module after you've died and re-required

I’m getting a problem where when I die, and put a print inside a module, it’s printing twice (onces for the new require, once for the old) and the old require ends up erroring out.

local Buttons = {}
	local CurrentButton = 1
	
	Title.Text = 'Choose gamemode'
	
	for _, v in pairs(Choices:GetChildren()) do
		v.Visible = true
		v.Size = UDim2.new(0.85, 0, 0.85, 0)
		
		if v.Name == '1' then
			v.Position = UDim2.new(0.15, 0, 1, 0)
		elseif v.Name == '3' then
			v.Position = UDim2.new(0.85, 0, 1, 0)
		end

		table.insert(Buttons, v)
	end
	
	print(Buttons)
	print(#Buttons)

So the prints

	print(Buttons)
	print(#Buttons)

First time printing

table
3

Then when I die, and respawn it prints

table
3
table
0

Which the table 3 is the new module require, table 0 is I’m guessing the old module require. How can I stop this problem from occuring??

A module script will only run once then the result is cached.

The cache will exist as long as the module script exists. To “clear” the cache one option is to clone and destroy the module.

e.g

local old = [module path]
local new = old:Clone()
new.Parent = old.Parent
old:Destroy()

But this can cause a lot of problems in your code and I would avoid doing this.

Without knowing what you want this module to do I cannot help much. I would however say to look into using a OOP approach to solve this.

1 Like

Umm, well the code is inside a function that’s called when a remote event fires, but apart from that, that’s really it

Put this code inside a method then call it when CharacterAdded fires as opposed to leaving it in the topmost scope. Leaving the code in the topmost scope should only be done for initialisation features that reasonably would need to be done only once ever when the module is required. Everything else should be done in functions.

What do you mean by that?? As I’m requiring it from a LocalScript in StarterGui, means I’d have to reference PlayerGui instead

I don’t understand your reply at all. What difference does this make? The contents of StarterGui are cloned over to PlayerGui, so you would have to reference PlayerGui regardless. As for what I’m saying, I mean exactly what I said: put your code in a function instead of having it run implicitly upon require and call that function each time it needs to spawn up again. You can’t “cancel” or “reload” modules.

Well cause my LocalScript is like so

local HUD = script.Parent

local Frame = HUD:WaitForChild('Frame')

local Module = require(Frame.Module)

So I don’t see how putting this local script inside StarterCharacter would change anything, as the GUI is reset with each new character anyway

I never said anything about StarterCharacter, I said to move the contents of the ModuleScript that aren’t in a function, into a function and then call that each time the Gui needs to reset or refresh something. The thing to understand here is that you aren’t “resetting” things, you’re accounting for respawns by adapting your code as so.

For example: you have a non-resetting HealthGui that also makes use of a ModuleScript and both items are under that Gui. In that case, you account for new character spawns using CharacterAdded so that your module isn’t referencing old items.

Outside of a function, your ModuleScript is still recognising the first Gui because that’s what’s indexed upon require. There’s no functions or CharacterAdded accounting anywhere so each require will always reference the same old Gui. Therefore you need to incorporate this code into a function that can be ran when a new character is added.

Take the PlayerModule and its controls for example. The PlayerModule is found in a non-resetting container, PlayerScripts. How is it able to then allow the client to control a new character every time it respawns without any weird tricks? It doesn’t reset itself, it accounts for new characters. See:

The following linked function is called when CharacterAdded fires. It is responsible for hooking up certain functionality to the new character, so that the current character and any new characters after respawn share that functionality. For example, at the very top of the function, it updates the Humanoid variable so that the ControlModule is acting on the current Humanoid rather than an old one.