Game bugs out with this error code when someone else joins or leaves

So my game is a zombie survival game where the player survives and goes to the next wave, everything works fine solo but when someone joins or leaves it stops the repeat loop and breaks everything, am so confused, please help!

This shows the wave stopping and not doing the loop of going to the next wave. Is this error causing my game to break?

line 101 is

v.Character:MoveTo(spawns[i].Position)

local roundMsg = game.ReplicatedStorage.Values:WaitForChild("roundMsg")
local zombieCount = game.ReplicatedStorage.Values:WaitForChild("zombiesRemaining")
local zombiesAlive = game.ReplicatedStorage.Values:WaitForChild("zombiesAlive")
local gameInProgress = game.ReplicatedStorage.Values:WaitForChild("gameInProgress")
local wave = game.ReplicatedStorage.Values:WaitForChild("Wave")
local collectionservice = game:GetService("CollectionService")

local Complete = game.Workspace["Level Complete"]

Maps = game.ServerStorage.Maps:GetChildren()

game.Players.PlayerRemoving:Connect(function(player)
	collectionservice:AddTag(player.Character, "Dead")
end)

while true do
	roundMsg.Value = "Waiting for enough players"
	repeat wait(1) until game.Players.NumPlayers >= 1
	
    for i = 10,0,-1 do
        roundMsg.Value = "Game Starting in: "..i
        if i == 1 then
         roundMsg.Value = "Choosing map..."
		wait(2)
		ranGame = math.random(1, #Maps)
		gameChosen = Maps[ranGame]
		roundMsg.Value = "Map chosen: " .. gameChosen.Name
		wait(2)
		gameChosenClone = gameChosen:Clone()
		gameChosenClone.Parent = workspace.Map
		wait(2)
for i, v in pairs(workspace.Map:FindFirstChildOfClass("Model"):GetChildren()) do
	if v.Name == "Spawner" then
		collectionservice:AddTag(v, "Spawner")
	end
end
wait()

spawns = gameChosenClone.Spawns:GetChildren()
wait()
for i, v in pairs(game.Players:GetPlayers()) do
	name = v.Name
	wait()
	check = game.Workspace:FindFirstChild(name)
	if check then
		checkHumanoid = check:findFirstChild("Humanoid")
		wait()
		if checkHumanoid then
			wait()
		v.Character:MoveTo(spawns[i].Position)
		wait()
		collectionservice:AddTag(v.Character, "Alive")
		
			
		end
	end
           end

            roundMsg.Value = "Game In Progress"
            zombieCount.Value = 6
            zombiesAlive.Value = 6
            wave.Value = 1
            gameInProgress.Value = true
       
            repeat
game.Players.PlayerRemoving:Connect(function(player)
	wait()
collectionservice:AddTag(player.Character, "Dead")
end)
                if #collectionservice:GetTagged("Alive") > 0 then
	wait()
                    if zombiesAlive.Value == 0 then
	for i, v in pairs(workspace.Map:GetDescendants()) do
		wait()
		if v.Name == "ZED" then
			wait()
			collectionservice:AddTag(v, "ZED")
			wait()
			v:Destroy()	
		end
	end	
                        wave.Value = wave.Value + 1
                        Complete:Play()
                        wait(2)
                        zombieCount.Value = 6 * wave.Value
                        zombiesAlive.Value = 6 * wave.Value
            for i, v in pairs(game.Players:GetPlayers()) do
	wait()
collectionservice:AddTag(v.Character, "Alive")
wait()
name = v.Name
wait()
check = game.Workspace:FindFirstChild(name)
wait()
if check then
	wait()
checkHumanoid = check:findFirstChild("Humanoid")
wait()
if checkHumanoid then
	wait()
v.Character:MoveTo(spawns[i].Position)
wait()
end
end
        end
           end
                    elseif #collectionservice:GetTagged("Alive") == 0 then
	wait()
                    gameInProgress = false
                end
                wait(1)
            until gameInProgress == false or #collectionservice:GetTagged("Alive") == 0
wait()
for i, player in pairs(game.Players:GetPlayers()) do
wait(1)
player:LoadCharacter()
wait()
end
wait()
gameChosenClone:Destroy()
        end
    wait(1)
    end
end

What is happening is that ‘i’ is retrieving a nil value from the spawns array, then it’s attempting to index ‘.Position’ from the nil value, which is whats throwing the error. That being said, the value of ‘i’ is likely greater then the amount of spawns inside the array. So what you’re going to want to do, is provide an extra check within your code to make sure the spawn you’re indexing from the array exists before you move the player’s character to the spawn the code has defined.


Going to be a critic here as well: You appear to be using an absurd amount of unneeded wait()s inside your code. To provide an example of what place has the unneeded waits. On lines 94 to 110. Every other line provided in that section of code, is wait(). Which really, only makes the script take longer in doing what it is supposed to do.

As well to mention: On the repeat loop that begins at line 72. You’re connecting the PlayerRemoving event to a function every time the the loop repeats itself. Which can cause a memory leak, which you absolutely do not want. The event’s function also adds a tag to the player’s character when the player is leaving the game. Which when a player does, their character is destroyed. So really, that part of code also isn’t needed.

2 Likes

So what your saying is there are more players than there is more spawn points should i add more spawns?
Also how would i provide an extra check, what would it look like?

Adding more spawns is an option you can do. However as mentioned before, you can implement checks in order to make sure the value accessed is not and will not be nil, come the time the piece of code is called. Possibly the easier one to do is to utilize math.random() to define what value you would like to index from the table. To provide an example of how to do so.

local chosenSpawn = Spawns[math.random(1, #Spawns)]

This would ensure that the number indexing the array is never to be larger then the amount of objects inside the array. As it would pick a random number between one and the amount in the array.