Hi everyone! I’m pretty new to roblox scripting, but a common trend I’ve noticed in experienced developers is that they always use the single script architecture. I’ve heard that it’s a good way to make sure your scripts are executed in order, preventing errors from stuff not loading and the like.
I’m currently using multiple scripts for each action in my personal project, and I often find bugs like GetChildren() not getting all children because it wasn’t loaded, and often had to put multiple waits inside of my script. I think that this is bad practice, and changing to module loaders would help with this. Here are my questions:
Should I really use module loaders for my game? (I’ve seen people said that it is bad coding practice, and hard to expand on, although I do not understand why)
What are the possible cons for this? I know that it removes Intellisense, but other than that I’m not aware of any other negatives.
I’d be very thankful if someone could answer these questions for me!
Knit sounds like something you are looking for. I recommend using it, but if you want your own, you can take a look at the source code and use it as a reference.
Unless you use single script to manipulate things more dirrectly dont go for it.
Don’t forget the fact you have 200 variables limit per stack + it completelly makes you unable to use parallel Luau as since you need multiple scripts and actors for that.
Sure you can localize it via:
do
end
But if its for a “sake of it” its not only not worth it but is also hurmful.
You should be focusing on a moderate OOP+functional programming and parallel programming as a main foundation for your game.
You should be trusting the code you write otherwise you are doing something wrong.
Its not only bloatware as bad but its just stuipid
That totally fair how people call it a bad coding practice
You need to use only module scripts that you need to not exghaust stack and load time;
More over i strongly advice you to cache module script functions like:
local module = require("./MyModule")
local Func1 = module.MyFunction
Althrought DONT DO THAT WITH LUAU GLOBAL VARIABLES!
I’ve been experimenting with ModuleLoaders recently, and I agree with you on point 2 that the removal of intellisense is annoying. Currently, I use them to run :init() and :start() methods in my code. I still require them as I normally would. Here’s one of my most recent ModuleLoader drafts:
--!strict
--------------
-- SERVICES --
--------------
local ServerScriptService = game:GetService("ServerScriptService")
-----------
-- TYPES --
-----------
type RequiredModule = {[any]: ()->()}
---------------
-- CONSTANTS --
---------------
local MODULES = ServerScriptService.Modules
---------------
-- VARIABLES --
---------------
---------------
-- FUNCTIONS --
---------------
local function verifyIsModule(module: ModuleScript)
local moduleType = module.ClassName
if moduleType ~= "ModuleScript" then
error("Expected module, received: " .. moduleType)
end
end
local function checkRunStart(module: ModuleScript): ()
verifyIsModule(module)
local requiredModule = require(module) :: RequiredModule
if requiredModule["start"] then
requiredModule["start"]()
end
end
local function checkRunInit(requiredModule: RequiredModule): ()
if requiredModule["init"] then
requiredModule["init"]()
end
end
local function manageModule(module: ModuleScript): ()
verifyIsModule(module)
local requiredModule = require(module) :: RequiredModule
checkRunInit(requiredModule)
end
local function startup(): ()
for _, moduleScript in ipairs(MODULES:GetChildren() :: { ModuleScript }) do
manageModule(moduleScript)
end
for _, moduleScript in ipairs(MODULES:GetChildren() :: { ModuleScript }) do
task.spawn(checkRunStart, moduleScript)
end
end
---------------
-- EXECUTION --
---------------
startup()
-------------
-- CLOSING --
-------------
For reference, i use :init() to establish connections and :start() to run code in each module.