_G for functions, is it good?

I want to use _G, as modulescripts always need to require and it’s pretty annoying, so _G would be like modulescripts without requiring.

What I do know:

This fact proven to be wrong:
_G is slower than modulescripts

Fact to be right:
_G could make you do minor mistakes, such as another script using _G and overwrites the important value

But it’s gonna be like modulescripts, what’s gonna be wrong with it? 1 script will just write g functions.

_G.Scripts = {
Mango = function()
print("Mango")
end,
Mongus = function()
print("Mongus")
end
}

-- other script

_G.Scripts.Mango()

So is it still safe/good to do or not?

2 Likes

they aren’t slower than module scripts nor are they faster, they’re about the same speed

the only con about _G is that exploiters may be able to access it & you may overwrite variables

This article should answer your question:

What is _G and for what i can use it? - Help and Feedback / Scripting Support - DevForum | Roblox

What I take from it is that there is no difference whatsoever in terms of speed between utilising _G or ModuleScripts, but that using _G can fall to issues with backdooring.

I mean I’m not gonna write it again in another script so it should be fine


So the main con is exploiters can access it, can they read it? Also can you prevent them from using it?

The only risk I see with using _G is other scripts might load before the script that assigns data to _G runs.

If you are using it on the client sure, but they can’t on the server unless you give them direct access to do so.

When people make this claim I find it strange because you can overwrite data even if you were to use modules. Basically just know what you’re doing and it’s fine. But if you could give a specific example of something like this that is an issue exclusive to _G?

Could you elaborate on this a little more?

4 Likes

i’m not 100% sure if exploiters can read it since i’m not an exploiter nor do i know much about client/server boundaries

however i’ll assume if for example _G.dog = "dog" was made on the server, on the client it will be seen as nil


i’m not 100% sure about this sorry, I was just taking information from other threads

1 Like

So it shouldn’t be a problem them as I’ll mainly use it for servers. I’d like to here more people’s opinions or advice.

1 Like

Yeah using it on the server an exploiter shouldn’t be able to access it

If you aren’t going to write to the data again after it’s first assignment you just have to make sure the script that assigns the data runs completely before other scripts try to access _G.

Good idea, the script accessing the g could be loaded before the script assigning the g.

I’m not really familiar with exploiters manipulating data, that information is what I gathered from the article itself, since many people mentioned it in the replies.

I might seem like an idiot but which article?

What is _G and for what i can use it? - #2 by quebecwhat

Oh okay

But I see people below saying that _G is not replicated across the server-client, if you assign a global variable in server and client can’t access

_G isn’t shared across the network so I don’t really see how that could be an issue. Although I kind of see what you are saying because any client can change the _G data on their device, so you just have to be careful using it on the client or only store data that affects maybe something like client settings.

Using it on the server is completely safe though; the only issue being different load times with scripts (also an issue on client).

Actually afaik, unless an exploiter can hook into the client VM (not saying this is completely impossible), _G is pretty secure.

Its 100% secure on the server.

However, you should not be using _G due to the issues of race conditions, Roblox loading order when it comes to scripts is undefined. Since _G exists on the VM stack the same way a module would, it would be much better to use a module as you can add extra functionality into the module to control when it loads

_G.Hello = "Hello World!"
print(_G.Hello) --> nil, oh no this script ran first

if you have implicit control over script loading order by encapsulating the scripts in ModuleScripts with a single loader script, since the loading order can be guaranteed, it’s safe to use _G in this case

local scripts = {
  script._GVariableSetter,
  script._GVariableReader
}

Another place where it’s safe to use _G is inside event handlers, since they’ll never run straight away.

1 Like

Race conditions wouldn’t be an issue if you don’t plan on modifying the data after first assignment.

Dont understand what you mean here, the OP wants to use _G to hold functions and call them, which means you need to read the table.

_G.TimesSaidHello = 0
function _G:SayHello()
  self.TimesSaidHello += 1
  print("Hello World")
end
_G:SayHello() --> attempt to call nil value

This is only an issue if the declaration happens in the same resumption cycle as it’s called in.

This code is safe, since we guarantee that the value is set beforehand

task.wait() --makes the thread wait a resumption cycle
_G:SayHello() --> Hello World

So this means I have to task.wait if I don’t expect _G script to be loaded right?

_G.Scripts = {
Yes = function()
print("yes")
end
}

--another script
task.wait()
_G.Scripts.Yes()

If you’re setting the value of _G within a script with no yields (waits), you can safely task.wait in any other scripts to ensure that the data is set.

If you want to add an extra level of safety, you can wrap access to _G in a while loop

local scripts = _G.Scripts
while not scripts then
  task.wait()
  scripts = _G.Scripts
end