• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Variables and Triggers

Do a large number of variables and triggers even when they are properly removed and cleaned up using custom script calls cause lag or performance issues? I’m asking because I’m currently creating custom abilities and relying heavily on them, so I’m concerned about their impact on overall performance

1776979871332.png
1776979876702.png
1776979881140.png
1776979885428.png
1776979889468.png
1776979979866.png
 
No. A large number of variables and triggers will not cause lag or performance issues if they are properly cleaned and well-structured. The engine can handle thousands of variables without breaking a sweat.

However, looking at your screenshots, you are going to run into performance and gameplay issues for other reasons:

Hidden Leaks - In your Invoker trigger, you use Position of VS_Caster twice but never clean it up. You need to assign that to a point variable (like you did in Scale) and use call RemoveLocation() afterward.

Waits in Damage Events- Your Trans trigger uses a Wait 8.00 seconds action. Using waits inside high-frequency events like 'Takes Damage' is very dangerous. It breaks MUI, overwrites your global variables if the unit attacks again, and can cause the trigger to bug out. You should use a Timer system or a Unit Indexer instead.

Using Unit - A unit Takes damage globally is very taxing. Every time a squirrel gets hit on the other side of the map, this trigger fires just to check if the Damage source is your summon. It’s much more efficient to register the damage event specifically to your VS_Summon when it is first created.


Consolidate: You have Invoker and Scale running on the exact same event. Combine them into one trigger to make the engine's job easier.

! Also, note about the Do Nothing Action: It isn't actually a "null" operation that the compiler skips; it’s a function call. Every time that Else branch hits, the engine has to pause, call the DoNothing() function in common.j, and then return. While one call won't lag a map, putting it inside high-frequency triggers like Takes Damage or Every 0.01 seconds is essentially asking the CPU to run a lap for no reason, so I’d delete that.


By the way, you should probably move this thread to the World Editor Help zone, where you will get more eyes from tech ppl.
 
The Axolotl's answer was great. I'd just like to add one detail, which is to point out the Thread written by PurgeandFire about the use of local variables in GUI (Here). In that Thread, he also explains the correct way to use waits.
 
No. A large number of variables and triggers will not cause lag or performance issues if they are properly cleaned and well-structured. The engine can handle thousands of variables without breaking a sweat.

However, looking at your screenshots, you are going to run into performance and gameplay issues for other reasons:

Hidden Leaks - In your Invoker trigger, you use Position of VS_Caster twice but never clean it up. You need to assign that to a point variable (like you did in Scale) and use call RemoveLocation() afterward.

Waits in Damage Events- Your Trans trigger uses a Wait 8.00 seconds action. Using waits inside high-frequency events like 'Takes Damage' is very dangerous. It breaks MUI, overwrites your global variables if the unit attacks again, and can cause the trigger to bug out. You should use a Timer system or a Unit Indexer instead.

Using Unit - A unit Takes damage globally is very taxing. Every time a squirrel gets hit on the other side of the map, this trigger fires just to check if the Damage source is your summon. It’s much more efficient to register the damage event specifically to your VS_Summon when it is first created.


Consolidate: You have Invoker and Scale running on the exact same event. Combine them into one trigger to make the engine's job easier.

! Also, note about the Do Nothing Action: It isn't actually a "null" operation that the compiler skips; it’s a function call. Every time that Else branch hits, the engine has to pause, call the DoNothing() function in common.j, and then return. While one call won't lag a map, putting it inside high-frequency triggers like Takes Damage or Every 0.01 seconds is essentially asking the CPU to run a lap for no reason, so I’d delete that.


By the way, you should probably move this thread to the World Editor Help zone, where you will get more eyes from tech ppl.
1776997888097.png
1776997899790.png


is it better this way?
 
is it better this way?
Converting VS_Timer to an Integer is an odd choice. You should just check if it's Greater than or equal to 8.00. Also, account for floating point error, so check if it's >= 7.99 OR set VS_Timer to say 0.01 instead of 0.00. Otherwise, you may round it down when converting it to an Integer and subtract a second from the duration. Also, 1.00 second is unnecessarily long, don't be afraid to use something like 0.10 seconds if you want better precision. You can also use a Timer variable for perfect precision.

For further performance gains, you could toggle the Trans trigger On/Off. So On while a VS_Summon exists and Off while this is no longer true.

Also, there's no reason to use Custom Script to destroy VS_Effect, but not a big deal.
 
Last edited:
Converting VS_Timer to an Integer is an odd choice. You should just check if it's Greater than or equal to 8.00. Also, account for floating point error, so check if it's >= 7.99 OR set VS_Timer to say 0.01 instead of 0.00. Otherwise, you may round it down when converting it to an Integer and add an extra 1 second to the duration. Also, 1.00 second is unnecessarily long, don't be afraid to use something like 0.10 seconds if you want better precision. You can also use a Timer variable.

For further performance gains, you could toggle the Trans trigger On/Off. So On while a VS_Summon exists and Off when this is no longer true.

Also, there's no reason to use Custom Script to destroy VS_Effect, but not a big deal.

Thank you so much! It’s surprising how much simpler it was than it seemed to be. Thank you!
 
One final hurdle to keep in mind

– this isn’t MUI-safe yet. You’re currently using a single VS_Timer and VS_Transformed, so if multiple summons exist simultaneously they’ll overwrite each other’s state. This will cause issues if you expand the system to include multiple units or multiplayer. You’ll need to manage durations resetting or effects ending incorrectly.

To fix this, store the timer per unit. You can do this using a Unit Indexer or arrays, or simply a timer per unit. This way each summon tracks its own duration independently.

What you have now works for a single instance but won’t scale safely.

To achieve this, you can refer to Uncle’s signature – Unit/Dynamic Indexing. You’ve got the solid logic covered so why not explore further.

The tutorial O_Vazio linked is a classic-shadowing local variables, is a great way to handle MUI for simple spells. However, I wouldn't rely on it as your only solution for a complex project.

If you want your map to be truly scalable, l'd suggest combining that knowledge with a Unit Indexer.

Indexing lets you store data (like your VS_Stacks) directly to the unit itself. That way, you aren't fighting the engine's 'scope' rules-the data just follows the unit everywhere. It's also worth taking a moment to look at how GUl gets parsed into JASS/ Lua; once you understand how the functions actually execute under the hood, you'll stop worrying about too many variables and start focusing on clean architecture.
 
Last edited:
One final hurdle to keep in mind

– this isn’t MUI-safe yet. You’re currently using a single VS_Timer and VS_Transformed, so if multiple summons exist simultaneously they’ll overwrite each other’s state. This will cause issues if you expand the system to include multiple units or multiplayer. You’ll need to manage durations resetting or effects ending incorrectly.

To fix this, store the timer per unit. You can do this using a Unit Indexer or arrays, or simply a timer per unit. This way each summon tracks its own duration independently.

What you have now works for a single instance but won’t scale safely.

To achieve this, you can refer to Uncle’s signature – Unit/Dynamic Indexing. You’ve got the solid logic covered so why not explore further.

The tutorial O_Vazio linked is a classic-shadowing local variables, is a great way to handle MUI for simple spells. However, I wouldn't rely on it as your only solution for a complex project.

If you want your map to be truly scalable, l'd suggest combining that knowledge with a Unit Indexer.

Indexing lets you store data (like your VS_Stacks) directly to the unit itself. That way, you aren't fighting the engine's 'scope' rules-the data just follows the unit everywhere. It's also worth taking a moment to look at how GUl gets parsed into JASS/ Lua; once you understand how the functions actually execute under the hood, you'll stop worrying about too many variables and start focusing on clean architecture.
1777041517969.png


Thank you very much for the answer! I just have one question: do you think it’s better to create an AI system using triggers, or to use the AI already included in the editor? ( Train, attack wave and Guard units) ?
 
Thank you very much for the answer! I just have one question: do you think it’s better to create an AI system using triggers, or to use the AI already included in the editor? ( Train, attack wave and Guard units) ?
It really depends on what you want the AI to feel like.


If you just need a basic base that sends waves of Grunts every 5 minutes, the AI Editor is fine for the 'Macro' (building and training). But the moment you want the AI to be 'Smart'; like kiting, focusing fire, or using your custom abilities correctly—you have to use triggers.

The AI Editor doesn't know about your VS_Stacks or your transformation logic. I’d suggest a Hybrid Approach:

-Use the AI Editor for the boring stuff (Economy/Training).
-Use Triggers for the 'Combat Logic.'

This is also where Unit Indexing comes back into play. If you index your AI units, you can run a specific trigger for each one that checks their HP or their Stacks and gives them custom orders. It’s more work, but it’s the only way to make the AI feel like it's actually playing the game against you instead of just walking into your base to die.

I recently played with some AI logic and built an AI Escort System, it is still a bit rough, but maybe it will be useful for inspiration. Regards!
 
Warcraft 3's AI Editor struggles with custom campaign units because it can't access the campaign's global database. Here's how to work around it:

-- Dummy Map: Copy custom units into a blank map. Edit AI in that map, then import the .ai file to your campaign maps.

Or, Manual ID Edit: Export the AI script with a placeholder unit. Manually replace the placeholder's rawcode with your custom unit's rawcode in a text editor.

Trigger Production: Use a trigger to manage unit production. If you have less than X units, order training. This bypasses the AI Editor entirely.
 
Warcraft 3's AI Editor struggles with custom campaign units because it can't access the campaign's global database. Here's how to work around it:

-- Dummy Map: Copy custom units into a blank map. Edit AI in that map, then import the .ai file to your campaign maps.

Or, Manual ID Edit: Export the AI script with a placeholder unit. Manually replace the placeholder's rawcode with your custom unit's rawcode in a text editor.

Trigger Production: Use a trigger to manage unit production. If you have less than X units, order training. This bypasses the AI Editor entirely.
Thanks! I was already trying to reproduce it on a blank map glad to know I was on the right track. Thanks again!
 
Back
Top