What is _G and for what i can use it?

The thing is, you would have to ensure that whatever code you wrote to put those service variables into _G ran before anything else that uses that service variable. You could do this by putting loops to check if the service variable has been instantiated in every script that uses it, but that’s no better than a simple require.

3 Likes

You wouldn’t need loops to check to see if the variable is declared if the script runs first, yes, but if you’re going to assign the service to a variable at the top of the script then pass it to the module scripts as an argument, _G should work better. A module script must be required before the code inside it can be run from a script and using _G on lines before the script is required would almost certainly work if only one script is requiring those modules.

Some people prefer to compartmentalize their code if it becomes too complex.

3 Likes

I’ve thought about that a lot. If you ask me, using global for constant values that are read-only doesn’t sound like a bad idea (though as mentioned you have to make sure the code that assigns it runs first)
It strikes me as the same kind of use as putting “pure” functions in there. Not much can go wrong if there’s only one place that could be defining it so you won’t end up with any run-away errors whose origin can’t be easily tracked.

2 Likes

Thank you, this is very useful!

One thing I don’t think was mentioned but I think could be an excellent use for the _G variable, is using the _G variable to create custom parts within your game. I could be wrong here but it seems like a good way of doing it.

This post explained all about _G

1 Like

Is it bad practice to make a global value that represents the localplayer?

Yes. You can already access the LocalPlayer conveniently as a property of the Players service across any LocalScript. If you have a framework, you can store a reference to the LocalPlayer in your framework table when it’s passed around/attached to other code. There’s virtually no need to use _G for this.

2 Likes

i meant when serverscripts want to access the player

Still no because LocalPlayer isn’t set on the server and shared/_G don’t replicate across environments. If the server needs to interact with a player there’s a good chance your system will be able to give the player over or you can index them in the Players service directly by name or otherwise.

is there a circumstance where _G should be used, even if it’s very situational?

Never. There is never a case where you need to, should or should want to use _G. Only very old games may encounter situational cases where it’s useful to expose something to _G and they don’t have the capacity to fully rework systems (yet). New work will never have this problem and as such should never be using _G. ModuleScripts cover every use case _G originally had and can be better tailored for your game’s structure.

1 Like

reminder that you should use modulescripts instead of using _G.
it’s fine to use it for executing code from the developer console

e.x. _G.dothisfunctioninsideofascript(…)

I’m not sure if this is considered bad on my end. In my frameworks, I store Utility modules inside of _G.Utilities, some of these modules include:

  • Welding
  • Animation
  • Tweening

Is this considered bad practice? I find it extremely useful; as I don’t have to require the function in every script.


Edit:

After reading this, I realized I could easily store all of the Utility modules inside of well, a ModuleScript that returns a table.

3 Likes

You’ll have to do some sort of polling like repeat wait() until _G.Utilities because you can’t guarantee it will be set in other scripts. Race conditions can be nasty. You also don’t get good autocomplete. You shouldn’t use something solely out of “convenience” (notice the quotes!) – it can backfire.

4 Likes

In most of the scripts I’m using, _G.Utilities has already loaded, but that is something to take into account. I’ll move toward ModuleScripts holding utility modules.

If you go in a server script and put

_G.PlayerName = "LightBeam_Studio"

Then in a local script do

print(_G.PlayerNane)

Would this work?

No, there is a separate table on every machine. Modules and attributes might prove to be better for this

Is _G's metatable locked? If not you could use __newindex to handle that possibly;

1 Like

Now you are unnecessarily complicating your code just for this. _G doesn’t even have a metatable as far as I am aware, but it would be several times easier to just use modules at that point

1 Like