_G Global Variables Help!

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want to access a name in a table from a _G variable
  2. What is the issue? Include screenshots / videos if possible!
    ServerScriptService.Payment:4: attempt to index nil with ‘Name’
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I tried remove Name from _G.hosts.Name but it just gives me a bunch of numbers and letters that I am guessing is the id of the table but I want to get the names of players in the table hosts.
    After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
-- This is an example Lua code block (Server Side)
local remote = game.ReplicatedStorage.RemoteEvents:WaitForChild("UserBoughtItem")
local logLabel = game.StarterGui.ScreenGui.Frame.ScrollingFrame:WaitForChild("logs")
local Time_Of_Purchase = os.date("%x")
local host = _G.hosts.Name
remote.OnServerEvent:Connect(function(player, perkId)
	print(host)
	remote:FireClient(host)
end)

--Other server side
_G.hosts = {"DelphinusTheDev", "Cartiergems"}
local perksOpenGui = game.StarterGui.OpenPerks


local function loopPlayers()
	for i, v in pairs(game.Players:GetChildren()) do
		if v then
			if table.find(_G.hosts, v.Name) then
				print("Player is in host table")
				perksOpenGui.Parent = v.PlayerGui
				perksOpenGui.Enabled = true
			else
				print("Player not found in host table")
			end
		end
	end
end

game.Players.PlayerAdded:Connect(loopPlayers)

Please do not ask people to write entire scripts or design entire systems for you. If you can't answer the three questions above, you should probably pick a different category.

Is it possible that _G.hosts hasn’t been created yet?

No it has if you look at the server script code below the first server script.

Carrying on from a discussion we had earlier, this is another reason why I don’t endorse use of _G, though this has more to do with your structuring and not with _G. It’s just that in using _G you have the potential to develop bad habits or overlook things that could otherwise be easily avoided.

Like the above post mentioned, you’re running into a race condition where the script that tries to access _G.hosts runs before the script that sets _G.hosts, so _G.hosts doesn’t exist to the remote script yet. You can quickly resolve this issue by waiting until hosts exists through a while loop:

while not _G.hosts do task.wait() end

If you had a ModuleScript that had your names written in and then required that, you wouldn’t have this issue. You could also combine these scripts since they’re related systems and then make hosts a local variable that’d be immediately accessible to subsequent scopes/lines after its declaration.

That being said, that’s not the end. There’s still a plethora of other practice problems and errors that you’ll run into with this code. Here’s to name them, potentially not extensively:

  • When working with interfaces do so from the client. StarterGui is only a container that holds elements that are later copied over to PlayerGui. It is not visible and its children are not interactable.

  • Use GetService when working with services. It’s more idiomatic and gives you a sense of consistency when working with other services that don’t share a Name with their ClassName (e.g. RunService is Run Service in the Workspace).

  • Not too sure what the remote’s doing, but you’re looking to fire to a host client right? You’d need an actual player instance for that. Right now, your current code - in the assumption that _G.hosts.Name would be a string - would throw an error. FireClient expects a Player instance as the first argument which is the client to deliver the event to.

  • Use UserIds when working with special grants. Usernames can change but UserIds are permanently tied to an account. If you’re too lazy, you can use GetUserIdFromNameAsync but I don’t particularly recommend it… you could cut out the internal web call and just use the UserId directly so that you can read off the Player’s UserId when looping players.

  • GetPlayers is idiomatic over GetChildren when getting players in the game. ipairs is more idiomatic for iterating arrays (which GetPlayers returns) over pairs which is better for tables with arbitrary keys (dictionaries). I do believe ipairs is also faster.

  • You’ll want to clone the PerksOpenGui in loop players, otherwise it’ll pass around the copy in StarterGui directly to PlayerGui to the next eligible player. When loopPlayersis called again and there’s an eligible player, it’ll be taken from the last player who had it and given to the new player with all states (like Gui visibility) retained.

You’re welcome to take this advice, do a bit of research and create a new code sample that works best for your use case.

3 Likes

Geez… I really have to recode EVERYTHING???

When your talking about the starterGui I know its a container for the instances inside of it but when I don’t parent the gui inside of starterGui to player the gui textlabels doesn’t display the text for me unless I parent it to playerGui.

For your last bullet wdym clone it in loop it is?

Also, thank you for your help.

Rather than parenting OpenPerks from StarterGui (which’ll already get parented to PlayerGui anyway since it exists there), you can instead clone it from another container (e.g. ReplicatedStorage) to players who should be eligible to receive it.

local function playerAdded(player)
    -- if table.find(hosts, player's name/uid)
    -- clone the Gui from, say, ReplicatedStorage
    -- enable it, then parent it to player's gui
end

Players.PlayerAdded:Connect(playerAdded)
for _, player in ipairs(Players:GetPlayers()) do
    playerAdded(player)
end
1 Like

This will fix the problem of the gui parenting to another player when they join the game?

Also, for some reason when I don’t parent the gui to the playerGui the text doesn’t update for me only when I parent it will update.

can you reply to me please… ?

They will reply when they can, and if they want to. It isn’t their duty to reply, and although it would be polite to respond at some point, they don’t have to, and may just be doing something else and will reply later.

1 Like