Issues with using RemoteEvents to cross information for commands

I’m trying to make a simple command system for my mining game where I can run a command to give myself ores.

The issue is no matter what I do, when I run the command it’ll just show this error Unable to assign property Name. string expected, got nil

This is my code,

This is used in both scripts to get all ores in the game.

local OreTable = {}

for Index, Inst in ipairs(RS.StoneOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.LimestoneOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.GraniteOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.DioriteOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.SandstoneOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.ObsidianOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.CrackedLavaOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.MagmaOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.BedrockOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.LavaOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

for Index, Inst in ipairs(RS.JokeOres:GetChildren()) do
	if Inst:IsA("Part") then
		table.insert(OreTable, Inst.Name:lower())
	end
end

This is the serverscript

local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")

local Admins = {
	2510778054,
	43078752,
	190238857
}

local Prefix = "/"

game.Players.PlayerAdded:Connect(function(plr)
	local luck = Instance.new("IntValue", plr)
	luck.Name = "luck"
	luck.Value = -1
	
	if table.find(Admins, plr.UserId) then
		plr.Chatted:Connect(function(msg)
			local loweredString = string.lower(msg)
			local args = string.split(loweredString," ")
			if args[1] == Prefix.."walkspeed" then
				for _,player in pairs(game:GetService("Players"):GetPlayers()) do
					if string.sub(string.lower(player.Name), 1, string.len(args[2])) == string.lower(args[2]) then
						player.Character.Humanoid.WalkSpeed = args[3]
					end
				end
			elseif args[1] == Prefix.."luck" then
				for _,player in pairs(game:GetService("Players"):GetPlayers()) do
					if string.sub(string.lower(player.Name), 1, string.len(args[2])) == string.lower(args[2]) then
						player.luck.Value = args[3]
					end
				end
			elseif args[1] == Prefix.."give" then
				for _,player in pairs(game:GetService("Players"):GetPlayers()) do
					if string.sub(string.lower(player.Name), 1, string.len(args[2])) == string.lower(args[2]) then
						if args[4] == nil then args[4] = 1 end
						if table.find(OreTable, args[3]:lower()) then
							RS.Give:FireClient(player, {args[3], args[4]})
						else
							RS.Give:FireClient(player, {"NotFound"})
						end
					end
				end
			end
		end)
	end
end)

And this is the localscript.

local Inv = {}
local InventoryUI = player:WaitForChild("PlayerGui"):FindFirstChild("Inventory").Frame.ScrollingFrame

Players.PlayerAdded:Connect(function(plr)
	table.clear(Inv)
	for Index, Inst in ipairs(player.Inventory:GetChildren()) do
		if Inst:IsA("IntValue") then
			table.insert(Inv, Inst.Name)
		end
	end
end)

RS.Give.OnClientEvent:Connect(function(givestuff)
	if givestuff[1] == "NotFound" then
		game.TextChatService.TextChannels.RBXSystem:DisplaySystemMessage("<font color=\"rgb(255, 0, 0)\"><b>Ore not found.</b></font>")
	else
		if not table.find(Inv, givestuff[1]) then
			local newOre = Instance.new("IntValue", player.Inventory)
			newOre.Name = OreTable[tostring(givestuff[1])]
			newOre.Value = givestuff[2]

			local newTB = RS.TextButton:Clone()
			newTB.Parent = InventoryUI
			newTB.Name = OreTable[tostring(givestuff[1])]

			newTB.LayoutOrder = 0

			local gValue = 0
			newTB.UIGradient.Color = ColorSequence.new(Color3.fromRGB(255,255,255), Color3.fromRGB(33, 33, 33))

			newTB.oName.Text = table.find(OreTable, givestuff[1])
			newTB.oName.TextColor3 = Color3.fromRGB(255,255,255)

			newTB.oCount.Text = newOre.Value
		else
			local existingOre = player.Inventory:FindFirstChild(givestuff[1])
			local existingUIElement = InventoryUI:FindFirstChild(givestuff[1])

			local addingOn = existingOre.Value + givestuff[2]
			existingOre.Value = addingOn
			existingUIElement.oCount.Text = addingOn
		end
	end
end)

I’d appreciate any help.

Could you please state which code line you are receiving this error from?

Line 19 in the localscript.

And I’d assume all the other variables assigned to the same thing would bring the same error

I going to assume the error line you are stating is here

newOre.Name = OreTable[tostring(givestuff[1])]

Try printing ‘givestuff’ and ‘givestuff[1]’ right before creating the newOre IntValue, and see what prints out.

image
There’s the error but it shows what I believe should work unless I have to do something different to get the instance.

If the server is passing the correct table values, then I believe this issue has something to do with the ‘OreTable’ table in the LocalScript.
Is the OreTable table variable created in the LocalScript, or are you getting it some other way? Have you confirmed that the table isn’t actually nil? If ‘OreTable’ is not nil in the LocalScript, then have you checked if the value you are attempting to get is listed in the OreTable?

It looks like you’re trying index the array as if it was a dictionary. You need to use table.find like you do here on the server.

if tablefind(OreTable, args[3]:lower()) then

Even then, using that isn’t gonna do anything as table.find just returns the index position if found. You can just set the name to tostring(givestuff[1]). Or you can update your OreTable module to be dictionaries.

I tried switching the table to be a dictionary but it still doesn’t work.

image
I printed args[3] and givestuff[1] so it’s clearly a string, even when I tried doing

table.find(OreTable, tostring(givestuff[1]))

it still wouldn’t work saying the same exact error still.

I even tried to switch it back to

OreTable[givestuff[1]]

but still the same error.
I’m so confused

I am pretty confused about this problem. I suggest printing all the values you would use. That is, print:
OreTable
givestuff
givestuff[1]
OreTable[givestuff[1]]

And maybe there is a hint of cause of the of the error.

printing givestuff[1] gave the same result as args[3] (the ore name that I typed in the command)
but printing OreTable[givestuff[1]] just gave nil
I tried printing table.find(OreTable, givestuff[1]) but that also gave nil
I even tried doing tostring(givestuff[1]) in both things but same result.

I tried even making sure it’s not just an issue with my capitalization when I type in chat but typing the correct capitalization doesn’t work either so that’s not it.

bump!!!
I still haven’t figured it out

Did you print OreTable, which is the table you are trying to access?

So in your OreTable module, the table looks like this?

for Index, Inst in ipairs(RS.StoneOres:GetChildren()) do
	if Inst:IsA("Part") then
		OreTable[string.lower(Inst.Name)] = {};
	end
end

If you are getting nil from the client when accessing the table then that means either the table doesn’t exist, in the localscript you provided it looks like you aren’t even requiring the OreTable module but you could have omitted that portion of the script. It also could mean the givestuff parameter isn’t containing all the variables you need for some reason.

image
Yep, it has the ore name as the variable name

It’s not a modulescript, would it be more efficient for it to be a module script?

I’m not sure about more efficient, but it would be nice to have one shared module make the table, instead of having to make the table on the client and server somewhere, right? Less code, and you don’t have to update things in different places.

In that case I’ll just leave it as it is because I tried adapting it to a module script earlier and there was a lot of issues so I’ll just keep it to the individual scripts.

So now that’s out of the way, I’m still confused on how I can refer to the indexes because they should work??? I’m referring to the dictionary indexes with a string which is how they’re supposed to be right
I printed OreTable and the dictionary indexes were all their respective ore names. So I still don’t get what I’m doing wrong.

Assuming you kept your OreTable the same and it isn’t actually a dictionary, meaning you’re just inserting the names of the instances in there, then

newOre.Name = OreTable[tostring(givestuff[1])]

won’t work when indexing the table, because that table is an array, not a dictionary. You’d have to use something like OreTable[1] or OreTable[3], not a string