Error in script

Hey, I was scripting my game and ran into an error ServerScriptService.OrbSystem:40: attempt to index nil with 'GetAttribute'
in this script

local Min
local Max
if v.Name == "DoubleJumpOrb" then
	Min = Mode:GetAttribute("DoubleJumpOrbsMin")
	Max = Mode:GetAttribute("DoubleJumpOrbMax")
elseif v.Name == "SwiftnessOrb" then
	Min = Mode:GetAttribute("SwiftnessOrbsMin")
	Max = Mode:GetAttribute("SwiftnessOrbsMax")
elseif v.Name == "DashOrb" then
	Min = Mode:GetAttribute("DashOrbsMin")
	Max = Mode:GetAttribute("DashOrbsMax")
elseif v.Name == "LowGravityOrb" then
	Min = Mode:GetAttribute("LowGravityOrbsMin") -- Error in this line
	Max = Mode:GetAttribute("LowGravityOrbsMax")
end


Mode in the script refers to the above Folder

1 Like

Can you send the whole script?

1 Like

Is the attribute definitely name “LowGravityOrbsMin”? Are there any rogue spaces in the work tree name? Copy and paste the name into the script from the work tree and see if they match exactlly? Or maybe we need to see the calling convention to this bit of code.

1 Like

it’s a long script but anyways

local OrbSystem = {}
OrbSystem.__index = OrbSystem

OrbSystem.Orbs = {}
OrbSystem.PlayersWithOrb = {}

function OrbSystem:SpawnOrbs(Mode, Bombs)
	local Tiles = game.Workspace.Map.Tiles:GetChildren()
	for i, v in pairs(OrbSystem.Orbs) do
		if table.find(Tiles, v) then
			table.remove(Tiles, table.find(Tiles, v))
		end
	end
	--for i, v in pairs(Bombs) do
	--	if table.find(Tiles, v) then
	--		table.remove(Tiles, table.find(Tiles, v))
	--	end
	--end
	game.Workspace.Orbs:ClearAllChildren()
	
	for i, v in pairs(game:GetService("ServerStorage"):WaitForChild("Orbs"):GetChildren()) do
		local Min
		local Max
		if v.Name == "DoubleJumpOrb" then
			Min = Mode:GetAttribute("DoubleJumpOrbsMin")
			Max = Mode:GetAttribute("DoubleJumpOrbMax")
		elseif v.Name == "SwiftnessOrb" then
			Min = Mode:GetAttribute("SwiftnessOrbsMin")
			Max = Mode:GetAttribute("SwiftnessOrbsMax")
		elseif v.Name == "DashOrb" then
			Min = Mode:GetAttribute("DashOrbsMin")
			Max = Mode:GetAttribute("DashOrbsMax")
		elseif v.Name == "LowGravityOrb" then
			Min = Mode:GetAttribute("LowGravityOrbsMin") -- Error in this line
			Max = Mode:GetAttribute("LowGravityOrbsMax")
		end
		if Max ~= 0 then
			for i = math.random(Min, Max), 1, -1 do
				if #Tiles >= 1 then
					local RndTile = Tiles[math.random(1, #Tiles)].Hitbox
					table.insert(OrbSystem.SpawnOrbs(), RndTile.Parent)
					local Clone = v:Clone()
					Clone.Parent = game.Workspace.Orbs
					Clone:MoveTo(RndTile.Position + Vector3.new(0, RndTile.Size.Y / 2 + Clone.Hitbox.Size.Y / 2 - 0.8, 0))
					for i, v in pairs(Clone:GetChildren()) do
						if v:IsA("Part") or v:IsA("MeshPart") then
							v.CanTouch = true
						end
					end
				end
			end
		end
	end
	
	for i, v in pairs(game.Workspace.Orbs:GetChildren()) do
		v.Hitbox.Touched:Connect(function(v1)
			if v1.Parent:FindFirstChild("Humanoid") ~= nil then
				if not table.find(OrbSystem.PlayersWithOrb, v1.Parent.Name) and table.find(BombSystem.PlayersWithBomb, v1.Parent.Name) then
					table.insert(OrbSystem.PlayersWithOrb, v1.Parent.Name)
					task.defer(function()
						task.wait(v:GetAttribute("AbilityTime") + 0.5)
						table.remove(OrbSystem.PlayersWithOrb, table.find(OrbSystem.PlayersWithOrb, v1.Parent.Name))
					end)
					if v.Name == "DoubleJumpOrb" then
						RemoteEvent:FireClient(game.Players:FindFirstChild(v1.Parent.Name), "Ability", v.Name, v:GetAttribute("AbilityTime"), v:GetAttribute("TimeToRefil"))
					elseif v.Name == "SwiftnessOrb" then
						RemoteEvent:FireClient(game.Players:FindFirstChild(v1.Parent.Name), "Ability", v.Name, v:GetAttribute("AbilityTime"), v:GetAttribute("SpeedMultiply"), v:GetAttribute("MultiplyWhenShpinting"))
					elseif v.Name == "DashOrb" then
						RemoteEvent:FireClient(game.Players:FindFirstChild(v1.Parent.Name), "Ability", v.Name, v:GetAttribute("AbilityTime"), v:GetAttribute("TimeToRefil"), v:GetAttribute("DashAnimation"))
					elseif v.Name == "LowGravityOrb" then
						RemoteEvent:FireClient(game.Players:FindFirstChild(v1.Parent.Name), "Ability", v.Name, v:GetAttribute("AbilityTime"), v:GetAttribute("LowGrav_FallAnim"))
					end
					for a, b in pairs(v:GetChildren()) do
						if b:IsA("Part") or b:IsA("MeshPart") then
							game:GetService("TweenService"):Create(b, TweenInfo.new(0.2, Enum.EasingStyle.Quint, Enum.EasingDirection.In, 0), {Size = Vector3.new(0, 0, 0)}):Play()
						end
					end
					task.wait(0.2)
					v:Destroy()
				end
			end
		end)
	end
end

return OrbSystem

yep, I copied and pasted itself…
here is the full code

Okay cool, was a little behind on the typing there. This is not a solution but I never understand why people choose to call a search function twice, just assign it on the first search and check its validity, i.e.:

	for i, v in pairs(OrbSystem.Orbs) do
		if table.find(Tiles, v) then
			table.remove(Tiles, table.find(Tiles, v))-- why the second search?
		end
	end

Not too inefficient with a handful of things, but it is still bad practice. It will never allow a piece of code to be scalable to include millions of things. This should be:

	for i, v in pairs(OrbSystem.Orbs) do
		local foundTile =  table.find(Tiles, v);
		if foundTile then
			table.remove(Tiles, foundTile);
		end
	end
1 Like

and not sure why but I am also getting an error in the second loop which I have turned into a comment (error before turning into a comment). This is how I called the function

OrbSystem.Orbs = {}
BombSystem.Bombs = {}
OrbSystem:SpawnOrbs(MatchSystem.Mode, BombSystem.Bombs)
BombSystem:SpawnBombs(MatchSystem.Mode, OrbSystem.Orbs)

and the error is ServerScriptService.OrbSystem:21: invalid argument #1 to 'pairs' (table expected, got nil)

Now this is tricky, I’ve never been sure if Lua passes by reference or by value. The second error might be coming in because the first loop has removed all of the elements from the local copy of Tiles that is being accessed by iterating Bombs. There is an external declaration of OrbSystem.Orbs in the calling script (i.e. the bit that is not in the ModuleScript) but the ModuleScript also has a reference to OrbSystem.Orbs. And it is obvious that BombSystem has a reference to OrbSystem.Orbs passed in which is the local calling one and not the one contained in the ModuleScript. Hard to tell without the full code what exactly is happening here.

1 Like

but the OrbSystem.Orbs table is an empty table, so it should not remove anything from the Tiles and I tried removing the first loop and still ran into the same error

Line 21 in the long script is here:

for i, v in pairs(game:GetService("ServerStorage"):WaitForChild("Orbs"):GetChildren()) do

This again is a concatenated function, try to avoid this, the #1 may be a return simply meaning success. Which is not a table to be iterated?

The error means that Mode does not exist. How are you calling the function?

I’m not sure, Mode could be nil, the code errors before Mode is even accessed.

From OP’s original post, the error occurs WHEN Mode is accessed.

Yeah I know, but it is not on line 21 though, something occurs that is causing a segmentation fault by the time it gets to any access of Mode. This should not error, it should only return nil:

Min = Mode:GetAttribute("LowGravityOrbsMin") -- Error in this line

As long as we deal with Min accordingly it should never error, unless Mode is nil.

unless Mode is nil.

Which it must be.

OP, can you please do print(Mode) prior to the if statements?

Whether Mode is nil or not, the code crashes when the earlier loop is uncommented. That must mean some logic flaw is trouncing the memory beforehand. I have yet to see the contents of Mode so it may well be that, but in my eyes there is something else at fault here.

Anyway, I hope you can sort it because it’s close to 3am here and I’m going to sleep. Good luck!

MatchSystem.Mode = game:GetService("ServerStorage"):WaitForChild("Maps"):FindFirstChild("Leader")

image
so the mode ain’t nil

Can you please put the print statement in? It’ll help to identify at what point in the script Mode stops existing

1 Like

umm I tried it, it’s kinda weird, the script from where the function is called works fine, the module script is kinda weird, it prints the name then it gives error in the same line


print statement : print(Mode.Name, Bombs) (line 14)

I believe that it is because the first time the function is called, the mode exists, but the second time, the mode DOESN’T exist. Can you check if you are calling the function anywhere where it isn’t meant to be called?