I’ve created a VFX Manager in order to modularise a bunch of loose-hanging code responsible for applying effects in my game. It looks good but I’m dissatisfied almost exclusively with the way I’ve structured my init(ialisation) function. Something about it looks horrible.
The content of my init function looks like this:
local function init()
-- Collect common modules
cacheVFXModules(Common, script.Common)
-- Prepare CollectionService visualisers
cacheVFXModules(ObjectVFX, script.Objects)
CollectionService:GetInstanceAddedSignal(VFX_TAG):Connect(linkObjectVFX)
CollectionService:GetInstanceRemovedSignal(VFX_TAG):Connect(unlinkObjectVFX)
Common.FastSpawn(function ()
for _, object in ipairs(CollectionService:GetTagged(VFX_TAG)) do
linkObjectVFX(object)
end
end)
-- Prepare ambient visualisers
cacheVFXModules(AmbientVFX, script.Ambient)
Common.FastSpawn(function ()
for _, visualiser in ipairs(AmbientVFX) do
visualiser.Start()
end
end)
end
cacheVFXModules is a function that requires, wraps and places the immediate modules of a folder into a dictionary. It is split into two types: ambient (these are run automatically via their Start function and are typically for grouped, static or other types of items) and objects (these are explicitly linkable with CollectionService and usually apply to a single object directly via the Link function).
I feel like there’s a far better way to be handling these modules which is why I’ve brought over my code to Code Review. I’ve referenced a couple of frameworks and other code that also does caching and deploying like this, but they look way cleaner. Could just be my perfectionist voice speaking and this could be completely fine.
A third party to reassure me that this is okay or that it needs changes would be appreciated. Looking for substantiated, knowledgeable answers - no speculation, no unnecessary changes and no questions that can be researched on your own time. I will not be replying to any posts that aren’t related to reviewing code or obtaining relevant information. Please keep it focused. Thank you!
The full source is available below. Feel free to use it in your projects if it tickles your fancy as well, but you probably won’t find any good use for it:
--- Manages visual effects for certain items.
-- @author colbert2677
local CollectionService = game:GetService("CollectionService")
local Common = {}
local AmbientVFX = {}
local ObjectVFX = {}
local VFX_TAG = "Apply VFX"
local commonMeta = {__index = Common}
--- Store the immediate modules of a folder into a table
-- @param tbl the table to add the modules to
-- @param storage the folder containing the modules
local function cacheVFXModules(tbl, storage)
for _, module in ipairs(storage:GetChildren()) do
local content = require(module)
if module.Parent ~= script.Common then
setmetatable(content, commonMeta)
end
tbl[module.Name] = content
end
end
--- Link effects to an object
-- @param object a newly tagged object
local function linkObjectVFX(object)
local effects = ObjectVFX[object.Name]
if effects then
effects.Link(object)
end
end
--- Unlink effects from an object
-- @param object an object that was removed from a collection
local function unlinkObjectVFX(object)
local effects = ObjectVFX[object.Name]
if effects and effects.Unlink then
effects.Unlink(object)
end
end
--- Run the manager
local function init()
-- Collect common modules
cacheVFXModules(Common, script.Common)
-- Prepare CollectionService visualisers
cacheVFXModules(ObjectVFX, script.Objects)
CollectionService:GetInstanceAddedSignal(VFX_TAG):Connect(linkObjectVFX)
CollectionService:GetInstanceRemovedSignal(VFX_TAG):Connect(unlinkObjectVFX)
Common.FastSpawn(function ()
for _, object in ipairs(CollectionService:GetTagged(VFX_TAG)) do
linkObjectVFX(object)
end
end)
-- Prepare ambient visualisers
cacheVFXModules(AmbientVFX, script.Ambient)
Common.FastSpawn(function ()
for _, visualiser in ipairs(AmbientVFX) do
visualiser.Start()
end
end)
end
init()