• 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.

Income Lag.

Status
Not open for further replies.
Level 1
Joined
Sep 20, 2018
Messages
2
Hello a few others and myself been having issues figuring out how to fix this issue where later in the game the trigger causes massive lag spikes at income. I have tried to add Waits but seem to only break the income not sure if i was placing them correctly but if some one could take a look and improve it would be helpful.

Code:
Give Income
    Events
        Time - Every 60.00 seconds of game time
    Conditions
    Actions
        For each (Integer B) from 1 to 24, do (Actions)
            Loop - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Race of (Player((Integer B)))) Equal to Human
                    Then - Actions
                        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            If - Conditions
                                (Current research level of Hero Mode  for (Player((Integer B)))) Equal to 0
                            Then - Actions
                                Custom script:   set bj_wantDestroyGroup = true
                                Set BuildingAmount = (Number of units in (Units owned by (Player((Integer B))) matching (((Matching unit) is A sapper) Equal to True)))
                                Player - Add (((BuildingAmount + 1) x CapitalIncome) x ((CivilWarMode x 2) + 1)) to (Player((Integer B))) Current gold
                                Player - Add (((BuildingAmount + 1) x CapitalIncome) x ((CivilWarMode x 2) + 1)) to (Player((Integer B))) Current lumber
                                For each (Integer A) from 1 to 9, do (Actions)
                                    Loop - Actions
                                        Custom script:   set bj_wantDestroyGroup = true
                                        Set BuildingAmount = (Number of units in (Units owned by (Player((Integer B))) of type IncomeBuildingType[(Integer A)]))
                                        Player - Add (BuildingAmount x BuildingIncomeAmount[(Integer A)]) to (Player((Integer B))) Current gold
                                For each (Integer A) from 14 to 22, do (Actions)
                                    Loop - Actions
                                        Custom script:   set bj_wantDestroyGroup = true
                                        Set BuildingAmount = (Number of units in (Units owned by (Player((Integer B))) of type IncomeBuildingType[(Integer A)]))
                                        Player - Add (BuildingAmount x BuildingIncomeAmount[(Integer A)]) to (Player((Integer B))) Current lumber
                            Else - Actions
                                Set BuildingAmount = (Number of units in (Units owned by (Player((Integer B))) matching (((Matching unit) is A sapper) Equal to True)))
                                Custom script:   set bj_wantDestroyGroup = true
                                Player - Add (CapitalIncome x ((CivilWarMode x 2) + 1)) to (Player((Integer B))) Current gold
                                Player - Add (CapitalIncome x ((CivilWarMode x 2) + 1)) to (Player((Integer B))) Current lumber
                                Player - Add (HeroIncome x HeroModeAlive[(Integer B)]) to (Player((Integer B))) Current gold
                                Player - Add (HeroIncome x HeroModeAlive[(Integer B)]) to (Player((Integer B))) Current lumber
                    Else - Actions
                        For each (Integer A) from 10 to 13, do (Actions)
                            Loop - Actions
                                Custom script:   set bj_wantDestroyGroup = true
                                Set BuildingAmount = (Number of units in (Units owned by (Player((Integer B))) of type IncomeBuildingType[(Integer A)]))
                                Player - Add (BuildingAmount x BuildingIncomeAmount[(Integer A)]) to (Player((Integer B))) Current gold
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Well, the bottleneck is coming from the (Number of units in (Units owned by (Player((Integer B))) of type IncomeBuildingType[(Integer A)])) lines. Picking every unit on the map many times in a row is not good for performance (especially so if the map is large or has lots of units active at once). In your case there are H*(18 or 1) + N*(3) of these being run when the income trigger goes off (H = # human players, N = # non-human players). If everyone is human and nobody's researched Hero Mode it will be 24*18 = 432 picks of every unit on the map.

You could also slightly improve performance by saving Player((Integer B)) into a variable instead of 'computing' many times per loop. Also one of your wantDestroys is misplaced, which could cause problems deleting groups you didn't mean to later on:
  • Set BuildingAmount = (Number of units in (Units owned by (Player((Integer B))) matching (((Matching unit) is A sapper) Equal to True)))
  • Custom script: set bj_wantDestroyGroup = true
Your two solutions for reducing the excessive lag are:
  1. Pre-store groups of each income unit type owned by each player. When an income building is built, add it to the proper groups; when one is destroyed, remove it from the proper group. I would suggest a fake 2D group array of size [24][22] using the formula [<player number>*<total number of income building types> + <income building type number>]. Done that way, Player(19)'s four groups of income buildings used for the non-Human check (10-13) are stored in indices [19*22+10], [19*22+11], [19*22+12], and [19*22+13]. Yes, this does completely ignore indices [0] through [22] but you're not gonna get anywhere near the max array index so it doesn't matter here.

  2. Grab one big group of all the player's units and loop through it one time counting up all the different types of income units into their own totals with a if-block sub-loop.
  • Events
    • Time - Every 60.00 seconds of game time
  • Conditions
  • Actions
    • For each (Integer B from 1 to 24 do (Actions)
      • Loop - Actions
        • Set IncomePlayer = Player((Integer B))
        • For each (Integer A) from 1 to 22 do (Actions)
          • Loop - Actions
            • Set IncomeCount[(Integer A)] = 0
        • Custom script: set bj_wantDestroyGroup = true
        • Unit Group - Pick every unit in (Units owned by IncomePlayer) and do (Actions)
          • Loop - Actions
            • Set IncomeType = (Unit-type of (Picked Unit))
            • For each (Integer A) from 1 to 22 do (Actions)
              • Loop - Actions
                • If (All conditions are true) then do (Then actions) else do (Else actions)
                  • If - Conditions
                    • IncomeType equal to IncomeBuildingType[(Integer A)]
                  • Then - Actions
                    • Set IncomeCount[(Integer A)] = IncomeCount[(Integer A)] + 1
                    • Custom script: exitwhen true //exits the loop because we found a match
                  • Else - Actions
        • -------- At this point the IncomeCount[] array has all the info you need for each of the subsequent 3 cases except maybe the sappers? I don't know why those are found differently --------
        • If (All conditions are true) then do (Then actions) else do (Else actions)
          • If - Conditions
            • (Race of (IncomePlayer) equal to Human)
          • Then - Actions
            • If (All conditions are true) then do (Then actions) else do (Else actions)
              • If - Conditions
                • (Current research level of Hero Mode for (IncomePlayer)) Equal to 0
              • Then - Actions
                • Custom script: set bj_wantDestroyGroup = true
                • Set BuildingAmount = (Number of units in (Units owned by (IncomePlayer) matching (((Matching unit) is A sapper) Equal to True)))
                • Player - Add (((BuildingAmount + 1) x CapitalIncome) x ((CivilWarMode x 2) + 1)) to (IncomePlayer) Current gold
                • Player - Add (((BuildingAmount + 1) x CapitalIncome) x ((CivilWarMode x 2) + 1)) to (IncomePlayer) Current lumber
                • For each (Integer A) from 1 to 9 do (Actions)
                  • Loop - Actions
                    • Player - Add (IncomeCount[(Integer A)] x BuildingIncomeAmount[(Integer A)]) to (IncomePlayer) Current gold
                • For each (Integer A) from 14 to 22 do (Actions)
                  • Loop - Actions
                    • Player - Add (IncomeCount[(Integer A)] x BuildingIncomeAmount[(Integer A)]) to (IncomePlayer) Current gold
              • Else - Actions
                • Custom script: set bj_wantDestroyGroup = true
                • Set BuildingAmount = (Number of units in (Units owned by (IncomePlayer) matching (((Matching unit) is A sapper) Equal to True)))
                • Player - Add (CapitalIncome x ((CivilWarMode x 2) + 1)) to (IncomePlayer) Current gold
                • Player - Add (CapitalIncome x ((CivilWarMode x 2) + 1)) to (IncomePlayer) Current lumber
                • Player - Add (HeroIncome x HeroModeAlive[(Integer B)]) to (IncomePlayer) Current gold
                • Player - Add (HeroIncome x HeroModeAlive[(Integer B)]) to (IncomePlayer) Current lumber
          • Else - Actions
            • For each (Integer A) from 10 to 13 do (Actions)
              • Loop - Actions
                • Player - Add (IncomeCount[(Integer A)] x BuildingIncomeAmount[(Integer A)]) to (IncomePlayer) Current gold
 
Status
Not open for further replies.
Top