[Tutorial] Functions

Rheias

New Helper (I got over 2000 posts)
Reaction score
232
Functions

Introduction

This tutorial (or rather, mini-tutorial) is for anyone who has a basic knowledge of JASS and is interested in learning a bit more. In this tutorial I will discuss that 3 types of functions, natives, BJs and finally the core of the tutorial, user designed functions. I will explain things that you are probably doing already, however this explanation will aid you in making things which are more advanced. In this tutorial I’m assuming you know the basics of JASS already (as I said already) so do not attempt to read this if you don’t.

You should use a JASS software in order to understand this tutorial properly (I use JassCraft, my favorite software).

What I expect you to know is basically how to create a simple trigger in JASS using locals, commands, etc. You should know the difference between “local”, “set” and “call” and know how to use each one, things of that kind.

Please note as well that English is a second language to me.

Natives

Let’s start with the basic form of functions, those are called natives. Natives are the core of JASS and everything (well almost everything some common.ai are independent) is built from those, whether it’s a BJ function or user-designed function. Natives execute a certain action which is assigned to them, these function can’t be modified (well they can, but most likely you wouldn’t do that). If you are using JassCraft (or a similar software) native functions will have the word native in them (or constant) when you click them. Here are few native examples:

JASS:

SetUnitPosition (native SetUnitPosition takes unit whichUnit, real newX, real newY returns nothing)
SetPlayerState (native SetPlayerState takes player whichPlayer, playerstate whichPlayerState, integer value returns nothing )
KillUnit (native KillUnit takes unit whichUnit returns nothing )
GetTriggerUnit (constant native GetTriggerUnit takes nothing returns unit)
CreateUnit (native CreateUnit takes player id, integer unitid, real x, real y, real face returns unit)

etc


Those are all natives, now let’s take one and analyze it. For example “KillUnit”. First of all we see the word “native” thus it is native, good, it shouldn’t tell you much now, soon enough you will know what it means that a function is native. After that you can see the function’s name which is KillUnit, thus we call the function by typing:

JASS:
 call KillUnit(etc.)


Now you see it says “takes unit”? That means we need to give the native a unit so it could do something with it (most natives take more then one value, for example CreateUnit). Examples:


JASS:

call KillUnit(GetTriggerUnit())

call KillUnit(GetEnumUnit())

call KillUnit(GetAttacker())

local unit caster = GetTriggerUnit()
call KillUnit(caster)

etc


And then we see “returns nothing” which means we don’t get a value from the function “KillUnit”. Let’s check another native, called GetTriggerUnit. You probably know that it returns triggering unit. “Constant native” That means it a native that doesn’t change its value. “Takes nothing” that means that in order to work the function doesn’t need anything to take (this is why we put “()” after using GetTriggerUnit, to show that this functions takes nothing) and then we see “returns unit” which means when we use this function we get refer to a unit, in this case triggering unit. So if we know that we can tell that a local unit can store this function. Example:

JASS:

local unit monkey = GetTriggerUnit()


This will returns triggering unit and put it inside a variable called monkey.

So let’s summarize it for a second to make sure you understand what happened here so far. We can recognize native functions by looking for the work “native” when clicking on them in one of the JASS programs. Natives can take something and return something. If they take something we put it between the () after them (separating values with commas, as you should know), if they take nothing we leave the “()” empty. If they return something it means we can store them inside a variable and refer to them easily. For example if you look at CreateUnit function you can see that it returns a unit, thus:


JASS:

local unit created = CreateUnit(etc.) // This will create a unit, and return it, the fact that it returns the unit means that we can store it inside variable, and this is what we are doing.


As you might have noticed, natives do different things, KillUnit, does something (kills a unit) while GetTriggerUnit simply finds a unit and gives it to use allowing us to refer to it, and CreateUnit does an action (creats a unit) and also returns it.

Alright so those are natives, you can go on and re-read this if you didn’t understand something, you should keep in mind that it’s easier that it looks, basically natives take something (or nothing) and then do with it something (usually), sometimes it returns a value and some times it doesn’t.

With that, I think you can move on and read about BJs.

Blizzard Jass

BJs stands for Blizzard JASS (Blizzard.j), BJs are functions made by Blizzard which store in them natives (or sometimes other BJs). What that means is that when you are calling a BJ, it will call another function/s, which means it will slows down the trigger. Why is that? Allow me to give you an example, say you want to get an apple, what would be faster, asking someone to bring it to you, or asking someone to ask from someone else to bring it to you? Usually you will get the apple quicker in the first situation, right? So do functions work.

So, we might ask ourselves why in the lord’s name did Blizzard create BJs? Well, it’s all because of GUI, almost all BJs were created to serve the GUIers, that’s why when you are converting a GUI trigger you would get loads of BJs instead of clean natives. However, there are few examples were BJs simply short long functions to make it easier for us (such as PolarProjectionBJ, ModifyGateBJ, etc.)

The next question is how can we recognize BJs? Well most BJs have swapped, BJ or other funny word in the end of them (like PolarProjectionBJ, ModifyGateBJ, AddHeroXPSwapped, UnitAddItemSwapped, etc.), however some of them don’t have those words in their end (such as DistanceBetweenPoints) and we need to check in one of the JASS programs if it’s a BJ or not. If when you click on the function there is no “native” in the start of it then it is BJ, BJs are always presented as a function with one or more actions in it which do something (usually takes values assigned to it and passes them to natives).

You should avoid using BJs, while usually their slowness is not noticeable, using them a lot in short durations will cause problems. For example if you create a timer that will run every 0.003 seconds and you would use lots of BJs, the timer wouldn’t have the time to complete it’s actions (in extreme cases) and that will create problems. Anyway, doesn’t having a cleaner code make you feel better about it?

Side Note: You should note that coordinates use natives while a lot of functions regarding locations are BJs that convert the location into coordinates, thus if possible you should use coordinates. Also locations are slow because destroying them (call RemoveLocation(loc)) is very slow.

User Defined

Finally we reached this chapter, everything until now was sort of a background so you could understand this better. So, what are user defined functions? User defined functions are every function you create. Did you just type a function that checks if the spell casted is Animate Dead? You just created a user defined function. Did you create a function that deals damage to everyone around the middle of the map? Indeed, that’s another user defined function. So we can say that user defined functions are the functions which JASSers create, thus they weren’t created by Blizzard (notice the name user defined).

As you might know user defined functions are create like so:

Code:
[b]function[b] [i]func_name[/i] [b]takes[/b] [/i]arguments[/i] [b]returns[/b] [i]value[/i]

Let’s explain that. “functions” Means that you are starting a function defining line, JASS knows now that here you define a function. You might noticed that every line in JASS starts with this kind of “line defining” word, “call” calls a functions, “local” defines a local variable, “set” stores a value inside a variable and finally “function” starts a function defining line.

Next, instead of func_name you need to put the function name (case sensitive), no spaces, use “_” instead, no special characters (such as “!”,”?”,”\”,”:”,”.”,”,”,”””, etc.), and the function name may not begin with an integer (however it may have integers in it later on).

Valid names:

Worms, Hi, h_e_l_l_0, aru5264927363, I_1_3_3_7 etc...

Invalid names:

h e l l o, 2727hi, My_Name_Is_!?.,"~@^%$#)(*&^ etc...

After that there is the word “takes”, like any other function (native or BJ) a user defined function can take something to do with it something. Let’s check for a second again the native KillUnit.

JASS:
 (native KillUnit takes unit whichUnit returns nothing )


You see that it takes a unit? We can do the same thing! Note that it gives the unit a name, in this case it calls it whichUnit, however you can name it however you want following the same rules as the func_name rules. The function will refer to the taken values as locals, thus you refer to them by typing in their name.Now say that we want to take few values? Let's check create unit then.

JASS:
 native CreateUnit takes player id, integer unitid, real x, real y, real face returns unit


As you can see, this function takes few values, player, integer, real, another real and a third real. For each taking value it assigns a type and a name, and it separates between different values with a comma, same thing goes to user-defined functions.

Lastly there is “returns value”, the function may return something, for example if it is a condition it will return a Boolean. Let’s see an example of a function

JASS:

function tut_example1337 takes unit a13373r returns integer
    return GetUnitUserData(a13373r)
endfunction


This takes a unit (a13373r) and returns its custom value. Here is another example:

JASS:

function GetAttackedUnitBJ takes nothing returns unit
    return GetTriggerUnit()
endfunction


Actually there is a function like that, which is a BJ made by blizzard, I just wanted to show you that user defined functions are BJs done by you. Let’s see two final examples:

JASS:

function useless_location_function takes real locX, locY returns location
    return Location(locX,locY)
endfunction


takes two reals and converts them into a location, (coordinates to location), and finally quick example of a function that returns nothing:

JASS:

function KillingFest takes unit unlucky_soldier returns nothing
    call KillUnit(unlucky_soldier)
    call PolledWait(2.00)
    call RemoveUnit(unlucky_soldier)
endfunction


Side Note: Return is a little tricky function. Firstly whenever the function runs a return line it skips remaining actions. Did you know that “Skip Remaining Functions” in GUI is “return” in JASS? Secondly you must have a “return” line outside a loop or if / then / else when dealing with a function that returns something. This will not work:

JASS:

function no_name takes nothing returns boolean
    if condition then
        return true
    endif
endfunction


You need to do this:

JASS:

function no_name takes nothing returns boolean
    if condition then
        return true
    endif
    return false
endfunction


Side note: When a function returns a Boolean you can simply do:

JASS:

function no_name takes nothing returns boolean
    return condition
endfunction


And then it will return true or false, depending if the Boolean is true or false.

Lastly you need to be careful when dealing with return functions because they can cause crashes if handled poorly (that's very rare, just keep it in mind).

Alright, we know how to create a working user defined function, now let’s see how we can call one. Calling a user-defined is just like calling a native.

JASS:
call func_name(arguments)


However, differently from native we must define the user defined function before the calling function.

Let’s give an example:


JASS:

function KillingFest takes unit unlucky_soldier returns nothing
    call KillUnit(unlucky_soldier)
    call PolledWait(2.00)
    call RemoveUnit(unlucky_soldier)
endfunction

function KillingFestCaller takes nothing returns nothing
    local unit victim = GetTriggerUnit()
    call KillingFest(victim)
endfunction


This will work, it will kill the triggering unit and after 2 seconds remove it from the game. This however will cause a syntax problem (I hate JASS’s syntax checker)

JASS:

function KillingFestCaller takes nothing returns nothing
    local unit victim = GetTriggerUnit()
    call KillingFest(victim)
endfunction

 function KillingFest takes unit unlucky_soldier returns nothing
    call KillUnit(unlucky_soldier)
    call PolledWait(2.00)
    call RemoveUnit(unlucky_soldier)
endfunction


When the trigger reads KillingFestCaller it didn’t read yet KillingFest, thus it wouldn’t know what to do.

Important note: Keeping everything in one function is faster then dividing it into 2 functions, like natives and BJs. This is faster then the previous example:

JASS:

function Efficent_Killing_Fest takes unit nothing returns nothing
    local unit unlucky_soldier = GetTriggerUnit()
    call KillUnit(unlucky_soldier)
    call PolledWait(2.00)
    call RemoveUnit(unlucky_soldier)
endfunction


Like we said, asking someone to bring an apple is faster then asking someone to ask someone to bring an apple.

So, those are more or less the basics of functions, I hope you enjoyed, this is my first tutorial written so please be patient with your comments, thanks for reading.
 

Tom Jones

N/A
Reaction score
437
This must be a typo, because I've seen your coding before:
JASS:
local unit worm = call CreateUnit(etc.) //call?


this is my first tutorial written so please be patient with your comments, thanks for reading.
Not bad at all, but it was abit disappointed that you didn't give any examples of BJ functions, especially those useless functions that only changes the order of the parameters.
 

Rheias

New Helper (I got over 2000 posts)
Reaction score
232
It doesn't matter how many times I read this, I missed somthing.

Thanks, indeed the "call" shouldn't be there, updated.
 

uberfoop

~=Admiral Stukov=~
Reaction score
177
Code:
local unit worm
call CreateUnit(etc.)
set worm = GetLastCreatedUnit()
Erm, that won't work.

CreateUnit doesn't store a last created unit.
 

Rheias

New Helper (I got over 2000 posts)
Reaction score
232
> CreateUnit doesn't store a last created unit

Nothing but a theoretical example here.

> Yes, it should be set worm = CreateUnit(etc)

> Nope, it should be: local unit worm = CreateUnit(...)

Yes.

> looks like ive read another tutorial simmilar to this before

Really? Oh well, another one can't hurt. ;)

Thanks for reading and commenting, I would love to hear more feedback about if the tutorial is clear, did I forget to metion somthing, etc.
 
Reaction score
456
Yeeeh! This is really quite useful.. for someone >_>!

You find a surprise from your User CP when you open it. Won't tell what it is, cause it would ruin the.. thing?
 

Omni

Ultra Cool Member
Reaction score
37
thank you for posting this <3
(i didnt know about functions cause ikilledkenny closed jass101 :( )
+rep? : yes
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,495
> did I forget to metion somthing

Some missing characters maybe? :)


> Nothing but a theoretical example here.

Bad idea.
People will read until there, go "yeah, just what I need", and, 5 minutes later, we get a "It doesn't work" post.


> “Constant native” That means it a native that doesn’t change it’s value.

Like "GetHeroLevel" for example?



What that means is that it means ... which means what it means.
You might agree this style not being very... um... good?

Or using "work" for "word".
Or "this function takes few values"... missing "a".
 

Rheias

New Helper (I got over 2000 posts)
Reaction score
232
I should have mentioned that English is a second language to me. I worked very hard on spelling and grammar mistakes, however it seems that this tutorials lacks of proper English, I'm sorry for that, I will re-read it, I did use spell-checker program, so I thought it should be readable.

> People will read until there, go "yeah, just what I need", and, 5 minutes later, we get a "It doesn't work" post.

Ok, then I'll add a side note stating that this wouldn't work, thanks for pointing it out.

> (i didnt know about functions cause ikilledkenny closed jass101)

Yes, this is why I decided to wrote this tutorial, I was very disappointed seeing that IKilledKEnny stopped teaching right before the most intresting part in jass (in my opinion). I hope to update this tutorial soon enough, thanks for the comments everybody!
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,495
> I should have mentioned that English is a second language to me

Nonsense.
English is only ever my fifth language, but you don't see me complain about it...

Anyway, I actually thought that people do post this stuff in the hopes that someone would read it?
Preferably with a comment other than "This, like, totally, so rules"?

You should see some posts of "natives" we get here... you'd never again hesitate.


And, instead of "well, yeah, this doesn't work", why not simply put the version that actually does?


> disappointed seeing that IKilledKEnny stopped teaching

No comment.

:)



There's some weird tags there.
b b and /i /i, which should be b /b and i /i.



If it makes you feel any better, I don't post on about half the "tutorials" we get...
That's reserved to those that make sense.
I couldn't care any less how great this is.
I expect a tutorial to be complete, and usable. Even when you stop reading somewhere in the middle.
My main objective here is getting some help to people that need it.
I'm not here to post "wow"s...
 

Rheias

New Helper (I got over 2000 posts)
Reaction score
232
Thanks for your comments AceHart.

> English is only ever my fifth language, but you don't see me complain about it...

That's a suprise, as far as I can tell you speak great English. I didn't mean to complain that my English is bad rather then letting you know that mistakes weren't caused by laziness of some kind but by merely grammar mistakes.

> And, instead of "well, yeah, this doesn't work", why not simply put the version that actually does?

That's an possibility, but my goal was to give few natives and then use them in the examples to stop confusio. Sure, I'll make an exception.

> There's some weird tags there.
b b and /i /i, which should be b /b and i /i.

I'll review the tutorial again, thanks.

> If it makes you feel any better, I don't post on about half the "tutorials" we get...
That's reserved to those that make sense.

I'm happy to hear that the tutorial meets this condition. :)

> I expect a tutorial to be complete, and usable. Even when you stop reading somewhere in the middle.

Yes, this is how I see tutorials as well.

> My main objective here is getting some help to people that need it.

And you do this very well. ;)

> I'm not here to post "wow"s...

And I appreciate that, I like to get a constructive feedback that can help me improve next time.

I hope to post the updated version of the tutorial within few hours.
 

elmstfreddie

The Finglonger
Reaction score
203
Yes, it should be set worm = CreateUnit(etc)


Uhmm sorry if this is a little late I haven't been watching these forums, but you were saying local unit worm = createunit(etc), I only said set worm = createunit if you wanted to set it later in the trigger... Obviously you set it to create unit when you make the variable :)


> (i didnt know about functions cause ikilledkenny closed jass101)
Well, it's kinda obvious if you have JASSCraft, you just look what it says at the bottom and copy it into your own form.
 

Sooda

Diversity enchants
Reaction score
318
Rheias said:
This tutorial (or rather, mini-tutorial) is for anyone who has a basic knowledge of JASS and is interested in learning a bit more.

You explaned syntax of JASS very well. By reading this tutorial you can get basic knowledge of JASS. It dosn' t teach you new tricks but instead tells the very basics.
Beginners should know only for start what is really called function (from function to endfunction). Then it would be nice to tell them these things can take arguments (explane what exactly are arguments, for example integer or real number, unit, player, boolean can be argument.). Functions even may return value but then in function there must be line what returns something. When using in function what returns value "if/ then" actions there needs to be after additional return value what still returns value even when "if/ then" actions can' t occur due to invalid condition. Technique how to make local loops. Lastly JASS ABC, local variables needs to be declared before any call function though you can set local variable to another function return value.

Can' t give much constructive criticism due to polished and good tutorial. Perhaps add one simple little tiny chapter how to pass arguments to other functions with global variables (These dosn' t need to be Blizzard global variables, I would recommend creating global variables for everyone because it' s simple and easy to use.).
Well done, Rheias.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top