Is it possible to define a require() in a function?

As stated above in my title, is it possible to do something like this:

local function ClassInfoGui(plr)
	local char = plr.Character
	print("start")
	if findPlayer(char) and not debounce2[plr] then debounce2[plr] = true print("past first if")
		if ss:WaitForChild("Classes"):FindFirstChild(class) then local dataget = ss.Classes[class] print("found class folder")
			if dataget:FindFirstChild(class) then local module = require(dataget[class]) print("found module and required")
				local returntable = { ["PSV"] = {}, ["ATK"] = {}, ["AB1"] = {}, ["AB2"] = {}, ["CRT"] = {}, ["Name"] = "", ["Cost"] = "" }
				for i,v in pairs(returntable) do
					if i ~= "Name" or i ~= "Cost" then local move = module:GetMove(i); v[1] = move.Icon; v[2] = move.Tooltip 
					elseif i == "Name" then v = tostring(class)
					elseif i == "Cost" then local cost = dataget:FindFirstChild("Cost"); local text = nil
						if cost.Value == 0 then text = "Free" elseif cost.Value == -1 then text = "Unlock" end
						v = tostring(text or cost.Value)
					end
				end rRemotes.ClassInfo:FireClient(plr, returntable) print("finished and fired")
			end
		end
		delay(1, function() debounce2[plr] = false end)
	end
end

So far, when I click the given part, it prints until the require() part, making me suspect that it isn’t possible. Are there any solutions, as I would like this to be adaptable as possible.

2 Likes

I wouldnt understand why require() wouldnt work. I think its something to do with the modulescripts state changing (are you using a passed parameter as the module script?)

1 Like

Not as far as I can tell.

3char

1 Like

Forgot to note, it definitely picked the module script up before it was added to require().

1 Like

I am trying to understand the script, there are a lot of variables missing. if you can give me some of them, I may be able to understand the script.

Or it may be because I am dumb.

1 Like

If the problem is trying to require, then I have been having some problems with require to. it keeps saying its a model, but its a module script named ā€œMainModuleā€. So If your having that problem, I am to.

1 Like

Wow that is a lot of code on so few lines… You may wanna add some enters :stuck_out_tongue:

In theory, it’s fine to require a modulescript anywhere, any time… But remember that the code in the modulescript is only executed once, the first time your require the modulescript, and the value returned by the modulescript (usually a table) is stored in memory… Next time you require the same modulescript, you will get a reference to the same table.

That shouldn’t matter if you use modulescripts correctly, because you organise what the modulescript should do in functions, instead of executing it directly. The table that require() returns then contains those functions.

But, you may consider wether picking up the same modulescripts over and over is the right structure… Sometimes importing them all and storing them in a dictionary once could be a lot cleaner… in the end a lazy evaluation / promise method or simply a cache might be an alternative if you have a lot of classes… the module’s tables are kept in memory anyway so it’s not a waste, just keep them clean.

1 Like

Yeah, I was simply trying to make something that would work given the amount of classes that will exist. I thought storing all of them would be well, a bit tedious and annoying if I was going to add another class.

1 Like

Haha, it happens that I’ve been trying something similar recently. (A class system for fighting games) and funny enough, this problem occured to me, too.
The problem I had was that there was 2 module scripts requiring each other, thus creating an infinite cycle of require()
So, my solution was to reorganize the code in a way that the code doesn’t have to require each other
(I ended up seperating the functions I need from the second module into another module)

As for the ā€˜be adaptable as possible’, I made the input connections handler a seperate script, and the player’s class a readable value (in my case, I used attribute)
Upon invoking a specified key, it will execute the function that is stored inside a module containing class info which goes like

-- Input Handler
class = player.PlayerData:GetAttribute("Class")
player.PlayerData:GetAttributeChangedSignal("Class"):Connect(function()
    class = player.PlayerData:GetAttribute("Class")
end)
Input.InputBegan:Connect(function(input, gameprocess)
if not gameprocess then
    if input.KeyCode = Enum.KeyCode.E then
        ClassInfo[class].SecondaryAbility()
    elseif ... then
    end
end)
local module = {}
module.prototype = {}
local class = module.prototype
class.basePrimaryDamage = 10
class.PrimaryAbility = function()
 -- stuff
end
class.SecondaryAbility = function()
-- stuff
end
-- and so forth

return module
1 Like

Well, yes, you wouldn’t want to do that manually, but maybe with some sort of loop over your class folders. In any case, something along these lines might work, because indeed it’s not pretty to load a large number of possibly unused classes:

local ss = game:GetService("ServerStorage")
local allClasses = {}
local function getClass(className)
	
	if not className then 
		error("Error! No class name given!")
	end
	
	local myClass = allClasses[className]
	
	if not myClass then
		local classFolder = ss:FindFirstChild(className)
		if classFolder then
			local classModuleScript = classFolder:FindFirstChild(className)
			if classModuleScript and (classModuleScript.ClassName == "ModuleScript") then
				myClass = require(classModuleScript)
				allClasses[className] = myClass
			end
		end	
	end
	
	if not myClass then
		error("Unknown class name: "..className)
	end
	
	return myClass
end
1 Like

I figured I would just have the script require a module script that returns the data I want as a super collective of all the classes; thank you all for your help anyway.