Use of module functions to store variables and firing functions

Variables module:

local var = {}

var.runService = game:GetService('RunService')
var.userInputService = game:GetService('UserInputService')

var.editCam = false
var.button2Down = false

var.WDown = false
var.ADown = false
var.SDown = false
var.DDown = false
var.QDown = false
var.EDown = false

var.plotRegion3 = nil
var.regionPoint1 = nil
var.regionPoint2 = nil
var.cameraRegion3 = nil

var.camera = workspace.CurrentCamera
var.plots = workspace:WaitForChild('Plots')

return var

Seperate module

local moveCamera = {}

local var = require(script.Parent.Var)

function moveCamera:Move()
	if var.editCam then

    end
end

return moveCamera

Another module

var.runService.RenderStepped:Connect(function()
	moveCamera:Move()
end)

My main question would be is this the appropriate way to store variables that would be check from multiple modules? It doesnā€™t look nice to have ā€˜var.ā€™ for before every single variable, but I donā€™t how else to do it.

Also with calling the function from one module to another. Is it possible to just have a module store one function, and whenever itā€™s required or called it runs that function? Also seems strange to call the Module MoveCamera, then have the function in it Move, moveCamera:Move() ultimately I would like to just do something like moveCamera() but having to also put down the name of function seems kinda redundant, when the module already has that name. Also donā€™t wanna do moveCamera:MoveCamera() cause that looks even more stupid

1 Like

I donā€™t think Iā€™ve ever had to have that many public variables in a module. You should consider putting the data close to the module that actually needs it, and these services should just be acquired at the top of each module where they are used. Youā€™re introducing coupling for no reason if you have everything refer back to this ā€œvarā€ table.

If you really canā€™t do without so many public variables, then write it like this:

local var = {
   editCam = false,
   button2Down = false,
   WDown = false,
   (...)
}

What do you mean by coupling?

As for having so many, I didnā€™t wanna keep referencing the same variables in every single script at the top (like camera, etc.)

1 Like

Every script that uses UserInputService through this module is now coupled to it. If you make a change to this var module, it potentially affects a lot of other modules that you would need to edit. If you want to take this module elsewhere, you need to decouple it from ā€œvarā€ or also transfer ā€œvarā€ along with it. You donā€™t want high coupling in your code base.

This is understandable but you will find that referencing the services in the modules that actually need them will make your code easier to understand and modify when you need to come back to it after not having touched it for a while, or if you want to reuse a module in a different game. You wonā€™t need to rewrite the module to not use this ā€œvarā€ module that way if it already is self-contained.

1 Like

Ok, I put the services in each of the scripts, I see what you mean now, and changed the variables to be inside the var = {} at the top of the module, however, they still require var.VARIABLE_NAME. Am I stuck to using that?

It is possible to avoid using ā€œvar.VARIABLE_NAMEā€ every time if you mess around with getfenv() and setfenv(), but itā€™s very messy and probably not reliable. Also, using getfenv and setfenv to share variables duplicates the variables, so changes made to them do not occur in other connected scripts. I recommend that you just stick with putting ā€œvar.ā€ before each variable.

Personally, I donā€™t like your solution. Adding tables just makes your code more complicated (although in some ways it can feel organised). But it is also acting like a disorganized dump for variables.

I prefer to organise things using do blocks. If I have a single function that uses lots of variables, instead of adding them to the global scope I just stick everything in a do block, and magically :star2: it becomes organised in the human brain.

If I have issues with having too many variables, my solution usually works like this:

local GlobalVariable1

local Something do
    local RelevantVariable1
    local RelevantVariable2

    Something = function()
        print(RelevantVariable1, RelevantVariable2)
    end
end

Something()

Let me break it down for you. GlobalVariable1 is a variable that gets used by multiple parts of the script. Think of a service you would use in lots of different situations (e.g. ReplicatedStorage).

local Something do is great. It allows you to define Something in the global scope so it can be used by other parts of the script, and the do allows you to define variables and do other things within a scope related only to the Something variable (that is, if you are staying organised). It also lets you name a do block, which is great because

do
   LotsOfStuffHere
end

is real ugly and uninformative in my opinion.

Inside the Something block two variables are defined. Since they are local, they canā€™t be used outside of the do block, which is great for variables that will only get used by the Something function.

As you now know, the Something variable is actually a function, and this is where the organisation shines. You can split up your code (and therefore your variables) into their own relevant, self-contained places. It can make your code easier to understand and work with.

Hereā€™s an example of this in the context of changing a gameā€™s scene (ignore the validity of the shorthand stuff):

local ChangeLighting do
    local Lighting = game:GetService("Lighting")
    local ColorCorrection = Instance.new("ColorCorrection", Lighting)

    ChangeLighting = function(NewLighting) end
end

local InsertMap do
    local MapFolder = workspace.Map
    local CurrentMap = MapFolder.Lobby    

    InsertMap = function(NewMap) end
end

local ChangeScene = function(NewLighting, NewMap)
    ChangeLighting(NewLighting)
    InsertMap(NewMap)
end

I only consider the solution of using a ModuleScript for variables useful when you have actual code you need to share ā€“ as duplicate code is no good. I have modules in my game for retrieving items for ReplicatedStorage, enabling/disabling certain types of input, calculating stats, etc.

But, itā€™s often better when scripting to know what a variable is at a glance (instead of having to navigate to another script) and you donā€™t want to get into dependency hell or anything like that ā€“ so I donā€™t really have any variables in a module.

Either way, itā€™s ultimately up to you. You want to find an environment you can work the best in (with the least amount of work on your end possible, too).

5 Likes