Hello,
I seen _G in some scripts and my question is:
What is it?
For what i can use it and how?
Hello,
I seen _G in some scripts and my question is:
What is it?
For what i can use it and how?
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â
It allows you to create shared variables so you do not have to define them in every script.
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.
Useful
Thanks for info.
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.
Doesnât it let exploiters also access _G from a local script, and potentially leading to exploiters changing values, for example player money?
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
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.
Does that make it possible to store functions? Like a module script?
_G == Global local thing
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)
_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.
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?
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.
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?
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.
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.
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?
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?