I need help improving a wave system

Include a standalone, bare-bones rbxl file with only the code you want reviewed.

  • Code Review is for reviewing specific parts of your code, and not your whole game.
  • Code Review is intended for improving already-working code. If you need help debugging your code, please use Scripting Support.

Provide an overview of:

  • What does the code do and what are you not satisfied with?

The code makes a wave system that spawns enemys depending the wave it is, it will wait certain time and if all the enemys are killed then the time skips and goes to the next wave

  • What potential improvements have you considered?

i want to make a simpler code so i can add more waves whitout making the code more messier

  • How (specifically) do you want to improve the code?

can make an list of the enemys that spawns depending the wave it is

local Value = game.ReplicatedStorage.WaveText
local Enemys = game.ServerStorage.NPCEnemys
local WaveNumber = 0
local Skeletons = 3
local neededtime = 60

WaveNumber = WaveNumber+1
Value.Value = "Wave 1"

for i = 1, Skeletons do
	wait(math.random(1, 3)*WaveNumber/2)	

	local rayParams = RaycastParams.new()
	local startpos = Vector3.new(math.random(-260, 260),300,math.random(-260, 260))
	local endpos = Vector3.new(startpos)+Vector3.new(0,-100,0)
	local ray = workspace:Raycast(startpos,endpos)

	if ray then
		if ray.Instance:IsA("Terrain") then

			local raycframe = CFrame.new(ray.Position)
			local SkeletonEnemy = Enemys.Easy.Skeleton:Clone()
			SkeletonEnemy.Parent = workspace.Enemys
			SkeletonEnemy:SetPrimaryPartCFrame(raycframe)
		end
		end
	
end

for i = 1, neededtime do
	wait(1)
	if game.ReplicatedStorage.EnemyCount.Value == 0 then
		break
	end
end

local Skeletons = 6
local neededtime = 70
WaveNumber = WaveNumber+1
Value.Value = "Wave " .. WaveNumber

for i = 1, Skeletons do
	wait(math.random(1, 3)*WaveNumber/2)	

	local rayParams = RaycastParams.new()
	local startpos = Vector3.new(math.random(-260, 260),300,math.random(-260, 260))
	local endpos = Vector3.new(startpos)+Vector3.new(0,-100,0)
	local ray = workspace:Raycast(startpos,endpos)

	if ray then
		if ray.Instance:IsA("Terrain") then

			local raycframe = CFrame.new(ray.Position)
			local SkeletonEnemy = Enemys.Easy.Skeleton:Clone()
			SkeletonEnemy.Parent = workspace.Enemys
			SkeletonEnemy:SetPrimaryPartCFrame(raycframe)
		end
	end
end

	for i = 1, neededtime do
	wait(1)
	if game.ReplicatedStorage.EnemyCount.Value == 0 then
		break
	end
end

    local Skeletons = 3
	local Archers = 3
    local neededtime = 70

	WaveNumber = WaveNumber+1
	Value.Value = "Wave " .. WaveNumber

	for i = 1, Skeletons do
		wait(math.random(1, 3)*WaveNumber/2)	

		local rayParams = RaycastParams.new()
		local startpos = Vector3.new(math.random(-260, 260),300,math.random(-260, 260))
		local endpos = Vector3.new(startpos)+Vector3.new(0,-100,0)
		local ray = workspace:Raycast(startpos,endpos)

		if ray then
			if ray.Instance:IsA("Terrain") then

				local raycframe = CFrame.new(ray.Position)
				local SkeletonEnemy = Enemys.Easy.Skeleton:Clone()
				SkeletonEnemy.Parent = workspace.Enemys
				SkeletonEnemy:SetPrimaryPartCFrame(raycframe)
		end
	 end
  end

	for i = 1, Archers do
		wait(math.random(1, 3)*WaveNumber/2)	

		local rayParams = RaycastParams.new()
		local startpos = Vector3.new(math.random(-260, 260),300,math.random(-260, 260))
		local endpos = Vector3.new(startpos)+Vector3.new(0,-100,0)
		local ray = workspace:Raycast(startpos,endpos)

		if ray then
			if ray.Instance:IsA("Terrain") then

				local raycframe = CFrame.new(ray.Position)
				local ArcherEnemy = Enemys.Easy.Archer:Clone()
				ArcherEnemy.Parent = workspace.Enemys
				ArcherEnemy:SetPrimaryPartCFrame(raycframe)
			end
		end
     end

	for i = 1, neededtime do
		wait(1)
		if game.ReplicatedStorage.EnemyCount.Value == 0 then
			break
		end
	end

There is an idea in coding that we don’t want to copy code that was already defined. I take a look at the code you provided and see its a lot of copy and paste.

Something else you can change is the single responsibility principle. We want to use functions that allow us to do one process and one process only. I see we are not using and functions which causes problems when we want to reuse code.

1 Like
local Value = game.ReplicatedStorage.WaveText
local Enemys = game.ServerStorage.NPCEnemys
local WaveNumber = 0

while true do
    local waveEnemies = {
        {Skeletons = 3, neededTime = 60},
        {Skeletons = 6, neededTime = 70},
        {Skeletons = 3, Archers = 3, neededTime = 70},
    }

    local waveData = waveEnemies[WaveNumber + 1]
    if not waveData then
        break
    end

    WaveNumber = WaveNumber + 1
    Value.Value = "Wave " .. WaveNumber

    local function spawnEnemy(enemyType)
        local rayParams = RaycastParams.new()
        local startPos = Vector3.new(math.random(-260, 260), 300, math.random(-260, 260))
        local endPos = Vector3.new(startPos) + Vector3.new(0, -100, 0)
        local ray = workspace:Raycast(startPos, endPos)

        if ray and ray.Instance:IsA("Terrain") then
            local rayCFrame = CFrame.new(ray.Position)
            local enemy = Enemys.Easy[enemyType]:Clone()
            enemy.Parent = workspace.Enemys
            enemy:SetPrimaryPartCFrame(rayCFrame)
        end
    end

    for i = 1, waveData.Skeletons or 0 do
        spawnEnemy("Skeleton")
        wait(math.random(1, 3) * WaveNumber / 2)
    end

    for i = 1, waveData.Archers or 0 do
        spawnEnemy("Archer")
        wait(math.random(1, 3) * WaveNumber / 2)
    end

    for i = 1, waveData.neededTime do
        wait(1)
        if game.ReplicatedStorage.EnemyCount.Value == 0 then
            break
        end
    end
end

This code reduces the amount of duplicated code and uses a loop to iterate through the different waves of enemies, rather than repeating the same code for each wave. It also defines a function to handle spawning enemies, which reduces the amount of duplicate code for spawning different types of enemies.

2 Likes

Thanks sorry for the late reply but this helps me so much! Also merry Christmas

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.