Sharing variables between modules

Hello. I’ve been developing on Roblox for awhile now but I’ve never actually attempted to optimize a game or anything like that. Now that I am attempting to do I have a question. I know you can share variables between scripts with several methods, such as:

  • shared
  • _G
  • Module Scripts

However, I’ve run into an issue while doing this. I want to have different modules that handle different things for the game, but I do not know how I should share variables or even if I should. I do not know if this would take up more memory:
module 1:

local Service = game:GetService("Service")

module 2:

local Service = game:GetService("Service") -- the same service the first module is using

or if something like this would be better:
shared module:

return {
	Service = game:GetService("Service"),
	-- Other stuff multiple modules need
}

modules that need the service:

local Service = require(PathToSharedModule).Service


So what I want is the best way to use the same service without increasing memory across multiple modules. If anyone has any knowledge about this then help would be appreciated!

This is called a Lazy Loader.

I’m not sure if having the same code in different modules increases memory. I use the “shared variables” technique just so I don’t have to write the same code multiple times, so it’s more of having an easier time coding rather than microoptimizing performance. There is actually less memory used with this technique because it only calls require() on modules that are needed immediately, instead of just requiring every module since you don’t know when you will use them.

Here’s the place with my lazy loader script:
Core.rbxl (25.7 KB)

How it works is that there is a module script in ReplicatedStorage called Core that will hold every single variable from every module. So, you can do easy things like:

local core = require(game:GetService("ReplicatedStorage"):WaitForChild("Core"))

core.RunService:BindToRenderStep("renderStuff", Enum.RenderPriority.Camera.Value + 2, function()
    -- Code
end)

Furthermore, you’ll notice that there are folders and modules underneath the script. My module will automatically find and require any script or folder underneath it, if the given path is correct. The script in StarterPlayer → StarterPlayerScripts demonstrates this, but you could also do something like:

local core = require(game:GetService("ReplicatedStorage"):WaitForChild("Core"))
local dictionary = {
    Pie = "Yummy",
    Complex = {
        {"One", "Two", "Three"},
        Artifact = "Legendary"
    },
    "OBC"
}

local clone = core.Table.deepCopy(dictionary)

My module also keeps a reference to every child of ReplicatedStorage on launch just to make getting assets easier like “core.Assets.Gun:Clone()” or “core.Themes.Blue” if you have Assets/Themes folders under ReplicatedStorage.

1 Like

GetService is somewhat analogous to require in the way it doesn’t compile modules until the first require, and returns a singleton to not have to recompile for subsequent requires. GetService will start a service that isnt already running the first time you get it, then return the singleton reference to that service for every subsequent GetService call.

Some people use service loaders but I find them to be tedious. GetService is accessible globally so theres no having to require a module. You’re replacing 1 line of code with 1 line of code which feels moot imo.