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

The Importance of Efficiency in Coding

Level 31
Joined
May 3, 2008
Messages
3,154

The Importance of Efficiency in Coding


A lot of mapper (Especially newbie) adopt the concept of "As long as it work". They do not give a damn about triggering/scripting as long as their map look nice or done.

This was a poor & awful concept to be adopt with, as it could lead to unnecessary catastrophe due to poor scripting/triggering.

What could possibly happen due to inproper coding? There is plenty of problem, I would listed all of it.

1) Lagging - The game would lag terribly especially for those with crappy internet connection or computer.
2) Long loading time - Player would have to wait longer for a map during the pre-load time.
3) Disconnect - There is a possibilities of player disconnect during the gameplay and it was quite awful to have such a situation happen.
4) Longer log off time - Whenever a game has end, player would have to wait for a period of time before they are complete log out from it.
5) Bigger file size - Having unnecessary scripting/trigger could resulted into a bigger file size by a increase of 1-10kb or probably higher. You might said 10kb is quite small, but if that map was a 11 player map. There is additional 100kb download time if you try to play under a full house condition.
6) Waste of time - Whenever you script/trigger a map using ineffective way, you might probably set it with a basic setup and the setup might be too long to get it done.

Now you know the 6 reason of what happen when you do not script it properly. I would now start with a simple way of scripting a much efficient and yet less time comsumption technique in GUI.

Simplified


Making your trigger as simple and lesser line as possible at most efficient way is the key to success. JASS/VJASS are the top performance scripting that does that, but for new user. I would said, learn GUI first. You can go ahead and jump to JASS, but if you gone berserk; do not blame me as I have warn you about it.

GUI are matter of using logic. It was rather simple to use if you know what to do. For here, I would show you a example of simplified a victory trigger.

  • Initialization
    • Events
      • Unit - Castle 0000 <gen> Dies
    • Conditions
    • Actions
      • Game - Victory Player 1 (Red) (Show dialogs, Show scores)
      • Game - Victory Player 2 (Blue) (Show dialogs, Show scores)
      • Game - Victory Player 3 (Teal) (Show dialogs, Show scores)
      • Game - Victory Player 4 (Purple) (Show dialogs, Show scores)
      • Game - Victory Player 5 (Yellow) (Show dialogs, Show scores)
      • Game - Victory Player 6 (Orange) (Show dialogs, Show scores)
      • Game - Defeat Player 7 (Green) with the message: Defeat!
      • Game - Defeat Player 8 (Pink) with the message: Defeat!
      • Game - Defeat Player 9 (Gray) with the message: Defeat!
      • Game - Defeat Player 10 (Light Blue) with the message: Defeat!
      • Game - Defeat Player 11 (Dark Green) with the message: Defeat!
      • Game - Defeat Player 12 (Brown) with the message: Defeat!
As you can see, player 1-6 earn victory if castle was destroy and player 7-12 would be defeated. This trigger does work, but it isn't at effective way.

If player 1-6 & 7-12 was at the same team, you can simplified it by setting it this way.

  • Initialization
    • Events
      • Unit - Castle 0000 <gen> Dies
    • Conditions
    • Actions
      • Player Group - Pick every player in (All allies of Player 1 (Red)) and do (Game - Victory (Picked player) (Show dialogs, Show scores))
      • Player Group - Pick every player in (All allies of Player 7 (Green)) and do (Game - Defeat (Picked player) with the message: Defeat!)
Since they are allies, you can set a player to share the same action in 1 simple action. Try make comparison between this 2 trigger. Do you want to use a trigger that consume 15-20 seconds longer or a trigger that could be done in less than 5 seconds?

There is a lot of action that could be simplified into 1 action since there is a exitense of player group and unit group action.

Player Group and Unit Group action serve the purpose of simplified it just like the example above.

Merge


A lot of new user usually set their scripting/trigger using the most basic way without the acknowledge of merging it.

For example, I usually seen a newbie triggering always been set at different trigger files although they are using the same action such as this example below.

  • Initialization
    • Events
      • Unit - A unit enters Region 000 <gen>
    • Conditions
    • Actions
      • Unit - Kill (Triggering unit)
  • Initialization
    • Events
      • Unit - A unit enters Region 001 <gen>
    • Conditions
    • Actions
      • Unit - Kill (Triggering unit)
  • Initialization
    • Events
      • Unit - A unit enters Region 002 <gen>
    • Conditions
    • Actions
      • Unit - Kill (Triggering unit)
  • Initialization
    • Events
      • Unit - A unit enters Region 003 <gen>
    • Conditions
    • Actions
      • Unit - Kill (Triggering unit)
  • Initialization
    • Events
      • Unit - A unit enters Region 004 <gen>
    • Conditions
    • Actions
      • Unit - Kill (Triggering unit)
  • Initialization
    • Events
      • Unit - A unit enters Region 005 <gen>
    • Conditions
    • Actions
      • Unit - Kill (Triggering unit)
To be honest, why do you want to set it at such a long way. It not only make your code messy, but if you probably have to redo the entire trigger if you make a slight mistake over it.

Since they are sharing the same action, but different event. They are still possible to be used in 1 trigger such as this example below.

  • Initialization
    • Events
      • Unit - A unit enters Region 000 <gen>
      • Unit - A unit enters Region 001 <gen>
      • Unit - A unit enters Region 002 <gen>
      • Unit - A unit enters Region 003 <gen>
      • Unit - A unit enters Region 004 <gen>
    • Conditions
    • Actions
      • Unit - Kill (Triggering unit)
Now, isn't that much better? Also, this was just a simple example. If you set a rather long scripting/triggering, you can bet that doing multiple trigger like this could be a nuisance; especially if there is a lot of different event for it.

Divide


Is it possible to make everything into 1 trigger files if they are sharing the same event, but different action?

Yes, they can. Since such a situation usually have a condition trigger for it. Let's take difficulty setup as a example.

  • Easy
    • Events
      • Dialog - A dialog button is clicked for Dialog
    • Conditions
      • (Clicked dialog button) Equal to Dialog_Button[1]
    • Actions
      • Game - Display to (All players) the text: Easy Mode Selected
  • Normal
    • Events
      • Dialog - A dialog button is clicked for Dialog
    • Conditions
      • (Clicked dialog button) Equal to Dialog_Button[2]
    • Actions
      • Game - Display to (All players) the text: Normal Mode Selected
  • Hard
    • Events
      • Dialog - A dialog button is clicked for Dialog
    • Conditions
      • (Clicked dialog button) Equal to Dialog_Button[3]
    • Actions
      • Game - Display to (All players) the text: Hard Mode Selected
As you can see, 3 different trigger files with same event. However, they have their own action and conditions. Since they have different condition, you can used If/Then/Else to make it into 1 trigger. Separate them isn't a good idea, since it would just call the action 3 times in a row.

  • Difficulty
    • Events
      • Dialog - A dialog button is clicked for Dialog
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Clicked dialog button) Equal to Dialog_Button[1]
        • Then - Actions
          • Game - Display to (All players) the text: Easy Mode Selected
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Clicked dialog button) Equal to Dialog_Button[2]
        • Then - Actions
          • Game - Display to (All players) the text: Normal Mode Selected
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Clicked dialog button) Equal to Dialog_Button[3]
        • Then - Actions
          • Game - Display to (All players) the text: Hard Mode Selected
        • Else - Actions
Isn't this much better? However, it still isn't at top performance despite the optimization of removing the call. To make the order much clear, you can set it this way.

  • Difficulty
    • Events
      • Dialog - A dialog button is clicked for Dialog
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Clicked dialog button) Equal to Dialog_Button[1]
        • Then - Actions
          • Game - Display to (All players) the text: Easy Mode Selected
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Clicked dialog button) Equal to Dialog_Button[2]
            • Then - Actions
              • Game - Display to (All players) the text: Normal Mode Selected
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Clicked dialog button) Equal to Dialog_Button[3]
                • Then - Actions
                  • Game - Display to (All players) the text: Hard Mode Selected
                • Else - Actions
Unnecessary Setup

Sometimes, I consider some trigger as sprt (Stupid pointless retarded trigger) as they hardly have any use.

A example would be this action.

  • Do nothing
This action is the most pointless action that called another action that does partically nothing. This action only have 1 purpose. For If/Then/Else single function action.

Apart from this, I notice another pointless trigger was this.

  • Initialization
    • Events
      • Unit - A unit owned by Player 1 (Red) Dies
      • Unit - A unit owned by Player 2 (Blue) Dies
      • Unit - A unit owned by Player 3 (Teal) Dies
      • Unit - A unit owned by Player 4 (Purple) Dies
      • Unit - A unit owned by Player 5 (Yellow) Dies
      • Unit - A unit owned by Player 6 (Orange) Dies
      • Unit - A unit owned by Player 7 (Green) Dies
      • Unit - A unit owned by Player 8 (Pink) Dies
      • Unit - A unit owned by Player 9 (Gray) Dies
      • Unit - A unit owned by Player 10 (Light Blue) Dies
      • Unit - A unit owned by Player 11 (Dark Green) Dies
      • Unit - A unit owned by Player 12 (Brown) Dies
      • Unit - A unit owned by Neutral Hostile Dies
      • Unit - A unit owned by Neutral Victim Dies
      • Unit - A unit owned by Neutral Extra Dies
      • Unit - A unit owned by Neutral Passive Dies
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Footman
        • Then - Actions
          • Player - Add 100 to (Owner of (Killing unit)) Current gold
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Triggering unit)) Equal to Knight
            • Then - Actions
              • Player - Add 150 to (Owner of (Killing unit)) Current gold
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Triggering unit)) Equal to Peasant
                • Then - Actions
                  • Player - Add 50 to (Owner of (Killing unit)) Current gold
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Unit-type of (Triggering unit)) Equal to Rifleman
                    • Then - Actions
                      • Player - Add 75 to (Owner of (Killing unit)) Current gold
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Unit-type of (Triggering unit)) Equal to Gryphon Rider
                        • Then - Actions
                          • Player - Add 300 to (Owner of (Killing unit)) Current gold
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Unit-type of (Triggering unit)) Equal to Siege Engine
                            • Then - Actions
                              • Player - Add 500 to (Owner of (Killing unit)) Current gold
                            • Else - Actions
To be honest, do you really want to waste 20 minutes to make such a long pointless trigger? I guess not.

There is a way to simplified such a trigger if a research is ever done. Such a trigger could be make it simple by merely setting this trigger. If you want to adjust the gold/lumber reward, simply go to object editor, find the unit, adjust the amount at Gold/Lumber bounty awarded.

It work the same way like the optimization example I show you does, but pointless because it can be done without the need of trigger.

Not everything need to be set this way, some could be done via object editor or gameplay constants.

  • Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Player - Turn Gives bounty On for (Picked player)

Variable & Array (The Sources Of Effectiveness)


Variable and array could be the sources of optimize trigger, fix memory leak and so on. They are so useful that their role in map making is definitely vital.

1 array could store up to 300 data (If my memory serve me right). If variable and array was use at the right way, they give a extraordinary benefict in every aspect.

For example, when you wanted to make a simple trigger that display a different game text every 60 seconds. You can set it into 2 trigger.

  • Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Hint[1] = You will lose 1 lives if a Acolyte is killed.
      • Set Hint[2] = Naga Myrmidon will grant you additional five lives if it is killed.
      • Set Hint[3] = If a Wisp is killed, every Orc will be killed as well.
      • Set Hint[4] = You will lose 3 lives if a Ghoul is killed.
      • Set Hint[5] = You will lose 5 lives if a Abomination is killed.
      • Set Hint[6] = Once your scores exceed 300, the difficulty would increase.
      • Set Hint[7] = Once your scores exceed 500, a Blademaster would arrive. Do not worry, he only spawn once.
      • Set Hint[8] = Kill Orc hero would give you 10 scores.
      • Set Hint[9] = Kill Human unit would resulted into score deduction.
      • Set Hint[10] = If your score goes below 300, the difficulty would be back to normal as long as you do not achieve 700 scores and above.
      • Set Hint[11] = Raider and Fel Orc Raider are the hardest to kill.
      • Set Hint[12] = Chaos Orc are harder to kill, but they give additional 1 point.
      • Set Hint[13] = If your score exceed 700, weaker orc unit such as peon would no longer be available.
      • Set Hint[14] = If your score exceed 700, unit would respawn much quicker.
      • Set Hint[15] = If your score exceed 700, the only undead unit that would appear is Abomination.
      • Set Hint[16] = You will lose 3 points if a Peasant is killed
      • Set Hint[17] = You will lose 7 points if a Footman is killed
      • Set Hint[18] = You will lose 15 points if a Knight is killed
      • Set Hint[19] = If your score exceed 900, the only orc unit available would be Raider and Fel Orc Raider.
      • Set Hint[20] = In order to reach Impossible stage, you must rake a score of 1,500.
      • Set Hint[21] = The only Orc unit available at Impossible stage is Drak'thul.
      • Set Hint[22] = At Impossible Stage, killing a human or undead unit could resulted into heavy loss.
      • Set Hint[23] = Wisp and Naga Myrmidon are not available at Impossible stage.
      • Set Hint[24] = Demon would kill Undead & Human unit only. This would resulted into lives and score deduction, be on the lookout.
      • Set Hint[25] = Nothing would happen if a Demon was killed.
  • Message
    • Events
      • Time - Every 60.00 seconds of game time
    • Conditions
    • Actions
      • Game - Display to (All players) for 30.00 seconds the text: (|cFF008000Hint|r - + Hint[(Random integer number between 1 and 25)])
      • Sound - Play Hint <gen>
As you can see, this way not only saves time. But enable you to make a accurate random text appear exactly the way you want.

This is the right way of using variable & array, cut down the time consumption and increase the efficiency at the same time. However, using it at wrong way could be prove to be fatal such as this example below.

  • Time
    • Events
      • Time - Every 3.00 seconds of game time
    • Conditions
    • Actions
      • Set Integer = 1
      • Wait 1.00 seconds
      • Set Integer = 2
      • Wait 1.00 seconds
      • Set Integer = 3
      • Wait 1.00 seconds
  • Time
    • Events
      • Time - Every 3.00 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Integer Equal to 1
        • Then - Actions
          • Game - Display to (All players) the text: Hello
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Integer Equal to 2
        • Then - Actions
          • Game - Display to (All players) the text: Game Over
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Integer Equal to 3
        • Then - Actions
          • Game - Display to (All players) the text: The End
        • Else - Actions
When you set up this way, it not only unprofessional. But you would never get the result you want as the text would usually wound up with action that contain condition integer 2 or 3 since they are sharing the same action time. Even if it use different action such as a unit dies, the result would never be accurate.

Variable not only be use to simplified, but to destroy leak or to recycle a usage of some data.

  • Spawn
    • Events
      • Time - Every 60.00 seconds of game time
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
As you can see, this trigger work. But they had the tendency of causing lag and not effective. If you constantly use this trigger, you can eventually avoid memory leak by storing the region into array.

  • Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Point[1] = (Center of (Playable map area))
  • Spawn
    • Events
      • Time - Every 60.00 seconds of game time
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at Point[1] facing Default building facing degrees
This way, you could avoid memory leak that cause lag.

What is memory leak? I going to make it simple about this. For example, if your cabinet capacity was able to hold up to 15 book. What happen if you add more than the cabinet capacity does? The answer was simple, it would burst.

By storing it into variable, you are recycle the usage of it such as taking 1 book out of the cabinet and replace it with another to avoid it from being crammed by it.

Although the example trigger above only leak once, actually it wasn't a leak considering that you re-use it all over again. If the function no longer serve it's purpose, simple use a custom script to destroy it depends on what kind of event you want such as this example below.

  • Destroy
    • Events
      • Unit - Mini Boss 0634 <gen> Dies
    • Conditions
    • Actions
      • Custom script: call RemoveLocation(udg_Point[1])
      • Custom script: call RemoveLocation(udg_Point[2])
      • Custom script: call RemoveLocation(udg_Point[3])
      • Custom script: call RemoveLocation(udg_Point[4])
      • Custom script: call RemoveLocation(udg_Point[5])
If the trigger was used only once, you can set it this way.

  • Boss
    • Events
      • Time - Elapsed game time is 500.00 seconds
    • Conditions
    • Actions
      • Sound - Play Warning <gen>
      • Game - Display to (All players) the text: |cffff0000Warning|r...
      • Set Point[1] = (Center of Playable map area <gen>)
      • Unit - Create 1 Boss for Player 12 (Brown) at Point[1] facing (Position of Heroes <gen>)
      • Custom script: call RemoveLocation(udg_Leak_Area[1])
This way, you use it once and destroy it right away.

What? I hear you said that you want to know how to destroy a memory leak after the trigger have been use several times without any event requirement. Do not worry, there is no need to create a require event for it. If you want to make a trigger that spawn creep for several times and then end it automatically. Variable is the key to do so.

  • Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Integer_Spawn_Once = 0
      • Set Point = (Center of (Playable map area))
  • Spawn
    • Events
      • Time - Every 60.00 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Integer_Spawn_Once Greater than or equal to 5
        • Then - Actions
          • Custom script: call RemoveLocation(udg_Leak_Area[1])
          • Trigger - Turn off (This trigger)
        • Else - Actions
          • Set Integer_Spawn_Once = (Integer_Spawn_Once + 1)
          • Unit - Create 1 Footman for Player 1 (Red) at Point facing Default building facing degrees
Surely you can set it at this example below to replace the variable, but think again; do you really need this useless trigger that could possibly increase the loading time of your map? 1 trigger, ok. But if there more? Messy, terrible and awful is what I would decribe it.

  • Off
    • Events
      • Time - Elapsed game time is 300.00 seconds
    • Conditions
    • Actions
      • Custom script: call RemoveLocation(udg_Leak_Area[1])
      • Trigger - Turn off Spawn <gen>
After all, you wanted to destroy the memory leak and turn off the trigger after several usage without the requirement of unnecessary event.

Know why and how to make a proper coding by now? Then start to do it right now. More information would be provided if I have anymore idea about it.

Note : Those trigger inside this tutorial was just a example of optimization and doesn't cover every single part of memory leak issue. There is a memory leak for unit, player group, and etc etc. That is why some example trigger you seen at here contain leak such as player group leak. For memory leak info, please browse memory leak tutorial.
 
Last edited by a moderator:
Level 21
Joined
Aug 21, 2005
Messages
3,699
Suggestions:

1) Add a contents overview with all chapters, and link the chapters to the correct position in your thread (goto tags)
2) Add some external links, for instance a link to a tutorial giving an extensive explanation on memory leaks
3) Check your "Difficulty" triggers (divide chapter). It's better to nest the if/then/else actions. In your current "Difficulty" trigger, you will ALWAYS do 3 checks. If you make them nested, it will only make 1 check if the pressed dialog button is button[1] because it immediately executes "then" actions and ignores "else" actions. After all, only ONE of the dialog buttons could have been pressed, so if it's the first dialog button, why bother checking the 2nd and 3rd dialog button.

4) The 3 separate "easy", "normal", "hard" triggers might actually be faster. I can't tell for sure because I didn't test it, but there are several reasons why this would possibly be a faster solution:
- Conditions in a trigger are executed faster than actions. Therefor, adding a condition (if...) in the actions will be slower than checking it under Conditions.
- The if/then/else gui action is implemented in a way that adds many additional functioncalls are added. Again a slow-down.

The fact that they're separate triggers isn't bad either. Dividing up your code can be useful and more manageable. So again, I can't say your solution is better.

P.s. It's also funny how you could use your list of problems with bad coding to prefer jass over gui.
If you do not know anything about programming language, it was recommend for you to stick with GUI.
If you're lazy, yes, but otherwise it's recommended to simply learn something about programming languages and move to jass.
 
Level 31
Joined
May 3, 2008
Messages
3,154
3) Check your "Difficulty" triggers (divide chapter). It's better to nest the if/then/else actions. In your current "Difficulty" trigger, you will ALWAYS do 3 checks. If you make them nested, it will only make 1 check if the pressed dialog button is button[1] because it immediately executes "then" actions and ignores "else" actions. After all, only ONE of the dialog buttons could have been pressed, so if it's the first dialog button, why bother checking the 2nd and 3rd dialog button.

They are using the same event, but different action. All it does was setting it into 1 files.

The fact that they're separate triggers isn't bad either. Dividing up your code can be useful and more manageable. So again, I can't say your solution is better.

P.s. It's also funny how you could use your list of problems with bad coding to prefer jass over gui.

It depends on the condition. I would ask somebody else about this divided trigger matter.

If you're lazy, yes, but otherwise it's recommended to simply learn something about programming languages and move to jass.

If they know nothing about programming language, it would only lead to a much worst disaster (Time comsumption and more error in scripting). Still, everything was depends on the situation.
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
If they know nothing about programming language, it would only lead to a much worst disaster (Time comsumption and more error in scripting). Still, everything was depends on the situation.

The amount of time you save once you get to know how to program makes the time you have wasted on learning it absolutely negligible. Therefor, using jass is recommended for anyone, no matter their background in programming. I can understand some people wish to stay at gui, and that's what this tutorial is about, but it isn't really correct to recommend gui. The thing is, if they know nothing about programming, then they should learn it. ALL programmers once knew nothing of programming...
But so far the nitpicking...

They are using the same event, but different action. All it does was setting it into 1 files.
I noticed that, but is there a good reason why, in this case, your solution would be so much better? The tutorial is about efficiency of proper coding, so can you explain why your merged trigger will run faster and why your if/then/else actions aren't nested?
 
Level 31
Joined
May 3, 2008
Messages
3,154
The amount of time you save once you get to know how to program makes the time you have wasted on learning it absolutely negligible. Therefor, using jass is recommended for anyone, no matter their background in programming. I can understand some people wish to stay at gui, and that's what this tutorial is about, but it isn't really correct to recommend gui. The thing is, if they know nothing about programming, then they should learn it. ALL programmers once knew nothing of programming...
But so far the nitpicking...

They have the freedom to choose what they prefer, don't they? XD

I noticed that, but is there a good reason why, in this case, your solution would be so much better? The tutorial is about efficiency of proper coding, so can you explain why your merged trigger will run faster and why your if/then/else actions aren't nested?

Both the trigger have the same number of comparisons it run but fewer events are triggered when you merge it into 1.

Because 3 events are triggered. That means 3 times a trigger with the same event get executed, which isn't good for the performance. That was only for a trigger with same event, but 3 different action. But if it was 5 or more? That is why it isn't a good idea to split it.

What do you mean by nested?
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
Both the trigger have the same number of comparisons it run but fewer events are triggered when you merge it into 1.
But as I told you, conditions run faster than actions. I wouldn't be surprised if the single trigger runs slower than the 3 separate triggers, especially because the GUI if/then/else action is an additional slow-down compared to jass if/then/else clauses (which is the case for "Conditions" in gui).

What do you mean by nested?
if (blabla = 1) then
--- do stuff
else
--- if (blabla = 2) then
--- --- do more stuff
--- else
--- --- if (blabla == 3) then
--- --- --- do even more stuff

As opposed to
if (blabla = 1) then
--- do stuff
if (blabla = 2) then
--- do more stuff
if (blabla = 3) then
--- do even more stuff

The latter one is what you do. Since blabla can NEVER be 1 AND 2 AND 3, it's useless to do all 3 checks each time you run the trigger. Therefor, nesting your if/then/else actions will make the trigger run faster in a best case scenario (if blabla = 1 we simply do stuff and no longer check if blabla = 2 or 3)
 
Level 31
Joined
May 3, 2008
Messages
3,154
But as I told you, conditions run faster than actions. I wouldn't be surprised if the single trigger runs slower than the 3 separate triggers, especially because the GUI if/then/else action is an additional slow-down compared to jass if/then/else clauses (which is the case for "Conditions" in gui).

I have ask this matter from Hanky and Dr Super Good, they said it was better to be in 1 trigger files.

if (blabla = 1) then
--- do stuff
else
--- if (blabla = 2) then
--- --- do more stuff
--- else
--- --- if (blabla == 3) then
--- --- --- do even more stuff

As opposed to
if (blabla = 1) then
--- do stuff
if (blabla = 2) then
--- do more stuff
if (blabla = 3) then
--- do even more stuff

I have ask both of them about it. Hanky said both of them work the same way, but the answer is similiar to yours. He told me the performance would be slightly reduce without nesting it.

Thank you for pointing out the nesting, I would fix my tutorial soon.

A +2 reputation for pointing out nesting.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Honestly, efficency in GUI is a joke. The very structure and nature of GUI is horriably unefficent so some optimizations make hardly any difference. Thus why for any efficient coding you have to use JASS as you can greatly improve the performance of a script.

However, it is a good idea to show some basic optimization tricks especially the turn of periodic spell triggers when there are no instances of that spell one.
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
I have ask this matter from Hanky and Dr Super Good, they said it was better to be in 1 trigger files.
I might test it with stopwatch... I personally think it'll hardly make a difference.

I have ask both of them about it. Hanky said both of them work the same way
No, they don't work the same way. That's actually the only difference. They do the same thing but nesting works in a "faster" way.

Honestly, efficency in GUI is a joke. The very structure and nature of GUI is horriably unefficent so some optimizations make hardly any difference. Thus why for any efficient coding you have to use JASS as you can greatly improve the performance of a script.
The thing is, if you're going to be coding in gui anyway, you're coding it in gui. And if you're coding it in gui, you better code it as efficient as possible, within the scope of gui.

Another optimization you could add is the extensive use of variables. Rather than using "triggering unit" 20 times, set a unit variable = triggering unit and then use that variable.
 
Level 9
Joined
Nov 28, 2008
Messages
704

The Importance of Efficiency in Coding



  • Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Hint[1] = You will lose 1 lives if a Acolyte is killed.
      • Set Hint[2] = Naga Myrmidon will grant you additional five lives if it is killed.
      • Set Hint[3] = If a Wisp is killed, every Orc will be killed as well.
      • Set Hint[4] = You will lose 3 lives if a Ghoul is killed.
      • Set Hint[5] = You will lose 5 lives if a Abomination is killed.
      • Set Hint[6] = Once your scores exceed 300, the difficulty would increase.
      • Set Hint[7] = Once your scores exceed 500, a Blademaster would arrive. Do not worry, he only spawn once.
      • Set Hint[8] = Kill Orc hero would give you 10 scores.
      • Set Hint[9] = Kill Human unit would resulted into score deduction.
      • Set Hint[10] = If your score goes below 300, the difficulty would be back to normal as long as you do not achieve 700 scores and above.
      • Set Hint[11] = Raider and Fel Orc Raider are the hardest to kill.
      • Set Hint[12] = Chaos Orc are harder to kill, but they give additional 1 point.
      • Set Hint[13] = If your score exceed 700, weaker orc unit such as peon would no longer be available.
      • Set Hint[14] = If your score exceed 700, unit would respawn much quicker.
      • Set Hint[15] = If your score exceed 700, the only undead unit that would appear is Abomination.
      • Set Hint[16] = You will lose 3 points if a Peasant is killed
      • Set Hint[17] = You will lose 7 points if a Footman is killed
      • Set Hint[18] = You will lose 15 points if a Knight is killed
      • Set Hint[19] = If your score exceed 900, the only orc unit available would be Raider and Fel Orc Raider.
      • Set Hint[20] = In order to reach Impossible stage, you must rake a score of 1,500.
      • Set Hint[21] = The only Orc unit available at Impossible stage is Drak'thul.
      • Set Hint[22] = At Impossible Stage, killing a human or undead unit could resulted into heavy loss.
      • Set Hint[23] = Wisp and Naga Myrmidon are not available at Impossible stage.
      • Set Hint[24] = Demon would kill Undead & Human unit only. This would resulted into lives and score deduction, be on the lookout.
      • Set Hint[25] = Nothing would happen if a Demon was killed.

Arrays start at [0]. This is an important coding concept, please fix it.
 
Level 31
Joined
May 3, 2008
Messages
3,154
Arrays start at [0]. This is an important coding concept, please fix it.

For your information, it can be start at any number that you wish to have it. Is just that I start it with 1 since it is much easier to organize the list.

Also, this tutorial is about efficiency in code. Not coding concept such as integer variable at JASS must have the code written in "i" instead of "Integer", "Num" and et cetc.
 
Level 9
Joined
Nov 28, 2008
Messages
704
Of course, you can start it at any number.. but you're wasting slots. Hence, not being efficient. I said nothing about i. I merely said it starts at 0 because that's how an array freaking works. >.>

Best just to get into the habit. An array is calculated when accessed by Location in Memory + (Index) * Size of Each Variable. Therefore ALLOWING you to use 0. Using 1 makes no sense.
 
Top