Hello there,
I am making a tower defense game but I have a problem with making the wave system work. The scripts work perfectly but the wave is not. It will spawn the first wave and keep doing it without waiting until the wave ends. Please help 
heres the codes:
GameLogic script:
local Round = require(script.Round)
local map = workspace:WaitForChild("Map")
local waypoints = map:WaitForChild("Waypoints")
for i=1, 3 do
print("starting wave")
if i < 3 then
Round.spawnEnemy(map, "Zombie", 2 * i)
elseif i == 3 then
Round.spawnEnemy(map, "Zombie", 4)
wait(3)
Round.spawnEnemy(map, "Zombie", 3)
elseif i > 3 then
Round.spawnEnemy(map, "Zombie", 2 * i)
end
print("game over")
task.wait(5)
end
Round module script:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local events = ReplicatedStorage.Events
local enemies = ServerStorage.Enemies
local Round = {}
function Round.patrol(map, enemy)
local humanoid = enemy:WaitForChild("Humanoid")
local waypoints = map.Waypoints
for i=1, #waypoints:GetChildren() do
humanoid:MoveTo(waypoints[i].Position)
humanoid.MoveToFinished:Wait()
end
enemy:Destroy()
end
function Round.spawnEnemy(map, name, quantity)
local exist = enemies:FindFirstChild(name)
if exist then
for i=1, quantity do
task.wait(2)
local enemy = exist:Clone()
enemy.HumanoidRootPart.CFrame = map.Spawn.CFrame
enemy.Parent = workspace.Enemies
-- setup enemy data
local humanoid = enemy.Humanoid
local enemyData = require(enemies.EnemyData)
humanoid.MaxHealth = enemyData[name]["Health"]
humanoid.WalkSpeed = enemyData[name]["Speed"]
-- move enemy
coroutine.wrap(Round.patrol)(map, enemy)
end
else
warn(name, "does not exist")
end
end
return Round
I appreciate all your responses 
2 Likes
Hello there!
So first of all the issue is that you are not giving a value to increment by each time in the for loop.
so basically you have to give it 3 values not 2, the 3rd value is the amount it increments by each time which in this case would be 1.
I also see that you are really using a bad practice way to do the Waves. Me myself is also currently working on a Tower Defense Game. I am using a module containing all of the Waves.
The way i store my Waves in the Module is Tables as waves and it will loop through them. Each Wave has stuff like Rewards and other stuff. It also has another Table inside containing all of the Enemies, each is a Table Containing the Enemies name nothing else, then you might be wondering why i am having 1 singular value and putting it in a Table instead of letting it stand alone. Well, that is because in Tables you cannot have any Values that are the same, though we want Lots of values that are the same, since if we wanna spawn 3 Zombies there is gonna be 3 of the same Values already there, that is why they are in tables because then they will not count as the same Values. Now how do we do delays? To make delays we do another value inside of the Enemies Table, but instead of: {[βNameβ] = Zombie}, we do {[βDelayβ] = 1} for example.
Now the way to handle and use this in the Main Script that you call GameLogic Script. The way i would do it if i was you would be like this:
local WavesModule = require(ReplicatedStorage.Modules.WavesModule)
for index, WaveTable in pairs(WavesModule.Waves) do
for i = 1, #WaveTable.Enemies, 1 do
local List = WaveTable.Enemies[i]
if list.Name then
Round.spawnEnemy(map, "Zombie", 1)
elseif List.Delay then
task.wait(list.Delay)
end
end
-- if you wanna do anything here this will run each time a wave is finished!
end
-- if you wanna do anything here this will run when every wave is done and they have won!
If this was helpfull please tell me, i would always like to help again 
Kind Regards, The_IntoDev.
1 Like