I’ve a module ( only using it for organization ) and I decided to add a function in my for loop.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local UpgradeUI = PlayerGui:WaitForChild("UpgradeUI")
local Frame = UpgradeUI.Frame
local CloseBTN = Frame.CloseFrame.Close
local Buttons = {CloseBTN}
local function loop()
for _, Button in ipairs(Buttons) do
if Button.Name == CloseBTN then
ReplicatedStorage.Audio.ClickSound:Play()
UpgradeUI.Enabled = false
end
end
end
loop()
return loop
Returning most non-table values from a ModuleScript instance is acceptable given that anyone involved with the project understands that not every ModuleScript instance returns a table, deviating from the typical convention.
There are plenty of compelling reasons to return a single function from a ModuleScript; the main reason is for readability. Assume we have a function, named “debounce”, and this function takes some other input function designed as an event handler. This “debounce” function returns a wrapped version of said input function that only cares about the end state; effectively, applying the theory of debouncing as one would expect without all of the boilerplate typically involved.
Given this “debounce” function, in a vacuum, there is no apparent namespace to group it under as opposed to common patterns such as “async”, “log”, or “string” as it is a singleton. Therefore, importing it directly as opposed to having some extraneous name resolution benefits the project as a whole, removing any possible confusion as well as strengthening readability.
Now, taking this idea into the context given, there are no clear reasons why this function got decoupled in the first place; it is unlikely this is the only code directly interfacing with the listed buttons. If that assumption is correct, then this is not a compelling case for returning a single function.
Modularity should get advocated for, but separating non-scalable specific game logic of one aspect of a project across multiple ModuleScript instances seems excessive enough to damage the project’s maintainability.
As an aside, this module having a side-effect is not beneficial either. When importing a function to disable a UI element, it is not intuitive to believe it gets called once upon its first time it gets loaded.
Ergo, if it gets decided to decouple logic in such incremental parts, the call to the function should be removed after the declaration.