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

Really old map lagging. Probably memory leaks. Warcraft version 1.26

Status
Not open for further replies.
Level 2
Joined
Mar 5, 2020
Messages
8
Hello,

I have been a longtime stalker of this beautiful website which helped me ALOT during the years. Much praise!

My problem is the following:

I have a map (very very old one) which I still play to this day. When I play it with my friends, it works perfectly. When I add 1-2-3 AIs max, it still runs smoothly. However, when I add more than 3 AIs, it begins to lag. The more computers I add, the more it lags. It seems to me like the game lags a bit the first 5-10 minutes, and then more as the game goes on. It seems to have the symptoms of a memory leak.

It would be a dream if I could play with lets say 6-10 AIs without the delay.

I`m assuming (pretty much sure) the triggers are causing the lag. The problem is I don`t know which ones.

If it`s possible I`d like to link them all here (5 in total), maybe someone knows where the delay is coming from / what needs fixing.

I`ll start with the one which (to me) seems to be the most likely one to cause lag.

  • AI
    • Events
      • Unit - A unit enters (Playable map area)
      • Unit - A unit owned by Player 1 (Red) Gains a level
      • Unit - A unit owned by Player 2 (Blue) Gains a level
      • Unit - A unit owned by Player 3 (Teal) Gains a level
      • Unit - A unit owned by Player 4 (Purple) Gains a level
    • Conditions
      • ((Owner of (Triggering unit)) controller) Equal to Computer
    • Actions
      • If ((Unit-type of (Triggering unit)) Equal to Dark Bandit Knight) then do (If ((Hero level of (Triggering unit)) Equal to 1) then do (Unit - Add Holy Light (Bandit)1 to (Triggering unit)) else do (Do nothing)) else do (Do nothing)
      • If ((Unit-type of (Triggering unit)) Equal to Dark Bandit Knight) then do (If ((Hero level of (Triggering unit)) Equal to 3) then do (Unit - Remove Holy Light (Bandit)1 from (Triggering unit)) else do (Do nothing)) else do (Do nothing)
      • If ((Unit-type of (Triggering unit)) Equal to Dark Bandit Knight) then do (If ((Hero level of (Triggering unit)) Equal to 3) then do (Unit - Add Holy Light (Bandit)2 to (Triggering unit)) else do (Do nothing)) else do (Do nothing)

And the list of Actions goes on for every hero (16 lines per hero x16 heroes = 256 lines).
Also, there are 5 events (4 players + the 1st one). If the map has 12 players, there will be 13 events.

Could it be that it lags because a trigger has 256 lines of Action?

PS: In the trigger: Dark Bandit Knight is the hero, Holy Light (Bandit)1 is a unit spell (the map was made before they added levels to unit spells), and it works: the computer AI learns the spell and casts it regularly! ...but it lags if 4+ AIs are added :(

Any help would be greatly appreciated!
Thank you for reading this! Have a wonderful day!
 
Level 2
Joined
Mar 5, 2020
Messages
8
The other Triggers are:

  • Tavern Heroes
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Player - Limit training of Trydentiq to 1 for Player 1 (Red)
      • Player - Limit training of Trydentiq to 1 for Player 2 (Blue)
      • Player - Limit training of Trydentiq to 1 for Player 3 (Teal)
      • Player - Limit training of Trydentiq to 1 for Player 4 (Purple)
Which contains 12x6 heroes = 72 Actions

  • Trydentiq
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
    • Actions
      • Wait 60.00 game-time seconds
      • If ((Unit-type of (Triggering unit)) Equal to Trydentiq) then do (Hero - Add 100 experience to (Triggering unit), Show level-up graphics) else do (Do nothing)
      • Wait 60.00 game-time seconds
      • If ((Unit-type of (Triggering unit)) Equal to Trydentiq) then do (Hero - Add 100 experience to (Triggering unit), Show level-up graphics) else do (Do nothing)


  • AI Gain
    • Events
      • Time - Elapsed game time is 2.00 seconds
      • Unit - A unit enters (Playable map area)
    • Conditions
      • ((Owner of (Triggering unit)) controller) Equal to Computer
    • Actions
      • Hero - Make (Owner of (Triggering unit)) Heroes gain 200.00% experience from future kills

  • AI Resources
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • ((Owner of (Triggering unit)) controller) Equal to Computer
    • Actions
      • Wait 600.00 game-time seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Owner of (Triggering unit)) controller) Equal to Computer
          • A Equal to True
        • Then - Actions
        • If ((Race of (Owner of (Triggering unit))) Equal to Undead) then do (Player - Add 5000 to (Owner of (Triggering unit)) Current lumber) else do (Do nothing)
          • Set A = False
        • Else - Actions
          • Do nothing
For this trigger, variable A is set as true by default.


Does anyone think that these trigger could`ve been done in a more efficient way? (to cause less lag)

Any help is much appreciated, thank you!
 
Level 6
Joined
Dec 31, 2017
Messages
138
I don't see a reason for AI and AI Gain to have "A unit enters (Playable map area)" Events.

AI Gain should (at Map Init or 2.00 sec elapsed) for each player in (All players) check if (Picked player) is controlled by Computer and then make (Picked player) get 200% exp.

I would've checked these 2 issues first.
 
Level 2
Joined
Mar 5, 2020
Messages
8
Thank you, Deserted! I will try your suggestion tomorrow, when I can get access to the map.
I`ll post an update ASAP.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
I`ll start with the one which (to me) seems to be the most likely one to cause lag.
This should not cause lag outside of initial hero learning ability data loading lag (unavoidable). It could be optimized by moving the unit type test to once in the trigger conditions instead of repeating the test 3 times in the actions. If the same trigger is used for many heroes, one can use multiple action/condition blocks to achieve something similar and reduce the number of comparisons.
And the list of Actions goes on for every hero (16 lines per hero x16 heroes = 256 lines).
Also, there are 5 events (4 players + the 1st one). If the map has 12 players, there will be 13 events.
In 1 trigger? Multiple triggers could cause issues since the Unit Enters Playable Map Area event is extremely resource intensive and will even break the path finder if used too much.
Could it be that it lags because a trigger has 256 lines of Action?
256 should be fine. One could optimize it with some data structures so fewer comparisons are made.
Trydentiq
That trigger is a major suspect. Every time a unit enters map it is adding net traffic which can easily cause lag, especially in most maps where units are added frequently. Move the unit type test to the trigger conditions.

Also you might want to merge this into a single trigger based on what I said above since Unit Enters Playable Map Area is a non-trivial event that only 1 trigger in a map should have. One can make that trigger run other triggers to prevent it from becoming monolithic and keep code more maintainable.
Again this should share the Unit Enters Playable Map Area event with he other triggers. The elapsed game time event makes no sense since the conditions will fail as there is no triggering unit in response to that event.

Seeing how the action is permanent and applies to all heroes one does not even need those events. One can set it to run at map initialization and use a player group loop to apply it to all computer players.
AI Resources
Again this should share the Unit Enters Playable Map Area event with he other triggers.

This could likely use another event. Such as elapsed game time of 600 seconds and a player group loop to add resources to all computer players.
Does anyone think that these trigger could`ve been done in a more efficient way? (to cause less lag)
Yes one could optimize these triggers with correct event usage and data structures.

However be aware that melee or AI editor based AI is just lag and stutter prone due to how the native AI works. For example if melee AI cannot find a building spot for a stock building there can be a drop of many frames every few seconds as the AI keeps trying to place the building and failing to do so after some exhaustive timeout.
 
Level 2
Joined
Mar 5, 2020
Messages
8
Thank you, Dr Super Good! I will try to make some modifications to see how it works afterwards.

The AI is the melee one, the units are pretty much the same (so it works in the same way that the frozen throne AI works). The buildings/upgrades are also the same.
The heroes are the same, but reworked. There are some extra heroes, but the AI doesn`t use them. Hero spells are not the same, thats why it needs triggers.

Thanks again for the detailed reply, really appreciated!
 
Level 2
Joined
Mar 5, 2020
Messages
8
I have replaced the AI Gain trigger with the following trigger, as Deserted suggested:
  • AI Gain
    • Events
      • Time - Elapsed game time is 2.00 seconds
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • If (((Picked player) controller) Equal to Computer) then do (Hero - Make (Picked player) Heroes gain 200.00% experience from future kills) else do (Do nothing)
and it seems to work fine! thanks again!

I will try to make more changes from the list suggested by Dr Super Good, but I will have to wait for the weekend until I can test over LAN. (in single player it never lags)

I was wondering about a few more things though:

If I use: Player group-pick every player action (as shown above in the trigger), do I have to "kill" the group afterwards with a command? or is this only for Unit groups actions?

Also: when using the wait X seconds command, do I have to delete the timer even if it is not stored in a variable in order to free up any possible memory leaks?
for example:
  • Wait 1.00 game-time seconds
  • If ((Unit-type of (Triggering unit)) Equal to Goblin Trader) then do (Hero - Create (Random level 1 Permanent item-type) and give it to (Triggering unit)) else do (Do nothing)
  • Wait 60.00 game-time seconds
just as a mention: I have read the "things that leak" thread. Please excuse me if this was asked before.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
If I use: Player group-pick every player action (as shown above in the trigger), do I have to "kill" the group afterwards with a command? or is this only for Unit groups actions?
All Players is constant so does not need to be destroyed.
Also: when using the wait X seconds command, do I have to delete the timer even if it is not stored in a variable in order to free up any possible memory leaks?
The timer gets destroyed but the function used by the action leaks a handle index when run with the JASS2 virtual machine due to a bug.
 
Level 2
Joined
Mar 5, 2020
Messages
8
All Players is constant so does not need to be destroyed.

The timer gets destroyed but the function used by the action leaks a handle index when run with the JASS2 virtual machine due to a bug.

Understood, so no other action should be used, it should work fine like this. I will test today on LAN.
Thank you for the explanations!

Sorry for the late replies, but I keep getting "waiting for moderation" for every message due to having a new account.
 
Level 2
Joined
Mar 5, 2020
Messages
8
I did the testing, and actually, it works MUCH MUCH better! yaay!
However, it still has a bit of lag.

Is there any way to optimize this?

  • Trydentiq
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • ((Unit-type of (Triggering unit)) Equal to Goblin Trader) or ((Unit-type of (Triggering unit)) Equal to Trydentiq)
    • Actions
      • If ((Unit-type of (Triggering unit)) Equal to Goblin Trader) then do (Hero - Create (Random level 2 Charged item-type) and give it to (Triggering unit)) else do (Do nothing)
      • If ((Unit-type of (Triggering unit)) Equal to Trydentiq) then do (Hero - Add 100 experience to (Triggering unit), Show level-up graphics) else do (Do nothing)
Is there any way to use the same trigger actions without using the 'A unit enters playable map area event' ?
I have tried alot, but I cannot seem to find a different event which will suite this action. (for a melee-type game).

Also: if the trigger "Trydentiq" (shown above) is used without the condition (only with the condition in the actions) will it cause more CPU stress? My train of thought was: that if I put that condition there, it will not run the actions (another two conditions) for 'A unit enters playable map area' that is not = to Goblin trader / Trydentiq so it will cause less lag.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Is there any way to use the same trigger actions without using the 'A unit enters playable map area event' ?
You can attach that to one trigger and then have that trigger run all sub triggers that use the same event. One wants just a single trigger with the unit enters playable map area event as the event itself is the demanding part due to creating a very large region with a lot of map cells.
Also: if the trigger "Trydentiq" (shown above) is used without the condition (only with the condition in the actions) will it cause more CPU stress? My train of thought was: that if I put that condition there, it will not run the actions (another two conditions) for 'A unit enters playable map area' that is not = to Goblin trader / Trydentiq so it will cause less lag.
Yes it puts more CPU load because it has to evaluate the conditions twice.

With scripting directly one can use a multiple if then else construct which is even more efficient since it can skip evaluating the rest if a match is found.

Creating items that have not existed before on the map may cause stutter while their assets and data are loaded. Same goes for units and even learning abilities. This is unavoidable outside of pre-placing the units on the map and removing them at map initialization which will move that stutter to the loading screen where people do not notice it (and make loading take longer). This is why many complex RPGs have long "loading" times at the beginning of the map.
 
Status
Not open for further replies.
Top