Here is my custom-made module loader! I have a tagging system which I now realize (from my testing) doesn’t have much of a use, but I mainly made this module loader with customization in mind, and i need advice for improvement.
local loader = {}
local require = require
-------CONST VARIABLES------ (These are just some basic directories if you didn't want to reference them)
loader.generic_client_directories = {
game:GetService("StarterPlayer").StarterPlayerScripts,
game:GetService("StarterPlayer").StarterCharacterScripts,
game:GetService("ReplicatedStorage")
}
loader.generic_server_directories = {
game:GetService("ReplicatedStorage"),
game:GetService("ServerStorage"), --FYI Depending on the circumstance ServerStorage may not be where you want to execute scripts
game:GetService("ServerScriptService")
}
loader.generic_methods = {
"Init",
"Start"
}
-------VARIABLES--------
local modulePrintTag = "("..string.upper(script.Name).."): "
local methodFinishedTag = "_"..math.random(1111,9999) --The reason why this exists is so that the key is different than the methodname.
--Attempts to execute the method in a module, and prints any warnings/errors
function loader.attemptMethod(methodName : string, module : {},...)
if loader.hasFinishedMethod(methodName, module) then
warn(modulePrintTag.."Attempted to execute "..methodName.."() in module ["..module._name.."] but it has already been executed!")
return
end
if module[methodName] then --If the module has the method
local success, errorMessage = pcall(module[methodName],...) --PCALL the method in the module
if not success then
--Failed
warn(modulePrintTag..methodName.."() in module ["..module._name.."] failed to be executed! Error Message : ")
error(errorMessage)
else
--Finished
loader.setFinishedMethod(methodName, module)
print(modulePrintTag.."Method "..methodName.."() in module ["..module._name.."] has executed successfully! :D")
end
else
--No method in module
warn(modulePrintTag.."Couldn't find "..methodName.."() in module ["..module._name.."]")
end
end
--Attempts to execute the method for each module in a table
function loader.attemptMassMethodCall(methodName : string, mods : {},...)
print(modulePrintTag.."Attempting a mass method call of "..methodName.."() in #"..#mods)
for i,module in pairs(mods) do
loader.attemptMethod(methodName,module,...)
end
end
--Gets a table of modules found in the descendences of the inputted folders
function loader.requireModulesInFolders(folders : {Instance} | Instance) : {}
local mods = {}
if type(folders) ~= "table" then
folders = {folders}
end
for _,directory in pairs(folders) do
for _,child in pairs(directory:GetDescendants()) do
if child:IsA("ModuleScript") then --Goes through every module script
local req = require(child)
if type(req) ~= "table" then
continue
end
req._name = child.Name
--Add other variables here! (Make sure to put a _ before any vars as you don't want multiple methods/variables with the same name)
----------------------
table.insert(mods,req)
end
end
end
return mods
end
--Returns true if the module has already executed the method with the name
function loader.hasFinishedMethod(methodName : string, module)
local tag = methodFinishedTag..methodName --Unique completion tag for the method Ex: module._1234Init = true so it wont call Init again. Just a useful procotion.
if module[tag] == true then
return true
end
return false
end
--Checks that the module has completed the method with name
function loader.setFinishedMethod(methodName : string, module)
local tag = methodFinishedTag..methodName
module[tag] = true
end
function loader.simpleLoad()
local isClient = game:GetService("RunService"):IsClient()
local directories : {Instance}
if isClient then
directories = loader.generic_client_directories
else
directories = loader.generic_server_directories
end
local modules = loader.requireModulesInFolders(directories)
for _,method in loader.generic_methods do
loader.attemptMassMethodCall(method,modules)
end
end
return loader
ISSUES
I have a simpleLoad() method that is suppose to go through all the common folders you would have modules in, but for the StarterPlayerScripts there are lots of modules which kinda messes everything up, and I was hoping for any advice on like a exclude list or something like that.
I want more convenience, just two or three lines of code and your game is loaded.
Example of a client-side script as you can see it has a lot of bloat (Mainly the directories)
local LoaderModule = require(game:GetService("ReplicatedStorage"):WaitForChild("Module Service"))
local directories = {
game:GetService("StarterPlayer").StarterPlayerScripts:WaitForChild("Modules", 1),
game:GetService("StarterPlayer").StarterPlayerScripts:WaitForChild("Events", 1),
game:GetService("StarterPlayer").StarterCharacterScripts
}
local modules = LoaderModule.requireModulesInFolders(directories)
LoaderModule.attemptMassMethodCall("Init",modules)
LoaderModule.attemptMassMethodCall("Start",modules)
--Example of adding Custom Method Calls for events
local player = game:GetService("Players").LocalPlayer
local char: Model = player.Character or player.CharacterAdded:Wait()
local humanoid: Humanoid? = char:FindFirstChildOfClass("Humanoid")
LoaderModule.attemptMassMethodCall("CharacterLoaded",modules, char, humanoid) --attemptMassMethodCall(methodName,modules,...)
23:10:56.370 (MODULE SERVICE): Attempting a mass method call of Init() in #2 - Client - Module Service:52
23:10:56.370 (MODULE SERVICE): Method Init() in module [CameraScript] has executed successfully! :D - Client - Module Service:42
23:10:56.371 (MODULE SERVICE): Method Init() in module [Animate] has executed successfully! :D - Client - Module Service:42
23:10:56.371 (MODULE SERVICE): Attempting a mass method call of Start() in #2 - Client - Module Service:52
23:10:56.371 (MODULE SERVICE): Couldn't find Start() in module [CameraScript] - Client - Module Service:46
23:10:56.371 (MODULE SERVICE): Method Start() in module [Animate] has executed successfully! :D - Client - Module Service:42
23:10:56.371 (MODULE SERVICE): Attempting a mass method call of CharacterLoaded() in #2 - Client - Module Service:52
23:10:56.371 (MODULE SERVICE): Method CharacterLoaded() in module [CameraScript] has executed successfully! :D - Client - Module Service:42
23:10:56.372 (MODULE SERVICE): Couldn't find CharacterLoaded() in module [Animate] - Client - Module Service:46
Any suggestions are appreciated