Warcraft 3 documentation
vJASS & Zinc Documentation
For the latest documentation about how it works vJASS and Zinc language layers for Warcraft III, please follow these links:
Jasshelper documentation - Zinc documentation - WC3 Optimizer documentation

Jassdoc introduction No New Posts Jassdoc

Started by
moyack

0 Members and 1 Guest are viewing this topic.

Jassdoc introduction
on: April 12, 2011, 08:34:58 PM

Introduction
Documentation taken from Jassdoc manual and adapted to reforged.

This manual is not a programming tutorial nor an introduction to the JASS language for non-programmers. It is not a JASS FAQ or a JASS primer. For introductory material, individuals unfamiliar with a programming language are directed to the discussion forums and FAQs at JASS vault in this site. Any questions related to JASS should be directed there as well.

This manual is divided into the following sections:
« Last Edit: August 15, 2020, 10:45:26 AM by moyack »



Global Declarations
Reply #1 on: April 12, 2011, 08:34:58 PM

Global Declarations

We define a JASS program or script to be a series of *.ai and *.j files that make up either a runnable map trigger script or an AI script.
  • A map script is responsible for initializing callbacks or triggers that are executed when certain events occur within a game. In addition, the map script generally initializes the map by creating the initial units and setting the initial properties of the map. The files that compose a map script are common.j, Blizzard.j, and war3map.j (loaded in that order).
  • An AI script is responsible for the continuous execution of building, training, and attacking commands by a single computer player within a game. The files that compose an AI script are common.j, common.ai, and a user-defined AI script (e.g., human.ai, elf.ai, etc.).
common.j, Blizzard.j, and common.ai are located in the Scripts/ directory in the CASC, but they can be overridded by placing them within a *.w3m. We call the declarations in these files library functions (and variables) since they are loaded with every map/AI script respectively. See Library Functions for more information.

war3map.j is located in each *.w3m or a *.w3x map file. It is automatically generated by the World Editor each time you save your map (so if you edit it directly, it will be overwritten when you edit your map again in the World Editor). However, you can edit segments of it directly in the World Editor by creating a trigger and using the "Convert to Custom Text" option in the "Edit" menu.

In addition, to quote Brett Wood,
Quote
In the Trigger Editor [of TFT], if you select the root of the tree on the left (the map name at the top), you can enter arbitrary custom script code on the right. This script code is included in the map script right before all of the trigger code. This is a good place to write custom functions, which can then be used by multiple triggers. Theoretically, you could even do all of your scripting here, and not make any 'regular triggers' (although you'd probably still need at least one to call into your script code somewhere).

Note that variables you create with the Variable Editor in the World Editor are global variables. However, when the World Editor actually creates the map script, it will transform the variable names by prefixing udg_ and replacing spaces with underscores (_). For example, if you create a variable called my unit group in the Variable Editor, you would actually refer to it as udg_my_unit_group in the map script.

A JASS script consists of a series of global declarations. Global declarations consist of:
  • type definitions
  • global variables
  • native functions
  • user defined functions
In each file, type declarations and global variables must be declared before all user-defined function declarations. In all cases, you can not refer to declarations made after the reference (i.e., you must declare a type on a line before you extend it; you must declare a global variable on a line before you refer to it in an expression; and you must declare a function on a line before you call it, with the exception that a function may call itself). Each declaration begins on a new line (some span multiple lines).

Type Definitions

JASS allows user-defined types to be declared with the following, where new_type is the user type being declared and parent_type is the previously defined type that this type is a subtype of. See Types for more information.

Code: jass
  1. type new_type extends parent_type

In each file, these must be declared before all functions.

Global Variables

There are two scopes for variables in JASS: global and function. Variables declared in global scope can be referenced from any function; variables declared in a function and function parameters can only be referenced within that function. Global variables are declared in the following manner:

Code: jass
  1. globals
  2.      type name = expression
  3.      type name = expression
  4.      type name = expression
  5.      ...
  6. endglobals

All declarations are enclosed within a globals block, and each is on a separate line. type is the type of the variable. This may either be a basic type or an array of basic types, declared as type array name. See Types for more information. name is the name of the variable and expression is an optional value to initially assign the variable. See Expressions for more information.

A non-array variable declaration may be prefixed with constant. This means the variable contains a value that can not be changed later (e.g., you can not use set on it). Hence, constant variables must be initialized with a value.

For example, here is an integer variable initialized to the value 10:

Code: jass
  1.      integer numberOfStuff = 10

A constant integer variable initialized to the product of two other variables:

Code: jass
  1.      constant integer howManyUnits = numberOfGrunts * numberOfAttacks

A string variable that is not initialized:

Code: jass
  1.      string someMessage

An array of units. Arrays can not be initialized.

Code: jass
  1.      unit array listOfUnits

If you only use JASS without the vJASS implementation, In each file the globals block must be declared before all functions and there can only be one globals block. vJASS now allows to implement globals more freely.

Native Functions

Native functions are functions that are implemented within the Warcraft III engine. They form the API which the game exports to JASS programmers. Unless you have access to Warcraft III's source code, you probably will not be defining a new native function, but you will probably call them. Their prototypes are declared in common.j, common.ai, and Blizzard.j. The prototypes look like the following:

Code: jass
  1. native func_name takes param_list returns return_type

Where func_name is the name of the function, param_list is an ordered, comma separated list of argument types that must be passed to the function when called, and return_type is the type of the return value of the function, if any. If param_list is nothing then the function takes no parameters; if the return_type is nothing then the function does not return a value and hence can not be used as a valid expression.

For example, a native function that takes a string and a unit and has no return value:

Code: jass
  1. native MakeUnitTalk takes string whatToSay, unit targetUnit returns nothing

Native functions may be declared with constant as a prefix. See Functions for more information.

User-Defined Functions

A user-defined function is similar to a native function but has a body consisting of its implementation (e.g., what it does). It is declared in the following manner:

Code: jass
  1. function func_name takes param_list returns return_type
  2.      variable_declaration
  3.      variable_declaration
  4.      ...
  5.      statement
  6.      statement
  7.      statement
  8.      ...
  9. endfunction

The prototype values are the same as with native functions. The function body consists of a series of local variable declarations followed by a series of statements (either of which may be empty). See Functions for more information.

Functions may also be declared with constant as a prefix.
« Last Edit: June 26, 2020, 05:13:20 PM by moyack »



Types
Reply #2 on: April 12, 2011, 08:34:58 PM

Types

JASS has a type system that helps to ensure correctness of assignments and expressions (i.e., that you don't assign strings to integer variables or try to add two units together). There are several native types which are predefined, but users can also declare subtypes of the basic native types. An array of any type can also be declared.

Native Types

  • integer - integer variables can hold the range of integral numbers ranging from -2147483647 to 2147483647.
  • real - real variables can hold rational numbers (i.e., floating-point or fractional numbers). One assumes the values are 32-bit and conform to the IEEE Standard 754 Floating-Point standard (someone want to verify this?).
  • boolean - boolean variables can take on the values true or false. Boolean values are returned by boolean operations and predicates to "if" statements must be boolean types.
  • string - strings variables hold a series of characters. The value of a string variable may be null in which case the variable refers to nothing and it is illegal to use it (except to assign a value to it).
  • handle - a handle variable is basically a "pointer". It refers to some data structure that is internal to Warcraft III which you can not manipulate directly. All user-defined types inherit from handle. For example, a unit is a subtype of handle that points to some unit data-structure in the game. Any handle variable can be assigned the value null, which means it refers to nothing.
  • code - A function may have parameters that are of type code. This means it must take a function reference as an argument. This is similar to a function pointer in C or C++. A function is referenced with the expression function func_name. For example, a function with the prototype:

    function RunFunctionForAllPlayers takes code theFunction returns nothing

    Would be called like this RunFunctionForAllPlayers(function someFunction).

    A code value can also be null, which means it refers to no function (and should not be used in any native function).

User-Defined Types

The handle type can be subtyped, meaning users can define more specific classes of handles. See Global Declarations for more information. All types used in native functions are declared in common.j.

A type new_type which extends another type parent_type is said to be a child of parent_type. For example, widget is a child of handle and unit is a child of widget. The arrangement of children forms a type-tree which is rooted at the base-type, handle.

We define any type to be an ancestor of itself. In addition, a type a is an ancestor of type b if b is the child of some type c, which a is also the ancestor of (i.e., ancestry is transitive). In other words, a is an ancestor of b if there is a path going down from a to b in the type-tree. For example, if c extends a, d extends c, and b extends d, then a is an ancestor of b, and so are c and d. See Figure 1.

 
 
Figure 1. A type tree. Example: handle is an ancestor of player and unit.

We say type b conforms to type a if a is an ancestor of b. If a variable is of type b and b conforms to a, then the variable is a a as well as a b. For example, a unit variable is a widget as well as a handle, since unit conforms to both.

The bottom-line is that a function that has a parameter of type a can take any argument that is a value of type a. For example, given the following function declaration:

Code: jass
  1. function DestroyWidget takes widget toDestroy returns nothing

The argument can be a unit, destructable, item, or widget, since all those types conform to the type widget. Note however that the converse is not true. If the function was declared as:

Code: jass
  1. function DestroyUnit takes unit toDestroy returns nothing

The argument must be of type unit and not widget because a widget is not necessarily a unit.

Arrays

A variable can be declared as an array of any basic type (i.e., non-array type) except for code ( code array is not legal). See Global Declarations for more information.

Array variables are initialized to "empty" values (e.g., 0 for integer arrays, and null for handle arrays) and have a fixed size. Each index in an array holds a value of its declared type and is referenced with the standard bracket notation. For example, my_array[10] refers to the 11th element of my_array.

Although you can store an element in any index of an array (from 0 to the maximum positive integer value), you can only store up to JASS_MAX_ARRAY_SIZE = 32768 (patch 1.29 as far as I remember...) elements total in a given array (defined in common.j). In other words, an array is more like a sparse hashtable with a fixed size of 32768. (Data Taken from the latest common.j in patch 1.32.6)

Functions may not take arrays as arguments, nor may arrays be returned from functions. Array variables can not be reassigned (i.e., it is illegal to call set on an array variable). This means the following is illegal:

Code: jass
  1. ...
  2.      unit array myUnits
  3.      unit array yourUnits
  4. ...
  5.      set myUnits = yourUnits         // illegal
  6.      set myUnits[0] = yourUnits[10]  // legal
« Last Edit: June 26, 2020, 05:24:00 PM by moyack »



Functions
Reply #3 on: April 12, 2011, 08:34:58 PM

Functions

A function is declared in the following manner:

Code: jass
  1. function func_name takes param_list returns return_type
  2.      variable_declaration
  3.      variable_declaration
  4.      ...
  5.      statement
  6.      statement
  7.      statement
  8.      ...
  9. endfunction

See Global Declarations for more information. Remember that you can not call functions you have not yet declared (no forward references), but you can call a function within itself (i.e., recursion is legal).

If a function declaration is prefixed with constant, like the following:

Code: jass
  1. constant function const_func takes integer a returns nothing
  2.      ...
  3. endfunction

then you can not call non-constant functions within the function body. (Nevertheless, note that you can still use the set statement in the body to alter function arguments, so it is not really "constant" in the typical sense; it is more of a hint to the programmer than anything else)

Parameters

As noted in the Globals Section, a function is declared with a comma separated parameter list which parameterizes the types of the arguments it takes. When calling a function, the caller passes in a list of argument expressions which evaluate to values of types conforming to the list of parameters. See Types for more information.

All integer, real, and boolean arguments have pass-by-value semantics. Because string and code values are immutable (can not be modified after creation), arguments with these types can be thought of as having pass by value semantics also. In other words:

Code: jass
  1. function Foo takes integer a, string b returns nothing
  2.      set a = 10
  3.      set b = b + " is a dummy"
  4.      // a == 10 and b == "joe is a dummy"
  5.      // but the original arguments passed in are NOT modified
  6. endfunction
  7.  
  8. ...
  9.      local integer i = 5
  10.      local string  j = "joe"
  11.  
  12.      call Foo(i, j)
  13.      // i is still == 5, and j is still == "joe"

However, all handle arguments (and handle subtypes) have roughly pass-by-reference semantics. In other words, modifying the "internals" of a handle variable, like a unit, passed to a function as an argument will alter the variable both within the called function and the caller. For example:

Code: jass
  1. function Bar takes unit u returns nothing
  2.      call PauseUnit(u, true)
  3.      // the unit u is paused, but u and y refer to the same
  4.      // data structure so y is also paused
  5. endfunction
  6.  
  7. ...
  8.      local unit y = GetTriggeringUnit()
  9.  
  10.      call Bar(y)
  11.      // the unit y is paused

Note: strictly speaking, handle values do not have true pass-by-reference semantics. It is more correct to say that handle values are equivalent to pointers, and using a native function to modify a handle value is like dereferencing the pointer and modifying the object that the variable points to (like in Java). In particular, altering the value of a handle variable in a function does affect the argument in the caller. In other words:

Code: jass
  1. function Goo takes unit u returns nothing
  2.      set u = CreateUnit(player1, 'hC00', 100, 100, 90)
  3.      // u now refers to the newly created unit
  4.      // but y still refers to the triggering unit
  5. endfunction
  6.  
  7. ...
  8.      local unit y = GetTriggeringUnit()
  9.  
  10.      call Goo(y)
  11.      // y still refers to the trigger unit

Local Variables

The first part of a function body consists of local variable declarations. These are variables which are initialized each time we enter the function and can only be referenced within the function. They are declared in the following manner:

Code: jass
  1.      local type name = expression

This is similar to the global variable declaration. The expression is optional. There may be no local variables, in which case the function body only consists of statements (or is empty). Local variable names should not be identical to function parameter names.

Within a function, expressions can reference local variables, the names of function parameters, as well as global variables.

Statements

After the list of local variables is a list of statements which performs the actions the function wants to execute. See Statements for more information.

If the function returns a value, then every execution path in the function must reach a return statement which returns a value of the appropriate type.

Return Value

A function may be declared to return a value (if the return type is not nothing). In this case, calling the function as an expression will evaluate to a value. See Expressions for more information.

Return values have the same by-value/by-reference semantics as arguments (see above).

Entry Point Functions

AI scripts require a user-defined main function, while map trigger scripts require a main function and a config function. The config function is run before the game starts initializing the map. The main function is the entry point for execution when the game begins.

These must have the following prototypes, respectively:

Code: jass
  1. function main takes nothing returns nothing
  2.  
  3. function config takes nothing returns nothing
« Last Edit: August 15, 2020, 11:10:09 AM by moyack »



 

Vivir aprendiendo.co - A place for learning stuff, in Spanish   Chaos Realm - The world of Game modders and wc3 addicts   Diplo, a gaming community   Power of Corruption, an altered melee featuring Naga and Demon. Play it now!!!   WC3JASS.com - The JASS Vault + vJASS and Zinc   Jetcraft - A Starcraft II mod   WormTastic Clan (wTc)   Warcraft RESOURCES Reforged: Modelos, mapas, proyectos y mas...