• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Trigger works fine but causes a lot of lag - can I make it more efficient?

Status
Not open for further replies.
Level 2
Joined
Dec 21, 2018
Messages
12
Hello everyone,

I have made the following trigger which works perfectly fine functionality wise, but it makes the game lag-spike whenever it is executed. Is there something I can do to avoid this problem without altering the functionality? Perhaps some jass code?

The trigger spawns units but limits the amount of total units on the map to ensure that it is not too difficult and prevents spawning too many units making the game lag if they are killed too slowly.

There are some weak units and some heroes with strong AOE damage and they can periodically kill about ~20 units with an ultimate spell which lag-spikes the map when it has to spawn units and iterate through the spawn loops.

Here is a snippet of the trigger:

  • For each (Integer Spawn) from 1 to 30, do (Actions)
    • Loop - Actions
      • Wait until ((Number of units in (Units in (Playable map area) matching (((Entire Region that I want to exclude <gen> contains (Matching unit)) Equal to False) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True)))) Less than or equal to XXX), checking every 2.00 seconds
      • Unit - Create 1 Voidwalker for (Random player from Legion_of_Monsters) at (Center of Spawn Area Late <gen>) facing Default building facing degrees
      • Unit - Create 1 Crypt Fiend for (Random player from Legion_of_Monsters) at (Center of Spawn Area Late <gen>) facing Default building facing degrees
      • Wait until ((Number of units in (Units in (Playable map area) matching (((Entire Region that I want to exclude <gen> contains (Matching unit)) Equal to False) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True)))) Less than or equal to XXX), checking every 2.00 seconds
      • Unit - Create 1 Abomination for (Random player from Legion_of_Monsters) at (Center of Spawn Area Late <gen>) facing Default building facing degrees
      • Unit - Create 1 Felguard for (Random player from Legion_of_Monsters) at (Center of Spawn Area Late <gen>) facing Default building facing degrees
Spawning 20 units at once does not make the game lag. The problem is the Wait for Condition part. I made a trigger and made it loop 50 times at once and the game lag-spikes for 3 seconds:


  • Actions
    • For each (Integer numberxxx) from 1 to 50, do (Actions)
      • Loop - Actions
        • Wait until ((Number of units in (Units in (Playable map area) matching (((Entire Region that I want to exclude <gen> contains (Matching unit)) Equal to False) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True)))) Less than or equal to 99999), checking every 2.00 seconds
Thank you for reading :)
 
Level 39
Joined
Feb 27, 2007
Messages
5,013
Yeah, I would say there is no reason to ever use wait for condition inside an integer loop. For that matter no waits should be used in integer loops unless you're doing the "integer variable" and only using that variable for that wait. Basically loops are not wait-safe. Also you leak a group every time it checks the number of units and a point every time you create a unit. A better approach would be to use a unit group (or multiple groups, if you want to track each unit-type separately) and manually remove them from that group when they die:

  • Events
    • Time - Elapsed Game-time is 0.10 seconds
  • Conditions
  • Actions
    • Set SPAWN_MAX = 999
    • Set SPAWN_TYPE[1] = Voidwalker
    • Set SPAWN_TYPE[2] = Crypt Fiend
    • Set SPAWN_TYPE[3] = Abomination
    • Set SPAWN_TYPE[4] = Felguard
    • Set SPAWN_TYPECOUNT = 4
    • Set SPAWN_POINT = Center of Spawn Area Late <gen>
  • Events
    • Unit - A unit dies
  • Conditions
    • ((Triggering Unit) is in SpawnGroup) equal to true
  • Actions
    • Unit Group - Remove (Triggering Unit) from SpawnGroup
  • Events
    • Time - Every 2.00 seconds of game-time
  • Conditions
  • Actions
    • Set COUNT = (Number of Units in SpawnGroup)
    • If (Conditions) then (Actions) else (Actions)
      • If - Conditions
        • COUNT less than SPAWN_MAX
      • Then - Actions
        • For each (Integer A) from 1 to SPAWN_MAX - COUNT do (Actions)
          • Loop - Actions
            • Set WHICH_SPAWN = WHICH_SPAWN + 1
            • If (Conditions) then (Actions) else (Actions)
              • If - Conditions
                • WHICH_SPAWN greater than SPAWN_MAX
              • Then - Actions
                • Set WHICH_SPAWN = 1
              • Else - Actions
            • Unit - Create 1 SPAWN_TYPE[WHICH_SPAWN] for (Random player from Legion of Monsters) at SPAWN_POINT facing Default building facing degrees
            • Unit Group - Add (Last created unit) to SpawnGroup
      • Else - Actions
 
Level 2
Joined
Dec 21, 2018
Messages
12
Thank you for your reply I really appreciate it. I have about 6-7 different letters, Q, W, E, R, T, Y that I use for the different spawn loops that I have because I also encountered weird behaviour because they would reset the loop count when another instance is executed :-D Perhaps I should try to follow these instructions on that matter but it works so now so I don't feel like it: How to create MUI loops with waits in GUIHow to create MUI loops with waits in GUI

Regarding the leaking thank you for pointing it out. I have played the map numerous times but I did not crash a single time. So what exactly does it help to clear the leaks? I have not noticed that the game felt slower than the beginning as more leaks accumulated, so I don't think it reduces performance?

Regarding the unit group (or multiple) I have set the map up linearly so the heroes face a few hundred of the same 3-5 units before better units are spawning instead so I only care about the total count of spawned units alive. I think of it as a queue where you have 1000 easy units, then 1000 medium units, then 1000 hard units etc... Would it also make sense to set custom value of units spawned instead of a unit group?

The triggers you came up with are very helpful to illustrate what you mean as I otherwise would not follow you as well :) I have questions. How can I make them spawn in a queueing fashion with first the easy units, then medium and then hard units?
Also, at trigger 3, what purpose does SPAWN_TYPECOUNT have? Should it be used instead of SPAWN_MAX for the If - Conditions at trigger 3's loop?

I am totally going to steal your triggers if I can figure out how to make it work with queueing the units so I can progressively spawn harder units and define how many units should be spawned of each type. I can add another trigger to increase the SPAWN_MAX which I understand sets the maximum amount of units that can be spawned at once.

Now I just wish that WC3 could use more than 1 CPU core so my sloppy code would run faster without lag haha :-D

Thank you for your reply!
 
Level 2
Joined
Dec 21, 2018
Messages
12
Would these triggers work fine or do you find any issues with them? :) (From another map)

It does not lag because (I think) it does integer comparison which is way easier for the game to handle than counting the units on the map.



  • Set various variables
    • Events
      • Time - Elapsed game time is 1.50 seconds
    • Conditions
    • Actions
      • Set Spawn_Current = Attackmove 2 <gen>
      • Set Units_Spawned = 0
      • Set waiting_to_spawn = 0
      • Set Units_Limit = 0
      • Set Increase_Units_Limit = (Increase_Units_Limit + 2000)
      • Set Revives = 50

  • Leaderboard and update waiting to spawn
    • Events
      • Time - Every 3.00 seconds of game time
    • Conditions
    • Actions
      • Set waiting_to_spawn = 0
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Abomination)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Archer)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Banshee)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_BlackKnight)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_BloodElf)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Bloodfiend)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Captain)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_CryptFiend)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_DragonTurtle)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Dryad)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_EliteKnight)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_EradarSorcerer)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Felguard)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Footman)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Ghoul)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Grunt)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Huntress)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Knight)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_MeatWagon)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Militia)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_MortarTeam)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_MountainGiant)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_MurgulReaver)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_NagaRoyalGuard)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_NagaSiren)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Necromancer)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_NightElfArcher)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_OverloadGuardian)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Priest)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Rifleman)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_SnapDragon)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Sorceress)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_SpellBreaker)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Summoner)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_SylvanasWindrunner)
      • Set waiting_to_spawn = (waiting_to_spawn + Spawn_Warden)
      • Leaderboard - Create a leaderboard for (All players) titled Map Information
      • Leaderboard - Add Player 1 (Red) to (Last created leaderboard) with label Unit Cap and value Units_Limit
      • Leaderboard - Add Player 2 (Blue) to (Last created leaderboard) with label Units Spawned and value Units_Spawned
      • Leaderboard - Add Player 3 (Teal) to (Last created leaderboard) with label Room to spawn and value (Units_Limit - Units_Spawned)
      • Leaderboard - Add Player 4 (Purple) to (Last created leaderboard) with label In queue to spawn and value waiting_to_spawn
      • Leaderboard - Add Player 5 (Yellow) to (Last created leaderboard) with label Teamrevives remaini... and value Revives
      • Leaderboard - Show (Last created leaderboard)
  • When a unit dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Owner of (Dying unit)) is in HumanForcesPlayerGroup) Equal to True
        • Then - Actions
          • Player Group - Pick every player in Heroes and do (Actions)
            • Loop - Actions
              • Player - Add (Point-value of (Dying unit)) to (Picked player) Current gold
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Custom value of (Dying unit)) Equal to 1
            • Then - Actions
              • Set Units_Spawned = (Units_Spawned - 1)
            • Else - Actions
              • Do nothing
          • Unit - Remove (Dying unit) from the game
          • Skip remaining actions
        • Else - Actions
          • Do nothing
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Dying unit) belongs to an ally of Player 1 (Red)) Equal to True
          • ((Dying unit) is A Hero) Equal to True
          • Revives Greater than 0
        • Then - Actions
          • Set Revives = (Revives - 1)
          • Hero - Instantly revive (Dying unit) at (Center of Revive Point <gen>), Show revival graphics
          • Camera - Pan camera for (Owner of (Dying unit)) to (Position of (Dying unit)) over 0.00 seconds
          • Selection - Select (Dying unit) for (Owner of (Dying unit))
        • Else - Actions
          • Do nothing
  • Amount of units to spawn and spawn order
    • Events
    • Conditions
    • Actions
      • Trigger - Turn on Increase Units Limit <gen>
      • Set Spawn_Militia = (Spawn_Militia + 750)
      • Wait until (Spawn_Militia Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Humans have rec...
      • Set Spawn_Footman = (Spawn_Footman + 1000)
      • Wait until (Spawn_Footman Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Humans have rec...
      • Set Spawn_Knight = (Spawn_Knight + 1000)
      • Set Spawn_Archer = (Spawn_Archer + 1000)
      • Set Spawn_Sorceress = (Spawn_Sorceress + 1000)
      • Wait until (Spawn_Knight Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Humans have rec...
      • Set Spawn_Captain = (Spawn_Captain + 750)
      • Set Spawn_Priest = (Spawn_Priest + 1000)
      • Set Spawn_SpellBreaker = (Spawn_SpellBreaker + 750)
      • Set Spawn_Rifleman = (Spawn_Rifleman + 1000)
      • Wait until (Spawn_Captain Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Humans have rec...
      • Set Spawn_MortarTeam = (Spawn_MortarTeam + 1000)
      • Set Spawn_EliteKnight = (Spawn_EliteKnight + 1000)
      • Wait until (Spawn_EliteKnight Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Humans have rec...
      • Set Spawn_BloodElf = (Spawn_BloodElf + 750)
      • Set Spawn_Grunt = (Spawn_Grunt + 750)
      • Wait until (Spawn_Grunt Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Humans have rec...
      • Set Spawn_SylvanasWindrunner = (Spawn_SylvanasWindrunner + 1000)
      • Set Spawn_BlackKnight = (Spawn_BlackKnight + 1000)
      • Wait until (Spawn_BlackKnight Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Undead have rec...
      • Set Spawn_Ghoul = (Spawn_Ghoul + 2500)
      • Set Spawn_Banshee = (Spawn_Banshee + 1500)
      • Wait until (Spawn_Ghoul Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Undead have rec...
      • Set Spawn_Necromancer = (Spawn_Necromancer + 1500)
      • Set Spawn_Abomination = (Spawn_Abomination + 1500)
      • Wait until (Spawn_Necromancer Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Undead have rec...
      • Set Spawn_CryptFiend = (Spawn_CryptFiend + 1500)
      • Set Spawn_MeatWagon = (Spawn_MeatWagon + 1500)
      • Wait until (Spawn_CryptFiend Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Naga have recei...
      • Set Spawn_MurgulReaver = (Spawn_MurgulReaver + 1500)
      • Set Spawn_NagaSiren = (Spawn_NagaSiren + 1500)
      • Wait until (Spawn_MurgulReaver Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Naga have recei...
      • Set Spawn_SnapDragon = (Spawn_SnapDragon + 1500)
      • Set Spawn_Summoner = (Spawn_Summoner + 1500)
      • Wait until (Spawn_Summoner Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Naga have recei...
      • Set Spawn_NagaRoyalGuard = (Spawn_NagaRoyalGuard + 1500)
      • Set Spawn_DragonTurtle = (Spawn_DragonTurtle + 1500)
      • Wait until (Spawn_NagaRoyalGuard Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Night Elves hav...
      • Set Spawn_NightElfArcher = (Spawn_NightElfArcher + 1000)
      • Set Spawn_Dryad = (Spawn_Dryad + 1150)
      • Wait until (Spawn_NightElfArcher Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Night Elves hav...
      • Set Spawn_Huntress = (Spawn_Huntress + 1100)
      • Set Spawn_Warden = (Spawn_Warden + 1000)
      • Set Spawn_MountainGiant = (Spawn_MountainGiant + 750)
      • Wait until (Spawn_Huntress Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Demons have rec...
      • Set Spawn_EradarSorcerer = (Spawn_EradarSorcerer + 2000)
      • Set Spawn_Felguard = (Spawn_Felguard + 2000)
      • Wait until (Spawn_EradarSorcerer Less than 10), checking every 1.00 seconds
      • Game - Display to (All players) the text: The Demons have rec...
      • Set Spawn_Bloodfiend = (Spawn_Bloodfiend + 3000)
      • Set Spawn_OverloadGuardian = (Spawn_OverloadGuardian + 5000)
      • Custom script: call DestroyTrigger(GetTriggeringTrigger())
  • Increase Units Limit
    • Events
      • Time - Every 2.00 seconds of game time
    • Conditions
      • Increase_Units_Limit Greater than or equal to 1
    • Actions
      • Set Increase_Units_Limit = (Increase_Units_Limit - 1)
      • Set Units_Limit = (Units_Limit + 1)
  • Spawn units
    • Events
      • Time - Elapsed game time is 6.00 seconds
    • Conditions
    • Actions
      • Wait until (waiting_to_spawn Greater than 0), checking every 0.25 seconds
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Militia Greater than 0
        • Then - Actions
          • Set Spawn_Militia = (Spawn_Militia - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Militia for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Footman Greater than 0
        • Then - Actions
          • Set Spawn_Footman = (Spawn_Footman - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Footman for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Priest Greater than 0
        • Then - Actions
          • Set Spawn_Priest = (Spawn_Priest - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Priest for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Sorceress Greater than 0
        • Then - Actions
          • Set Spawn_Sorceress = (Spawn_Sorceress - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Sorceress for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_MortarTeam Greater than 0
        • Then - Actions
          • Set Spawn_MortarTeam = (Spawn_MortarTeam - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Mortar Team for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Archer Greater than 0
        • Then - Actions
          • Set Spawn_Archer = (Spawn_Archer - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Archer for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Rifleman Greater than 0
        • Then - Actions
          • Set Spawn_Rifleman = (Spawn_Rifleman - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Rifleman for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_SpellBreaker Greater than 0
        • Then - Actions
          • Set Spawn_SpellBreaker = (Spawn_SpellBreaker - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Spell Breaker for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Captain Greater than 0
        • Then - Actions
          • Set Spawn_Captain = (Spawn_Captain - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Captain for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Knight Greater than 0
        • Then - Actions
          • Set Spawn_Knight = (Spawn_Knight - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Knight for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_EliteKnight Greater than 0
        • Then - Actions
          • Set Spawn_EliteKnight = (Spawn_EliteKnight - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Elite Knight for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_BloodElf Greater than 0
        • Then - Actions
          • Set Spawn_BloodElf = (Spawn_BloodElf - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Blood Elf Lieutenant for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Grunt Greater than 0
        • Then - Actions
          • Set Spawn_Grunt = (Spawn_Grunt - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Grunt for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_MountainGiant Greater than 0
        • Then - Actions
          • Set Spawn_MountainGiant = (Spawn_MountainGiant - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Mountain Giant for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_BlackKnight Greater than 0
        • Then - Actions
          • Set Spawn_BlackKnight = (Spawn_BlackKnight - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Black Knight for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_SylvanasWindrunner Greater than 0
        • Then - Actions
          • Set Spawn_SylvanasWindrunner = (Spawn_SylvanasWindrunner - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Sylvanas Windrunner for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Hero - Set (Last created unit) Hero-level to 10, Hide level-up graphics
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Ghoul Greater than 0
        • Then - Actions
          • Set Spawn_Ghoul = (Spawn_Ghoul - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Ghoul for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_CryptFiend Greater than 0
        • Then - Actions
          • Set Spawn_CryptFiend = (Spawn_Abomination - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Crypt Fiend for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Banshee Greater than 0
        • Then - Actions
          • Set Spawn_Banshee = (Spawn_Banshee - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Banshee for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Necromancer Greater than 0
        • Then - Actions
          • Set Spawn_Necromancer = (Spawn_Necromancer - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Necromancer for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Abomination Greater than 0
        • Then - Actions
          • Set Spawn_Abomination = (Spawn_Abomination - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Abomination for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_MeatWagon Greater than 0
        • Then - Actions
          • Set Spawn_MeatWagon = (Spawn_MeatWagon - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Meat Wagon for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_MurgulReaver Greater than 0
        • Then - Actions
          • Set Spawn_MurgulReaver = (Spawn_MurgulReaver - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Mur'gul Reaver for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_NagaSiren Greater than 0
        • Then - Actions
          • Set Spawn_NagaSiren = (Spawn_NagaSiren - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Naga Siren for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_SnapDragon Greater than 0
        • Then - Actions
          • Set Spawn_SnapDragon = (Spawn_SnapDragon - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Snap Dragon for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_NagaRoyalGuard Greater than 0
        • Then - Actions
          • Set Spawn_NagaRoyalGuard = (Spawn_NagaRoyalGuard - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Naga Royal Guard for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_DragonTurtle Greater than 0
        • Then - Actions
          • Set Spawn_DragonTurtle = (Spawn_DragonTurtle - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Dragon Turtle for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Summoner Greater than 0
        • Then - Actions
          • Set Spawn_Summoner = (Spawn_Summoner - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Summoner for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_NightElfArcher Greater than 0
        • Then - Actions
          • Set Spawn_NightElfArcher = (Spawn_NightElfArcher - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Night Elf Archer for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Huntress Greater than 0
        • Then - Actions
          • Set Spawn_Huntress = (Spawn_Huntress - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Huntress for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Dryad Greater than 0
        • Then - Actions
          • Set Spawn_Dryad = (Spawn_Dryad - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Dryad for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Warden Greater than 0
        • Then - Actions
          • Set Spawn_Warden = (Spawn_Warden - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Warden for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_EradarSorcerer Greater than 0
        • Then - Actions
          • Set Spawn_EradarSorcerer = (Spawn_EradarSorcerer - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Eredar Sorcerer (Demon) for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Felguard Greater than 0
        • Then - Actions
          • Set Spawn_Felguard = (Spawn_Felguard - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Felguard (Demon) for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_Bloodfiend Greater than 0
        • Then - Actions
          • Set Spawn_Bloodfiend = (Spawn_Bloodfiend - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Bloodfiend (Demon) for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Wait until (Units_Spawned Less than Units_Limit), checking every 0.25 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Spawn_OverloadGuardian Greater than 0
        • Then - Actions
          • Set Spawn_OverloadGuardian = (Spawn_OverloadGuardian - 1)
          • Set tempPoint = (Center of Spawn_Current)
          • Unit - Create 1 Overlord Guardian (Demon) for (Random player from HumanForcesPlayerGroup) at tempPoint facing tempPoint
          • Unit - Set the custom value of (Last created unit) to 1
          • Set Units_Spawned = (Units_Spawned + 1)
          • Custom script: call RemoveLocation( udg_tempPoint )
        • Else - Actions
          • Do nothing
      • Trigger - Run Spawn units <gen> (checking conditions)
Edit: Does this trigger leak?

  • Cam
    • Events
      • Time - Every 6.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 24, do (Actions)
        • Loop - Actions
          • Camera - Set (Player((Integer A)))'s camera Height Offset to 500.00 over 2.00 seconds
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
5,013
Edit: Does this trigger leak?
Nope.
It does not lag because (I think) it does integer comparison which is way easier for the game to handle than counting the units on the map.
No, your triggers were laggy because every 2 seconds it started 50 loops and each loop waited for some condition check so there were actually a FUCKLOAD of slept loops all going at the same time. Picking every unit on the map can be performance-intensive but only if you really do have thousands of units. Counting all the units in a group is perfectly fine and not slow.
Would these triggers work fine or do you find any issues with them? :) (From another map)
No, they do far more than you need to do for what you've described in this map. And honestly your method seems to be way inefficient with all the waiting_to_spawn stuff (also this is a perfect example of an integer array being useful for saving you a lot of time in the editor clicking on and changing stuff). I would use a slight variation on the triggers I posted before, see below.
I also encountered weird behaviour because they would reset the loop count when another instance is executed
Yes, Integer A and Integer B are both global variables and cannot be used simultaneously between 2 triggers without the second one fucking with the first. The "for each integer variable" version is probably the one you want to use if the loops use waits (which, as I said, you should probably not do) or might fire simultaneously. The GUI MUI tutorial you linked shows how to shadow globals to make them work like locals (which don't overwrite each other) so you can shadow the looper variable for a custom integer loop and it will be 100% wait-safe.
Regarding the leaking thank you for pointing it out. I have played the map numerous times but I did not crash a single time. So what exactly does it help to clear the leaks? I have not noticed that the game felt slower than the beginning as more leaks accumulated, so I don't think it reduces performance?
Any individual leak is unnoticeable, but together they can become a huge problem. Memory Leaks or Things That Leak
Would it also make sense to set custom value of units spawned instead of a unit group?
No, often times custom value is needed for Unit Indexer systems to work properly, which help in attaching data to units are are used by a majority of systems you might want to import into your map. It's best not to use CV at all unless you know you will never need a unit indexer or are willing to rewrite your code if you do. A group in this case is perfectly adequate.
Also, at trigger 3, what purpose does SPAWN_TYPECOUNT have? Should it be used instead of SPAWN_MAX for the If - Conditions at trigger 3's loop?
Yes, I made a mistake writing there. It should be SPAWN_TYPECOUNT.
I am totally going to steal your triggers
That's the point of us posting triggers on this forum. They're always examples to be used at will.
I have set the map up linearly so the heroes face a few hundred of the same 3-5 units before better units are spawning instead so I only care about the total count of spawned units alive. I think of it as a queue where you have 1000 easy units, then 1000 medium units, then 1000 hard units etc...
The triggers are nearly the same:

  • Events
    • Time - Elapsed Game-time is 0.10 seconds
  • Conditions
  • Actions
    • Set SPAWN_MAX = 200 //max 200 spawns on the map at once
    • Set SPAWNS_KILLED = 0 //how many spawns have been killed total
    • Set SPAWN_SWITCHCOUNT = 1000 //after 1000 spawns we'll switch
    • Set SPAWN_PHASE = 1 //1 = early, 2 = mid, 3 = late, do as many as you want.
    • Set SPAWN_TYPE[1] = EarlyUnit 1
    • Set SPAWN_TYPE[2] = EarlyUnit 2
    • Set SPAWN_TYPE[3] = EarlyUnit 3
    • Set SPAWN_TYPE[4] = EarlyUnit 4
    • Set SPAWN_TYPECOUNT = 4
    • Set SPAWN_POINT = Center of Spawn Area Early <gen>
  • Events
    • Unit - A unit dies
  • Conditions
    • ((Triggering Unit) is in SpawnGroup) equal to true
  • Actions
    • Unit Group - Remove (Triggering Unit) from SpawnGroup
    • Set SPAWNS_KILLED = SPAWNS_KILLED + 1
    • If (All conditions are true) then (Then actions) else (Else actions)
      • If - Conditions
        • SPAWNS_KILLED greater than or equal to SPAWN_SWITCHCOUNT
      • Then - Actions
        • Set SPAWN_PHASE = SPAWN_PHASE + 1
        • Set SPAWNS_KILLED = 0
        • If (All conditions are true) then (Then actions) else (Else actions)
          • If - Conditions
            • SPAWN_PHASE equal to 2
          • Then - Actions
            • Custom script: call RemoveLocation(udg_SPAWN_POINT) //cleaning the point leak
            • Set SPAWN_POINT = Center of Spawn Area Mid <gen>
            • Set SPAWN_TYPECOUNT = 4 //if there aren't 4 types then you'd need to also change Typecount; I put it here for completeness
            • Set SPAWN_SWITCHCOUNT = 500 //in case you want mid to go faster you can change this variable too
            • Set SPAWN_TYPE[1] = MidUnit 1
            • Set SPAWN_TYPE[2] = MidUnit 2
            • Set SPAWN_TYPE[3] = MidUnit 3
            • Set SPAWN_TYPE[4] = MidUnit 4
          • Else - Actions
        • If (All conditions are true) then (Then actions) else (Else actions)
          • If - Conditions
            • SPAWN_PHASE equal to 3
          • Then - Actions
            • Custom script: call RemoveLocation(udg_SPAWN_POINT)
            • Set SPAWN_POINT = Center of Spawn Area Late <gen>
            • Set SPAWN_TYPECOUNT = 5 //say there's a 5th unit lategame
            • Set SPAWN_SWITCHCOUNT = 100000 //there's no easy way built into this method for the spawns to happen indefinitely, but putting a big number here is essentially good enough
            • Set SPAWN_TYPE[1] = LateUnit 1
            • Set SPAWN_TYPE[2] = LateUnit 2
            • Set SPAWN_TYPE[3] = LateUnit 3
            • Set SPAWN_TYPE[4] = LateUnit 4
            • Set SPANW_TYPE[5] = LateUnit 5
          • Else - Actions
      • Else - Actions
  • Events
    • Time - Every 2.00 seconds of game-time
  • Conditions
  • Actions
    • Set COUNT = (Number of Units in SpawnGroup)
    • If (Conditions) then (Actions) else (Actions)
      • If - Conditions
        • COUNT less than SPAWN_MAX
      • Then - Actions
        • For each (Integer A) from 1 to SPAWN_MAX - COUNT do (Actions)
          • Loop - Actions
            • Set WHICH_SPAWN = WHICH_SPAWN + 1
            • If (Conditions) then (Actions) else (Actions)
              • If - Conditions
                • WHICH_SPAWN greater than SPAWN_TYPECOUNT
              • Then - Actions
                • Set WHICH_SPAWN = 1
              • Else - Actions
            • Unit - Create 1 SPAWN_TYPE[WHICH_SPAWN] for (Random player from Legion of Monsters) at SPAWN_POINT facing Default building facing degrees
            • Unit Group - Add (Last created unit) to SpawnGroup
      • Else - Actions
To get the spawns to change, all you have to do is set a different SPAWN_POINT (if you want) and update SPAWN_TYPE[] as well as SPAWN_TYPECOUNT. Since the spawning happens by pulling from those variables all you have to do is change the unit types and they'll automatically start spawning those instead. You can do this at any time, so a timer could do it after 10 minutes instead of kills, or any other criteria. The way I wrote it checks when a spawn unit dies and increases the kill counter but you could use any trigger. The beauty of using the variable is that it's extremely easy to change on-the-fly for any reason!
 
Last edited:
Level 2
Joined
Dec 21, 2018
Messages
12
Thank you so much the help :D The triggers are really useful for me and perhaps other people encountering a similar problem with spawning a lot of units :-D I will convert the spawning system to yours. Only thing I cannot seem to wrap my head around is how to spawn boss units once in a while, but I can do that with a separate trigger. I guess I will use the SPAWNS_KILLED integer variable and wait for it to reach a certain value.

Since you have been so helpful and have a brilliant mind for triggers I have 2 more questions for you if you do not mind.

The following trigger also causes lag. It is used in the boss area, which is very very big, to move the units that the players have skipped past and teleport them to help the boss. The map is rather large and some spawns are spawning a lot of units but in a slow pace. This means that players who are not that great (or if they are not full house) can still progress, albeit slower, and train to become strong enough to still beat the map. So some spawns spawn a lot of units after a while and these are then sent to the boss area.

Is there a way to make this smarter?

  • For each (Integer Y) from 1 to 99999, do (Actions)
    • Loop - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Final Boss unit 0252 <gen> is alive) Equal to True
        • Then - Actions
          • Wait 0.00 seconds
          • Wait until ((Number of units in (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True)))) Greater than or equal to 1), checking every 5.00 seconds
          • Wait until ((Number of units in (Units in Entire Boss Area <gen> matching (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True))) Less than or equal to 100), checking every 1.00 seconds
          • Unit - Move (Random unit from (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and ((((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True) and (((Matching unit) is A structure) Equal to False instantly to (Center of Boss Area <gen>)
        • Else - Actions
          • Wait 0.00 seconds
          • Wait until ((Number of units in (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True)))) Greater than or equal to 1), checking every 5.00 seconds
          • Wait until ((Number of units in (Units in Entire Boss Area <gen> matching (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True))) Less than or equal to 300), checking every 1.00 seconds
          • Unit - Move (Random unit from (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and ((((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True) and (((Matching unit) is A structure) Equal to False instantly to (Center of Boss Area <gen>)
          • Wait until ((Number of units in (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True)))) Greater than or equal to 1), checking every 5.00 seconds
          • Wait until ((Number of units in (Units in Entire Boss Area <gen> matching (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True))) Less than or equal to 300), checking every 1.00 seconds
          • Unit - Move (Random unit from (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and ((((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True) and (((Matching unit) is A structure) Equal to False instantly to (Center of Boss Area <gen>)
          • Wait until ((Number of units in (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True)))) Greater than or equal to 1), checking every 5.00 seconds
          • Wait until ((Number of units in (Units in Entire Boss Area <gen> matching (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True))) Less than or equal to 300), checking every 1.00 seconds
          • Unit - Move (Random unit from (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and ((((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True) and (((Matching unit) is A structure) Equal to False instantly to (Center of Boss Area <gen>)
          • Wait until ((Number of units in (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True)))) Greater than or equal to 1), checking every 5.00 seconds
          • Wait until ((Number of units in (Units in Entire Boss Area <gen> matching (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True))) Less than or equal to 300), checking every 1.00 seconds
          • Unit - Move (Random unit from (Units in (Playable map area) matching (((Entire Boss Area <gen> contains (Matching unit)) Equal to False) and ((((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True) and (((Matching unit) is A structure) Equal to False instantly to (Center of Boss Area <gen>)
My last question is that I played the other map I posted triggers from in the last post. I noticed that it crashed when I played it with a friend after we had explored about 50% of the map. It crashed straight to desktop (no Blizzard crash prompt). Is there something I can do to make it playable all the way to the end? I noticed that it has a gold to lumber system. Does it leak, or is it otherwise problematic when you have the following triggers to handle it?

  • Money from Lumber
    • Events
      • Player - Player 1 (Red)'s Current gold becomes Less than 100000.00
      • Player - Player 2 (Blue)'s Current gold becomes Less than 100000.00
      • Player - Player 3 (Teal)'s Current gold becomes Less than 100000.00
      • Player - Player 4 (Purple)'s Current gold becomes Less than 100000.00
      • Player - Player 5 (Yellow)'s Current gold becomes Less than 100000.00
      • Player - Player 6 (Orange)'s Current gold becomes Less than 100000.00
      • Player - Player 7 (Green)'s Current gold becomes Less than 100000.00
      • Player - Player 8 (Pink)'s Current gold becomes Less than 100000.00
      • Player - Player 9 (Gray)'s Current gold becomes Less than 100000.00
      • Player - Player 10 (Light Blue)'s Current gold becomes Less than 100000.00
      • Player - Player 11 (Dark Green)'s Current gold becomes Less than 100000.00
      • Player - Player 12 (Brown)'s Current gold becomes Less than 100000.00
      • Player - Player 13 (Maroon)'s Current gold becomes Less than 100000.00
      • Player - Player 14 (Navy)'s Current gold becomes Less than 100000.00
      • Player - Player 15 (Turquoise)'s Current gold becomes Less than 100000.00
      • Player - Player 16 (Violet)'s Current gold becomes Less than 100000.00
      • Player - Player 17 (Wheat)'s Current gold becomes Less than 100000.00
      • Player - Player 18 (Peach)'s Current gold becomes Less than 100000.00
      • Player - Player 19 (Mint)'s Current gold becomes Less than 100000.00
      • Player - Player 20 (Lavender)'s Current gold becomes Less than 100000.00
      • Player - Player 21 (Coal)'s Current gold becomes Less than 100000.00
      • Player - Player 22 (Snow)'s Current gold becomes Less than 100000.00
      • Player - Player 23 (Emerald)'s Current gold becomes Less than 100000.00
      • Player - Player 24 (Peanut)'s Current gold becomes Less than 100000.00
    • Conditions
      • ((Triggering player) Current lumber) Greater than or equal to 1
    • Actions
      • Player - Add -1 to (Triggering player) Current lumber
      • Player - Add 100000 to (Triggering player) Current gold
  • Money to Lumber
    • Events
      • Player - Player 1 (Red)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 2 (Blue)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 3 (Teal)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 4 (Purple)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 5 (Yellow)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 6 (Orange)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 7 (Green)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 8 (Pink)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 9 (Gray)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 10 (Light Blue)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 11 (Dark Green)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 12 (Brown)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 13 (Maroon)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 14 (Navy)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 15 (Turquoise)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 16 (Violet)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 17 (Wheat)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 18 (Peach)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 19 (Mint)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 20 (Lavender)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 21 (Coal)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 22 (Snow)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 23 (Emerald)'s Current gold becomes Greater than or equal to 100000.00
      • Player - Player 24 (Peanut)'s Current gold becomes Greater than or equal to 100000.00
    • Conditions
      • ((Triggering player) Current gold) Greater than 1000000
    • Actions
      • Player - Add -100000 to (Triggering player) Current gold
      • Player - Add 1 to (Triggering player) Current lumber
One of the triggers in my above post gives gold based on the unit's point value on each unit kill to all players, so maybe it leaks an event so to speak?
 
Level 39
Joined
Feb 27, 2007
Messages
5,013
Your gold/lumber triggers can cause an infinite loop when one of them fires. Imagine a scenario where you have 100,000 gold and then spend 5000 of it on something. Your gold drops below 100k to 95k so the first trigger fires, which subtracts 1 lumber and gives 100k gold, bringing you to 195k. But that causes the second trigger to fire because your gold became > 100k, so it gives you a lumber and takes away 100k gold, leaving you with 95k. But that means you fire the first trigger again, which fires the second trigger again, which fires the first... etc. This loop of trigger firings will fully crash the game (not a threadcrash since a thread isn't timing out here).

To solve this simply turn off the other trigger temporarily whenever one of them fires. There is the Trigger - Turn off action. You may also consider that a player could get stuck with very little gold and a whole bunch of lumber but would be unable to buy anything if they can't manually convert that lumber into gold (and you would also have to turn off the triggers at that time too otherwise you'll get another loop when they manually convert).
I guess I will use the SPAWNS_KILLED integer variable and wait for it to reach a certain value.
You can periodically check it, say every 10 seconds or something. Even every 2 seconds wouldn't be a performance problem. Or add the check to the spawning or unit death triggers instead of making a new trigger.
The following trigger also causes lag. It is used in the boss area, which is very very big, to move the units that the players have skipped past and teleport them to help the boss. The map is rather large and some spawns are spawning a lot of units but in a slow pace. This means that players who are not that great (or if they are not full house) can still progress, albeit slower, and train to become strong enough to still beat the map. So some spawns spawn a lot of units after a while and these are then sent to the boss area.
Again the problem is not that the game is lagging, just your egregious use of the wait until condition action here. I'm not trying to chastise you, just trying to get you to understand that you should basically never use wait until condition, especially never inside a loop. As for how to do it better, that really depends how you are deciding which units should be teleported. How do you know which units have been 'skipped past' by players? Are they trying to reach some region somewhere?
 
Status
Not open for further replies.
Top