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.