Ending game when too many zombies or clock runs out

I was trying to make a game in which you need to close zombie spawners or you lose the game if there are too many zombies or the timer runs out. The code below has the zombie spawner and when I touch 3 parts it will delete the spawner and no more zombies come out. How do I make it to where there is a counter showing all players the zombie count and lets say if 15 zombies come out you lose the game, or lose the game if the timer runs out in 5 minutes and you win the game if you close the spawner? I tried looking for videos on youtube literally all day yesterday and couldnā€™t really find anything.

    local spawns = script.Parent
local spawn_time = 5

local part1 = workspace.Part1
local part2 = workspace.Part2
local part3 = workspace.Part3


local Part1Enabled = false
local Part2Enabled = false
local Part3Enabled = false

local PartsTouched = 0

part1.Touched:Connect(function(Hit)
    if Part1Enabled == false then
        Part1Enabled = true
        PartsTouched += 1
    end
end)

part2.Touched:Connect(function(Hit)
    if Part2Enabled == false then
        Part2Enabled = true
        PartsTouched += 1
    end
end)

part3.Touched:Connect(function(Hit)
    if Part3Enabled == false then
        Part3Enabled = true
		PartsTouched += 1
	end
end)

while PartsTouched ~= 3 do
	
	wait(spawn_time)
	
	for _, spwn in pairs(spawns:GetChildren()) do
		
        if spwn:IsA("BasePart") then
		    local zombieCopy = game.ReplicatedStorage['Zombie']:Clone()
			zombieCopy.Parent = game.Workspace
			zombieCopy.HumanoidRootPart.CFrame = CFrame.new(spwn.Position + Vector3.new(0,3,0))	
			
		end	
		
	end
	
	
end

spawns:Destroy()
1 Like

There are a couple of ways you could go about this, but Iā€™ll just start with the simple one

You can reference a couple of variables at the start of your script, and inside your while PartsTouched ~= 3 do loop you can also check if there are too much zombies, or if the time is over

    local spawns = script.Parent
local spawn_time = 5
local MaxZombieLimit = 25
local CurrentZombies = 0

local TimeRemaining = 30 --Relies every 5 seconds, so 30 * 5 = 150 seconds I believe

local part1 = workspace.Part1
local part2 = workspace.Part2
local part3 = workspace.Part3


local Part1Enabled = false
local Part2Enabled = false
local Part3Enabled = false

local PartsTouched = 0

part1.Touched:Connect(function(Hit)
    if Part1Enabled == false then
        Part1Enabled = true
        PartsTouched += 1
    end
end)

part2.Touched:Connect(function(Hit)
    if Part2Enabled == false then
        Part2Enabled = true
        PartsTouched += 1
    end
end)

part3.Touched:Connect(function(Hit)
    if Part3Enabled == false then
        Part3Enabled = true
		PartsTouched += 1
	end
end)

while PartsTouched ~= 3 do
	
	wait(spawn_time)
	TimeRemaining -= 1
	for _, spwn in pairs(spawns:GetChildren()) do
		
        if spwn:IsA("BasePart") then
		    local zombieCopy = game.ReplicatedStorage['Zombie']:Clone()
			zombieCopy.Parent = game.Workspace
			zombieCopy.HumanoidRootPart.CFrame = CFrame.new(spwn.Position + Vector3.new(0,3,0))	
            CurrentZombies += 1
		end	
		
	end
	if CurrentZombies > MaxZombieLimit or TimeRemaining == 0 then
        break --This would break the loop, then removing the spawns
    end
	
end

spawns:Destroy()
1 Like

Is there a way to make the game end once it reaches the zombie limit, the time runs out or you touch the 3 parts? How do I display the time and number of zombies?

1 Like

Thatā€™s what itā€™s literally doing though

If you want to display the amount of time remaining, youā€™d have to calculate it on a different script if you want to count the amount of seconds & zombies

You could use a IntValue inside ReplicatedStorage that would detect the changes using a GUI Object from the client side, create a LocalScript inside a UI that would show the time & remaining zombies

local TimeLeft = game.ReplicatedStorage:WatiForChild("TimeLeft")
local ZombiesLeft = game.ReplicatedStorage:WaitForChild("ZombiesLeft")
local MainUI = script.Parent

TimeLeft.Changed:Connect(function(NewValue)
    MainUI.Time.Text = NewValue
end)

ZombiesLeft.Changed:Connect(function(NewValue)
    MainUI.Zombies.Text = NewValue
end)
1 Like

I went to Starter GUI, Screen GUI, Local script and pasted that code. Is that right? Iā€™m not really sure what to do in ReplicatedStorage.

You could also make a folder of the zombies inside of workspace and do this:

local zombies = workspace.ZombiesFolder
local children = zombies:GetChildren()

if #children > ["Your Desired Number"] then
    ["Whatever you use to end game"]
    ["Make your gui text also #children"]
end
1 Like

On serverscriptservice I have this script. It will allow me to switch from lobby to main game but how do I make it where the game ends instantly once I close off the zombie spawner or the max amount of zombies are reached?

local lobbyLocation = game.Workspace.Lobby.Position + Vector3.new(0,3,0)
local gameLocation = game.Workspace.Main.Position + Vector3.new(0,3,0)

local ReplicatedStorage = game:GetService('ReplicatedStorage')
local timeEvent = ReplicatedStorage:WaitForChild('TimeEvent')

local function playGame()
	local timeAmount = 10
	local timerText = 'Remaining Time: '
	while timeAmount > 0 do
		timeEvent:FireAllClients(timeAmount, timerText)
		wait(1)
		timeAmount -= 1
	end
end

local function playIntermission()
	local intermission = 5
	local timerText = 'Intermission: '
	while intermission > 0 do
		timeEvent:FireAllClients(intermission, timerText)
		wait(1)
		intermission -=1
	end
end

local function resetPlayers()
	for _, plr in pairs(game.Players:GetChildren()) do
		plr.Character.HumanoidRootPart.CFrame = CFrame.new(lobbyLocation)
	end
end


local function teleportPlayers()
	for _, plr in pairs(game.Players:GetChildren()) do
		plr.Character.HumanoidRootPart.CFrame = CFrame.new(gameLocation)
	end
end

while true do
	resetPlayers()
	playIntermission()
	teleportPlayers()
	playGame()
end

And I have this on starterGUI, screenGUI, Text label, local script

local label = script.Parent

local ReplicatedStorage = game:GetService('ReplicatedStorage')

local timeEvent = ReplicatedStorage:WaitForChild('TimeEvent')

timeEvent.OnClientEvent:Connect(function(timeAmount, timerText)

label.Text = timerText..timeAmount

end)

I see that this part will destroy the zombie spawner,

if CurrentZombies > MaxZombieLimit or TimeRemaining == 0 then
    break --This would break the loop, then removing the spawns
end

but how do I make it to where it ends the game and sends all players to intermission? Instead of break canā€™t I put something like playIntermission() as I tried that but it didnā€™t work. Kep in mind that I added that serverscriptservice script in my previous post.

Is your loop above it? If so the loop will stop the code below just use a couroutine

1 Like

I tried this. All I did was change break to playIntermission() near the end of the code but Iā€™m guessing its not calling on this part from the other script in serverscript service. It says "attempt to call a nil value "

local spawns = script.Parent
local spawn_time = 5
local MaxZombieLimit = 25
local CurrentZombies = 0

local TimeRemaining = 30 --Relies every 5 seconds, so 30 * 5 = 150 seconds I believe

local part1 = workspace.Part1
local part2 = workspace.Part2
local part3 = workspace.Part3


local Part1Enabled = false
local Part2Enabled = false
local Part3Enabled = false

local PartsTouched = 0

part1.Touched:Connect(function(Hit)
    if Part1Enabled == false then
        Part1Enabled = true
        PartsTouched += 1
    end
end)

part2.Touched:Connect(function(Hit)
    if Part2Enabled == false then
        Part2Enabled = true
        PartsTouched += 1
    end
end)

part3.Touched:Connect(function(Hit)
    if Part3Enabled == false then
        Part3Enabled = true
		PartsTouched += 1
	end
end)

while PartsTouched ~= 3 do
	
	wait(spawn_time)
	TimeRemaining -= 1
	for _, spwn in pairs(spawns:GetChildren()) do
		
        if spwn:IsA("BasePart") then
		    local zombieCopy = game.ReplicatedStorage['Zombie']:Clone()
			zombieCopy.Parent = game.Workspace
			zombieCopy.HumanoidRootPart.CFrame = CFrame.new(spwn.Position + Vector3.new(0,3,0))	
            CurrentZombies += 1
		end	
		
	end
	if CurrentZombies > MaxZombieLimit or TimeRemaining == 0 then
        playIntermission()
    end
	
end

spawns:Destroy()

wait I know why I think bro :rofl:

1 Like

Do #CurrentZombies and #MaxZombieLimit

I tried this but it didnt work.

if #CurrentZombies > #MaxZombieLimit or TimeRemaining == 0 then
        playIntermission()
    end

I also tried this but it didnt work either. At first I thought maybe its conflicting with Timeremaining so I did this

if #CurrentZombies > #MaxZombieLimit  == 4 then
        playIntermission()
    end

I did change the MaxZombieLimit at the top of the code to 4. I feel like Iā€™m almost there.

1 Like

Why didnā€™t that work though? It shouldā€™ve as long as you were able to access the function within the script itself?

I removed TimeRemaining as the counter will automatically send the players to the intermission. This is the problem

if #CurrentZombies > #MaxZombieLimit then

I donā€™t think that the CurrentZombies, which is 0, will ever be greater than the #MaxZombieLimit, which is 25.

I tried doing this, but the error I got was ā€œattempt to get length of a number valueā€

if #MaxZombieLimit then
playIntermission()

I tried this but the error I got was ā€œExpected ā€˜thenā€™ when parsing if statement, got ā€˜=ā€™ā€

    if #MaxZombieLimit = 2 then
        playIntermission()

I also tried this but the error is Expected ā€˜thenā€™ when parsing if statement, got ā€˜=ā€™ -

  if #MaxZombieLimit == 2 then
        playIntermission()

I want the intermission to play once there are 25 zombies to show that the game is over and it will restart again.

Donā€™t reference the CurrentZombies & MaxZombieLimit as # operators, theyā€™re already defined as a ā€œNumberā€ value thereā€™s no need to be adding that

Also this would only check if the MaxZombieLimit is equal to 2, which you donā€™t want

You have to check if the CurrentZombies that are currently in the game is equal to 2 or not

Do you mean like this?

CurrentZombies > MaxZombieLimit == 5

For the sake of testing I changed the variable local MaxZombieLimit = 5 so that I wont have to wait until 25 zombies to appear

1 Like

No, you should compare if the CurrentZombies are greater than the MaxZombieLimit so that your Intermission function can run

local spawns = script.Parent
local spawn_time = 5
local MaxZombieLimit = 5
local CurrentZombies = 0

local TimeRemaining = 30 --Relies every 5 seconds, so 30 * 5 = 150 seconds I believe

local part1 = workspace.Part1
local part2 = workspace.Part2
local part3 = workspace.Part3


local Part1Enabled = false
local Part2Enabled = false
local Part3Enabled = false

local PartsTouched = 0

part1.Touched:Connect(function(Hit)
    if Part1Enabled == false then
        Part1Enabled = true
        PartsTouched += 1
    end
end)

part2.Touched:Connect(function(Hit)
    if Part2Enabled == false then
        Part2Enabled = true
        PartsTouched += 1
    end
end)

part3.Touched:Connect(function(Hit)
    if Part3Enabled == false then
        Part3Enabled = true
		PartsTouched += 1
	end
end)

while true do
	
	wait(spawn_time)
	TimeRemaining -= 1
	for _, spwn in pairs(spawns:GetChildren()) do
		
        if spwn:IsA("BasePart") then
		    local zombieCopy = game.ReplicatedStorage['Zombie']:Clone()
			zombieCopy.Parent = game.Workspace
			zombieCopy.HumanoidRootPart.CFrame = CFrame.new(spwn.Position + Vector3.new(0,3,0))	
            CurrentZombies += 1
		end	
		
	end
	if CurrentZombies > MaxZombieLimit then
        playIntermission()
    end
	
end

spawns:Destroy()
1 Like

I input the code you gave me but it says ā€œ55: attempt to call a nil valueā€ I noticed that the spawner will stop bringing in zombies into my game once it reaches 5 zombies. Could it be that the spawns:Destroy() is in the wrong place?

If you want to end the game when every zombie is dead then do this

local Max_Zombies = 0 --put an amount here (If the zombies amount reach this value the game will end)

local Zombies = --location of the zombies (They all must be in one folder and that folder must contain every single zombie inside it)
local plr = game.Players.LocalPlayer
wait(0.5)
for i, v in pairs (Zombies: GetChildren ()) does
if  v == Max_Zombies  then
print("Every zombie is dead game ended")
        --End game.
   end
end