Why is this occasionally indexing as nil

For some reason, sometimes the character is being indexed as nil. Even though he’s still alive for some reason, the character is being indexed as nil

Script
local status = game:GetService("ReplicatedStorage"):WaitForChild("Status")
local serverstorage = game:GetService("ServerStorage")
local inround = game.ReplicatedStorage:WaitForChild("InRound")
local intermissionlength = 10
local increment = 1
local goal = 0
local roundlength = 10
local highest
local teams = game:GetService("Teams")
local playing = teams:WaitForChild("Playing")
local lobby = teams:WaitForChild("Lobby")
local playerservice = game.Players
local obj
local deathmatch = false
local won = false
local eventlength = 2
function resetround()
	roundlength = 10
end
function resetintermission()
	intermissionlength = 10
end
function resetevent()
	eventlength = 2
end
function awardcoins(plr, input)
	print(plr.Name)
	print(plr.ClassName)
	plr:WaitForChild("leaderstats"):WaitForChild("Coins").Value += input
end
function awardlevels(plr, input)
	plr:WaitForChild("Levels"):WaitForChild("Exp").Value += input
end
local clone
local clone1
inround.Changed:Connect(function()
	if inround.Value == true and #playerservice:GetChildren() > 1 then
		for i,v in pairs(playerservice:GetChildren()) do
			local char = v.Character or v:LoadCharacter()
			char.HumanoidRootPart.CFrame = workspace.Goal.CFrame
			v.Team = playing
			
		end
		while true do
			task.wait(1)
			if #playerservice:GetChildren() <= 1 then
				deathmatch = false
				status.Value = "Not enough players to start the game!"
			end
			if inround.Value == false then
				break
			end
			eventlength -=1
			if deathmatch == true then
				status.Value = "Death match ends in: ".. roundlength .. " seconds"
			else
				status.Value = "Next event in: ".. eventlength .. " seconds"
				if eventlength == goal then
					if clone ~= nil then
						clone:Destroy()
					end
					if clone1 ~= nil then
						clone1:Destroy()
					end
					local random = math.random(1,2)
					if random == 1 then
						--clone = tornado:Clone()
						--clone.Parent = workspace
						status.Value = "Event is low gravity"
					elseif random == 2 then
						--clone1 = tsunami:Clone()
						--clone1.Parent = workspace
						status.Value = "Event is tsunami"
					end
					resetevent()
				end
			end
			roundlength -= increment
			if roundlength == 0 then
				for i,v in pairs(playing:GetPlayers()) do
					for i,v in pairs(v.Character:GetChildren()) do
						if not highest then
							highest = v.Parent.Tag.Value
							continue
						end
						if  v.Parent.Tag.Value	 > highest then
						highest = v.Parent.Tag.Value
						obj = v.Parent.Tag
						end
					end
					if obj ~= nil then
						
						---v.Character.Humanoid.Health = 0

						status.Value = "And ".. obj.Parent.Name .. " is the winner!"
						print(obj.Name)
						print(obj.Parent.Name)
						awardcoins(game:GetService("Players"):FindFirstChild(obj.Parent.Name), 150)
						deathmatch = false
						inround.Value = false
						resetevent()
						resetround()
					end

				end
			end
			if roundlength == goal then
				if clone ~= nil then
					clone:Destroy()
				end
				if clone1 ~= nil then
					clone1:Destroy()
				end
				inround.Value = false
				resetround()
				break
			end
		end
	elseif inround.Value == false and #playerservice:GetChildren() > 1 then
		for i,v in pairs(playerservice:GetChildren()) do
			local char =  v:LoadCharacter() or v.Character
			char:WaitForChild("HumanoidRootPart").CFrame = workspace.Spectator.CFrame
			v.Team = lobby
		end
		while true do
			if #playerservice:GetChildren() <= 1 then
				status.Value = "Not enough players to start the game!"
				resetintermission()
			end
			task.wait(1)
			status.Value = "Intermission: ".. intermissionlength .. " seconds"
			intermissionlength -= increment
			if intermissionlength == goal then
				inround.Value = true
				intermissionlength = 10
				break
			end
		end
	end
end)
game.Players.PlayerAdded:Connect(function()
	if #playerservice:GetChildren() <= 1 then
		status.Value = "Not enough players to start the game!"
		resetintermission()
		resetround()
	else
		inround.Value = false
	end
end)
game.Players.PlayerRemoving:Connect(function()
	if #playerservice:GetChildren() <= 1 then
		resetintermission()
		resetround()
		status.Value = "Not enough players to start the game!"
	end
end)

Sometimes it happens in random lines like this one
char.HumanoidRootPart.CFrame = workspace.Goal.CFrame

But it’s mainly happening here even though the script literally asked if variable ‘obj’ was nil and there’s no reason for the character to not be present.

			if obj ~= nil then
						
						---v.Character.Humanoid.Health = 0

						status.Value = "And ".. obj.Parent.Name .. " is the winner!"
						print(obj.Name)
						print(obj.Parent.Name)

Maybe it’s a problem with the variable ‘obj’ but it’s also happening with the line I stated above, please help.

2 Likes

Looks like some other scripts are also doing the same thing. This a roblox problem?

Hi! I don’t have all information about your problem, can you please show us more information about your code?

Edit:
I think HumanoidRootPart just didn’t load in second case

What information are you looking for in particular?

How code works. Like what’s obj variable? How it sets? When it sets?

Full Script
local status = game:GetService("ReplicatedStorage"):WaitForChild("Status")
local serverstorage = game:GetService("ServerStorage")
local inround = game.ReplicatedStorage:WaitForChild("InRound")
local intermissionlength = 10
local increment = 1
local goal = 0
local roundlength = 10
local highest
local teams = game:GetService("Teams")
local playing = teams:WaitForChild("Playing")
local lobby = teams:WaitForChild("Lobby")
local playerservice = game.Players
local obj
local deathmatch = false
local won = false
local eventlength = 2
function resetround()
	roundlength = 10
end
function resetintermission()
	intermissionlength = 10
end
function resetevent()
	eventlength = 2
end
function awardcoins(plr, input)
	print(plr.Name)
	print(plr.ClassName)
	plr:WaitForChild("leaderstats"):WaitForChild("Coins").Value += input
end
function awardlevels(plr, input)
	plr:WaitForChild("Levels"):WaitForChild("Exp").Value += input
end
local clone
local clone1
inround.Changed:Connect(function()
	if inround.Value == true and #playerservice:GetChildren() > 1 then
		for i,v in pairs(playerservice:GetChildren()) do
			local char = v.Character or v:LoadCharacter()
			char.HumanoidRootPart.CFrame = workspace.Goal.CFrame
			v.Team = playing
			
		end
		while true do
			task.wait(1)
			if #playerservice:GetChildren() <= 1 then
				deathmatch = false
				status.Value = "Not enough players to start the game!"
			end
			if inround.Value == false then
				break
			end
			eventlength -=1
			if deathmatch == true then
				status.Value = "Death match ends in: ".. roundlength .. " seconds"
			else
				status.Value = "Next event in: ".. eventlength .. " seconds"
				if eventlength == goal then
					if clone ~= nil then
						clone:Destroy()
					end
					if clone1 ~= nil then
						clone1:Destroy()
					end
					local random = math.random(1,2)
					if random == 1 then
						--clone = tornado:Clone()
						--clone.Parent = workspace
						status.Value = "Event is low gravity"
					elseif random == 2 then
						--clone1 = tsunami:Clone()
						--clone1.Parent = workspace
						status.Value = "Event is tsunami"
					end
					resetevent()
				end
			end
			roundlength -= increment
			if roundlength == 0 then
				for i,v in pairs(playing:GetPlayers()) do
					for i,v in pairs(v.Character:GetChildren()) do
						if not highest then
							highest = v.Parent.Tag.Value
							continue
						end
						if  v.Parent.Tag.Value	 > highest then
						highest = v.Parent.Tag.Value
						obj = v.Parent.Tag
						end
					end
					if obj ~= nil then
						
						---v.Character.Humanoid.Health = 0

						status.Value = "And ".. obj.Parent.Name .. " is the winner!"
						print(obj.Name)
						print(obj.Parent.Name)
						awardcoins(game:GetService("Players"):FindFirstChild(obj.Parent.Name), 150)
						deathmatch = false
						inround.Value = false
						resetevent()
						resetround()
					end

				end
			end
			if roundlength == goal then
				if clone ~= nil then
					clone:Destroy()
				end
				if clone1 ~= nil then
					clone1:Destroy()
				end
				inround.Value = false
				resetround()
				break
			end
		end
	elseif inround.Value == false and #playerservice:GetChildren() > 1 then
		for i,v in pairs(playerservice:GetChildren()) do
			local char =  v:LoadCharacter() or v.Character
			char:WaitForChild("HumanoidRootPart").CFrame = workspace.Spectator.CFrame
			v.Team = lobby
		end
		while true do
			if #playerservice:GetChildren() <= 1 then
				status.Value = "Not enough players to start the game!"
				resetintermission()
			end
			task.wait(1)
			status.Value = "Intermission: ".. intermissionlength .. " seconds"
			intermissionlength -= increment
			if intermissionlength == goal then
				inround.Value = true
				intermissionlength = 10
				break
			end
		end
	end
end)
game.Players.PlayerAdded:Connect(function()
	if #playerservice:GetChildren() <= 1 then
		status.Value = "Not enough players to start the game!"
		resetintermission()
		resetround()
	else
		inround.Value = false
	end
end)
game.Players.PlayerRemoving:Connect(function()
	if #playerservice:GetChildren() <= 1 then
		resetintermission()
		resetround()
		status.Value = "Not enough players to start the game!"
	end
end)

These lines show how the variable is set

if roundlength == 0 then
				for i,v in pairs(playing:GetPlayers()) do
					for i,v in pairs(v.Character:GetChildren()) do
						if not highest then
							highest = v.Parent.Tag.Value
							continue
						end
						if  v.Parent.Tag.Value	 > highest then
						highest = v.Parent.Tag.Value
						obj = v.Parent.Tag
						end
					end
					if obj ~= nil then
						
						---v.Character.Humanoid.Health = 0

						status.Value = "And ".. obj.Parent.Name .. " is the winner!"
						print(obj.Name)
						print(obj.Parent.Name)
						awardcoins(game:GetService("Players"):FindFirstChild(obj.Parent.Name), 150)
						deathmatch = false
						inround.Value = false
						resetevent()
						resetround()
					end

try waiting for the HumanoidRootPart

char:WaitForChild("HumanoidRootPart").CFrame = workspace.Goal.CFrame

That worked but what about the other one why is that still happening?


For more info, tag has to be inside something for it to exist, IM SO CONFUSED.

I did some tests and discovered EXTREMELY weird thing

print(obj.Parent) <<<<<<<Here
if obj ~= nil then
	---v.Character.Humanoid.Health = 0
	status.Value = "And ".. obj.Parent.Name .. " is the winner!"
	print(obj.Name)

For some reason, if you add print(obj.Parent) before if obj ~= nil then then error never occur

I think we should ask the Roblox staff about this