What is _G and for what i can use it?

Hello,

I seen _G in some scripts and my question is:
What is it?
For what i can use it and how?

138 Likes

You can access variables from different server side scripts.
If you have this in one script

_G.player = "player"

and this in another

print(_G.player)

it will print “player”

43 Likes

It allows you to create shared variables so you do not have to define them in every script.

35 Likes

If you know what module scripts are, _G is basicly the default ‘module’ script.
_G is a table, so you can assign it keys and values like any other table, but the special thing about _G is that it saves cross-script.
Let’s say you have 2 scripts. In the first script you write:

local LocalValue = "This is not saved across scripts"
_G.GlobalValue = "This is saved across scripts"

Now if you have another script with the following:

print(LocalValue) --this will print nil, localvalue was only defined in the other script
print(_G.GlobalValue) --this will print 'This is saved across scripts' because that's how _G works

_G can be usefull for storing things like player money, usually you have multiple scripts which need to know how much money a player has. So with _G you can easily store that across scripts.

--script 1
_G.PlayerCash = 10 --gives the player 10 cash
--script 2
_G.PlayerCash = _G.PlayerCash + 5 --adds 5 to player cash
--script 3
print(_G.PlayerCash) --prints out 15

In short: _G is a table which saves across scripts.
If you heared of module scripts, _G is basicly that.

Important thing to note:
_G IS NOT SLOWER THAN MODULESCRIPTS. It makes no difference if you use _G or require(modulescript) both do the exact same thing and both are as fast.

324 Likes

Useful :slight_smile:
Thanks for info.

11 Likes

A little something I’d like to comment on.

This is not saved across scopes, with exceptions to upvalues.*

When you have a local variable in your script that isn’t under any function or whatever, this is called an upvalue. It’s essentially a local variable to the scope of the main executing body. If you open a new scope (function, do, then, etc) and create a local variable in there, they aren’t accessible out-of-scope.

20 Likes

Doesn’t it let exploiters also access _G from a local script, and potentially leading to exploiters changing values, for example player money?

13 Likes

Not sure the reason for the bump but the point is you should never use _G and instead make your code be more modular in nature. Yes exploiters can modify the _G on their machine

9 Likes

Yes, a client could change _G values - but they could equally do this for your scripts values.

You shouldn’t trust the client to have control of their own money value.

11 Likes

Does that make it possible to store functions? Like a module script?

3 Likes

_G == Global local thing

2 Likes

Yes, you can use functions using _G. Heres an example.

function _G.FunctionNameHere(argument)
-- run code here
end

To use the function, heres how.

_G.FunctionNameHere(argument)
8 Likes

_G is not shared between the client and server. Because of that (as others have stated) it’s not different than any other variable exploiters could modify. Use server sanity checks when needed for security and avoid using _G.

13 Likes

I don’t understand why it’s unsafe to use _G. If it’s not shared across the network doesn’t that mean the _G on a server script is safe? Is using things such as module scripts or bindable functions on a localscript really safer than using _G? Aren’t they all vulnerable?

14 Likes

Apologies for not being clear, but I say “avoid using _G” because it’s bad practice, not due to any safety reasons.

You can find a lot of resources online about why you should avoid them. For example, design patterns - Why is Global State so Evil? - Software Engineering Stack Exchange.

10 Likes

Interesting read. I didn’t really know about _G until recently so I haven’t picked up any bad habits like using it instead of function parameters thankfully.
You say avoid using _G. Does that mean it would be ok to do things such as to define general isolated “pure” functions for use (IE Roblox Lua doesn’t have a math.round or math.lerp, would it make sense to define such functions in _G?) or would that still be bad practice?

3 Likes

I think that’s fine given it’s a very generic/broad helper function which isn’t doing something difficult to track/understand (like passing a global variable around that gets read from and modified in multiple scripts). Although, it’s possible to put those functions in a module script for that purpose too.

2 Likes

I just find it tedious to have many lengthy references at the start of my scripts to multiple modules nested deep in folders just to have basic features that more advanced engines come pre-built with such as the mindnumbing ability to lerp a float so that’s why I got excited when I learned of _G.
The less development time I spend doing the same thing over and over such as redefining basic functions or writing out lengthy require()s the better.

6 Likes

So if you make

_G.player = "player"

It is no longer able to be used across the platform if you try to reference it to be something different?

2 Likes

I had a thought when I came across this thread again after a while. Using _G is said to be terrible because using variables in the global scope can result in them being unpredictably modified by methods. I was going to ask this and Noobot9k had beat me to it already to some degree, but what if we’re dealing with values that are read only?

Say I have a script that requires several module scripts. Each module script requires the same service. Instead of getting the service over and over again and assigning it to a short variable in each script, couldn’t I simply make those service variables global? I’m sure that I could call that service directly and even declare the service once at the top of the script and then pass it to the module script functions as an argument but would using _G here be any worse?