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 The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top