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

[General] Optimization of Simple Triggers

Level 9
Joined
Mar 17, 2016
Messages
153
Hello,

I'm working on a game mode where I'm using a Damage Engine with quite a few different units.
For example, there are about 112 different units so far and I'd estimate about 50% are using triggers like this:

1735895885253-png.506440

Essentially my question here is very simple:
Would it be better in terms of optimization, for the game to run smoothly when things are getting crazy, eg. large scale battles with a bunch of different units, to compile all of the simple DamageEvent triggers into one Event with multiple If/Then/Else functions to find the correct function that corresponds with the unit that is attacking?
Or is it ideal to spread them out in the way I have done it, each event being linked with a different Unit-Type?



Edit: For clarification, I'm primarily wondering this because I would imagine that less events firing is ideal, however there are a lot of units that will not be using any triggers like this. So when the units that are not linked to a trigger attack, the way it's done here prevents the trigger from ever making it to the "Actions" stage. However, if I do compile them to make less events fire on each instance of damage, any time any damage is done whatsoever the computer will need to do a lot of condition checking, to end on doing nothing, which may be counter-intuitive.
But I have zero programming knowledge, especially involving theory, thus I am asking here.
 

Attachments

  • 1735895885253.png
    1735895885253.png
    27.7 KB · Views: 38
Level 45
Joined
Feb 27, 2007
Messages
5,578
It should make no functional difference to you either way.

A better-optimized approach would be to save the damage ranges and effect path for each unit-type into a hashtable. Then you use the unit type of the triggering unit to look up these values rather than do a series of checks. GUI won't let you use a unit type as a hashtable key even though they're both just integers so you do have to use a bonus variable:
  • Set UType = (Unit-type of (Triggering Unit))
  • Custom script: set udg_UType_I = udg_UType
  • Set DMG_min = (Load Key(min) of UType_I from YourHashtable)
  • Set DMG_max = (Load Key(max) of UType_I from YourHashtable)
  • Set SFX = (Load Key(sfx) of UType_I from YourHashtable)
You would populate the hashtable with all the appropriate data on map init.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Adding onto what Pyro said, you can also register your "on damage" triggers directly to a Unit OR Unit-Type if you'd like.

So you have a central trigger like this which handles everything:
  • Events
    • Game - DamageEvent becomes Equal to 1.00
  • Conditions
  • Actions
    • Custom script: set udg_ID = udg_DamageEventSource OR GetUnitTypeId(udg_DamageEventSource)
    • If all conditions are true then do (Actions)
      • If - Conditions
        • (Load -1 of ID in Hash_Damage_Attacks) Equal to False // Some kind of identifier that the unit/unit-type has registered at least 1 damage event of any type
      • Then - Actions
        • Skip remaining actions
    • -------- --------
    • If all conditions are true then do (Actions)
      • If - Conditions
        • IsDamageAttack Equal to True
      • Then - Actions
        • Set Damage_Trigger_Count = (Load 0 of ID in Hash_Damage_Attacks)
        • If all conditions are true then do (Actions)
          • If - Conditions
            • Damage_Trigger_Count Greater than 0
          • Then - Actions
            • For each (Integer X) from 1 to Damage_Trigger_Count do (Actions)
              • Loop - Actions
                • Trigger - Run (Load X of ID from Hash_Damage_Attacks) (ignoring conditions)
          • Else - Actions
        • Skip remaining actions
    • -------- --------
    • If all conditions are true then do (Actions)
      • If - Conditions
        • IsDamageSpell Equal to True
      • Then - Actions
        • Set Damage_Trigger_Count = (Load 0 of ID in Hash_Damage_Spells)
        • If all conditions are true then do (Actions)
          • If - Conditions
            • Damage_Trigger_Count Greater than 0
          • Then - Actions
            • For each (Integer X) from 1 to Damage_Trigger_Count do (Actions)
              • Loop - Actions
                • Trigger - Run (Load X of ID from Hash_Damage_Spells) (ignoring conditions)
          • Else - Actions
I imagine this would help since you've narrowed it down to the following:

1) If the unit hasn't registered any damage events then you skip everything. In this case you only set one variable, check one condition, and make a couple of function calls.
2) If the unit has dealt ATTACK damage then you skip everything related to Spell damage.
3) If the unit has dealt SPELL damage then you skip everything related to Attack damage.

I don't know the price of these For Loops and Run Trigger actions but I imagine this is more efficient. It also allows you to order the execution of these triggers by sorting the Hashtable data.

Then the registering process could be designed so that you set a few variables and run a trigger to store everything in your Hashtable(s):
  • Actions
    • Set Register_Damage_Unit = ...
    • Set Register_Damage_Mode = IsAttack
    • Set Register_Damage_Trigger = Templar <gen>
    • Trigger - Run Register Damage Event (ignoring conditions)
 
Last edited:
Top