# How to make simple zombie spawner algorithm?!

Goal: Create algorithm that intelligently spawns zombies based on their strength. Example, at Wave 1 most zombies should be strength 1 with a few strength 2, and at wave 5 most zombies should be strength 5 with some lower and some higher. like in Zombie Attack the zombies seamlessly become progressively stronger as the wave number goes up

Is there a standard type of algorithm that I can use? Meanwhile here is what I came up with. Tell me if it’s good or bad or needs any improvements.

Each Zombie has a property called `Cost` and each Wave has a property called `Budget`. Wave also has a property called `TotalEnemies`. Then I have a basic algorithm that spawns the right zombies by using up the entire Budget and making sure to spawn as many zombies as the TotalEnemies.

So my question is:

• How do I make a basic algorithm that will do this?
2 Likes

Just make them deal more damage.

1 Like

Have int values called (I’ll call it Wave Strength for this example) and set it to 1, when a new zombie spawns it’s Strength Value will be equal to Wave Strength Value.
At the end of each Wave you simply increase Wave Strength by whatever number you want

1 Like

I want all different level zombies to spawn in the same wave. Just like in Zombie Attack on Wave 1 only weak zombies spawn but by Wave 30 all different zombies spawn weak ones and strong ones.

1 Like

Use math.random then
Wave 1 would have Wave Strength equal to 1
So zombie strength would be math.random(1,1)

On Wave 30, Wave Strength would equal to 30
So zombie strength would be math.random(1,30)

1 Like

You could do

``````local Strength = math.random(1,5)
local zombie = --whatever model

zombie.Strength = Strength
``````
1 Like

Something like this :

``````If it’s wave 1 it looks something like this :

local WaveStrength = 1

local NewZombie = Zombie:Clone()
NewZombie.Strength.Value = math.random(1,WaveStrength)

If it’s wave 30 then it looks like this :

local WaveStrength = 30

local NewZombie = Zombie:Clone()
NewZombie.Strength.Value = math.random(1,WaveStrength)

``````

sorry if it’s messy I’m typing on mobile

1 Like

You can create a weighted system or just a simple random range for that. You’d have the level as a variable and get zombie levels based on the level:

``````--// Random Range
local currentLevel = 1

local function getZombieLevel()
return math.random(
math.clamp(currentLevel - 1, 0, math.huge), -- make sure the minimum level doesn't go under 1
currentLevel + 1
)
end
``````

The code above makes the zombies have a level of 1 level higher to 1 level lower than the current level.

Thats what im saying. Stronger zombies deal more damage.

But to make it so where you don’t have to put the script in every zombie do:

``````local strength = 0
local zombie = nil

if zombie == nil then
strength = math.random(1,5) -- random strength
zombie = script.Parent.Parent:WaitForChild("Zombie")  -- gets the zombie
zombie.Strength = strength -- applies the variable "strength" to the zombie's strength
return -- returns
end
``````

You’d need to either determine the exact number of Zombies with x amount of strength or create an algorithm that gives more weight to choosing stronger zombies when at higher wave numbers.

Here is an example:

``````local waveStrengths = {}
waveStrengths.Wave1 = {.3, .3, .2, .1, .1} --Total percentage must be 100% or 1
waveStrengths.Wave5 = {.1, .1, .2, .3, .3} --More stronger ones in wave 5

local totalZombies = 50
print("Zombies at strength 1: ", totalZombies * waveStrengths.Wave1[1]) --15 Zombies at strength lvl 1
print("Zombies at strength 2: ", totalZombies * waveStrengths.Wave1[2]) --15 Zombies at strength lvl 2
print("Zombies at strength 3: ", totalZombies * waveStrengths.Wave1[3]) --10 Zombies at strength lvl 3
print("Zombies at strength 4: ", totalZombies * waveStrengths.Wave1[4]) --5 Zombies at strength lvl 4
print("Zombies at strength 5: ", totalZombies * waveStrengths.Wave1[5]) --5 Zombies at strength lvl 5
``````

Firstly, I’m not changing the strength of the zombie. I am selecting zombies with different strengths.

math.random(1,waveNumber) can work but it doesn’t ensure that a high wave will get strong zombies. It’s leaving it to chance, obviously there is more of a chance it will pick stronger zombies but still. That’s why I thought of making a budget that has to get used.

1 Like

Then you just increase the minimum number in math.random every wave by a small amount

1 Like

okay I’ll see what I come up with

1 Like

if you want to get non integer values use Random.new():NextNumber(min,max) it should work flawlessly,
This returns ANY number randomly and clamped from min to max including decimal numbers.

1 Like

``````local waveStrengths = {
{.4, .3, .2, .05, .05}, --Wave 1 Strength Weights
{.3, .4, .2, .05, .05},
{.1, .3, .4, .1, .1},
{.1, .2, .4, .2, .1},
{.05, .05, .2, .4, .3}, --Wave 5 strength weights
}

local totalZombies = 50

--Wave Loop
for i = 1, #waveStrengths do
local zombieWeights = waveStrengths[i]
print("Wave: ", i)
for x = 1, #zombieWeights do
local ZombieCount = math.floor(waveStrengths[i][x] * totalZombies)
print(ZombieCount, "Zombies at strength", x)
end
end
``````
1 Like

That’s why I thought of the budget. On wave 1 the budget will be 50, then the algorithm spawns zombies of varying costs but it must equal up to 50. Then on wave 2 the budget increases with a formula (for now I just have it, `budget *= 1.1`) then the algorithm spawns zombies of varying costs but it must equal up to the new budget (55 in this case) and so on.