This is a tutorial/example map I will serve up to to enlighten the community on how to use functions with the trigger GUI.
First, heres a very simple (Fellow programmers will want to bash their heads in with disgust if you continue reading) explanation of a function, this will be using generic code to get a point across before delving into the Trigger GUI:
A function is a special block of code with a name. It can receive information, process it, and then return information. The reason it is a powerful tool in creating YOUR map is because it can be told to do some actions with a value you give it, then it will do those actions using that value, and return a value to you based on those actions. First I will go over the format of a function in generic code, then I while explain how it is translatable in GUI.
You see the word int a lot of times in the above definition, it is a value that is interchanged based on the Object type, or Variable type. For example, the first int is considered the functions return type, that is to say, the type of variable this function returns to you when called. The second int is inside the parenthesis, which means its a paramater type, or the variable type of a kind of variable you are GIVING to the function to play with, and the int inside the body of the function is just a variable type, it is the type of a variable you declare, in this case, a local variable. Common types of variable/Object types are int, char, String, boolean or bool, double, float, and many more.
The top line of this function definition is called the method. A function method is the line that gives the function return type, name, and parameter(s). A method helps defines how a function can be called in code or in this case your Triggers.
The inside of the two brackets { } is considered the function body, and is what the function executes, very much like the ACTIONS in a TRIGGER.
All variables in a function are local variables, functions can refer to global variables, or variables outside of themselves, but can only create local variables inside of their bodies.
A functions parameters are just the framework variables you declare for a function, for example, if I made some of my function's parameters:
Then the function would know to expect an int variable, a boolean variable, and a String variable to be given to IT, by the USER, whenever it is CALLED. Once a function is called and it has it's parameters, the parameters can be thought of as local variables, you can use them much like variables in triggers except that you shouldn't be altering the value of a parameter, which is why programmer's usually create local variables inside a function and then SET it to a parameter, so they can always modify that new local variable without messing with the parameter.
[/list]
Inside the body you can see a variable declaration for a local variable called functionVariable
Where the function has functionActions, that is just a placeholder for all of the stuff you want the function to do.
The return value of the function, or what the function returns to the user and then exits, is denoted by
returnfunctionReturnValue;
This return value can be a variable, or a simple 1,2,3,4,5,6,true,false,"I Like Sandwhiches", whatever. Examples:
Now the important stuff about returns, ALL FUNCTIONS NEED THEM, they do not function without a return value, and once you return a value within a function, that function stops executing, no matter where in that function you returned a value, this can be used as an exit from the function in things like if/elses, and loops.
Now that you have functional knowledge of a function, hahaha........, It's time to show you how this relates to the GUI functions in the Trigger Editor.
Here is a picture of a new function in the trigger editor, and circled is the button that creates it.
Now lets take a look at the actual inner-workings of a GUI Function and relate back to the code function we talked about.
Options: Function Ignore this, I know I have and with wonderful results! (Note: Might be useful, might not be, either way, of no concern for newbie function enthusiasts.
Return Type: Boolean This sets what type of value the function returns, this is the functions Return type as seen in the method of the code example.
Parameters Right click on this and go to new > new paramater, you create this very much like you create a variable, and the way you order them matters for whenever you call your function
Grammar Text: HERPDERPFUNCTION() This is how you would type the function call were you to call a function, you will see that as you change the name of the function, and add or remove parameters, this value changes.
Hint Text I haven't needed this yet, so I will take the liberty of saying you don't either.
Custom Script Code Same as Above
Local Variables Any local variables you want to declare for this function, it is damn good programming etiquette to create and set a local variable for every parameter variable you have.
Ok Now that you took a break I know you couldn't help but notice that the Break was labelled with a numerical symbol of counting, yes this tutorial is gonna be that long. Lets get back into it.
Now that you know what a function works, what a GUI function looks like, and how to create one, it's time to USE one. I am going to create just some Trigger, it can be about anything but mine is going to be a trigger that executes a function every time a player presses the spacebar.
I am not gonna post a picture of my Trigger, because I assume you know how to make one, but here is the text for it >
Untitled Trigger 001
Events
UI - Player Any Player presses Space key Down with shift Allow, control Allow, alt Allow
Local Variables
Conditions
Actions
Placeholdercommentforcallingthetrigger
Yes that's right, my actions is just a comment so far, thats because we will come back to this trigger once we finish creating our function!
Alright, so lets think about what I would want my function to do every time I run it, I would want it to take the triggering player, such as player 1, and then display a game message saying that player is the greatest player of all time, then I would like it to return a boolean that equals true, if it did so without any problems.
Lets convert what I want into function terms
Return type : boolean
Parameters: int thePlayer
Local Variables: int player = thePlayer ( You can select a parameter much like you select a variable, it has its own tab)
Aaaaand Now lets see what that looks like inside the GUI Function:
Ok, so we have the skeleton of the function set up, notice that I created an action that returns true, this is how the function exits itself, and how it tells you whatever you want to know, which in this case is: Did it do it's stuff properly? = TRUE
Now lets just add some actions in there to make it do its thing and go back to the Trigger to see how to use the function:
Alright you were probably less tired with reading on that last one, we were actually learning to create the thing this tutorial is about! Now, lets go back to the Trigger to learn the most important part, how to call the function in the current Galaxy Editor using GUI and absolutely ZERO Code!
...
...
...
...
Theres no way to do that at the moment. Yep, seriously, we can create functions in GUI but we can't call them, I mean hell, we can call other triggers and they are just glorified functions themselves! WAIT WAIT don't close the window, I didn't lie to you, I just omitted an ugly truth. You will need to do a little typing to run a function. To call a function using GUI you need to create a new action, go to general, and click on custom script.
Now that you have custom script going, type in the following to run this specific function
gf_improvePlayerEgo(EventPlayer());
That will execute the function everytime the Trigger is executed. Now to explain some things you are now asking your computer screen:
technically your function call should be improvePlayerEgo(EventPlayer()); but Galaxy requires a prefix to tell it where to look, let me go over some prefixes with you.
gf = global function
gv = global variable
lv = local variable
sc = Starcraft, you now understand my name if you didn't before. Please don't use that in your function calls... :)
So, using the prefix we need to make our function call gf_improvePlayerEgo(EventPlayer());
BUT WAIT, whats event player? Thats the script for TriggeringPlayer, which is a Galaxy Function that returns the integer of whatever player triggered the event. So if you just want to do player 1, your function call would be, gf_improvePlayerEgo(1);
Now, even more tricky is if you wanted to do Picked Player, the function for determining that is PlayerGroupLoopCurrent(); , so your function call would be gf_improvePlayerEgo(PlayerGroupLoopCurrent());
The semicolon at the end of all of my statements is used in code to denote the end of a line, and is what tells the compiler to treat that line as a statement.
If you didn't understand any of that, don't worry, some playing around with it will get you on track. Now, run the map and keep pressing Space to see that functions really do work!
Some final conclusion statements and answers to questions:
Why didn't I do anything with the return of the function? Because for my specific example, I don't need to store the boolean of true to know that my function worked out, the Game Message does that for me! But, If I really wanted to store into a variable whatever my function returned, I would use some more Custom script, assume that myVariable, is the variable you want to store in, remember from above lv = local variable, and gv = global variable
Now if you were to query those variables, you would find that they held the values of TRUE, and the function ran!
Biggest Question of All time: But SCMapper, why did I make a function, I could have just done triggering player inside of the Trigger! Well yes, this implementation of a function isn't very efficient. But what if you wanted to display a different message every-time of your own choice? You could add another parameter of type string, and then along with giving the function a player value, send it that string as well, and you could modify it to display the player's name and a different string with each run. BUT SCMAPPER..... I could still do that in in the trigger. You're right you can, but what if you did this 1000 times through 100 different triggers, and you realized you wanted to change something about it? Oops. There goes your month. BUT WAIT! Functions to save the day! Go into your function, modify what you want to modify, and those triggers will still all operate without a hitch.
Ask any questions you want, I am very tired and probably left something out :) ENJOY
You outdid yourself here SCMapper, functions are a great way to speed up any map, use them left and right my bound, makes one "death square" so much faster to make =)
Id love to see more tutorials by you, keep them coming.
Rollback Post to RevisionRollBack
Random Information
Tutorials - Map Development - Galaxy wiki
|Issues? PM me|
Took me ages before I realized the editor had functions haha
There's actually a way to call functions from the GUI; have the function return boolean true after completing successfully and use a "SetVariable blnOk = myFunction(params)" to call the function.
Took me ages before I realized the editor had functions haha
There's actually a way to call functions from the GUI; have the function return boolean true after completing successfully and use a "SetVariable blnOk = myFunction(params)" to call the function.
Ok so I was able to follow your tutorial alright, but now I am having trouble adjusting this to my needs. This is my first real attempt at using functions and I keep getting the error "expected a return value" but as far as I understand it I have a return value. I'm using the fuction to try to call back the integer value a a unit variables array from the unit rather than from the variable. This is something I will have to do frequently in my map so I thought a function would be a good approach. I want the function to return an integer. I want the parameter to be a specific unit. By setting this parameter equal to a local variable I attempt then run an integer loop for all numbers 1-10. The loop is an if than statement, if local variable unit=global variable (picked integer) then return value pick integer. If I read the above correctly the function should end after it successfully makes a return so I do not see what I am doing wrong. I am calling the function with a custom script in place of an integer (gf_unitarray(EventUnitTarget()) My function is as follows:
unitarray
Options: Function
Return Type: Integer
Parameters
parameter(unit) = No Unit <Unit>
Grammar Text: unitarray(parameter(unit))
Hint Text: (None)
Custom Script Code
Local Variables
localUnit = No Unit <Unit>
Actions
Variable - Set localUnit = parameter(unit)
General - Pick each integer from 1 to 10, and do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
You shouldn't bother with explaining Galaxy in a tutorial teaching people about GUI. GUI exists because people don't like Galaxy.
Anyways a couple points you should probably fix:
Quote:
Local Variables Any local variables you want to declare for this function, it is damn good programming etiquette to create and set a local variable for every parameter variable you have.
Sorry, but this is blatantly wrong. Using parameter variables is fine, and its far better programming etiquette to not create useless extraneous variables.
Also you don't need to use custom script to call functions (and this is a pain for someone who uses GUI). Essentially, you only need to use a variable set action to call them - ie, Set variable myInt to value myFunction(). If you don't want to have a variable storing the value you get from the function, why are you making a return function anyways? You can use an action definition instead to do the same thing more efficiently.
Hint text is basically like comments regarding the function. For example, you could include notes on what the function does exactly or other things. I would say tis important for anyone making libraries, but if the functions are just for personal use in a map its pretty extraneous.
EDIT: Also you should include that the function needs to be able to return a value every time, outside of if/then blocks. For example, if you have a function that returns X if "2 + 2 == 4", then it will have an error saying that its possible for it to not return a value. Even though this is obviously untrue, you need to include a return statement outside of the if/then statement so that it can compile properly.
Once a function is called and it has it's parameters, the parameters can be thought of as local variables, you can use them much like variables in triggers except that you shouldn't be altering the value of a parameter, which is why programmer's usually create local variables inside a function and then SET it to a parameter, so they can always modify that new local variable without messing with the parameter.
This is so wrong I want to hit you. Please, never, EVER, post such obviously wrong crap.
When you act on a parameter, unless it is a pointer-type (unit, doodad, actual in-game objects that the variable is referring to) it is not changed. Parameters are copied by value, not reference. This is true of every single freaking programming language ever, unless you specifically state you want to pass a variable by reference.
Furthermore, if it is a pointer-type, setting a variable equal to it still does nothing. You still get a reference to the same object.
int, char, String, boolean or bool, double, float, and many more.
This is not Java. It is "bool", "string", "fixed" (instead of double/float). Lowercase. Galaxy cares about that. Please learn the language you are writing a tutorial on.
Using parameter variables is fine, and its far better programming etiquette to not create useless extraneous variables.
Yep, that's true for Sc2.
For languages where you can pass variables by reference it's different, but Galaxy isn't that advanced.
You can even directly change the function's parameters without trouble.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
FAIR WARNING, LOTS OF READING, A FEW PICTURES
This is a tutorial/example map I will serve up to to enlighten the community on how to use functions with the trigger GUI.
First, heres a very simple (Fellow programmers will want to bash their heads in with disgust if you continue reading) explanation of a function, this will be using generic code to get a point across before delving into the Trigger GUI:
A function is a special block of code with a name. It can receive information, process it, and then return information. The reason it is a powerful tool in creating YOUR map is because it can be told to do some actions with a value you give it, then it will do those actions using that value, and return a value to you based on those actions. First I will go over the format of a function in generic code, then I while explain how it is translatable in GUI.
Things to note on the above structure:
[/list]
Now the important stuff about returns, ALL FUNCTIONS NEED THEM, they do not function without a return value, and once you return a value within a function, that function stops executing, no matter where in that function you returned a value, this can be used as an exit from the function in things like if/elses, and loops.
Now that you have functional knowledge of a function, hahaha........, It's time to show you how this relates to the GUI functions in the Trigger Editor.
Here is a picture of a new function in the trigger editor, and circled is the button that creates it.
Now lets take a look at the actual inner-workings of a GUI Function and relate back to the code function we talked about.
Options: Function Ignore this, I know I have and with wonderful results! (Note: Might be useful, might not be, either way, of no concern for newbie function enthusiasts.
Return Type: Boolean This sets what type of value the function returns, this is the functions Return type as seen in the method of the code example.
Parameters Right click on this and go to new > new paramater, you create this very much like you create a variable, and the way you order them matters for whenever you call your function
Grammar Text: HERPDERPFUNCTION() This is how you would type the function call were you to call a function, you will see that as you change the name of the function, and add or remove parameters, this value changes.
Hint Text I haven't needed this yet, so I will take the liberty of saying you don't either.
Custom Script Code Same as Above
Local Variables Any local variables you want to declare for this function, it is damn good programming etiquette to create and set a local variable for every parameter variable you have.
$ $ $ $ $ $ $ $ $ $ $
$ $ $ $ $ $ $ $ $ $ $
$ $ $ $ $ $ $ $ $ $ $
5 Minute Nap Time #1
$ $ $ $ $ $ $ $ $ $ $
$ $ $ $ $ $ $ $ $ $ $
$ $ $ $ $ $ $ $ $ $ $
Ok Now that you took a break I know you couldn't help but notice that the Break was labelled with a numerical symbol of counting, yes this tutorial is gonna be that long. Lets get back into it.
Now that you know what a function works, what a GUI function looks like, and how to create one, it's time to USE one. I am going to create just some Trigger, it can be about anything but mine is going to be a trigger that executes a function every time a player presses the spacebar.
I am not gonna post a picture of my Trigger, because I assume you know how to make one, but here is the text for it >
Untitled Trigger 001
Events
UI - Player Any Player presses Space key Down with shift Allow, control Allow, alt Allow
Local Variables
Conditions
Actions
Placeholdercommentforcallingthetrigger
Yes that's right, my actions is just a comment so far, thats because we will come back to this trigger once we finish creating our function!
Alright, so lets think about what I would want my function to do every time I run it, I would want it to take the triggering player, such as player 1, and then display a game message saying that player is the greatest player of all time, then I would like it to return a boolean that equals true, if it did so without any problems.
Lets convert what I want into function terms
Return type : boolean
Parameters: int thePlayer
Local Variables: int player = thePlayer ( You can select a parameter much like you select a variable, it has its own tab)
Aaaaand Now lets see what that looks like inside the GUI Function:
Ok, so we have the skeleton of the function set up, notice that I created an action that returns true, this is how the function exits itself, and how it tells you whatever you want to know, which in this case is: Did it do it's stuff properly? = TRUE
Now lets just add some actions in there to make it do its thing and go back to the Trigger to see how to use the function:
$ $ $ $ $ $ $ $ $ $ $
$ $ $ $ $ $ $ $ $ $ $
$ $ $ $ $ $ $ $ $ $ $
5 Minute Nap Time #2
$ $ $ $ $ $ $ $ $ $ $
$ $ $ $ $ $ $ $ $ $ $
$ $ $ $ $ $ $ $ $ $ $
Alright you were probably less tired with reading on that last one, we were actually learning to create the thing this tutorial is about! Now, lets go back to the Trigger to learn the most important part, how to call the function in the current Galaxy Editor using GUI and absolutely ZERO Code!
...
...
...
...
Theres no way to do that at the moment. Yep, seriously, we can create functions in GUI but we can't call them, I mean hell, we can call other triggers and they are just glorified functions themselves! WAIT WAIT don't close the window, I didn't lie to you, I just omitted an ugly truth. You will need to do a little typing to run a function. To call a function using GUI you need to create a new action, go to general, and click on custom script.
Now that you have custom script going, type in the following to run this specific function
gf_improvePlayerEgo(EventPlayer());
That will execute the function everytime the Trigger is executed. Now to explain some things you are now asking your computer screen:
technically your function call should be improvePlayerEgo(EventPlayer()); but Galaxy requires a prefix to tell it where to look, let me go over some prefixes with you.
gf = global function
gv = global variable
lv = local variable
sc = Starcraft, you now understand my name if you didn't before. Please don't use that in your function calls... :)
So, using the prefix we need to make our function call gf_improvePlayerEgo(EventPlayer());
BUT WAIT, whats event player? Thats the script for TriggeringPlayer, which is a Galaxy Function that returns the integer of whatever player triggered the event. So if you just want to do player 1, your function call would be, gf_improvePlayerEgo(1);
Now, even more tricky is if you wanted to do Picked Player, the function for determining that is PlayerGroupLoopCurrent(); , so your function call would be gf_improvePlayerEgo(PlayerGroupLoopCurrent());
The semicolon at the end of all of my statements is used in code to denote the end of a line, and is what tells the compiler to treat that line as a statement.
If you didn't understand any of that, don't worry, some playing around with it will get you on track. Now, run the map and keep pressing Space to see that functions really do work!
Some final conclusion statements and answers to questions:
Why didn't I do anything with the return of the function? Because for my specific example, I don't need to store the boolean of true to know that my function worked out, the Game Message does that for me! But, If I really wanted to store into a variable whatever my function returned, I would use some more Custom script, assume that myVariable, is the variable you want to store in, remember from above lv = local variable, and gv = global variable
lv_myVariable = gf_improvePlayerEgo(EventPlayer());
gv_myOtherVariable = gf_improvePlayerEgo(EventPlayer());
Now if you were to query those variables, you would find that they held the values of TRUE, and the function ran!
Biggest Question of All time: But SCMapper, why did I make a function, I could have just done triggering player inside of the Trigger! Well yes, this implementation of a function isn't very efficient. But what if you wanted to display a different message every-time of your own choice? You could add another parameter of type string, and then along with giving the function a player value, send it that string as well, and you could modify it to display the player's name and a different string with each run. BUT SCMAPPER..... I could still do that in in the trigger. You're right you can, but what if you did this 1000 times through 100 different triggers, and you realized you wanted to change something about it? Oops. There goes your month. BUT WAIT! Functions to save the day! Go into your function, modify what you want to modify, and those triggers will still all operate without a hitch.
Ask any questions you want, I am very tired and probably left something out :) ENJOY
MAP DOWNLOAD: http://dl.dropbox.com/u/6541938/tutorials/functions/001.SC2Map
Thanks a ton for this. I can already think of ways I'll apply this
@SCMapper: Go
You outdid yourself here SCMapper, functions are a great way to speed up any map, use them left and right my bound, makes one "death square" so much faster to make =)
Id love to see more tutorials by you, keep them coming.
Took me ages before I realized the editor had functions haha
There's actually a way to call functions from the GUI; have the function return boolean true after completing successfully and use a "SetVariable blnOk = myFunction(params)" to call the function.
Genius, thank you for that bit of information.
Ok so I was able to follow your tutorial alright, but now I am having trouble adjusting this to my needs. This is my first real attempt at using functions and I keep getting the error "expected a return value" but as far as I understand it I have a return value. I'm using the fuction to try to call back the integer value a a unit variables array from the unit rather than from the variable. This is something I will have to do frequently in my map so I thought a function would be a good approach. I want the function to return an integer. I want the parameter to be a specific unit. By setting this parameter equal to a local variable I attempt then run an integer loop for all numbers 1-10. The loop is an if than statement, if local variable unit=global variable (picked integer) then return value pick integer. If I read the above correctly the function should end after it successfully makes a return so I do not see what I am doing wrong. I am calling the function with a custom script in place of an integer (gf_unitarray(EventUnitTarget()) My function is as follows:
unitarray
Options: Function
Return Type: Integer
Parameters
parameter(unit) = No Unit <Unit>
Grammar Text: unitarray(parameter(unit))
Hint Text: (None)
Custom Script Code
Local Variables
localUnit = No Unit <Unit>
Actions
Variable - Set localUnit = parameter(unit)
General - Pick each integer from 1 to 10, and do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
localUnit == Zerglings[(Picked integer)]
Then
General - Return (Picked integer)
Else
Nevermind, figured it out. I had to create a local integer variable, assign the picked integer to it and return the value from outside of the loop.
You shouldn't bother with explaining Galaxy in a tutorial teaching people about GUI. GUI exists because people don't like Galaxy.
Anyways a couple points you should probably fix:
Sorry, but this is blatantly wrong. Using parameter variables is fine, and its far better programming etiquette to not create useless extraneous variables.
Also you don't need to use custom script to call functions (and this is a pain for someone who uses GUI). Essentially, you only need to use a variable set action to call them - ie, Set variable myInt to value myFunction(). If you don't want to have a variable storing the value you get from the function, why are you making a return function anyways? You can use an action definition instead to do the same thing more efficiently.
Hint text is basically like comments regarding the function. For example, you could include notes on what the function does exactly or other things. I would say tis important for anyone making libraries, but if the functions are just for personal use in a map its pretty extraneous.
EDIT: Also you should include that the function needs to be able to return a value every time, outside of if/then blocks. For example, if you have a function that returns X if "2 + 2 == 4", then it will have an error saying that its possible for it to not return a value. Even though this is obviously untrue, you need to include a return statement outside of the if/then statement so that it can compile properly.
This is so wrong I want to hit you. Please, never, EVER, post such obviously wrong crap.
When you act on a parameter, unless it is a pointer-type (unit, doodad, actual in-game objects that the variable is referring to) it is not changed. Parameters are copied by value, not reference. This is true of every single freaking programming language ever, unless you specifically state you want to pass a variable by reference.
Furthermore, if it is a pointer-type, setting a variable equal to it still does nothing. You still get a reference to the same object.
This is not Java. It is "bool", "string", "fixed" (instead of double/float). Lowercase. Galaxy cares about that. Please learn the language you are writing a tutorial on.
Yep, that's true for Sc2.
For languages where you can pass variables by reference it's different, but Galaxy isn't that advanced.
You can even directly change the function's parameters without trouble.