I have tons of modules for the sake of the organization of the studio. After some research on Modules, you can not unload the module after require ing them.
So this brought me to a question, would it be safe to require a module multiple times? In this particular case I have this:
requestCombat.OnServerInvoke = function(Player, MouseHit)
if tick() - COOLDOWN_HANDLER.getCooldown(Player, "Combat") >= 0.5 and STATES_DATA.requestCombat(Player) then
COOLDOWN_HANDLER.setCooldown(Player, "Combat", tick())
local PlayerData = DATASTORE.getData(Player)
--> If there are no logs of last combo
if not module[Player] then
module[Player] = {1, tick()}
elseif tick() - module[Player][2] <= 1 then
module[Player] = {module[Player][1] + 1, nil}
else
module[Player] = {1, nil}
end
if module[Player][1] > #PlayerData.Equipped.Combo then
module[Player] = {1, nil}
end
Player.States["Casting"].Value = true
module[PlayerData.Equipped.Combo[module[Player][1]]].Execute(Player, MouseHit)
module[Player] = {module[Player][1], tick()}
Player.States["Casting"].Value = false
return true, PlayerData.Equipped.Combo[module[Player][1]]
else
return false
end
end
I have all the modules loaded into a table and then I find the corresponding ability and run the function. I’ve noticed that because of it being the same module, the wait() or anything regarding yielding will stack for the next player or user. So should I require and get a new copy every time? Would this cause some form of memory leak?
My other solution is to wrap it in a coroutine but because it is the same module I’m not sure if that would work.
To answer the question in the title, yes it is safe.
I’ve noticed that because of it being the same module, the wait() or anything regarding yielding will stack for the next player or user
My other solution is to wrap it in a coroutine
From what I am seeing in the code sample you provided in the post, you are using the modules as a response to a RemoteFunction, this means you are already using a different thread for each call and the “wait stacking” you are experiencing is the result of something else.
Do you perhaps have a variable inside the module scripts that gets locked everytime the function is called? do you have maybe a Queue structure inside?
module.Execute = function(Player, MouseHit)
local Character = Player.Character
local cParts = Character:GetChildren()
coroutine.wrap(function()
for i = 1, #cParts do
wait(0.04)
if cParts[i]:IsA("BasePart") then
local startPos = (cParts[i].CFrame * CFrame.new(0,0,1)).Position
local endPos = (Character.HumanoidRootPart.CFrame * CFrame.new(0,0,-5)).Position --(cParts[i].CFrame * CFrame.new(0,0,-5)).Position
local ray = Ray.new(startPos, (endPos - startPos).Unit * 5)
local hit, pos = game.Workspace:FindPartOnRayWithIgnoreList(ray, {Character, game.Workspace.World.Visuals})
if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
local Enemy = hit.Parent
local Inflicted = DAMAGE_HANDLER.inflictDamage(Player, Enemy, 5)
local plrs = Players:GetPlayers()
if Inflicted then
stun(Enemy)
for i = 1, #plrs do
if GlobalFunctions.isAlive(plrs[i].Character) then
if (Character.PrimaryPart.Position - plrs[i].Character.PrimaryPart.Position).Magnitude <= WORLD_DATA.effectsRenderDistance then
replicateEffects:FireClient(plrs[i], {
Module = "Left Punch",
Function = "Execute",
Data = {
["Character"] = Character,
["Target"] = Enemy
}
})
end
end
end
coroutine.wrap(function()
wait(0.5)
unstun(Enemy)
end)()
break
end
end
end
end
end)()
end
The coroutine was me attempting to put it into a new thread because multiple people would be using this piece of code. I’ve also read that Remote Events and Remote Functions upon being called or triggered automatically creates a new thread which wouldn’t that mean technically I wouldn’t need these coroutines?
EDIT: As far as I know there are no queue system implemented.
wouldn’t that mean technically I wouldn’t need these coroutines?
I’d say it depends, here because you are using a remoteFunction and you want it to return as soon as possible you probably want to keep the coroutines for the Execute() function.
Well for a quick look inside one of my modules
I skimmed through the code at it appears it should work, but what about the “COOLDOWN_HANDLER” in your original script? it seems like the issue could lie there
You can definitely require a module multiple times, but this wont solve any of the issues presented in the thread and there is no real need to do it more than once per script.
If you find the solution make sure to post it so other users with similar issues can find it!