Global or local variables?

In a case like this, which one is better?

local a = false
if a == false then
a = true
end

Or

a = false
If a == false then
a = true

If opition number 1 is better, when should I ever use global variables?

1 Like

there is no reason to use a global variable ever ngl

1 Like

Kind of depends on what you’re doing. Typically you want to localize the variable, but in an instance of using recursion you’d want to have it global (but then again, the variable for the function could be pre-defined as a local variable)

-- local changeAllPartsToHi
function changeAllPartsToHi(p)
    for _, v in ipairs(p:children()) do
        if v.className == "Part" then
            v.Name = "Hi"
        end
        changeAllPartsToHi(v)
    end
end

EDIT

No.

I barely touch studio anymore so my knowledge is based off of years-old experience. Back then to utilize recursion you had to do it as I’d written it out, otherwise it would throw an exception about how changeAllPartsToHi was nil. If Roblox had changed that, then color me surprised.

Refer to the above ¯_(ツ)_/¯

Alternatively you could pre-define the variable as a local one before that, similar to the function example I gave.

local funnyMoment;
function funnyMoment(prt)
    local conn;
    conn = prt.Touched:Connect(function()
        conn:Disconnect()
        print("Hey, I'm talking here!")
    end)
    wait(2)
    funnyMoment(prt)
end

funnyMoment(Workspace.BasePlate)
1 Like

Global, 100%

_G is love, _G is life

Global variable is just if you want a value that you can access in multiple different scripts

Never use global variables. Many reasons to do this, one of them is this:

x = 5
getfenv()["x"] = "EVIL VALUE" -- x is now EVIL VALUE.
x += 5 -- We think that x is still a number, but now it is a string, and this will error at runtime.
print(`X is {x}`)

Another reason is global variables have a performance cost because they have to be put into the globals table.

Those are still local variables; they just aren’t prefixed with local.

1 Like

Is it different in Studio?

Variables must be explicitly defined as “local” to be local variables.

The difference between the two, to Luau, is that locals can be optimized out (i.e. “inlined”) or referenced by an ID, instead of by their name. This is why script decompilers cannot extract the names of local variables and instead leave them as, for example, v_122. I believe this optimization is disabled when you use getfenv/setfenv/loadstring.

1 Like

It’s recommended to never use global variables.

Anything you can do with global variables you can do with local ones, but the code is much clearer with local variables.


By the canonical definition of local variables in CS, variables defined in for loops like that are local: they can’t be accessed outside the scope of the loop and don’t affect the variables outside the loop.

This is simply illustrated with this code:

local i = -1

for i = 1, 10 do
    print(i)
end

print(i)
-- -1

I was under the impression omega was referring to the function itself, instead of the variables in the loop. My mistake.

What I was going to say

But we are referring to local variables in terms of Luau, which has an explicit keyword for them

local a = 0
local b = 0

-- create a new scope
do
	a = 1
	local b = 2
end

-- prints "1 0"
print(a, b)

Demo - Luau

1 Like

Variables are cool.

In Luau, you’ll often see most scripts rely on local to define the scope of their variable, whether it be in the scope of just a for loop, or the entire script! For example:

local coolStringVariable = "hi there!"

for i = 1, 10 do
    local otherStringVar = "woah."
    print(otherStringVar.." "..coolStringVariable)
end

In this script, otherStringVar can only be used within the context of the for loop. However, by defining coolStringVariable on the first lines, and just plainly on the script, we’re allowed to use it! Sweet.

While you could call it like this instead…

coolStringVariable = "hi there!"

For readability and style purposes, it’s typically recommended not to do that. It can get hard to identify and parse through when you’re dealing with huge scripts later on.

As for global variables across the entire project, if you need them, Roblox has the _G library that you can call upon and use to store variables across various scripts on the server or client. To use it:

--> Script 1
_G.testing = "this is another way!"


--> Script 2
print(_G.testing) --> this is another way!

:warning: However, it’s also advised strongly against using _G. One primary reason being that it becomes very difficult to maintain and understand what you’ve defined under it. The better and preferred way of accomplishing this is by simply using the ObjectValue, StringValue, and other Value objects that Roblox provides, and referring to those within your scripts. That way, you can get the usage of a global variable, while also being able to more readily identify and look through it in the Explorer.

TL;DR: To help make your code cleaner and readable, use local even if technically not needed. If you want fully global variables of some sort, I’d look into the Value objects that Roblox provides.

Lot of info in here that is either wrong or irrelevant and some other stuff which is relevant not even brought up so, here we go:

Global or Local? More importantly why?

  • Local, but not always.

From the wiki:

  1. Luau accesses global variables and functions with a hash lookup, so it’s expensive to use in terms of performance. Using a global variable in a time-critical loop can make it perform more than 10% slower than using a local variable in the same loop.

  2. Luau disposes of local variables after their scope ends, reducing memory usage.

  3. You can access global variables and functions within the same script, but not between multiple scripts. Therefore, a global variable or function doesn’t provide any benefit over an in-scope local equivalent, an upvalue, or a shadow.

Basically local variables have more benefits and less drawbacks at no additional cost

So when to use global?

  • In short, recursive functions.

^ You can just define the function as local and call it still, thus this is less efficient than if you were to make it local:

local function thisStillWorks()
	task.wait(1)
	if math.random(1,2) > 1 then
		print('huzzah')
		thisStillWorks()
	end
end
thisStillWorks()

Alternatively, this code will break if you make the globalVar local:

globalVar = workspace.Baseplate.Touched:Connect(function()
	if globalVar then 
		globalVar:Disconnect() 
	end
end)

Ignoring the part about the global table (_G) – which the original post does not mention and thus is not relevant here – you shouldn’t use local variables with the expectation that they cant be exloited; getfenv can just recursively parse any lower level functions that it returns and keep looking for the variable you’ve declared locally until it identifies it and can adjust as desired.

tl;dr Local variables can be cracked all the same as global

In Summary

local variables offer performance benefits over global, and while not inherently safer than using global variables, they do offer more obfuscation when buried in functions

2 Likes