PVZ Wave System Help

Hello! Lately I’ve been progressing in my PvZ game but I’m stuck somewhere specific!

I finally reached the part where I gotta code a wave system like in PvZ (1,2,3 depending on the difficulty hard,mid,easy and each difficulties and waves includes specific zombie types) but I got no absolute idea on how to code that and been stuck for two days. If one of you kind souls could help me it’d be very much appreciated !


What code do you have already?

Honestly nothing too useful it’s just three Tables for each difficulties with Waves from 1 to 3, ZombieTypes (which is a table) WaveCount which sets the amount of wave in the difficulty. ATM I cannot share the code as I’m not on my PC

Well when you get on your PC you can share the code

If I recall, stages in PvZ have a set amount of zombies each with different type, expect in endless, are you aiming for something like in endless? Oh waves, I mean you can just set different attributes for which zombies should appear.

it’s not actually too hard you would just check what wave type it is and then depending on the wave type you would do different things inthis case Object Oriented Programming could actually be useful because you’re going to most certainly have some functions that will do the same thing in all the waves but some waves will have special things happen

Yeah that’s correct, and the annoying thing is also setting a spawn rate for each zombies.

To be honest I know nothing about OOP, perhaps could you lighten my lamp?

1 Like

I found this for you.

Hold on im making a quick class to to show you what it could possibly look like, one moment

local Waves = {
	[1] = {
		Zombies = "Cone Head, Browncoat Zombie", -- do a :split(","),
		RateToSpawn = 1,-- How often should they spawn?
		NextWave = function()
			-- Do something here like make themm all appear.
	[2] = {
		Zombies = "Bucket Head, Cone Head, All-Star, Zombie",
		RateToSpawn = 0.35,
		EndWave = function()

You could set a class for each stage and assign them a wave dictionary like this (Utilizing the screenshot from above)

1 Like

Also OOP is basically a coding paradigm where everything is an object that has its own properties and methods (functions)

This will work well in your case because you want the waves to obviously work similiarly but you want some things to be different

1 Like

I see, but how would I individually give percentages of spawn for each zombies?

I appreciate the help but in my case it’s a tiny bit more complicated than what seems to be displayed in the screenshot

You can set a class for them,

local ZombiesData = {
	["Cone Head"] = {
		Health = 150,
		Damage = 10,
		Speed = 2,
		Percentage = 2 -- 50/50
local ChosenZombie = Waves[1].Zombies:split(",")[math.random(1, #Waves[1].Zombies:split(","))]
local Zombie = ZombiesData[ChosenZombie]

if math.random(1,Zombie.Percentage) == Zombie.Percentage then
	print("Spawn them!")

Well it was an extremely short video and I figured it would give you the ideas you need to create the larger version you’re going for.

1 Like

Well thanks a lot my friend! I’ll try this out when I wake up.

1 Like

Here is a quick simple class which would of course need more added but basically, we know that every wave has zombies and every wave will have an active loop that will spawn zombies

local Wave = {}
Wave.__index = Wave

local ZombieInfo = {
   Zombie = {
      SpawnChance = 0.5
   FlagZombie = {
      SpawnChance = 0.3
   ConeheadZombie = {
      SpawnChance = 0.7
   BucketheadZombie = {
      SpawnChance = 0.1
   NewspaperZombie = {
      SpawnChance = 0.2

local lastSpawnTime = 0

function Wave.new(zombieFolder, WaveSpawnRate)
   local self = {}

   self.zombieFolder = zombieFolder
   self.WaveSpawnRate = WaveSpawnRate

   return setmetatable(self, Wave)

function Wave:SpawnRandomZombie()
   local totalSpawnChance = 0 
   for _, zombieInfo in pairs(ZombieInfo) do 
      totalSpawnChance = totalSpawnChance + zombieInfo.SpawnChance
   local randomSpawnChance = math.random() * totalSpawnChance 
   local accumulatedSpawnChance = 0

   for zombieType, zombieInfo in pairs(ZombieInfo) do
      accumulatedSpawnChance = accumulatedSpawnChance + zombieInfo.SpawnChance
         if randomSpawnChance <= accumulatedSpawnChance then 
         local zombie = self.zombieFolder:FindFirstChild(zombieType):Clone()
         zombie.Parent = workspace

function Wave:Start()
   self.Connection = game:GetService("RunService").Heartbeat:Connect(function()
      if tick() - lastSpawnTime > self.WaveSpawnRate then
         lastSpawnTime = tick()
         print("Spawned zombie")

function Wave:Stop()
   self.Connection = nil


1 Like

I’m sure your code could work, but it ain’t easy to just give some OOP code to an absolute noob at OOP, making the transition to OOP would NOT be easy for such an advanced code, to sum it up I don’t get it, I don’t get how it works.

1 Like

You’re sure you shoudl incldue ChosenZombie outside of the if math.random? It wouldn’t be practical to randomize a zombie just for all of them to be the same ones.