• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Solved] This trigger causes lag, help needed!!

Status
Not open for further replies.
Level 17
Joined
Nov 12, 2016
Messages
796
hi everyone, so i made this trigger and it lags upon every x amount of time set in the periodic time event, its not as noticeable if one has less then 50 units on the map but as more are trained it happens quite often.
so what did i do wrong in this ?? i have no idea.
also as you see in the screen shot there are 2 parts to this trigger, but do notice that its not just this 2 parts it goes down and down for about 7-8 (more planning to be add) for all kinds of different buffs used to function verious abilities. (i also think i overcheck the trigger i might remove 1 one them but for now i can really use some extra help in getting this lag removed)
new stuff 2.PNG
 
Level 17
Joined
Nov 12, 2016
Messages
796
  • Events
    • Time - Every 1.00 seconds of game time
  • Conditions (nothing is set here)
  • Actions
    • Set ShadowAura = (Units in (Playable map area) matching ((((Matching unit) has buff Shadow aura 1) Equal to True) or ((((Matching unit) has buff Shadow aura 2) Equal to True) or (((Matching unit) has buff Shadow aura 3) Equal to True))))
    • Unit Group - Pick every unit in ShadowAura and do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) has buff Shadow aura 1) Equal to True
          • Then - Actions
            • Unit - Add Shadow aura hider 1 to (Picked unit)
          • Else - Actions
            • Unit - Remove Shadow aura hider 1 from (Picked unit)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • ((Picked unit) has buff Shadow aura 2) Equal to True
              • Then - Actions
                • Unit - Add Shadow aura hider 2 to (Picked unit)
              • Else - Actions
                • Unit - Remove Shadow aura hider 2 from (Picked unit)
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • ((Picked unit) has buff Shadow aura 3) Equal to True
                  • Then - Actions
                    • Unit - Add Shadow aura hider 3 to (Picked unit)
                  • Else - Actions
                    • Unit - Remove Shadow aura hider 3 from (Picked unit)
    • Custom script: call DestroyGroup(udg_ShadowAura)
    • Set ShadowAura = (Units in (Playable map area) matching (((Matching unit) has buff Codex of Knight's Prime) Equal to True))
    • Unit Group - Pick every unit in ShadowAura and do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) has buff Codex of Knight's Prime) Equal to True
          • Then - Actions
            • Unit - Add COK Prime Booster to (Picked unit)
          • Else - Actions
            • Unit - Remove COK Prime Booster from (Picked unit)
    • Custom script: call DestroyGroup(udg_ShadowAura) [trigger/]
  • (it does not end here but its all the same as the 2 examples above for about 7-8 more of this same thing used... so if one is fixed i can use it fix othersaswell)
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
Hmmmmmm... I'd say reduce it to only one unit group pick. Each of these:
  • Set ShadowAura = (Units in (Playable map area) matching ((((Matching unit) has buff Shadow aura 1) Equal to True) or ((((Matching unit) has buff Shadow aura 2) Equal to True) or (((Matching unit) has buff Shadow aura 3) Equal to True))))
Interpolates through all units in the map and does checks to see if they are what you are looking for. Those are extremely expensive if I am not mistaken.

Instead, turn it into a single all-units group like:
  • Event
    • Time - Every 1.00 seconds of game time
  • Conditions
  • Actions
    • Set UnitsGroupToUse = (Units in (Playable map area)
    • Unit Group - Pick every unit in UnitsGroupToUse and do (Actions)
      • Loop - Actions
        • If (Picked unit has Buff1)
          • Then
            • Do Stuff for Buff1
        • If (Picked unit has Buff2)
          • Then
            • Do Stuff for Buff2
        • If (Picked unit has Buff3)
          • Then
            • Do Stuff for Buff3
        • If (Picked unit has Buff...)
          • Then
            • Do Stuff for Buff...
        • If (Picked unit has BuffN)
          • Then
            • Do Stuff for BuffN
Otherwise, split it into multiple triggers so they do not run all the actions at the same time.

Hope this helps!
-Ned
 
Level 17
Joined
Nov 12, 2016
Messages
796
thanks of the tip man, i'll try and see what happens.

i originally had all of em split but i thought if i could get it to work with a single trigger then why not as i and i felt it was laggin more and more i made one of these triggers...

if anyone has any other suggestions i'm all ears...
 
Last edited:
Level 16
Joined
Mar 25, 2016
Messages
1,327
Yes nedio95 is right.
Using matching units is not efficient here, because the game still has loop through all units on the map checking for the conditions.

Further optimization would be to have a constant unit group and adding/removing units to it when the enter/leave the map, so you do not have to create a unit group every second.

Also as he said splitting it into different times will help. Just using two triggers that run every 1 seconds won't help, but if you second trigger that runs every 1 seconds, but starts 0.5 seconds after the first one this can improve performance.

Combining these two approaches and having several unit groups and distributing units somewhat equally among them should increase the performance by a lot.
Let's say you have 4 groups, then you would have one trigger for each group. The trigger runs every second, but each trigger has an offset of 0.25 seconds to the previous one.
Trigger 1 starts after 0 seconds, trigger 2 starts after 0.25 seconds, trigger 3 after 0.5 seconds, trigger 4 after 0.75 seconds.
This means less actions performed at the same time which results in less lag, even though the total amount of actions per second is at least as high as before.
 

Wrda

Spell Reviewer
Level 28
Joined
Nov 18, 2012
Messages
2,011
Also as he said splitting it into different times will help. Just using two triggers that run every 1 seconds won't help, but if you second trigger that runs every 1 seconds, but starts 0.5 seconds after the first one this can improve performance.

Combining these two approaches and having several unit groups and distributing units somewhat equally among them should increase the performance by a lot.
Let's say you have 4 groups, then you would have one trigger for each group. The trigger runs every second, but each trigger has an offset of 0.25 seconds to the previous one.
Trigger 1 starts after 0 seconds, trigger 2 starts after 0.25 seconds, trigger 3 after 0.5 seconds, trigger 4 after 0.75 seconds.
This means less actions performed at the same time which results in less lag, even though the total amount of actions per second is at least as high as before.
No offense but that just seems ridiculous and won't solve the lag at all.

Yes nedio95 is right.
Using matching units is not efficient here, because the game still has loop through all units on the map checking for the conditions.

Further optimization would be to have a constant unit group and adding/removing units to it when the enter/leave the map, so you do not have to create a unit group every second.
Yes, a constant unit group would be an option but in this trigger it won't work because you can't detect whether a dying unit had/has a buff, thus you can't remove the unit from group.
I'd suggest to make a unit variable and make "set TempUnit = (Picked Unit)" and then use the variable for other actions, you would reduce a great part of the function calls you're calling.
 
Level 16
Joined
Mar 25, 2016
Messages
1,327
No offense but that just seems ridiculous and won't solve the lag at all.
Lag spikes occur, if too many actions are performed at the same time. In this case you would have a lag spike every second. My approach reduces the amount of actions at the same time, by performing them over this one second, but only a small portion at the same time. This means you would have more "lag spikes", but they are much smaller. The goal is to make them so small, that they can no longer be noticed, so they are no longer lag spikes.
I can provide a map showcasing the performance difference.
 
  • Set ShadowAura = (Units in (Playable map area) matching ((((Matching unit) has buff Shadow aura 1) Equal to True) or ((((Matching unit) has buff Shadow aura 2) Equal to True) or (((Matching unit) has buff Shadow aura 3) Equal to True))))
  • Unit Group - Pick every unit in ShadowAura and do (Actions)
    • Loop - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Picked unit) has buff Shadow aura 1) Equal to True
        • Then - Actions
          • Unit - Add Shadow aura hider 1 to (Picked unit)
        • Else - Actions
          • Unit - Remove Shadow aura hider 1 from (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) has buff Shadow aura 2) Equal to True
            • Then - Actions
              • Unit - Add Shadow aura hider 2 to (Picked unit)
            • Else - Actions
              • Unit - Remove Shadow aura hider 2 from (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) has buff Shadow aura 3) Equal to True
                • Then - Actions
                  • Unit - Add Shadow aura hider 3 to (Picked unit)
                • Else - Actions
                  • Unit - Remove Shadow aura hider 3 from (Picked unit)
  • Custom script: call DestroyGroup(udg_ShadowAura)
  • Set ShadowAura = (Units in (Playable map area) matching (((Matching unit) has buff Codex of Knight's Prime) Equal to True))
  • Unit Group - Pick every unit in ShadowAura and do (Actions)
    • Loop - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Picked unit) has buff Codex of Knight's Prime) Equal to True
        • Then - Actions
          • Unit - Add COK Prime Booster to (Picked unit)
        • Else - Actions
          • Unit - Remove COK Prime Booster from (Picked unit)
  • Custom script: call DestroyGroup(udg_ShadowAura)
(It does not end here but its all the same as the 2 examples above for about 7-8 more of this same thing used... so if one is fixed i can use it fix others as well)

Solution already posted by @nedio95

Hmmmmmm... I'd say reduce it to only one unit group pick. Each of these:
  • Set ShadowAura = (Units in (Playable map area) matching ((((Matching unit) has buff Shadow aura 1) Equal to True) or ((((Matching unit) has buff Shadow aura 2) Equal to True) or (((Matching unit) has buff Shadow aura 3) Equal to True))))
Interpolates through all units in the map and does checks to see if they are what you are looking for. Those are extremely expensive if I am not mistaken.

Instead, turn it into a single all-units group like:
  • Event
    • Time - Every 1.00 seconds of game time
  • Conditions
  • Actions
    • Set UnitsGroupToUse = (Units in (Playable map area)
    • Unit Group - Pick every unit in UnitsGroupToUse and do (Actions)
      • Loop - Actions
        • If (Picked unit has Buff1)
          • Then
            • Do Stuff for Buff1
        • If (Picked unit has Buff2)
          • Then
            • Do Stuff for Buff2
        • If (Picked unit has Buff3)
          • Then
            • Do Stuff for Buff3
        • If (Picked unit has Buff...)
          • Then
            • Do Stuff for Buff...
        • If (Picked unit has BuffN)
          • Then
            • Do Stuff for BuffN
Otherwise, split it into multiple triggers so they do not run all the actions at the same time.

Hope this helps!
-Ned

I would recommend assigning the (picked unit) to a variable as that would waste some potentially crucial resources on callback.

Try and avoid picking every unit on the map. I am sure there is a way one could get a much smaller unit group to filter through.

This would be a viable approach, but we would need more information (in this case, triggers or details on what's supposed to happen) in order to understand what's going on and suggest the appropriate optimizations.
 
Level 17
Joined
Nov 12, 2016
Messages
796
Thank you from all of you trying to support me on this matter, and sorry if i responded late.


No offense but that just seems ridiculous and won't solve the lag at all.


Yes, a constant unit group would be an option but in this trigger it won't work because you can't detect whether a dying unit had/has a buff, thus you can't remove the unit from group.
I'd suggest to make a unit variable and make "set TempUnit = (Picked Unit)" and then use the variable for other actions, you would reduce a great part of the function calls you're calling.

i will certainly keep in mind of what you said but i will first try to make what nedio95 said supported with what jampion suggested.
this topic will still stay open for quite a while now as i am caught in a very bad situation in life and cant put down all my attention to this.

Solution already posted by @nedio95



I would recommend assigning the (picked unit) to a variable as that would waste some potentially crucial resources on callback.



This would be a viable approach, but we would need more information (in this case, triggers or details on what's supposed to happen) in order to understand what's going on and suggest the appropriate optimizations.

in regards of this MyPad if i wanted to clarify of what i'm exactly doing: the map that i am making has no dispells/purge (debuffer's in general) so i'm trying to take an advantage of this by using a coded buff system to run the functionalities of a sizeable number of the abilities i make just by the function of "a unit has a buff on it" and also depending on the idea of the various types of abilities i come up with it can actually be used to make a lot of unique stuff as it can also serve as a great detection tool.

so all in all, i will "in time" will be trying to make this system work with as less or no lag as i can.
i will certainly update this topic in the coming weeks as soon as i have some time to sit down and try the suggestions all of you said and generally wrap my head around it.
 
Last edited:
Level 17
Joined
Nov 12, 2016
Messages
796
(its technically 48 hours passed so i hope i'm not braking any rules)

whichever just to update that my issue was fixed thanks to "Jampion" (that helped me with the trigger's in person) and "nedio95" (who suggested the idea)

and thanks to everyone else who chimed in.
 
Status
Not open for further replies.
Top