Zombie Spawning Algorithm

Uszi

New Member
Reaction score
5
Let me ask this first, and then read on if you think you can answer:

What I'm asking is: Does anyone have any experience with this sort of spawning system that can give me some pointers?

Second, I don't need a custom designed trigger, just a few suggestions as to where to begin. If you want to make the trigger, feel free, but I'm content to work it out.

Ok:

I'm trying to work out a spawning system that will take into consideration a difficulty level, the number of players playing, and the round number. There should be more zombies if there are more players, playing on a higher difficulty level, later on in the game.

I want to have lots and lots of rounds, on the order of 50-100, and to make it easier than triggering each round, I would like to do it systematically with a few triggers, so I'm looking to make a system where the value increases.

Right now, here's what I got:

Trigger:
  • Game Settings
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set ZombiestoSpawn[0] = ((NumPlayersPlaying x 2) + ((NumPlayersPlaying x GameDifficulty) + (((RoundNumber x NumPlayersPlaying) + (GameDifficulty x 2)) / 2)))

NumPlayersPlaying is an integer = number of players in All Players slot status = user, and = playing.

GameDifficulty is an integer set at a selection screen:
Easy is 0
Normal is 1
Hard is 2
Insane is 3

RoundNumber is an integer set to RoundNumber+1 each round, so round 1 is 1, round 2 is 2, etc.

So far it would do what I want, though it makes the game really rough if you were trying to play it by yourself, 1 player. The math works out like this: 6 players playing on normal difficulty would face 22 zombies in the first round. 1 player playing on normal difficulty would face 4 zombies in the first round. 3 players playing on insane difficulty would face 19 zombies in the first round.

However, I'm trying to figure out how to use it now. I'm thinking that I would at the start of the round, take ZombiesToSpawn[0] and set ZombiesToSpawn[1] = ZombiesToSpawn[0], spawn a zombie, set ZombiesToSpawn[1] = ZombiesToSpawn[1]-1 and reroll like that till ZombiesToSpawn[1] is empty.

I think I can do that.

Problem is now I also want to have different "breed" of more difficult zombies (Zombies with auras, zombies with plague, etc). I'm trying to figure out a system of weighting these advanced zombie types, so that I could control when they spawn: how many rounds in, what the difficulty is, etc. Maybe on Insane mode, I want my players to have to deal with one or two immolation zombies by as early as round 3, but on Easy mode I wouldn't want one to show up until round 10.

The first step seems to be to be to make a unit type array for the types of zombies:

Trigger:
  • Game Settings
    • Events
    • Conditions
    • Actions
      • Set UnitType[1] = Zombie
      • Set UnitType[2] = Diseased Zombie
      • Set UnitType[3] = Fiend
      • Set UnitType[4] = Burning Zombie
      • Set UnitType[5] = Ghoul
      • Set UnitType[6] = Abomination


Then... I'm not sure where to go.


And a final consideration: I would like for the zombies to spawn over a period of time. So that those 6 players don't face all 22 zombies in the first 10 seconds of the round.


So...

What I'm asking is: Does anyone have any experience with this sort of spawning system that can give me some pointers?
 

mathiashl

New Member
Reaction score
0
you want the zombies to spawn over time. thats easy:
use the wait action to spawn them over time. Example.
event - the time they are spawning
conditions - you choice
action - create 3 zombies
- wait 2.00 sec.
- create 3 zombies
- wait 2.00 sec.
- create 3 zombies
and so on.

is that what you are looking for
:)
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
Just a few ideas.

First, you could make an array with a large array size to store the zombie types, and have duplicate types for units with heavier weight. It is lazy, but it's easy, and there is very little downside.
ie.
UnitType[1] = Zombie
UnitType[2] = Zombie
UnitType[3] = Zombie
UnitType[4] = Zombie
UnitType[5] = Zombie
UnitType[6] = Super Zombie
UnitType[7] = Super Zombie
UnitType[8] = Mega Zombie
And then when you spawn a zombie, you could roll between 1 and MaxPower, where MaxPower would be a variable that controls how powerful zombies can get for this level.


Spawning lots of units at once can result in lag spikes, it might be better to spawn them constantly? Another trick you can combine it with, is to find a point on a map that isn't visible to the player. There is a boolean condition to check whether a point on the map is visible to a player - you can use that.


I think unitpools have some kind of inbuilt weighting method, you might want to have a look at that.
 

Uszi

New Member
Reaction score
5
you want the zombies to spawn over time. thats easy:
use the wait action to spawn them over time. Example.
event - the time they are spawning
conditions - you choice
action - create 3 zombies
- wait 2.00 sec.
- create 3 zombies
- wait 2.00 sec.
- create 3 zombies
and so on.

is that what you are looking for
:)

Yeah, that sounds pretty close. I would like to try and keep only 5-15 zombies on a screen at a time, to try and keep the screen from becoming some sort of clusterfuck.

However, I thought waits were generally shunned by map makers everywhere. I wasn't going to try and use them because I thought they would make problems. If there aren't any problems, then using the waits seems very intuitive and easy.

First, you could make an array with a large array size to store the zombie types, and have duplicate types for units with heavier weight. It is lazy, but it's easy, and there is very little downside.
ie.
UnitType[1] = Zombie
UnitType[2] = Zombie
UnitType[3] = Zombie
UnitType[4] = Zombie
UnitType[5] = Zombie
UnitType[6] = Super Zombie
UnitType[7] = Super Zombie
UnitType[8] = Mega Zombie
And then when you spawn a zombie, you could roll between 1 and MaxPower, where MaxPower would be a variable that controls how powerful zombies can get for this level.

That seems pretty good. I could also roll it from 4-Maxpower for later levels to keep beginning units out. And I could probably develop some way of weighting max power by the round number, and the minimum number by the round number too.

Spawning lots of units at once can result in lag spikes, it might be better to spawn them constantly? Another trick you can combine it with, is to find a point on a map that isn't visible to the player. There is a boolean condition to check whether a point on the map is visible to a player - you can use that.

Right, and I think it would be more aesthetically pleasing to have only a few zombies on the screen at a time. Even for 6 players, I would never want to spawn all the zombies for the round and have them bum rush the players.

The point-in-the-map-outside-visibility thing might solve a lot of problems for me if I don't need to make a bunch of regions, I'll look into that.


I think unitpools have some kind of inbuilt weighting method, you might want to have a look at that.

I'll look into it as well. The key is that I can with one or two triggers, makes a system that weights the number and types of units spawned in relation to difficulty and how long the game has been played.

------------------------------------------------------------------------------------

Finally, there was one other direction I was considering going in: Giving each unit type some integer value or custom score, and subtracting that value from the ZombiesToSpawn integer I did above. I said that the equation I put in my first post does pretty much what I want it to do like rounds 1-10. But when you get up to round 30 or so, you start dealing with very large values for ZombiesToSpawn. On insane difficulty, with 6 players, ZombiesToSpawn = 123 for round 30. For round 40, it's 153.

If I make a basic zombie value like 1, and then more advanced zombies like 5, 10, etc, then it seems like I could use that to weight the number/difficulty as well.

e.g. on round 1, you fight 20 basic zombies. Round 40 you don't fight 153 zombies, maybe you fight like 15 basic zombies, 10 disease zombies, and 6 ghouls. Etc, Etc.

------------------------------------------

Anyway, thanks for the thoughts so far guys! I'll definitely tinker with different systems over the next few days.

To that end, if anyone else has any input, in the form of ideas, comments, criticisms, haiku, etc please let me know!

:thup:
 

Uszi

New Member
Reaction score
5
Update:

Alright guys, here's the deal.

I worked out a spawning system based on the suggestions given here.

It works really well, I would say. Of course, I'm a novice trigger-editor, so I don't know if this sort of thing will leak, etc.

There are some limitations here.

1). The unit array system seemed to work pretty well. But in trying to weight it for the round and difficulty, it stopped spawning basic zombies pretty early. I kinda wanted to keep throwing the basic ones in, in larger numbers, towards the end. In the test map I made, I was fighting 13 abominations by round 7 or 8. I would rather that you fight like 2 or 3, and a mess of lower level zombies. Any suggestions on how to fix this?

2). After about round 10, the unit array system starts picking values greater than what I coded for. So it picks between 1 and a maximum weighted by difficulty and round number, and that maxiumum exceeds the unit array. So it spawns nothing. Any suggestions here?

These are the triggers I used, also the test map I made to figure out how to do things. The gameplay of this test map is pretty similar to what the final map I'm working on will be like.

These are the relevant spawning triggers only:

Trigger:
  • SetVar
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Player - Turn Gives bounty On for Player 12 (Brown)
      • Set PlayerNum = (Number of players in (All players controlled by a User player))
      • Set RoundNum = 0
      • Set Ztype[1] = Zombie
      • Set Ztype[2] = Zombie
      • Set Ztype[3] = Zombie
      • Set Ztype[4] = Zombie
      • Set Ztype[5] = Zombie
      • Set Ztype[6] = Zombie
      • Set Ztype[7] = Zombie
      • Set Ztype[8] = Zombie
      • Set Ztype[9] = Zombie
      • Set Ztype[10] = Dalaran Mutant
      • Set Ztype[11] = Dalaran Mutant
      • Set Ztype[12] = Dalaran Mutant
      • Set Ztype[13] = Dalaran Mutant
      • Set Ztype[14] = Dalaran Mutant
      • Set Ztype[15] = Dalaran Mutant
      • Set Ztype[16] = Dalaran Mutant
      • Set Ztype[17] = Ghoul
      • Set Ztype[18] = Ghoul
      • Set Ztype[19] = Ghoul
      • Set Ztype[20] = Ghoul
      • Set Ztype[21] = Ghoul
      • Set Ztype[22] = Ghoul
      • Set Ztype[23] = Ghoul
      • Set Ztype[24] = Ghoul
      • Set Ztype[25] = Abomination
      • Set Ztype[26] = Abomination
      • Set Ztype[27] = Abomination
      • Trigger - Run PickDiff <gen> (ignoring conditions)


Trigger:
  • SpawnZombies
    • Events
      • Time - Every 4.00 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Count non-structure units controlled by Player 12 (Brown) (Exclude incomplete units)) Equal to 0
        • Then - Actions
          • Set ZombiesDead = True
        • Else - Actions
          • Set ZombiesDead = False
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RoundInProg[1] Equal to True
        • Then - Actions
          • Trigger - Run Round1 <gen> (checking conditions)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RoundInProg[2] Equal to True
            • Then - Actions
              • Trigger - Run All Other Rounds <gen> (checking conditions)
            • Else - Actions
              • Do nothing



Trigger:
  • Round1
    • Events
    • Conditions
    • Actions
      • Set RoundInProg[1] = True
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • z2spawn Greater than 0
        • Then - Actions
          • For each (Integer A) from 1 to 1, do (Actions)
            • Loop - Actions
              • Set tempINT = (Random integer number between 1 and z2spawn)
              • Unit - Create tempINT Ztype[(((diff x (RoundNum + PlayerNum)) / PlayerNum) + 0)] for Player 12 (Brown) at (Random point in (Playable map area)) facing Default building facing degrees
              • Unit Group - Pick every unit in (Units in (Playable map area) owned by Player 12 (Brown)) and do (Unit - Order (Picked unit) to Attack PlayerUnits[1])
              • Set z2spawn = (z2spawn - tempINT)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ZombiesDead Equal to True
            • Then - Actions
              • Set RoundInProg[1] = False
              • Wait 0.05 seconds
              • Countdown Timer - Create a timer window for BetweenRndTimer with title Time till next Zomb...
              • Set BetweenRndTimerWin = (Last created timer window)
              • Countdown Timer - Start BetweenRndTimer as a One-shot timer that will expire in 25.00 seconds
              • Countdown Timer - Show BetweenRndTimerWin
            • Else - Actions
              • Do nothing


Trigger:
  • All Other Rounds
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • z2spawn Greater than 0
        • Then - Actions
          • For each (Integer A) from 1 to 1, do (Actions)
            • Loop - Actions
              • Set tempINT = (Random integer number between 1 and z2spawn)
              • Unit - Create tempINT Ztype[(((diff x (RoundNum + PlayerNum)) / PlayerNum) + 0)] for Player 12 (Brown) at (Random point in (Playable map area)) facing Default building facing degrees
              • Unit Group - Pick every unit in (Units in (Playable map area) owned by Player 12 (Brown)) and do (Unit - Order (Picked unit) to Attack PlayerUnits[1])
              • Set z2spawn = (z2spawn - tempINT)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ZombiesDead Equal to True
            • Then - Actions
              • Set RoundInProg[2] = False
              • Wait 0.05 seconds
              • Countdown Timer - Create a timer window for BetweenRndTimer with title Time till next Zomb...
              • Set BetweenRndTimerWin = (Last created timer window)
              • Countdown Timer - Start BetweenRndTimer as a One-shot timer that will expire in 15.00 seconds
              • Countdown Timer - Show BetweenRndTimerWin
            • Else - Actions
              • Do nothing


Trigger:
  • Timer
    • Events
      • Time - BetweenRndTimer expires
    • Conditions
    • Actions
      • Sound - Play FootmanYesAttack3 <gen>
      • Set RoundNum = (RoundNum + 1)
      • Countdown Timer - Hide BetweenRndTimerWin
      • Countdown Timer - Destroy BetweenRndTimerWin
      • Set z2spawn = (((PlayerNum x diff) + (RoundNum x diff)) / 2)
      • Set RoundInProg[2] = True



Again, please post any comments, suggestions, etc. :D
 

Attachments

  • Test Zombie Spawn.w3x
    55.2 KB · Views: 175
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top