• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Reviewed: BlinkBoy] Understanding triggers and creating them.

Level 8
Joined
May 21, 2008
Messages
218

Understanding triggers and creating them


By Zypher



What will this tutorial teach you?

  • -------------------
  • Beginner
  • What is a trigger?
  • What is an event?
  • What is a condition?
  • What is an action?
  • How can I make these work to my advantage?
  • --------------------
  • Intermediate
  • What is a variable?
  • What is an array?
  • What is a loop?
  • What is a memory leak?
  • Side Notes to remember.
  • --------------------
  • Expert
  • There is no such thing as GUI expert :p, now it's time you start learning jass.


Beginner



What is a trigger?

A trigger is something that happens when something happens in a warcraft game.
Ex: A unit dies Then do this: Create unit for Player 1 Red

A trigger consists of 3 parts:
Event-Something that happens that makes the trigger activate/go.
Condition-If this isn't met then the trigger won't run.
Action--What happens when your trigger runs and the condition(s) are met.

An analogy for a trigger would be:
Imagine there is a marble a track and a hole it has to go into to come out the other side.An event is like putting the marble down on the track, a condition is the marble will only go out the other side if the whole is big enough, the action is going out the hole.

Example:
  • A trigger
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Dying unit)) Equal to Footman
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees

I will explain how this works.
Event-This trigger runs everytime a unit dies

Condition-If this is met then the actions will run (In this case if the dying unit is a footman then the action will run.)

Action-This creates a footman for player 1 red at the center of the playable map area(the map) facing 0 degrees (left)


What is an event?


An event is something that happens that makes a trigger run.These include the following.Bolded text is changeable to equel, not equel, greater than, less than, greater than or equel to, less than or equel to. The underlined text is changed to your variable, a preset, or a raw id(selecting something).Astricks (*) are the exception for bold text.


General Event

-Map initialization

Destructible Event

-Destructible dies
-Destructible within reigon dies

Dialog Event

-A dialog button is clicked for dialog

Game Event

-The in-game time of day becomes Equal to Time
-Variable becomes equal to Number
-A saved game is loaded
-The game is about to be saved
-The hero abilities button is clicked
-The build structure button is clicked
-The tournament game must end now

Player Event

-Player types a chat message containing text as an Exact Match*
-Player skips a cinematic sequence
-Player selects* a unit
-Player presses* the left* arrow key
-Player's current gold * becomes equal to Number
-Player changes Alliance settings
-Player changes Alliance (non-aggression) settings
-Player leaves the game with a victory
-Player leaves the game with a defeat
-Player leaves the game

Time Event

-Elapsed game time is number seconds
-Every number seconds of game time
-timer expires

Unit event

-Unit Dies*(specific)
-A unit owned by Player Dies*
-A unit Dies*(generic)
-A unit enters Reigon
-A unit leaves Reigon
-A unit comes within Number of Unit
-Unit's life becomes Less than Number
-Unit's mana becomes Less than Number

What is a condition?


A condition is something that a trigger checks before it runs it's actions. If the condition is met then the actions run and the trigger does something.These include the following.Bolded text is changeable to equel, not equel, greater than, less than, greater than or equel to, less than or equel to. Titles of conditions are bolded so you can see them better. The underlined text is changed to your variable, a preset, or a raw id(selecting something).Astricks (*) are the exception for bold text.

Boolean comparison
-checks for something and can come back true or false
Ability comparison
-checks what ability is being cast Ex: Acid Bomb
Buff comparison
-checks to see if a buff variable is a certain buff Ex:Bloodlust
Destructible comparison
-checks to see if a destrucible is equal to a variable or other destructible. Ex: Summer Tree wall
Destructible type comparison
-checks to see if the destructible is a certain type Ex: Summer Tree Wall
Dialog button comparison
-checks to see if the clicked dialog button is a certain dialog button
Game difficulty comparison
-checks game difficulty to see if it is a certain difficulty Ex: easy
Game speed comparison
-checks the game speed to see if it's a certain game speed Ex:fast
Hero Skill Comparison
-checks to see if the learned hero skill is a certain skill Ex:Holy Light
Integer Comparison
-checks to see if an integer is equal to a Number
Item Comparison
-checks to see if an item being dropped, manipulated, or aquired ect. is a certain item
Item Class Comparison
-checks to see if an item class is a certain class Ex: Power-Up
Item Type Comparison
-checks to see if an item type is a certain item type Ex: Talismen of Evasion
Melee AI Comparison
-checks to see if a computer player's level is a certain level Ex: easy,normal,insane
Order Comparison
-checks to see if an order is a certain order
Player Comparison
-Many different variations on this one, I'll list a few. Owner of unit, Owner of Item, Picked player, Triggering player is a certain player Ex:player 1 Red
Player Color Comparison
-checks if the color of Player is a certain color
Player Controller Comparison
-checks to see the controller of a player Ex: computer, neutral, player
Player Slot Status Comparison
-checks to see if a player's slot status is a certain slot status Ex: Playing, Unused, Left
Race comparison
-checks to see if a players race is a certain race Ex: Human, Undead
Real comparison
-Checks to see if a Number is equal to a Number
String Comparison
-checks a string(text) to see if it is a certain string Ex:-save
Tech-Type Comparison
-checks to see if the researched tech-type is a certain tech type
Terrain Type Comparison
-checks to see if the terrain type at a Point is a certain terrain type.
Trigger Comparison
-checks to see if a trigger is a certain trigger(variable)
Unit Comparison
-checks to see if a unit is a certain unit Ex: Picked unit equal to casting unit
Unit Type Comparison
-checks to see if a unit is a certain type Ex: Footman
And(multiple conditions)
-I think it's useless, might as well just use two conditions
Or(multiple conditions)
-Used so If any of the conditions are true the actions run

What is an action?


An action is the part of a trigger that does something, an action only runs if the conditions are met.For the sake of time I am only going to post catagories of actions as it is not completely necessary for me to spend an hour writing down all the actions. On request I will write them down in this tutorial. The following are action catagories.

AI

Animation

Camera

Cinematic

Countdown Timer

Destructible

Dialog

Enviroment

Floating Text

Game

Game cashe

Hero

Item

Image

Leaderboard

Lightning

Melee Game

Multiboard

Neutral Building

Player

Player Group

Quest

Reigon

Selection

Sound

Special Effect

Trigger

Unit

Unit Group

Ubersplat

Visibility


How can I make these work to my advantage?


If you combine these events, conditions,and actions you can do just about anything in warcraft 3. heres an example trigger just for you to look at and guess at what it does.
  • Player Leaves Game Gold Division
    • Events
      • Player 1 Red leaves the game
      • Player 2 Blue leaves the game
      • Player 3 Teal leaves the game
      • Player 4 Purple leaves the game
      • Player 5 Yellow leaves the game
      • Player 6 Orange leaves the game
      • Player 7 Green leaves the game
      • Player 8 Pink leaves the game
      • Player 9 Grey leaves the game
      • Player 10 LightBlue leaves the game
      • Player 11 Brown leaves the game
      • Player 12 DarkGreen leaves the game
    • Conditions
    • Actions
      • Set LeavingPlayer = (Triggering player)
      • Set LeavingPlayersGold = (LeavingPlayer Current gold)
      • Set LeavingPlayersLumber = (LeavingPlayer Current lumber)
      • Set AllPlayers = (All players)
      • Player Group - Remove LeavingPlayer from AllPlayers
      • Player Group - Pick every player in AllPlayers and do (Actions)
        • Loop - Actions
          • Player - Add (LeavingPlayersGold / (Number of players in AllPlayers)) to (Picked player) Current gold
          • Player - Add (LeavingPlayersLumber / (Number of players in AllPlayers)) to (Picked player) Current lumber
      • Set LeavingPlayersGold = 0
      • Set LeavingPlayersLumber = 0
      • Custom script: Call DestroyForce (udg_AllPlayers)
      • Custom script: Call Destroyplayer (udg_LeavingPlayer)
If you already guessed what this was then good job, your definatly learning :grin:. If not then keep trying :hohum:, keep experimenting with triggers and such, You'll get it. What this does is it divides a leaving players gold between all the remaining players. The actions that have an [X=] before them are actions that set variables.The custom script at the bottom fixes this thing called a memory leak you will learn about that later.

Intermediate


What is a variable?

A variable is a reference to data stored in the computer's memory, variables are used to store values and get them back (in the case you want to use them again). A variable can be a number, unit, destructable, terrain type, ect...
It can be set to anything using the set variable = Something action.
  • Setting a variable
    • Events
      • Your Event
    • Conditions
      • Your Condition
    • Actions
      • Set My_Unit_Type = Footman
VARIABLES ARE YOUR FRIENDS, USE THEM, I CAN'T STRESS THIS ENOUGH!

What is an array?

An array is a group of more that one variable. You have to test this out yourself to understand it, but heres an explanation anyway. An array stores things just like a variable does but when making an array you must set the size. In order to find out which part of the array you are refering to the variable array needs an index number to refer to the variable in the variable array that you are trying to access. Heres an example trigger.
  • Setting a variable array
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set PlayingPlayers[1] = Player 1 (Red)
      • Set PlayingPlayers[2] = Player 2 (Blue)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (PlayingPlayers[1] controller) Equal to User
          • (PlayingPlayers[1] slot status) Equal to Is playing
        • Then - Actions
          • Do nothing
        • Else - Actions
          • Game - Defeat PlayingPlayers[1] with the message: Defeat!
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (PlayingPlayers[2] controller) Equal to User
          • (PlayingPlayers[2] slot status) Equal to Is playing
        • Then - Actions
          • Do nothing
        • Else - Actions
          • Game - Defeat PlayingPlayers[2] with the message: Defeat!
This checks if Player 1 Red and Player 2 Blue are playing and user controled. This is the inefficent way to do it and will teach you a better way in the next part: What is a loop?

What is a loop?


A loop is something that keeps going until through or cleared. Loops are another tricky thing to understand but in my opinion are by far the most useful, time-saving action/function in warcraft 3. LOOPS ARE ALSO YOUR FRIENDS. Heres an example trigger for a loop.
  • Defeating a computer empty slot status player
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set PlayingPlayers[1] = Player 1 (Red)
      • Set PlayingPlayers[2] = Player 2 (Blue)
      • Set PlayingPlayers[3] = Player 3 (Teal)
      • Set PlayingPlayers[4] = Player 4 (Purple)
      • Set PlayingPlayers[5] = Player 5 (Yellow)
      • Set PlayingPlayers[6] = Player 6 (Orange)
      • Set PlayingPlayers[7] = Player 7 (Green)
      • Set PlayingPlayers[8] = Player 8 (Pink)
      • Set PlayingPlayers[9] = Player 9 (Gray)
      • Set PlayingPlayers[10] = Player 10 (Light Blue)
      • Set PlayingPlayers[11] = Player 11 (Dark Green)
      • Set PlayingPlayers[12] = Player 12 (Brown)
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (PlayingPlayers[(Integer A)] slot status) Equal to Is playing
              • (PlayingPlayers[(Integer A)] controller) Equal to User
            • Then - Actions
              • Do nothing
            • Else - Actions
              • Game - Defeat PlayingPlayers[(Integer A)] with the message: Defeat!
This defeats all the Computer/Unused player's in the game at map initilization using a loop.

What is a memory leak?

A memory leak happens when the game uses something and forgets about it. This creates lagg over time if enough of them pile up. I just learned these and am only 90% sure about what I say so I will post a link to what I consider the most helpful memory leak tutorial.

~~emjlr3's Memory Leak / Custom Script Guide~~

I have seen this going around a lot lately, people asking for help with memory leaks and custom scripts. This tutorial is to provide knowledge of the basic memory leaks and ways to clean them up using custom scripts, for those of us who are not yet intone enough with JASS to make all our triggers using such. This also should provide us with a quick answer to all those posts about this, so we can just send people in the direction of this thread, and tell them to read. Let us begin:

Let me start by introducing everyone to the not so common terms I will be using:

Memory Leak: the leakage of handle objects, or in other words, basically whenever you create something or reference something, other than integers the game loses it’s location, thus causing a leaked piece of memory. Now granted these are cleaned at the end of the game, but if enough pile up during play without being removed, it can cause serious lag to the players, ranging from a little here and there, to complete un-playability, neither of which is wanted.

Jass: the scripting language used for scripting Maps and AI files in Blizzard Entertainment's Warcraft III game. Most people make triggers in GUI format, the premade template triggers that are in the World Editor. However, the actual language of these is that of JASS, which can give you almost free reign over every aspect of the game.

Custom Script: this is an action in the World Editor Trigger Editor which allows you to type one line of JASS script as opposed to using a template GUI script. This is what we will be using to clean up most of our memory leaks, since Blizzard put in the ability to remove these leaks, but neglected to add them to basic GUI.


Now many different things can cause memory leaks, these include:

Special Effects
Groups
Points
Units
Regions
Forces
Lightning Effects
Floating Text
Countdown Timers
(There may be more which I have forgotten, but these are the ones that need to be dealt with the most, since they are most commonly used.)


Now I will show you examples of each of the most common, with memory leaks, and then after cleaning them up:

Unit Groups


Code:
  • Unit Group Bad
    • Events
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • Unit - Kill (Picked unit)Now this will leak memory for every unit picked, which, depending on how many times this is ran, can add up heavily.
Code:
  • Unit Group Good
    • Events
    • Conditions
    • Actions
      • Set Temp_Group = (Units in (Playable map area))
      • Unit Group - Pick every unit in Temp_Group and do (Actions)
        • Loop - Actions
          • Unit - Kill (Picked unit)
      • Custom script: call DestroyGroup (udg_Temp_Group)
This cleans up all of your leaks. We first set our unit group to a unit group variable, pick all the units in this variable, do our actions, and then destroy the unit group variable, using a Custom Script. Remember that when referencing a variable in JASS, you most use underlines for spaces and put ‘udg’ before the Variable name.


Points


Code:
  • Point Bad
    • Events
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
The unit created at the region leaks. This is not a major leak, but depending on the amount of units created, and how often, it can add up.


Code:
  • Point Good
    • Events
    • Conditions
    • Actions
      • Set Temp_Point = (Center of (Playable map area))
      • Unit - Create 1 Footman for Player 1 (Red) at Temp_Point facing Default building facing degrees
      • Custom script: call RemoveLocation (udg_Temp_Point)
By setting our position that we want the unit to be created at, creating it at the variable, then removing it, we remove all leaks.


Special Effects


Code:
  • Special Effect Bad
    • Events
    • Conditions
    • Actions
      • Special Effect - Create a special effect at (Center of (Playable map area)) using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
This introduces a new leak, the special effect leak, and has one we just went over, the point leak. We need to remove both of these.


Code:
  • Special Effect Good 1
    • Events
    • Conditions
    • Actions
      • Set Temp_Point = (Center of (Playable map area))
      • Special Effect - Create a special effect at Temp_Point using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation (udg_Temp_Point)
In the same fashion as before, we remove our leaks. Special effects are one of the only things you can remove through GUI functions, and no custom script is needed. Whenever you create a special effect, you should always destroy it, even if it looks as though it destroys itself, such as in this case with Thunder Clap. Now some special effects, if destroyed directly after being made, never show at all. In that case you have to add a wait in, then destroy the special effect at a later time.


Code:
  • Special Effect Good 2
    • Events
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions
          • Set Temp_Point = (Center of (Playable map area))
          • Special Effect - Create a special effect at Temp_Point using Abilities\Spells\Undead\UnholyAura\UnholyAura.mdl
          • Set Temp_SFX[(Integer A)] = (Last created special effect)
          • Custom script: call RemoveLocation (udg_Temp_Point)
      • Wait 2.00 seconds
      • For each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions
          • Special Effect - Destroy Temp_SFX[(Integer A)]
This is an example if you wanted to have a wait, and create many special effects at once. This stores each into a special effect variable array, and destroys them all at a later time.

Units

The last major leak is that of units. Many people like to use dummy units to create neat triggered spells and such. If these units are not removed, they can just pile up all around the map, leading to some major lag. We use our example from before:


Code:
  • Units Bad
    • Events
    • Conditions
    • Actions
      • Unit - Create 1 Dummy Caster for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
There is a very easy way to remove them after they are no longer needed. Remember to fix your other point leak too.


Code:
  • Units Good
    • Events
    • Conditions
    • Actions
      • Set Temp_Point = (Center of (Playable map area))
      • Unit - Create 1 Dummy Caster for Player 1 (Red) at Temp_Point facing Default building facing degrees
      • Custom script: call RemoveLocation (udg_Temp_Point)
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
This adds an expiration timer to the unit, so it is destroyed after 2 seconds. This is usually enough time for it to do what it needs to, but you can change it for your personal needs.

Other Possibilities

That pretty much covers all the major leaks problems people have in their maps. Here are a few more custom script functions you can use to remove other leaks that sometimes occur:


Code:
  • Custom script: call DestroyForce( udg_Your_Variable )
//Player GroupCode:
  • Custom script: call RemoveRect(udg_Your_Variable)
//RegionCode:
  • Custom script: call DestroyLightning( udg_Your_Variable )
//Lightning EffectCode:
  • Custom script: call DestroyTextTag( udg_Your_Variable )
//Floating TextThis is one of the only things that can also be easily destroyed in GUI. There ar two way of doing this, each are equally effective.


Code:
  • Floating Text - Change the lifespan of (Last created floating text) to 5.00 seconds
  • Floating Text - Destroy (Last created floating text)
The first simply adds a destroy timer to the text tag, and it will be destroyed in 5 seconds, the second is a manual destroy you can do yourself.



Code:
  • Custom script: call DestroyTimer( udg_Your_Variable )
//Countdown Timerand lastly, one good Custom Script to use is that when you have a trigger that will only run once, then is useless. In those cases, put this at the end of the trigger. It can greatly reduce lag in your maps.


Code:
  • Custom script: call DestroyTrigger( GetTriggeringTrigger() )
Final Trigger

Let us put all our newly acquired knowledge together for one final leak less trigger.


Code:
  • Final Good Trigger
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Animate Dead
    • Actions
      • Set Temp_Point = (Position of (Casting unit))
      • Special Effect - Create a special effect at Temp_Point using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Special Effect - Destroy (Last created special effect)
      • Set Temp_Group = (Units within 512.00 of Temp_Point matching (((Matching unit) is A structure) Equal to False))
      • Custom script: call RemoveLocation (udg_Temp_Point)
      • Unit Group - Pick every unit in Temp_Group and do (Actions)
        • Loop - Actions
          • Set Temp_Point = (Position of (Picked unit))
          • Unit - Create 1 Dummy Caster for (Owner of (Casting unit)) at Temp_Point facing Default building facing degrees
          • Unit - Order (Last created unit) to Human Priest - Inner Fire (Picked unit)
          • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
          • Custom script: call RemoveLocation (udg_Temp_Point)
      • Custom script: call DestroyGroup (udg_Temp_Group)
You have completed my tutorial. I hope you have learned a thing or two, and happy mapping!!

Feel free to visit JASS Tools for a list of all JASS functions known, some JASS tools, and a very good JASS manual.

v 1.03

Possibly More To Come...

This is what I used and now use in all my triggers ^

Side Notes

  • Do not use Do Nothing as it basically compiles to a blank function call that does its name and wastes processor time.
  • A global variable stores a value so that it can be used at a later point in time, even if that point is near immediatly.
  • Also for the array, the size parameter that the globals editor provides mostly does nothing and so can be ignored but the true maximum size on an array is 8191.

Expert


The rest is up to you, have fun creating maps with triggers. If you still don't get it and need help creating a trigger then just ask and I'll be happy to help. I created this entire tutorial for +rep so please I would like to become more well known on THW. Some other talents of mine include: loading screens, loading minimap, any graphic design Ex:skinning. If you need any of those I will probobly be willing to help. In conclusion I hope everyone who read this learned a little something about triggering. I also hope the 4 hours I put into this tutorial don't go to waste.My warcraft 3 account is named Zypher and I am in no way aphiliated with the other Zypher that lurks THW, just a coincidence. Happy triggering.

-Zypher
------------------------------------------------------------------------------------
READING OPTIONAL-----------READING OPTIONAL------------READING OPTIONAL
------------------------------------------------------------------------------------
CONSTRUCTIVE CRITISISM IS APPRICIATED!
-Dr Super Good:
Nice tutorial that some people may find useful to learn from.

I think you need to explain better what GUI is, as it is basically a higher level language than JASS that gets compiled down to JASS on map save (quite badly I may add).

I also would advise you to recomend to people to not use Do Nothing as it basically compiles to a blank function call that does its name and wastes processor time.
You may also wish to wrap some more trigger tags aaround some of that GUI code.

Also you may want to emphisise that a global variable stores a value so that it can be used at a later point in time, even if that point is near immediatly.
Also for the array I recomend mentioning that the size parameter that the globals editor provides mostly does nothing and so can be ignored but the true maximum size on an array is 8191.

Although I have not read it in detail (do not have enough time to now), it probably could help someone and thus it may be worth approving.
hmm many concepts aren't well explained, is nice that you try to make it sound simple, but you also leave a lot of information for the reader to guess.

I think you could have explained a bit more what variables are. a good concept is " A variable is a reference to data stored in the computer's memory, variables are used to store values and get them back (in the case you want to use them again)."

Since you touched the topic of memory leaks, you could have also explained variable types as Pointers(Handles and references) and Not-Pointers.

The rest is fine, good job.
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Nice tutorial that some people may find useful to learn from.

I think you need to explain better what GUI is, as it is basically a higher level language than JASS that gets compiled down to JASS on map save (quite badly I may add).

I also would advise you to recomend to people to not use Do Nothing as it basically compiles to a blank function call that does its name and wastes processor time.
You may also wish to wrap some more trigger tags aaround some of that GUI code.

Also you may want to emphisise that a global variable stores a value so that it can be used at a later point in time, even if that point is near immediatly.
Also for the array I recomend mentioning that the size parameter that the globals editor provides mostly does nothing and so can be ignored but the true maximum size on an array is 8191.

Although I have not read it in detail (do not have enough time to now), it probably could help someone and thus it may be worth approving.
 
hmm many concepts aren't well explained, is nice that you try to make it sound simple, but you also leave a lot of information for the reader to guess.

I think you could have explained a bit more what variables are. a good concept is " A variable is a reference to data stored in the computer's memory, variables are used to store values and get them back (in the case you want to use them again)."

Since you touched the topic of memory leaks, you could have also explained variable types as Pointers(Handles and references) and Not-Pointers.

The rest is fine, good job.
 
Top