<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Greenberet</id>
	<title>AlliedModders Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Greenberet"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Greenberet"/>
	<updated>2026-06-06T20:07:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=5020</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=5020"/>
		<updated>2007-08-10T22:09:03Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Two Dimensional Arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&lt;br /&gt;
new z = 1_000_000 // Pawn supports numbers like this. So big values are easier to read.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number.&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
&lt;br /&gt;
//So this is valid:&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
b = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || false)             //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it 6 (binary 0110).&lt;br /&gt;
//This is the &amp;quot;bitwise complement&amp;quot; operator, which performs a !(not) on each bit.&lt;br /&gt;
(~(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Multiple conditions are also possible in pawn:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of an multiple switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 1, 2, 3:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 1 or 2 or 3&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 4, 5, 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 4 or 5 or6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7, 8, 9:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7 or 8 or 9&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
You could use the switch statement also for ranges:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of an range switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 0 .. 50:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 0 &amp;lt;= a &amp;lt;= 50&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 51 .. 100:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 51 &amp;lt;= a &amp;lt;= 100&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 101 .. 200:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 101 &amp;lt;= a &amp;lt;= 200&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated.&lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [2][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = HELLO&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Pawn documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=AMX_Mod_X_1.8.0_Changes&amp;diff=5017</id>
		<title>AMX Mod X 1.8.0 Changes</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=AMX_Mod_X_1.8.0_Changes&amp;diff=5017"/>
		<updated>2007-08-09T08:21:14Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Scripting Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AMX Mod X 1.8 is a large feature release with many changes, both to the development API and user-mode features.&lt;br /&gt;
&lt;br /&gt;
=Changelog=&lt;br /&gt;
==Overall Changes==&lt;br /&gt;
*Added a new module, Ham Sandwich, for hooking virtual CBaseEntity functions in mods.&lt;br /&gt;
*Command flags are now initially dumped to disk and can be edited via &amp;lt;tt&amp;gt;configs/cmdaccess.ini&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Added {{AMBug|48738}}: Romanian translation from X-5173.&lt;br /&gt;
*Added {{AMBug|50741}} and {{AMBug|43830}}: per-map plugins files can now be prefixed based.&lt;br /&gt;
*Added {{amb|17}}: New menu rendering is now more consistent; non-consistent controls are deprecated.&lt;br /&gt;
*Added {{amb|32}}: The server console commands &amp;quot;amxx cvars&amp;quot; and &amp;quot;amxx cmds&amp;quot; can now filter by plugin.&lt;br /&gt;
*Added {{amb|122}}: Log file names now include a four-digit year.&lt;br /&gt;
*Fixed {{amb|18}}: New menus are now properly destroyed if overridden.&lt;br /&gt;
*Fixed {{amb|46}}: &amp;lt;tt&amp;gt;is_user_bot&amp;lt;/tt&amp;gt; had some false positives.&lt;br /&gt;
*Fixed {{amb|69}}: Fixed Metamod trying to reload AMX Mod X against a poorly configured clock.&lt;br /&gt;
*Fixed {{amb|207}}: New menus now display &amp;quot;0&amp;quot; instead of &amp;quot;10.&amp;quot;&lt;br /&gt;
*Fixed {{amb|208}}: New menus did not reset callback results after each call.&lt;br /&gt;
*Fixed {{amb|200}}: Dynamic/fake natives were not re-entrant.&lt;br /&gt;
*Fixed {{amb|244}}: Run-time errors blocked forwards.&lt;br /&gt;
*Fixed {{amb|305}}: Core crashed on mods that removed the standard &amp;lt;tt&amp;gt;mp_timelimit&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
*Fixed many various internal new menu rendering and item selection bugs.&lt;br /&gt;
==Scripting Changes==&lt;br /&gt;
*Added natives for dynamic global arrays.&lt;br /&gt;
*Added a new, magic &amp;lt;tt&amp;gt;any&amp;lt;/tt&amp;gt; tag from [[SourceMod]].&lt;br /&gt;
*Added a &amp;lt;tt&amp;gt;charsmax&amp;lt;/tt&amp;gt; makro for safe sizeof(string)-1 usage.&lt;br /&gt;
*Added &amp;lt;tt&amp;gt;set_pcvar_string&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added &amp;lt;tt&amp;gt;LookupLangKey&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added &amp;lt;tt&amp;gt;SQL_QuoteString&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added &amp;lt;tt&amp;gt;[g|s]et_pdata_cbase[_safe]&amp;lt;/tt&amp;gt;() to the Ham Sandwich module.&lt;br /&gt;
*Added &amp;lt;tt&amp;gt;geoip_code[2|3]_ex&amp;lt;/tt&amp;gt;(), which address a serious issue in the now deprecated &amp;lt;tt&amp;gt;geoip_code[2|3]&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added &amp;lt;tt&amp;gt;lookup_sequence&amp;lt;/tt&amp;gt;(), &amp;lt;tt&amp;gt;set_controller&amp;lt;/tt&amp;gt;(), &amp;lt;tt&amp;gt;set_pev_string&amp;lt;/tt&amp;gt;(), and &amp;lt;tt&amp;gt;pev_serial&amp;lt;/tt&amp;gt;() to Fakemeta.&lt;br /&gt;
*Added &amp;lt;tt&amp;gt;ns_get_user_team&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Added a menu property to change the numbering color.&lt;br /&gt;
*Added {{amb|27}}: &amp;lt;tt&amp;gt;SQL_Rewind&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|37}}: &amp;lt;tt&amp;gt;cs_[g|s]et_user_submodel&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|38}}: &amp;lt;tt&amp;gt;cs_[g|s]et_user_lastactivity&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|39}}: &amp;lt;tt&amp;gt;cs_[g|s]et_hostage_lastuse&amp;lt;/tt&amp;gt;() and &amp;lt;tt&amp;gt;cs_[g|s]et_hostage_nextuser&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|63}}: &amp;lt;tt&amp;gt;floatmin&amp;lt;/tt&amp;gt;(), &amp;lt;tt&amp;gt;floatmax&amp;lt;/tt&amp;gt;(), and &amp;lt;tt&amp;gt;floatclamp()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Added {{amb|76}}: Formatting functions can now use %x or %X for hexadecimal numbers.&lt;br /&gt;
*Added {{amb|92}}: &amp;lt;tt&amp;gt;create_tr2&amp;lt;/tt&amp;gt;() and &amp;lt;tt&amp;gt;free_tr2&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|205}}: &amp;lt;tt&amp;gt;cs_[g|s]et_c4_explode_time&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|216}}: &amp;lt;tt&amp;gt;SQL_MakeStdTuple&amp;lt;/tt&amp;gt;() now has a timeout parameter.&lt;br /&gt;
*Added {{amb|237}}: Fakemeta can now call &amp;quot;ServerPrint.&amp;quot;&lt;br /&gt;
*Added {{amb|242}}: &amp;lt;tt&amp;gt;cs_[g|s]et_user_hostagekills&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|245}}: &amp;lt;tt&amp;gt;precache_sound&amp;lt;/tt&amp;gt; now returns a precache index.&lt;br /&gt;
*Added {{amb|261}}: &amp;lt;tt&amp;gt;has_flag&amp;lt;/tt&amp;gt;() and &amp;lt;tt&amp;gt;has_all_flags&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|291}}: &amp;lt;tt&amp;gt;cs_[g|s]et_c4_defusing&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{amb|673}}: &amp;lt;tt&amp;gt;regex_compile&amp;lt;/tt&amp;gt;() and &amp;lt;tt&amp;gt;regex_match_c&amp;lt;/tt&amp;gt; for pre-compiling expressions.&lt;br /&gt;
*Added {{AMBug|46213}}: &amp;lt;tt&amp;gt;player_menu_info&amp;lt;/tt&amp;gt;() now returns a page number.&lt;br /&gt;
*Added {{AMBug|51064}}: Some parameters to &amp;lt;tt&amp;gt;get_plugin&amp;lt;/tt&amp;gt; are now optional.&lt;br /&gt;
*Added {{AMBug|50610}}: Some parameters to &amp;lt;tt&amp;gt;get_user_weapon&amp;lt;/tt&amp;gt; are now optional.&lt;br /&gt;
*Added {{AMBug|48841}}: &amp;lt;tt&amp;gt;tfc_is_user_feigning&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Added {{AMBug|45664}}: &amp;lt;tt&amp;gt;tfc_is_team_ally&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Fixed {{AMBug|49337}}: &amp;lt;tt&amp;gt;get_pcvar_float&amp;lt;/tt&amp;gt;() malfunctioned on high numbers.&lt;br /&gt;
*Fixed {{amb|78}}: &amp;lt;tt&amp;gt;get_concmdsnum&amp;lt;/tt&amp;gt; could return an incorrect result.&lt;br /&gt;
*Fixed {{amb|85}}: Tag mismatches on &amp;lt;tt&amp;gt;ShowSyncHudMsg&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Fixed {{amb|90}}: &amp;lt;tt&amp;gt;set_native_filter&amp;lt;/tt&amp;gt;() did not work in rare cases.&lt;br /&gt;
*Fixed {{amb|107}}: &amp;lt;tt&amp;gt;socket_open&amp;lt;/tt&amp;gt;() didn't return an error by reference.&lt;br /&gt;
*Fixed {{amb|110}}: &amp;lt;tt&amp;gt;socket_change&amp;lt;/tt&amp;gt;() could return 1 on certain failures.&lt;br /&gt;
*Fixed {{amb|116}}: &amp;lt;tt&amp;gt;DispatchKeyValue&amp;lt;/tt&amp;gt;() did not work on worldspawn (entity 0).&lt;br /&gt;
*Fixed {{amb|149}}: &amp;lt;tt&amp;gt;register_event&amp;lt;/tt&amp;gt; with the &amp;quot;e&amp;quot; flag could catch incorrect players.&lt;br /&gt;
*Fixed {{amb|230}}: &amp;lt;tt&amp;gt;radius_damage&amp;lt;/tt&amp;gt;() didn't kill players on all mods.&lt;br /&gt;
*Fixed {{amb|257}}: &amp;lt;tt&amp;gt;get_user_origin&amp;lt;/tt&amp;gt;() mode 4 had false positives.&lt;br /&gt;
*Fixed {{amb|343}}: &amp;lt;tt&amp;gt;TFC_ClearModel&amp;lt;/tt&amp;gt;() did not function as documented.&lt;br /&gt;
*Fixed {{amb|421}}: &amp;lt;tt&amp;gt;get_user_weapons&amp;lt;/tt&amp;gt;() could omit a weapon on Day of Defeat.&lt;br /&gt;
*Fixed {{amb|437}}: &amp;lt;tt&amp;gt;dod_set_user_kills&amp;lt;/tt&amp;gt;() and &amp;lt;tt&amp;gt;dod_set_user_score&amp;lt;/tt&amp;gt;() could mess up the scoreboard.&lt;br /&gt;
*Fixed {{amb|519}}: &amp;lt;tt&amp;gt;geoip_code[2|3]&amp;lt;/tt&amp;gt;() buffer overflowed on error.&lt;br /&gt;
*Fixed {{amb|736}}: &amp;lt;tt&amp;gt;find_entity&amp;lt;/tt&amp;gt;() was defined twice.&lt;br /&gt;
*Fixed a memory leak in &amp;lt;tt&amp;gt;SortCustom1D&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Fixed a crash bug in &amp;lt;tt&amp;gt;fwrite_blocks&amp;lt;/tt&amp;gt;().&lt;br /&gt;
&lt;br /&gt;
==Plugin Changes==&lt;br /&gt;
*There is no longer a hardcoded limit to the number of admins.&lt;br /&gt;
*There is no longer a hardcoded limit to the map list.&lt;br /&gt;
*There is no longer a hardcoded limit to the number of &amp;quot;imessages.&amp;quot;&lt;br /&gt;
*Added {{amb|34}}: There are now plugin command/cvar menus.&lt;br /&gt;
*Added {{AMBug|45044}}: amx_banmenu now prints the ban time length.&lt;br /&gt;
*Added {{AMBug|43757}}: amx_addadmin now writes a comment with the player's name.&lt;br /&gt;
*Added {{AMBug|29353}}: amx_plugins now prints paginated output.&lt;br /&gt;
*Added {{AMBug|50742}}: admin.sma now supports prefix based per-map configs.&lt;br /&gt;
*Added {{amb|28}}: statscfg.sma can now use translations.&lt;br /&gt;
*Added {{amb|30}}: &amp;lt;tt&amp;gt;csstats_rankbots&amp;lt;/tt&amp;gt; prevents bots from showing on &amp;lt;tt&amp;gt;/top15&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Added {{amb|31}}: plmenu.sma ban and slap options are now configurable.&lt;br /&gt;
*Added {{amb|42}}: Added new values for &amp;lt;tt&amp;gt;amx_show_activity&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Added {{amb|51}}: amx_vote can now take more than two options.&lt;br /&gt;
*Added {{amb|64}}: amx_voteban autodetects whether it should IP ban.&lt;br /&gt;
*Added {{amb|307}}: amx_addban now caches the last ten connections.&lt;br /&gt;
*Added {{amb|311}}: mapcycle file now ignores .bsp extensions.&lt;br /&gt;
*Added {{amb|340}}: amx_ban/amx_banip now display a reason in the activity.&lt;br /&gt;
*Added {{amb|427}}: Additional weapons to &amp;lt;tt&amp;gt;dod_[g|s]et_user_ammo&amp;lt;/tt&amp;gt;().&lt;br /&gt;
*Fixed {{amb|29}}: pausecfg.sma did not translate two phrases.&lt;br /&gt;
*Fixed {{amb|91}}: miscstats.sma truncated some language translations.&lt;br /&gt;
*Fixed {{amb|94}}: amx_psay sometimes sent truncated messages.&lt;br /&gt;
*Fixed {{amb|109}}: mapsmenu.sma now checks &amp;lt;tt&amp;gt;mapcyclefile&amp;lt;/tt&amp;gt; before reverting to &amp;lt;tt&amp;gt;mapcycle.txt&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Fixed {{amb|118}}: amx_help would not list &amp;lt;tt&amp;gt;ADMIN_ADMIN&amp;lt;/tt&amp;gt; commands.&lt;br /&gt;
*Fixed {{amb|130}}: Various menus did not take &amp;lt;tt&amp;gt;ADMIN_ALL&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;ADMIN_ADMIN&amp;lt;/tt&amp;gt; into account.&lt;br /&gt;
*Fixed {{amb|183}}: plmenu.sma did not work on Natural Selection.&lt;br /&gt;
*Fixed {{amb|196}}: amx_modules did not handle invalid modules properly.&lt;br /&gt;
*Fixed {{amb|222}}: cl_rebuy could exploit CS weapon restrictions.  This also makes CZ bots obey restrictions.&lt;br /&gt;
*Fixed {{amb|228}}: amxmod_compat could cause &amp;lt;tt&amp;gt;set_user_hitzones&amp;lt;/tt&amp;gt;() to break.&lt;br /&gt;
*Fixed {{amb|350}}: &amp;lt;tt&amp;gt;traceline_set_float&amp;lt;/tt&amp;gt; from the AMX Mod Compat layer was broken.&lt;br /&gt;
*Fixed {{amb|467}}: &amp;lt;tt&amp;gt;conmotd.txt&amp;lt;/tt&amp;gt; is now removed.&lt;br /&gt;
*Fixed {{amb|633}}: Immune admins can now target themselves.&lt;br /&gt;
*Fixed a potential exploit in adminslots.sma.&lt;br /&gt;
*SQL cvars are now protected.&lt;br /&gt;
*Added {{amb|743}}: plmenu for cstrike has an option to move to spectator.&lt;br /&gt;
&lt;br /&gt;
==Module Changes==&lt;br /&gt;
*Fixed {{amb|108}}: IP-based stats no longer include a port when saving.&lt;br /&gt;
*Fixed {{amb|503}}: CSX did not set a META_RESULT when paused.&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=AMX_Mod_X_1.75_Scripting_Changes&amp;diff=3074</id>
		<title>AMX Mod X 1.75 Scripting Changes</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=AMX_Mod_X_1.75_Scripting_Changes&amp;diff=3074"/>
		<updated>2006-06-10T19:14:02Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* New Engine/GameDLL Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The AMX Mod X 1.75 release made important changes.  While backwards compatibility was kept, intended functionality shifted in esoteric areas that will affect some plugins.  Reading this article is highly recommended.&lt;br /&gt;
&lt;br /&gt;
=Module Requirement System=&lt;br /&gt;
As part of the new Automatic Module Loading, the old &amp;lt;tt&amp;gt;#pragma library&amp;lt;/tt&amp;gt; has been deprecated.  You must now use:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma reqlib &amp;lt;library&amp;gt;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This means &amp;quot;require library&amp;quot;.  Plugins still compiled with &amp;lt;tt&amp;gt;#pragma library&amp;lt;/tt&amp;gt; will still fail on load if the given module is not found.  However, core will try to load each module given the rules below under &amp;quot;Automatic Module Loading&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Auto Plugin Files=&lt;br /&gt;
With the introduction of callfunc and register_native, many people now distribute plugins in large sets.  To make this easier on users, you can now distribute an &amp;quot;extended plugin file.&amp;quot;  For example, say you have five plugins in a set.  Normally, you would have to ask the user to write each name into plugins.ini, like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 file1.amxx   ;file1&lt;br /&gt;
 file2.amxx   ;file2&lt;br /&gt;
 file3.amxx   ;file3&lt;br /&gt;
 file4.amxx   ;file4&lt;br /&gt;
 file5.amxx   ;file5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With AMX Mod X 1.75, any file in the configs folder which follows a certain name pattern will be auto-loaded as an additional plugins.ini file.  The pattern is: plugins-*.ini.  &lt;br /&gt;
&lt;br /&gt;
For example, you could distribute &amp;lt;tt&amp;gt;plugins-carmod.ini&amp;lt;/tt&amp;gt; as:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;put a semi-colon to disable a plugin&lt;br /&gt;
cars_honda.amxx  &lt;br /&gt;
cars_toyota.amxx&lt;br /&gt;
cars_ford.amxx&lt;br /&gt;
cars_bmw.amxx&lt;br /&gt;
cars_gaben.amxx&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way, you can easily distribute an extractable install, rather than giving the user overcomplicated instructions.  Furthermore, the file is easily disabled by simply modifying the name (for example, &amp;quot;disabled-carmod.ini&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Automatic Module Loading=&lt;br /&gt;
==Overview==&lt;br /&gt;
As of AMX Mod X 1.75, there is a new, powerful automatic module loading system.  That means that &amp;lt;tt&amp;gt;modules.ini&amp;lt;/tt&amp;gt; is largely deprecated for general use.  Instead, modules are loaded as plugins need them.  This is done dynamically by core before plugins are even loaded, without the need to patch &amp;lt;tt&amp;gt;modules.ini&amp;lt;/tt&amp;gt; and then change the map.&lt;br /&gt;
&lt;br /&gt;
Modules can now define &amp;quot;Libraries&amp;quot; and &amp;quot;Library Classes&amp;quot;.  A library is a specific identifier that should match the filename of the module.  For example, Engine's defined library is &amp;quot;engine&amp;quot;.  FakeMeta's library is &amp;quot;fakemeta&amp;quot;, and so on.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;library class&amp;quot; defines membership to a set of modules.  For example, CSX has the library name &amp;quot;csx&amp;quot;, but it is part of the library class &amp;quot;xstats&amp;quot;.  Library classes are also used for DBI and SQLX.  This is very useful for being able to require one module type of any implementation.&lt;br /&gt;
&lt;br /&gt;
==New API==&lt;br /&gt;
===Compiler Pragmas===&lt;br /&gt;
This is expanded with a number of new &amp;lt;tt&amp;gt;#pragma&amp;lt;/tt&amp;gt; directives:&lt;br /&gt;
*&amp;lt;tt&amp;gt;#pragma reqlib &amp;amp;lt;library&amp;gt;&amp;lt;/tt&amp;gt; - Requires that a given library must be loaded.&lt;br /&gt;
*&amp;lt;tt&amp;gt;#pragma reqclass &amp;amp;lt;libclass&amp;gt;&amp;lt;/tt&amp;gt; - Requires that a given library class must be loaded.&lt;br /&gt;
*&amp;lt;tt&amp;gt;#pragma loadlib &amp;amp;lt;library&amp;gt;&amp;lt;/tt&amp;gt; - Automatically attempts to load a given library (see more info below).&lt;br /&gt;
*&amp;lt;tt&amp;gt;#pragma expectlib &amp;amp;lt;library1&amp;gt; &amp;amp;lt;library2&amp;gt;&amp;lt;/tt&amp;gt; - If the first library is not loaded, the second one will be attempted to load (not very useful).&lt;br /&gt;
*&amp;lt;tt&amp;gt;#pragma expectclass &amp;amp;lt;class&amp;gt; &amp;amp;lt;library&amp;gt;&amp;lt;/tt&amp;gt; - If the expected class is not found, the given library will be attempted to load.  This is useful for defining a default module to be loaded with a given class of modules.&lt;br /&gt;
*&amp;lt;tt&amp;gt;#pragma defclasslib &amp;amp;lt;class&amp;gt; &amp;amp;lt;library&amp;gt;&amp;lt;/tt&amp;gt; - Same as &amp;lt;tt&amp;gt;expectclass&amp;lt;/tt&amp;gt;, however, &amp;lt;tt&amp;gt;defclasslib&amp;lt;/tt&amp;gt; waits until all expectations are resolved.  This lets plugins override defaults by adding their own expectations.&lt;br /&gt;
&lt;br /&gt;
===Module Filtering===&lt;br /&gt;
The module_filter prototype now includes a second parameter, which tells you whether the requirement is a class or library.&lt;br /&gt;
&lt;br /&gt;
Furthermore, module_exists has been deprecated for LibraryExists().&lt;br /&gt;
&lt;br /&gt;
==How it Works==&lt;br /&gt;
The precise order of events is as follows:&lt;br /&gt;
*When the first entity is spawned, AMX Mod X loads all unloaded modules in &amp;lt;tt&amp;gt;modules.ini&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*After &amp;lt;tt&amp;gt;modules.ini&amp;lt;/tt&amp;gt; is parsed, &amp;lt;tt&amp;gt;plugins.ini&amp;lt;/tt&amp;gt; is read.  Each file is mapped into a cache.&lt;br /&gt;
*The cache is previewed.&lt;br /&gt;
**First, the &amp;quot;library&amp;quot; table is read.  This table is read for backwards compatibility with AMX Mod X 1.71 and prior.  Each entry is read as a module file shortname, and the module is loaded if it exists.  &lt;br /&gt;
**Next, the &amp;quot;pubtags&amp;quot; table is read.  Each entry is decoded to one of the special #pragma commands.&lt;br /&gt;
***All loadlib commands are executed, and the modules loaded.&lt;br /&gt;
***All expect commands are executed.&lt;br /&gt;
***All defclasslib commands are executed.&lt;br /&gt;
*AMX Mod X then waits until ServerActivate is called.&lt;br /&gt;
*All plugins are loaded.  If the plugin is in the cache, the cache is read instead.  For each plugin...&lt;br /&gt;
**The library table is read.  For each library that is both nonexistant and unhandled by a module filter, the plugin fails to load.&lt;br /&gt;
**The pubtags table is read.  For each reqlib and reqclass entry that are both nonexistant and unhandled by a module filter, the plugin fails to load.&lt;br /&gt;
*The plugin cache is invalidated and the server is considered &amp;quot;loaded&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=SQLX=&lt;br /&gt;
==Introduction==&lt;br /&gt;
SQLX is a new Database API that supercedes DBI.  Its main feature is that you can load two SQLX modules at once, whereas you cannot with DBI.  It also supports threaded queries, which let you process data without interrupting gameplay from a bad network connection.&lt;br /&gt;
&lt;br /&gt;
These additions come at a hefty price.  The SQLX API is significantly more complex than DBI.  Although some might find it easier to use due to its simpler error checking and iteration, it requires more manual memory management and has less simple abstraction.  Furthermore, taking advantage of the new &amp;lt;tt&amp;gt;SQL_ThreadQuery&amp;lt;/tt&amp;gt; native will require nothing short of a rewrite for most plugins, as it is ''asynchronous'' instead of ''synchronous''.  Because of this, the new SQLX modules also implement the old DBI functionality, for both backwards compatibility and for plugin developers familiar with the old API.  All three APIs - SQL-threaded, SQL-non-threaded, and DBI, are still fully supported.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Since SQLX is an expansive API, showing a single plugin of its usage would be difficult.  It is highly recommended that users interested in the new API look at the [http://cvs.tcwonline.org/viewvc.cgi/amxmodx/plugins/testsuite/sqlxtest.sma?view=log SQLxTest] plugin, which compares two different DBI methods and both SQL methods of querying a database.  It is highly useful for both regression testing and for getting an idea of how the API works.&lt;br /&gt;
&lt;br /&gt;
The most important concept of SQLX is &amp;quot;Handles,&amp;quot; which are a precursor to a system planned for SourceMod.  Handles are datatypes that store internal information that you should not modify.  Whenever you create a handle, you must also free it, with &amp;lt;tt&amp;gt;SQL_FreeHandle&amp;lt;/tt&amp;gt;().&lt;br /&gt;
&lt;br /&gt;
==Native Overview==&lt;br /&gt;
The basic natives of SQLX are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_MakeDbTuple&amp;lt;/tt&amp;gt; (or simple stock version, &amp;lt;tt&amp;gt;SQL_MakeStdTuple&amp;lt;/tt&amp;gt;) - This creates a variable that holds information about a database.  It does not connect to the database.  This is so you don't have to keep retrieving cvar info on every connection.  You do not have to free these handles, although it is a good idea if you create them dynamically.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Connect&amp;lt;/tt&amp;gt; - Connects to a database and returns a new Handle, or &amp;lt;tt&amp;gt;Empty_Handle&amp;lt;/tt&amp;gt; on failure.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_PrepareQuery&amp;lt;/tt&amp;gt; - Prepares a query for execution, and returns a new Handle to the query.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_Execute&amp;lt;/tt&amp;gt; - Executes a prepared query, and returns 0 on failure (1 on success).&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_MoreResults&amp;lt;/tt&amp;gt; - Returns 1 if there are more results in the query result queue, 0 if none.&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_ReadResult&amp;lt;/tt&amp;gt; - Reads the current row result by the column's numerical index, similar to dbi_field/dbi_result.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_NextRow&amp;lt;/tt&amp;gt; - Advances to the next result row.  '''Compatibility Warning''': This does not need to be called first! Unlike &amp;lt;tt&amp;gt;dbi_nextrow&amp;lt;/tt&amp;gt;, the query is automatically at the first row.  If you call &amp;lt;tt&amp;gt;SQL_NextRow&amp;lt;/tt&amp;gt; before &amp;lt;tt&amp;gt;SQL_ReadResult&amp;lt;/tt&amp;gt;, your are actually skipping a row.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_FreeHandle&amp;lt;/tt&amp;gt; - Frees a Handle.  You must do this or else memory will leak.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SQL_ThreadQuery&amp;lt;/tt&amp;gt; - Places a query and connection info into a threaded queue.  In another thread, the connection is established, the query is executed, and the connection is dropped.  The query results are then posted back into the main thread and given to the plugin on the next server-frame.  &lt;br /&gt;
**Note that while powerful, the mechanism is very simplistic.  Similar to &amp;lt;tt&amp;gt;set_task&amp;lt;/tt&amp;gt;, you must differentiate multiple queries having the same callback by packing binary data into an array.  Furthermore, you can only make one query at a time, since the queue is &amp;quot;push one, resolve one, pop one.&amp;quot;  If you plan on making five queries in a row in order to get aggregate information about a player, you must make each of these five queries in separate stages, and you must also take into account asynchronous factors such as the player dropping during the middle of a query.  (One way to do this is to pack the player's authid and client index into the callback data and verify it when the query finishes.)&lt;br /&gt;
&lt;br /&gt;
=New Natives / Native Changes=&lt;br /&gt;
==Register Message==&lt;br /&gt;
The &amp;lt;tt&amp;gt;register_message&amp;lt;/tt&amp;gt; set of natives, including &amp;lt;tt&amp;gt;get/set_msg_block&amp;lt;/tt&amp;gt;, has been moved to Core.  This is to facilitate users who prefer to use FakeMeta, and like the simplicity and speed of using Engine's message interception functions.  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
This change is backwards compatible.&lt;br /&gt;
&lt;br /&gt;
==Argument Formatting==&lt;br /&gt;
The &amp;lt;tt&amp;gt;format_args&amp;lt;/tt&amp;gt; function is now replaced with a much faster, more compatible &amp;lt;tt&amp;gt;vformat&amp;lt;/tt&amp;gt; function.  Its usage is slightly different (read the include file, &amp;lt;tt&amp;gt;string.inc&amp;lt;/tt&amp;gt;), but it accepts %L, whereas format_args does not.  A quick example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;debugprint(const fmt[], ...)&lt;br /&gt;
{&lt;br /&gt;
   static temp[2048]&lt;br /&gt;
   vformat(temp, sizeof(temp)-1, fmt, 2)&lt;br /&gt;
   log_message(&amp;quot;[DEBUG] %s&amp;quot;, temp)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Other Core Natives==&lt;br /&gt;
*&amp;lt;tt&amp;gt;register_plugin&amp;lt;/tt&amp;gt; - Now returns a plugin id.&lt;br /&gt;
*&amp;lt;tt&amp;gt;get_amxx_verstring&amp;lt;/tt&amp;gt; - Returns the AMX Mod X version string.&lt;br /&gt;
*&amp;lt;tt&amp;gt;get_weaponid&amp;lt;/tt&amp;gt; - Gets a weapon id from a weapon name.&lt;br /&gt;
&lt;br /&gt;
==FakeMeta==&lt;br /&gt;
===New Natives===&lt;br /&gt;
*&amp;lt;tt&amp;gt;get_orig_retval&amp;lt;/tt&amp;gt; - Gets the original return value of an engine or game DLL function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;copy_infokey_buffer&amp;lt;/tt&amp;gt; - Copies the given infobuffer pointer into output buffer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;get/set_cd&amp;lt;/tt&amp;gt; - Gets or sets members of a clientdata data structure (used with UpdateClientData).&lt;br /&gt;
*&amp;lt;tt&amp;gt;get/set_es&amp;lt;/tt&amp;gt; - Gets or sets members of an entity_state data structure (used with AddToFullPack).&lt;br /&gt;
*&amp;lt;tt&amp;gt;get/set_uc&amp;lt;/tt&amp;gt; - Gets or sets members of a usecmd data structure (used with CmdStart).&lt;br /&gt;
&lt;br /&gt;
===New Engine/GameDLL Functions===&lt;br /&gt;
The &amp;lt;tt&amp;gt;register_forward&amp;lt;/tt&amp;gt; native now allows for hooking a number of new functions from the engine or game DLL including:&lt;br /&gt;
*&amp;lt;tt&amp;gt;UpdateClientData&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddToFullPack&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;CmdStart&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;CmdEnd&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;CreateInstBaselines&amp;lt;/tt&amp;gt; - Game DLL function&lt;br /&gt;
*&amp;lt;tt&amp;gt;CreateInstBaseline&amp;lt;/tt&amp;gt; - Engine function&lt;br /&gt;
*&amp;lt;tt&amp;gt;CreateBaseline&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;GetInfoKeyBuffer&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;AlertMessage&amp;lt;/tt&amp;gt; - This now can be called via &amp;lt;tt&amp;gt;engfunc&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;ClientPrintf&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These functions can also be called via &amp;lt;tt&amp;gt;engfunc&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;dllfunc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Breaking Changes===&lt;br /&gt;
Using &amp;lt;tt&amp;gt;engfunc&amp;lt;/tt&amp;gt; in order to call &amp;lt;tt&amp;gt;EngFunc_InfoKeyValue&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;EngFunc_SetKeyValue&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;EngFunc_SetClientKeyValue&amp;lt;/tt&amp;gt; now requires passing an infobuffer pointer. An infobuffer pointer can be obtained by calling &amp;lt;tt&amp;gt;EngFunc_GetInfoKeyBuffer&amp;lt;/tt&amp;gt;. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;some_function(id, name[])&lt;br /&gt;
{&lt;br /&gt;
   new infokey = engfunc(EngFunc_GetInfoKeyBuffer, id)&lt;br /&gt;
   engfunc(EngFunc_SetClientKeyValue, id, infokey, &amp;quot;model&amp;quot;, name)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you hook ClientUserInfoChanged via Fakemeta, an infobuffer pointer is now also forwarded to your function in addition to the client id.&lt;br /&gt;
&lt;br /&gt;
==Cstrike==&lt;br /&gt;
*&amp;lt;tt&amp;gt;cs_get_user_mapzones&amp;lt;/tt&amp;gt; - Returns bitwise flags of where on the map a player is located such as buy zone, bomb site, hostage rescue zone, VIP safety zone, and escape zone.&lt;br /&gt;
*&amp;lt;tt&amp;gt;cs_set_user_vip&amp;lt;/tt&amp;gt; - Now takes two additional (but optional) parameters for determining whether or not the player model and scoreboard get updated.&lt;br /&gt;
&lt;br /&gt;
==New Stocks==&lt;br /&gt;
===Engine===&lt;br /&gt;
*&amp;lt;tt&amp;gt;IsInWorld&amp;lt;/tt&amp;gt; - Checks if an entity is within the bounds of the world (from HLSDK).&lt;br /&gt;
&lt;br /&gt;
===FakeMeta===&lt;br /&gt;
*&amp;lt;tt&amp;gt;DF_UpdateClientData&amp;lt;/tt&amp;gt; - Calls UpdateClientData game DLL function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;DF_AddToFullPack&amp;lt;/tt&amp;gt; - Calls AddToFullPack game DLL function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;DF_CmdStart&amp;lt;/tt&amp;gt; - Calls CmdStart game DLL function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;DF_CmdEnd&amp;lt;/tt&amp;gt; - Calls CmdEnd game DLL function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;DF_CreateBaseline&amp;lt;/tt&amp;gt; - Calls CreateBaseline game DLL function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;DF_CreateInstBaselines&amp;lt;/tt&amp;gt; - Calls CreateInstancedBaselines game DLL function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;EF_CreateInstBaseline&amp;lt;/tt&amp;gt; - Calls CreateInstancedBaseline engine function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;EF_GetInfoKeyBuffer&amp;lt;/tt&amp;gt; - Calls GetInfoKeyBuffer engine function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;EF_ClientPrintf&amp;lt;/tt&amp;gt; - Calls ClientPrintf engine function.&lt;br /&gt;
&lt;br /&gt;
==New Constants==&lt;br /&gt;
Various sound constants (&amp;lt;tt&amp;gt;SND_SPAWNING&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SND_STOP&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SND_CHANGE_VOL&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;SND_CHANGE_PITCH&amp;lt;/tt&amp;gt;) from the HL SDK as well as a constant for pi were added to &amp;lt;tt&amp;gt;amxconst.inc&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;TE_*&amp;lt;/tt&amp;gt; (temp entity) message constants have also been added which will automatically be included with &amp;lt;tt&amp;gt;#include &amp;lt;amxmodx&amp;gt;&amp;lt;/tt&amp;gt;. And finally, a new &amp;lt;tt&amp;gt;hlsdk_const.inc&amp;lt;/tt&amp;gt; file has been added that contains many more constants from the SDK. This is automatically included with &amp;lt;tt&amp;gt;#include &amp;lt;engine&amp;gt;&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;#include &amp;lt;fakemeta&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Module API=&lt;br /&gt;
The AMX Mod X module API received a small overhaul for 1.75.&lt;br /&gt;
&lt;br /&gt;
==Versioning/Interface Additions==&lt;br /&gt;
The internal module interface version is 4.  However, modules from M/SDK 3 will still load.  &lt;br /&gt;
&lt;br /&gt;
M/SDK Version 4 modules have two new members of public information: the library string, and the library class string.  These contain comma delimited names of whatever libraries or library classes the module would like to be registered.&lt;br /&gt;
&lt;br /&gt;
For backwards compatibility, M/SDK Version 4 modules have an automatically empty library class string, and a library string equal to the logtag string.&lt;br /&gt;
&lt;br /&gt;
==New Callbacks==&lt;br /&gt;
Modules can now be informed of when plugins are about to be unloaded, and when plugins have been fully unloaded.  This means that modules don't have to hook ServerActivate and ServerActivate_Post (implementation dependent), don't need to be loaded by Metamod, and don't need to detach simply to release resources.&lt;br /&gt;
&lt;br /&gt;
==New Functions==&lt;br /&gt;
*&amp;lt;tt&amp;gt;MF_GetLocalInfo&amp;lt;/tt&amp;gt; - Intended for modules using LOCALINFO, which required a Metamod attachment.  This is equal to AMX Mod X's core function &amp;lt;tt&amp;gt;get_localinfo&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;MF_OverrideNatives&amp;lt;/tt&amp;gt; - Given a native list, this specifies that any other module already providing these natives will no longer provide them.  This was added to force backwards compatibility between SQLITE and MySQLX.  Usage is not recommended.&lt;br /&gt;
*&amp;lt;tt&amp;gt;MF_FindLibrary&amp;lt;/tt&amp;gt; - Essentially the same function as LibraryExists() for plugins.&lt;br /&gt;
*&amp;lt;tt&amp;gt;MF_AddLibraries&amp;lt;/tt&amp;gt; - Adds a comma delimited list of libraries or library classes.  You must specify a &amp;quot;parent&amp;quot; pointer that identifies the module.  This is easily accomplished by taking the address of any static variable.&lt;br /&gt;
*&amp;lt;tt&amp;gt;MF_RemoveLibraries&amp;lt;/tt&amp;gt; - Removes all library entries with the given parent pointer.  This is useful if your module adds custom entries not in its defined list.  &lt;br /&gt;
&lt;br /&gt;
==MSVC8 Compatibility==&lt;br /&gt;
M/SDK Version 4 now contains preprocessor definitions for compatibility with Microsoft's Visual Studio 2005/8.0 (provided by [[User:Damaged Soul|Damaged Soul]]).  These macros can be turned off in the &amp;lt;tt&amp;gt;moduleconfig.h&amp;lt;/tt&amp;gt; file by uncommenting the definition of &amp;lt;tt&amp;gt;NO_MSVC8_AUTO_COMPAT&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Minor Changes=&lt;br /&gt;
==Compiler Defines==&lt;br /&gt;
Since &amp;lt;tt&amp;gt;__DATE__&amp;lt;/tt&amp;gt; was fixed in 1.75, the macro &amp;lt;tt&amp;gt;__TIME__&amp;lt;/tt&amp;gt; was also added.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Full Changelog=&lt;br /&gt;
This changelog is tentative.  Developers will be editing it as things are changed.&lt;br /&gt;
&lt;br /&gt;
* Core Changes&lt;br /&gt;
** Modules are now automatically loaded by detecting plugin usage.&lt;br /&gt;
*** modules.ini is now primarily deprecated, except for SQL and unsupported libraries.&lt;br /&gt;
** Rewrote SQLX modules (again).  You can now load multiple SQL modules and toggle them per-plugin.&lt;br /&gt;
*** Added new SQL API called SQLX.  DBI was kept backwards-compatible.&lt;br /&gt;
*** Added new function to thread SQL queries (which prevents lag from a bad connection).&lt;br /&gt;
** Fixed some very small memory leaks.&lt;br /&gt;
** Fixed binary logging building wrong on Linux.&lt;br /&gt;
** Fixed some debugging crashes.&lt;br /&gt;
** Fixed serious bug when creating plugin_pause/plugin_unpause forwards.&lt;br /&gt;
** Fixed serious crash bug involving set_hudmessage and plugins using high hudchannels.&lt;br /&gt;
** Added natives:&lt;br /&gt;
*** fputs()&lt;br /&gt;
*** get_weaponid()&lt;br /&gt;
*** rename_file()&lt;br /&gt;
*** vformat()&lt;br /&gt;
** Any file starting with &amp;quot;plugins-&amp;quot; and ending in &amp;quot;.ini&amp;quot; will now be treated as an extended plugins file.  This is useful for distributing sets of plugins separately, and easily disabling them with a name change.&lt;br /&gt;
&lt;br /&gt;
* Fakemeta Changes&lt;br /&gt;
** Added new hookable/callable functions:&lt;br /&gt;
*** AddToFullPack&lt;br /&gt;
*** AlertMessage&lt;br /&gt;
*** ClientPrintf&lt;br /&gt;
*** ClientUserInfoChanged&lt;br /&gt;
*** CmdEnd&lt;br /&gt;
*** CmdStart&lt;br /&gt;
*** CreateBaseline&lt;br /&gt;
*** CreateInstancedBaseline&lt;br /&gt;
*** GetInfoKeyBuffer&lt;br /&gt;
*** InfoKeyValue&lt;br /&gt;
*** UpdateClientData&lt;br /&gt;
*** SetClientKeyValue&lt;br /&gt;
*** SetKeyValue&lt;br /&gt;
** Added new natives:&lt;br /&gt;
*** copy_infokey_buffer&lt;br /&gt;
*** get_orig_retval&lt;br /&gt;
** Fixed various trace bugs in FakeMeta with certain natives.&lt;br /&gt;
** Fixed some unhooking on server-deactivate problems in FakeMeta.&lt;br /&gt;
&lt;br /&gt;
* Scripting Changes:&lt;br /&gt;
** Added __DATE__ and __TIME__ auto-macros to the compiler.&lt;br /&gt;
** Added many HLSDK constants and improved include organization.&lt;br /&gt;
** Added new compiler #pragma directives for using the module autoloading system.&lt;br /&gt;
** Added cs_get_user_mapzones (thanks VEN!).&lt;br /&gt;
** Added IsInWorld() stock (thanks Twilight Suzuka!).&lt;br /&gt;
** Added nvault_remove().&lt;br /&gt;
** Moved various natives from Engine and into Core:&lt;br /&gt;
*** register_message&lt;br /&gt;
*** get_msg_args&lt;br /&gt;
*** get/set_msg_arg_type&lt;br /&gt;
*** get/set_msg_arg_int&lt;br /&gt;
*** get/set_msg_arg_float&lt;br /&gt;
*** get/set_msg_arg_string&lt;br /&gt;
*** get_msg_origin&lt;br /&gt;
*** get/set_msg_block&lt;br /&gt;
*** velocity_by_aim&lt;br /&gt;
*** vector_to_angle&lt;br /&gt;
*** angle_vector&lt;br /&gt;
*** vector_length&lt;br /&gt;
*** vector_distance&lt;br /&gt;
*** precache_generic&lt;br /&gt;
** Dynamic natives that are paused now also pause parent plugins (with an error).&lt;br /&gt;
** register_plugin() now returns the plugin ID.&lt;br /&gt;
** Fixed a corruption bug in strip_user_weapons().&lt;br /&gt;
** Fixed a bug in set_view() (thanks jtp10181!).&lt;br /&gt;
** Fixed is_in_viewcone() always returning 0.&lt;br /&gt;
** Fixed is_visible causing a crash, improved accuracy.&lt;br /&gt;
** Fixed a crash bug in get_tr2() (thanks Orangutanz!).&lt;br /&gt;
** Fixed cs_get_user_buyzone() returning existence in other areas.&lt;br /&gt;
** Fixed a rare floatround() bug where values ending strictly in .5 were IEEE rounded.&lt;br /&gt;
** Fixed a bug where removing the current parent task could damage the task queue.&lt;br /&gt;
** Fixed a bug in get_entity_visibility (thanks VEN!).&lt;br /&gt;
** Removed non-existant take_damage() entry.&lt;br /&gt;
** Expanded XS Stock Library with addition of xs_vec_make2d.&lt;br /&gt;
** Expanded usage of cs_set_user_vip().&lt;br /&gt;
** Improved get_brush_entity_origin() and ViewContents (thanks Orangutanz!).&lt;br /&gt;
&lt;br /&gt;
* Plugin Changes:&lt;br /&gt;
** Added amx_showrcon command to show rcon results in admincmd.sma.&lt;br /&gt;
** Added weapon restriction compatibility for bots in CS (KWo).&lt;br /&gt;
** Added admin identifier (asterisk which is red if colors are available) to all menus with a user list.&lt;br /&gt;
** Upgraded admin.sma to the new SQLX API.&lt;br /&gt;
** Fixed a bug in amx_reloadadmins not giving admins new access.&lt;br /&gt;
** Fixed a weapon restriction exploit in restmenu.sma.&lt;br /&gt;
** Fixed an HTML exploit in /top15 displaying player names.&lt;br /&gt;
** Fixed various and plentiful amx_addadmin bugs.&lt;br /&gt;
** Fixed telemenu.sma not letting you teleport yourself (thanks jtp10181!).&lt;br /&gt;
** Fixed a bug with adminslots.sma lowering the slots by 1.&lt;br /&gt;
** Fixed overlapping hud messages with miscstats.&lt;br /&gt;
&lt;br /&gt;
* Module API Changes:&lt;br /&gt;
** Added and fixed module API for inter-module communication.&lt;br /&gt;
** Added native overriding and replacing to module API.&lt;br /&gt;
** Added plugin unloading/unloaded callbacks to module API.&lt;br /&gt;
** Added MSVC8 project files to most CVS projects.&lt;br /&gt;
&lt;br /&gt;
* Configuration Changes:&lt;br /&gt;
** Added amx_sql_type cvar to sql.cfg.&lt;br /&gt;
** Re-organized and simplified modules.ini.&lt;br /&gt;
** Error logging can now be redirected to separate logs.&lt;br /&gt;
** Fixed modules.ini parsing bugs and simplified parsing.&lt;br /&gt;
** Fixed a double entry in cvars.ini.&lt;br /&gt;
&lt;br /&gt;
* Other Changes:&lt;br /&gt;
** Added a Bulgarian translation (thanks lubb!).&lt;br /&gt;
** Added a leetspeak translation (thanks, I think, Twilight Suzuka!).&lt;br /&gt;
** Improved FTP option of the graphical installer.&lt;br /&gt;
** Updated the GeoIP library to June.&lt;br /&gt;
** Updated PCRE from v6.1 to v6.4.&lt;br /&gt;
** Updated sqLite from 3.3.4 to 3.3.5.&lt;br /&gt;
** Fixed a steam account path bug in the installer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AMX Mod X]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2813</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2813"/>
		<updated>2006-03-26T08:22:45Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Compiler Pre-processor Directives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&lt;br /&gt;
new z = 1_000_000 // Pawn supports numbers like this. So big values are easier to read.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || false)             //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it 6 (binary 0110).&lt;br /&gt;
//This is the &amp;quot;bitwise complement&amp;quot; operator, which performs a !(not) on each bit.&lt;br /&gt;
(~(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Multiple conditions are also possible in pawn:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of an multiple switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 1, 2, 3:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 1 or 2 or 3&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 4, 5, 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 4 or 5 or6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7, 8, 9:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7 or 8 or 9&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
You could use the switch statement also for ranges:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of an range switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 0 .. 50:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 0 &amp;lt;= a &amp;lt;= 50&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 51 .. 100:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 51 &amp;lt;= a &amp;lt;= 100&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 101 .. 200:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 101 &amp;lt;= a &amp;lt;= 200&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated.&lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = HELLO&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Pawn documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2812</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2812"/>
		<updated>2006-03-26T08:20:36Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Switch Statements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&lt;br /&gt;
new z = 1_000_000 // Pawn supports numbers like this. So big values are easier to read.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || false)             //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it 6 (binary 0110).&lt;br /&gt;
//This is the &amp;quot;bitwise complement&amp;quot; operator, which performs a !(not) on each bit.&lt;br /&gt;
(~(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Multiple conditions are also possible in pawn:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of an multiple switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 1, 2, 3:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 1 or 2 or 3&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 4, 5, 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 4 or 5 or6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7, 8, 9:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7 or 8 or 9&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
You could use the switch statement also for ranges:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of an range switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 0 .. 50:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 0 &amp;lt;= a &amp;lt;= 50&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 51 .. 100:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 51 &amp;lt;= a &amp;lt;= 100&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 101 .. 200:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if 101 &amp;lt;= a &amp;lt;= 200&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated.&lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = {HELLO}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Pawn documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=2661</id>
		<title>Intro to AMX Mod X Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=2661"/>
		<updated>2006-02-26T22:10:20Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Building Admin Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic overview to scripting [[AMX Mod X]] plugins.&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
So you want to create a plugin? You should have a good understand of how Pawn works, so make sure Sections 0 and 1 of this manual make perfect sense to you. You should be reading this portion of the document, sitting at a computer, with a text editor and small compiler at hand. Doing this interactively helps learning. You won't be writing plugins like WC3, Matrix Mod, and CSDM right away, but this is meant to give you a kick start to the modding world of AMX Mod X. For a good text editor that is AMX Pawn enabled, try Crimson Editor (it's free as in beer): http://www.crimsoneditor.com/&lt;br /&gt;
&lt;br /&gt;
You should get familiar with compiling plugins. Refer to the &amp;quot;[[Compiling Plugins (AMX Mod X)|Compiling Plugins]]&amp;quot; section of the AMX Mod X Documentation, as it will not be provided here. You should also be familiar with adding new plugins, so you can test your plugins out.&lt;br /&gt;
&lt;br /&gt;
=Beginning=&lt;br /&gt;
&lt;br /&gt;
An AMX Mod X plugin can have four main types of functions. The first is a &amp;quot;public&amp;quot; function. This means it is publically viewable to the AMX Mod X engine. The second is a &amp;quot;native&amp;quot; function, which is declared in a module or the AMX Mod X Core. The third is a regular user function, which is declared without any special attributes. The fourth is a &amp;quot;forward&amp;quot; function, which is called whenever a special event occurs (a forward is also public). An AMX Mod X plugin must begin with a function initializing the plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This makes it so you can use the core AMX Mod X functions&lt;br /&gt;
//It &amp;quot;includes&amp;quot; the native definitions from includes\amxmodx.inc&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Declare three string variables&lt;br /&gt;
new PLUGIN[]=&amp;quot;AMXX Demo&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//This is a public function.  &lt;br /&gt;
//It is necessary to initialize your script under AMX Mod X.&lt;br /&gt;
//It takes no parameters, and is called right after map load.&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     //This is a function that takes three strings.&lt;br /&gt;
     //It registers your function in AMX Mod X, and assigns some basic information.&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try compiling the script above. It will be very small - as it does nothing so far. However, if you load this script, and type &amp;quot;amxx plugins&amp;quot;, you should see the new entry on the list.&lt;br /&gt;
&lt;br /&gt;
=Building Admin Commands=&lt;br /&gt;
&lt;br /&gt;
AMX Mod X provides a way to easily add console admin commands. Each command is &amp;quot;registered&amp;quot; as a console command. When you register a command, you must define four properties: The console command that is typed in, the function you are making that interprets the command, the access level required to use it, and a short description of the command.&lt;br /&gt;
&lt;br /&gt;
For this demonstration, let's build a plugin that lets you change the health of players on the server with the command &amp;quot;amx_hp&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
We'll need to do two things to start off - first, we need to register the command in the console. As we are binding a command to a public function, we must then make sure that function exists.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt; //This contains some useful functions&lt;br /&gt;
#include &amp;lt;fun&amp;gt;     //This contains the function to change health&lt;br /&gt;
&lt;br /&gt;
new PLUGIN[]=&amp;quot;Change Health&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first new function is &amp;quot;register_concmd&amp;quot;, which takes four parameters. The first is the command that a player must type into their console. The second is the public function that will handle the command. The third is the access level your command needs. Lastly, you can pass a string that describes how to use your command (for amx_help).&lt;br /&gt;
&lt;br /&gt;
Next, we have created a public function to handle the amx_hp command. Note that we are giving it three parameters. These parameters will hold special data when the command is used - id will hold the player's id who started the command, level will hold the access level of the command (you must do access checking yourself), and cid will hold the command's internal id.&lt;br /&gt;
&lt;br /&gt;
Also, note PLUGIN_HANDLED. There are two main return values you should concern yourself with. PLUGIN_CONTINUE generally means &amp;quot;continue with normal operation&amp;quot;, and PLUGIN_HANDLED means &amp;quot;block further operation&amp;quot;. The differences are subtle but important. For example, when binding a command, you should never return PLUGIN_CONTINUE. But if you return PLUGIN_HANDLED while binding to the &amp;quot;say&amp;quot; command, it will block the player's text from ever appearing. You must be careful with which you choose in certain situations. However, most things are unaffected (such as tasks, events, and other things you will run into later on).&lt;br /&gt;
&lt;br /&gt;
So, first things first. How do we make sure this user is an admin who has ADMIN_SLAY access?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cmd_access() function will check a command's information (user, access level, and id) and makes sure of two things: that the user has access to it, and that it was given a minimum number of parameters. Here we passed three, because the command will look like this: amx_hp &amp;lt;target&amp;gt; &amp;lt;amount&amp;gt;, and the actual command itself counts as a parameter. If cmd_access fails, we have the command immediately end.&lt;br /&gt;
&lt;br /&gt;
The next portion to solve is: we need to take the two parameters and decode them. The &amp;quot;amount&amp;quot; parameter is easy, as we just convert it from a string to a number. The second parameter will be trickier, as we want to be able to target three different types of people:&lt;br /&gt;
&lt;br /&gt;
* @CT or @T - CTs or Ts&lt;br /&gt;
* @ALL - Everyone&lt;br /&gt;
* &amp;lt;target&amp;gt; - Partial name of a player &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          //Check which team was specified.&lt;br /&gt;
          //Note that we start from [1], this is okay&lt;br /&gt;
          // it just means the @ isn't included&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          //This function will fill the players[32] variable&lt;br /&gt;
          // with valid player ids.  num will contain the number&lt;br /&gt;
          // of players that are valid.&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    //Set this player's health&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          //finds a player id that matches the partial name given&lt;br /&gt;
          //the 1 means that it will not target the player if he&lt;br /&gt;
          // has immunity access&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               //this will print a message to the user who tried the command&lt;br /&gt;
               //The format for this command is called &amp;quot;format()&amp;quot; style,&lt;br /&gt;
               // where the first string formats the message according&lt;br /&gt;
               // to any number of following parameters.&lt;br /&gt;
               //  %s means a string&lt;br /&gt;
               //  %d or %i means an integer&lt;br /&gt;
               //  %f means a float&lt;br /&gt;
               // so &amp;quot;Hello %s, I am %d years old&amp;quot; will &lt;br /&gt;
               //  require a string and integer to follow&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, our final stripped amx_hp plugin will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new PLUGIN[]=&amp;quot;Change Health&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;lt;hp&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=CVARs=&lt;br /&gt;
&lt;br /&gt;
CVARs are server-side storage keys. For example, &amp;quot;mp_startmoney&amp;quot; is the Counter-Strike CVAR to hold how much money people get when they join the game. You can make your own CVARs by registering them in plugin_init(). Let's replicate mp_startmoney.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(&amp;quot;CVAR Test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
     //set default value to 500&lt;br /&gt;
     register_cvar(&amp;quot;amx_startmoney&amp;quot;, &amp;quot;500&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//this occurs when a client is put in game&lt;br /&gt;
public client_putinserver(id)&lt;br /&gt;
{&lt;br /&gt;
     if (get_cvar_num(&amp;quot;amx_startmoney&amp;quot;) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;amx_startmoney&amp;quot;))&lt;br /&gt;
     } else {&lt;br /&gt;
	    cs_set_user_money(id, get_cvar_num(&amp;quot;mp_startmoney&amp;quot;))&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this plugin probably won't work, it's just a demonstration). You can set CVARs as floats, numbers, or strings, and you can modify just about any valid CVAR from the HL engine or mod.&lt;br /&gt;
&lt;br /&gt;
=Finding More=&lt;br /&gt;
&lt;br /&gt;
To learn more about scripting for AMX Mod X, you should look through the natives in the function reference or the include files. Include files generally follow two formats. They are named after a module or specific purpose. _const is appended if they contain pre-defined numbers or lists. _stocks is appended if they contain helper or useful wrapping functions. Remember, stocks are only compiled if you use them, so it is safe to include an include file with many stocks.&lt;br /&gt;
&lt;br /&gt;
You can also visit the [http://www.amxmodx.org/forums/ Forums] and ask questions, or read how other people achieved certain goals to learn and innovate.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=2660</id>
		<title>Intro to AMX Mod X Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=2660"/>
		<updated>2006-02-26T22:08:36Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Beginning */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic overview to scripting [[AMX Mod X]] plugins.&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
So you want to create a plugin? You should have a good understand of how Pawn works, so make sure Sections 0 and 1 of this manual make perfect sense to you. You should be reading this portion of the document, sitting at a computer, with a text editor and small compiler at hand. Doing this interactively helps learning. You won't be writing plugins like WC3, Matrix Mod, and CSDM right away, but this is meant to give you a kick start to the modding world of AMX Mod X. For a good text editor that is AMX Pawn enabled, try Crimson Editor (it's free as in beer): http://www.crimsoneditor.com/&lt;br /&gt;
&lt;br /&gt;
You should get familiar with compiling plugins. Refer to the &amp;quot;[[Compiling Plugins (AMX Mod X)|Compiling Plugins]]&amp;quot; section of the AMX Mod X Documentation, as it will not be provided here. You should also be familiar with adding new plugins, so you can test your plugins out.&lt;br /&gt;
&lt;br /&gt;
=Beginning=&lt;br /&gt;
&lt;br /&gt;
An AMX Mod X plugin can have four main types of functions. The first is a &amp;quot;public&amp;quot; function. This means it is publically viewable to the AMX Mod X engine. The second is a &amp;quot;native&amp;quot; function, which is declared in a module or the AMX Mod X Core. The third is a regular user function, which is declared without any special attributes. The fourth is a &amp;quot;forward&amp;quot; function, which is called whenever a special event occurs (a forward is also public). An AMX Mod X plugin must begin with a function initializing the plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This makes it so you can use the core AMX Mod X functions&lt;br /&gt;
//It &amp;quot;includes&amp;quot; the native definitions from includes\amxmodx.inc&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Declare three string variables&lt;br /&gt;
new PLUGIN[]=&amp;quot;AMXX Demo&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//This is a public function.  &lt;br /&gt;
//It is necessary to initialize your script under AMX Mod X.&lt;br /&gt;
//It takes no parameters, and is called right after map load.&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     //This is a function that takes three strings.&lt;br /&gt;
     //It registers your function in AMX Mod X, and assigns some basic information.&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try compiling the script above. It will be very small - as it does nothing so far. However, if you load this script, and type &amp;quot;amxx plugins&amp;quot;, you should see the new entry on the list.&lt;br /&gt;
&lt;br /&gt;
=Building Admin Commands=&lt;br /&gt;
&lt;br /&gt;
AMX Mod X provides a way to easily add console admin commands. Each command is &amp;quot;registered&amp;quot; as a console command. When you register a command, you must define four properties: The console command that is typed in, the function you are making that interprets the command, the access level required to use it, and a short description of the command.&lt;br /&gt;
&lt;br /&gt;
For this demonstration, let's build a plugin that lets you change the health of players on the server with the command &amp;quot;amx_hp&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
We'll need to do two things to start off - first, we need to register the command in the console. As we are binding a command to a public function, we must then make sure that function exists.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt; //This contains some useful functions&lt;br /&gt;
#include &amp;lt;fun&amp;gt;     //This contains the function to change health&lt;br /&gt;
&lt;br /&gt;
new PLUGIN[]=&amp;quot;Change Health&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first new function is &amp;quot;register_concmd&amp;quot;, which takes four parameters. The first is the command that a player must type into their console. The second is the public function that will handle the command. The third is the access level your command needs. Lastly, you can pass a string that describes how to use your command (for amx_help).&lt;br /&gt;
&lt;br /&gt;
Next, we have created a public function to handle the amx_hp command. Note that we are giving it three parameters. These parameters will hold special data when the command is used - id will hold the player's id who started the command, level will hold the access level of the command (you must do access checking yourself), and cid will hold the command's internal id.&lt;br /&gt;
&lt;br /&gt;
Also, note PLUGIN_HANDLED. There are two main return values you should concern yourself with. PLUGIN_CONTINUE generally means &amp;quot;continue with normal operation&amp;quot;, and PLUGIN_HANDLED means &amp;quot;block further operation&amp;quot;. The differences are subtle but important. For example, when binding a command, you should never return PLUGIN_CONTINUE. But if you return PLUGIN_HANDLED while binding to the &amp;quot;say&amp;quot; command, it will block the player's text from ever appearing. You must be careful with which you choose in certain situations. However, most things are unaffected (such as tasks, events, and other things you will run into later on).&lt;br /&gt;
&lt;br /&gt;
So, first things first. How do we make sure this user is an admin who has ADMIN_SLAY access?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cmd_access() function will check a command's information (user, access level, and id) and makes sure of two things: that the user has access to it, and that it was given a minimum number of parameters. Here we passed three, because the command will look like this: amx_hp &amp;lt;target&amp;gt; &amp;lt;amount&amp;gt;, and the actual command itself counts as a parameter. If cmd_access fails, we have the command immediately end.&lt;br /&gt;
&lt;br /&gt;
The next portion to solve is: we need to take the two parameters and decode them. The &amp;quot;amount&amp;quot; parameter is easy, as we just convert it from a string to a number. The second parameter will be trickier, as we want to be able to target three different types of people:&lt;br /&gt;
&lt;br /&gt;
* @CT or @T - CTs or Ts&lt;br /&gt;
* @ALL - Everyone&lt;br /&gt;
* &amp;lt;target&amp;gt; - Partial name of a player &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          //Check which team was specified.&lt;br /&gt;
          //Note that we start from [1], this is okay&lt;br /&gt;
          // it just means the @ isn't included&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          //This function will fill the players[32] variable&lt;br /&gt;
          // with valid player ids.  num will contain the number&lt;br /&gt;
          // of players that are valid.&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    //Set this player's health&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          //finds a player id that matches the partial name given&lt;br /&gt;
          //the 1 means that it will not target the player if he&lt;br /&gt;
          // has immunity access&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               //this will print a message to the user who tried the command&lt;br /&gt;
               //The format for this command is called &amp;quot;format()&amp;quot; style,&lt;br /&gt;
               // where the first string formats the message according&lt;br /&gt;
               // to any number of following parameters.&lt;br /&gt;
               //  %s means a string&lt;br /&gt;
               //  %d or %i means an integer&lt;br /&gt;
               //  %f means a float&lt;br /&gt;
               // so &amp;quot;Hello %s, I am %d years old&amp;quot; will &lt;br /&gt;
               //  require a string and integer to follow&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, our final stripped amx_hp plugin will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new PLUGIN[]=&amp;quot;Change Health&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;lt;hp&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=CVARs=&lt;br /&gt;
&lt;br /&gt;
CVARs are server-side storage keys. For example, &amp;quot;mp_startmoney&amp;quot; is the Counter-Strike CVAR to hold how much money people get when they join the game. You can make your own CVARs by registering them in plugin_init(). Let's replicate mp_startmoney.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(&amp;quot;CVAR Test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
     //set default value to 500&lt;br /&gt;
     register_cvar(&amp;quot;amx_startmoney&amp;quot;, &amp;quot;500&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//this occurs when a client is put in game&lt;br /&gt;
public client_putinserver(id)&lt;br /&gt;
{&lt;br /&gt;
     if (get_cvar_num(&amp;quot;amx_startmoney&amp;quot;) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;amx_startmoney&amp;quot;))&lt;br /&gt;
     } else {&lt;br /&gt;
	    cs_set_user_money(id, get_cvar_num(&amp;quot;mp_startmoney&amp;quot;))&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this plugin probably won't work, it's just a demonstration). You can set CVARs as floats, numbers, or strings, and you can modify just about any valid CVAR from the HL engine or mod.&lt;br /&gt;
&lt;br /&gt;
=Finding More=&lt;br /&gt;
&lt;br /&gt;
To learn more about scripting for AMX Mod X, you should look through the natives in the function reference or the include files. Include files generally follow two formats. They are named after a module or specific purpose. _const is appended if they contain pre-defined numbers or lists. _stocks is appended if they contain helper or useful wrapping functions. Remember, stocks are only compiled if you use them, so it is safe to include an include file with many stocks.&lt;br /&gt;
&lt;br /&gt;
You can also visit the [http://www.amxmodx.org/forums/ Forums] and ask questions, or read how other people achieved certain goals to learn and innovate.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=2659</id>
		<title>Intro to AMX Mod X Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Intro_to_AMX_Mod_X_Scripting&amp;diff=2659"/>
		<updated>2006-02-26T22:08:09Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Beginning */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic overview to scripting [[AMX Mod X]] plugins.&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
So you want to create a plugin? You should have a good understand of how Pawn works, so make sure Sections 0 and 1 of this manual make perfect sense to you. You should be reading this portion of the document, sitting at a computer, with a text editor and small compiler at hand. Doing this interactively helps learning. You won't be writing plugins like WC3, Matrix Mod, and CSDM right away, but this is meant to give you a kick start to the modding world of AMX Mod X. For a good text editor that is AMX Pawn enabled, try Crimson Editor (it's free as in beer): http://www.crimsoneditor.com/&lt;br /&gt;
&lt;br /&gt;
You should get familiar with compiling plugins. Refer to the &amp;quot;[[Compiling Plugins (AMX Mod X)|Compiling Plugins]]&amp;quot; section of the AMX Mod X Documentation, as it will not be provided here. You should also be familiar with adding new plugins, so you can test your plugins out.&lt;br /&gt;
&lt;br /&gt;
=Beginning=&lt;br /&gt;
&lt;br /&gt;
An AMX Mod X plugin can have four main types of functions. The first is a &amp;quot;public&amp;quot; function. This means it is publically viewable to the AMX Mod X engine. The second is a &amp;quot;native&amp;quot; function, which is declared in a module or the AMX Mod X Core. The third is a regular user function, which is declared without any special attributes. The fourth is a &amp;quot;forward&amp;quot; function, which is called whenever a special event occurs (a forward is also public). An AMX Mod X plugin must begin with a function initializing the plugin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
//This makes it so you can use the core AMX Mod X functions&lt;br /&gt;
//It &amp;quot;includes&amp;quot; the native definitions from includes\amxmodx.inc&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Declare three string variables&lt;br /&gt;
new PLUGIN[]=&amp;quot;AMXX Demo&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//This is a public function.  &lt;br /&gt;
//It is necessary to initialize your script under AMX Mod X.&lt;br /&gt;
//It takes no parameters, and is called right after map load.&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     //This is a function that takes three strings.&lt;br /&gt;
     //It registers your function in AMX Mod X, and assigns some basic information.&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try compiling the script above. It will be very small - as it does nothing so far. However, if you load this script, and type &amp;quot;amxx plugins&amp;quot;, you should see the new entry on the list.&lt;br /&gt;
&lt;br /&gt;
=Building Admin Commands=&lt;br /&gt;
&lt;br /&gt;
AMX Mod X provides a way to easily add console admin commands. Each command is &amp;quot;registered&amp;quot; as a console command. When you register a command, you must define four properties: The console command that is typed in, the function you are making that interprets the command, the access level required to use it, and a short description of the command.&lt;br /&gt;
&lt;br /&gt;
For this demonstration, let's build a plugin that lets you change the health of players on the server with the command &amp;quot;amx_hp&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
We'll need to do two things to start off - first, we need to register the command in the console. As we are binding a command to a public function, we must then make sure that function exists.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmisc&amp;gt; //This contains some useful functions&lt;br /&gt;
#include &amp;lt;fun&amp;gt;     //This contains the function to change health&lt;br /&gt;
&lt;br /&gt;
new PLUGIN[]=&amp;quot;Change Health&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first new function is &amp;quot;register_concmd&amp;quot;, which takes four parameters. The first is the command that a player must type into their console. The second is the public function that will handle the command. The third is the access level your command needs. Lastly, you can pass a string that describes how to use your command (for amx_help).&lt;br /&gt;
&lt;br /&gt;
Next, we have created a public function to handle the amx_hp command. Note that we are giving it three parameters. These parameters will hold special data when the command is used - id will hold the player's id who started the command, level will hold the access level of the command (you must do access checking yourself), and cid will hold the command's internal id.&lt;br /&gt;
&lt;br /&gt;
Also, note PLUGIN_HANDLED. There are two main return values you should concern yourself with. PLUGIN_CONTINUE generally means &amp;quot;continue with normal operation&amp;quot;, and PLUGIN_HANDLED means &amp;quot;block further operation&amp;quot;. The differences are subtle but important. For example, when binding a command, you should never return PLUGIN_CONTINUE. But if you return PLUGIN_HANDLED while binding to the &amp;quot;say&amp;quot; command, it will block the player's text from ever appearing. You must be careful with which you choose in certain situations. However, most things are unaffected (such as tasks, events, and other things you will run into later on).&lt;br /&gt;
&lt;br /&gt;
So, first things first. How do we make sure this user is an admin who has ADMIN_SLAY access?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cmd_access() function will check a command's information (user, access level, and id) and makes sure of two things: that the user has access to it, and that it was given a minimum number of parameters. Here we passed three, because the command will look like this: amx_hp &amp;lt;target&amp;gt; &amp;lt;amount&amp;gt;, and the actual command itself counts as a parameter. If cmd_access fails, we have the command immediately end.&lt;br /&gt;
&lt;br /&gt;
The next portion to solve is: we need to take the two parameters and decode them. The &amp;quot;amount&amp;quot; parameter is easy, as we just convert it from a string to a number. The second parameter will be trickier, as we want to be able to target three different types of people:&lt;br /&gt;
&lt;br /&gt;
* @CT or @T - CTs or Ts&lt;br /&gt;
* @ALL - Everyone&lt;br /&gt;
* &amp;lt;target&amp;gt; - Partial name of a player &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          //Check which team was specified.&lt;br /&gt;
          //Note that we start from [1], this is okay&lt;br /&gt;
          // it just means the @ isn't included&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          //This function will fill the players[32] variable&lt;br /&gt;
          // with valid player ids.  num will contain the number&lt;br /&gt;
          // of players that are valid.&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    //Set this player's health&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          //finds a player id that matches the partial name given&lt;br /&gt;
          //the 1 means that it will not target the player if he&lt;br /&gt;
          // has immunity access&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               //this will print a message to the user who tried the command&lt;br /&gt;
               //The format for this command is called &amp;quot;format()&amp;quot; style,&lt;br /&gt;
               // where the first string formats the message according&lt;br /&gt;
               // to any number of following parameters.&lt;br /&gt;
               //  %s means a string&lt;br /&gt;
               //  %d or %i means an integer&lt;br /&gt;
               //  %f means a float&lt;br /&gt;
               // so &amp;quot;Hello %s, I am %d years old&amp;quot; will &lt;br /&gt;
               //  require a string and integer to follow&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, our final stripped amx_hp plugin will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
#include &amp;lt;fun&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new PLUGIN[]=&amp;quot;Change Health&amp;quot;&lt;br /&gt;
new AUTHOR[]=&amp;quot;BAILOPAN&amp;quot;&lt;br /&gt;
new VERSION[]=&amp;quot;1.00&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(PLUGIN, VERSION, AUTHOR)&lt;br /&gt;
     register_concmd(&amp;quot;amx_hp&amp;quot;, &amp;quot;cmd_hp&amp;quot;, ADMIN_SLAY, &amp;quot;&amp;lt;target&amp;gt; &amp;lt;hp&amp;gt;&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public cmd_hp(id, level, cid)&lt;br /&gt;
{&lt;br /&gt;
     if (!cmd_access(id, level, cid, 3))&lt;br /&gt;
        return PLUGIN_HANDLED&lt;br /&gt;
&lt;br /&gt;
     new Arg1[24]&lt;br /&gt;
     new Arg2[4]&lt;br /&gt;
&lt;br /&gt;
     //Get the command arguments from the console&lt;br /&gt;
     read_argv(1, Arg1, 23)&lt;br /&gt;
     read_argv(2, Arg2, 3)&lt;br /&gt;
&lt;br /&gt;
     //Convert the health from a string to a number&lt;br /&gt;
     new Health = str_to_num(Arg2)&lt;br /&gt;
&lt;br /&gt;
     //Is the first character the @ symbol?&lt;br /&gt;
     if (Arg1[0] == '@')&lt;br /&gt;
     {&lt;br /&gt;
          new Team = 0&lt;br /&gt;
          if (equali(Arg1[1], &amp;quot;CT&amp;quot;))&lt;br /&gt;
          {&lt;br /&gt;
               Team = 2&lt;br /&gt;
          } else if (equali(Arg1[1], &amp;quot;T&amp;quot;)) {&lt;br /&gt;
               Team = 1&lt;br /&gt;
          }&lt;br /&gt;
          new players[32], num&lt;br /&gt;
          get_players(players, num)&lt;br /&gt;
          new i&lt;br /&gt;
          for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
          {&lt;br /&gt;
               if (!Team)&lt;br /&gt;
               {&lt;br /&gt;
                    set_user_health(players[i], Health)&lt;br /&gt;
               } else {&lt;br /&gt;
                    if (get_user_team(players[i]) == Team)&lt;br /&gt;
                    {&lt;br /&gt;
                         set_user_health(players[i], Health)&lt;br /&gt;
                    }&lt;br /&gt;
               }&lt;br /&gt;
          }&lt;br /&gt;
     } else {&lt;br /&gt;
          new player = cmd_target(id, Arg1, 1)&lt;br /&gt;
          if (!player)&lt;br /&gt;
          {&lt;br /&gt;
               console_print(id, &amp;quot;Sorry, player %s could not be found or targetted!&amp;quot;, Arg1)&lt;br /&gt;
               return PLUGIN_HANDLED&lt;br /&gt;
          } else {&lt;br /&gt;
               set_user_health(player, Health)&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     return PLUGIN_HANDLED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=CVARs=&lt;br /&gt;
&lt;br /&gt;
CVARs are server-side storage keys. For example, &amp;quot;mp_startmoney&amp;quot; is the Counter-Strike CVAR to hold how much money people get when they join the game. You can make your own CVARs by registering them in plugin_init(). Let's replicate mp_startmoney.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;amxmodx&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public plugin_init()&lt;br /&gt;
{&lt;br /&gt;
     register_plugin(&amp;quot;CVAR Test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;BAILOPAN&amp;quot;)&lt;br /&gt;
     //set default value to 500&lt;br /&gt;
     register_cvar(&amp;quot;amx_startmoney&amp;quot;, &amp;quot;500&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//this occurs when a client is put in game&lt;br /&gt;
public client_putinserver(id)&lt;br /&gt;
{&lt;br /&gt;
     if (get_cvar_num(&amp;quot;amx_startmoney&amp;quot;) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
          cs_set_user_money(id, get_cvar_num(&amp;quot;amx_startmoney&amp;quot;))&lt;br /&gt;
     } else {&lt;br /&gt;
	    cs_set_user_money(id, get_cvar_num(&amp;quot;mp_startmoney&amp;quot;))&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(this plugin probably won't work, it's just a demonstration). You can set CVARs as floats, numbers, or strings, and you can modify just about any valid CVAR from the HL engine or mod.&lt;br /&gt;
&lt;br /&gt;
=Finding More=&lt;br /&gt;
&lt;br /&gt;
To learn more about scripting for AMX Mod X, you should look through the natives in the function reference or the include files. Include files generally follow two formats. They are named after a module or specific purpose. _const is appended if they contain pre-defined numbers or lists. _stocks is appended if they contain helper or useful wrapping functions. Remember, stocks are only compiled if you use them, so it is safe to include an include file with many stocks.&lt;br /&gt;
&lt;br /&gt;
You can also visit the [http://www.amxmodx.org/forums/ Forums] and ask questions, or read how other people achieved certain goals to learn and innovate.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(AMX_Mod_X_Scripting)&amp;diff=2658</id>
		<title>Optimizing Plugins (AMX Mod X Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(AMX_Mod_X_Scripting)&amp;diff=2658"/>
		<updated>2006-02-25T08:34:39Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Lookup Tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
[[Admin-Mod]] and [[AMX Mod X]] became very popular because of their easy to use scripting language.  However, the words &amp;quot;scripting language&amp;quot; come with a lot of loaded preconceptions.  Most people assume that because it's scripted:&lt;br /&gt;
*You can't possibly make it any faster&lt;br /&gt;
*It's pre-compiled, so it's already quite fast&lt;br /&gt;
*Details don't matter, as it's only &amp;quot;scripting&amp;quot; anyway&lt;br /&gt;
&lt;br /&gt;
Especially, with [[Pawn]] (formerly Small), none of these are true.  The compiler, in fact, is very poor at optimizing, and you can '''greatly''' increase the speed and efficiency of your plugins by keeping a few rules in mind.  Remember - it's more important to minimize instructions than it is to minimize lines of code.&lt;br /&gt;
&lt;br /&gt;
===Terms===&lt;br /&gt;
To read this document, you will need to understand a few concepts beforehand:&lt;br /&gt;
*&amp;lt;tt&amp;gt;BRANCHING&amp;lt;/tt&amp;gt; - When the processor takes a different path of code.  For example, to call a function or to use an if statement, the processor will &amp;quot;branch&amp;quot;.  Modern processors attempt to predict pathways with &amp;quot;branch prediction&amp;quot;, but it's best to avoid branching a lot if possible.&lt;br /&gt;
*&amp;lt;tt&amp;gt;STACK ALLOCATION&amp;lt;/tt&amp;gt; - In Pawn, all local data is stored on the stack, a big chunk of continuous memory.  Whenever you create a variable on the stack, it is automatically written with zeroes.&lt;br /&gt;
*&amp;lt;tt&amp;gt;HEAP ALLOCATION&amp;lt;/tt&amp;gt; - In Pawn, temporary data that needs to be referenced by a native is stored on the heap, another area of contiguous, but less restrictive memory.&lt;br /&gt;
*&amp;lt;tt&amp;gt;DATA SECTION&amp;lt;/tt&amp;gt; - This is an area of memory built into your .amxx file.  In fact, it &amp;quot;becomes&amp;quot; the heap at load time.  All your strings and arrays are hardcoded into this area.&lt;br /&gt;
*&amp;lt;tt&amp;gt;EXPENSIVENESS&amp;lt;/tt&amp;gt; - To be &amp;quot;expensive&amp;quot; in computer science means an operation requires a lot of CPU processing.  It usually does not refer to memory size, only to processing cycles and time.  Addition is inexpensive, floating power operations are expensive.  However, both are inexpensive in comparison to writing a file.  An inexpensive operation can also be called &amp;quot;cheap&amp;quot;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;BIG-OH NOTATION&amp;lt;/tt&amp;gt; - O(*) notation refers to the expensiveness of an algorithm.  If something is O(n), it occurs in linear time -- meaning that for N items, it will complete relative to N.  O(N^2) means with N items, it will complete relative to N^2.  O(1) means &amp;quot;constant time&amp;quot; - no matter what N is, it will run in the same amount of time.&lt;br /&gt;
&lt;br /&gt;
==Compiler Optimizations==&lt;br /&gt;
These optimizations have to do with changing how your code is compiled.  While the syntax may remain the same, you are not only increasing compile time, but increasing your plugin's efficiency and speed at run time.&lt;br /&gt;
&lt;br /&gt;
===Always Save Results===&lt;br /&gt;
Observe the example code snippet below:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (get_user_team(player) == TEAM_T)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
} else if (get_user_team(player) == TEAM_CT) {&lt;br /&gt;
    //...code&lt;br /&gt;
} else if (get_user_team(player) == TEAM_SPECTATOR) {&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This is a mild example of &amp;quot;cache your results&amp;quot;.  When the compiler generates assembly for this code, it will (in pseudo code) generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Notice the problem?  We have called &amp;lt;tt&amp;gt;get_user_team&amp;lt;/tt&amp;gt; an extra two times than necessary.  The result doesn't change, so we can save it.  Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = get_user_team(player)&lt;br /&gt;
if (team == TEAM_T)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
} else if (team == TEAM_CT) {&lt;br /&gt;
    //...code&lt;br /&gt;
} //...etc&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now, the compiler will only generate this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If &amp;lt;tt&amp;gt;get_user_team&amp;lt;/tt&amp;gt; were an expensive operation (it's relatively cheap), we would have recalculated the entire result each branch of the &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Switch instead of If===&lt;br /&gt;
If you can, you should use &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; cases instead of &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;.  This is because for an if statement, the compiler must branch to each consecutive &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case.  Using the example from above, observe the switch version:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = get_user_team(player)&lt;br /&gt;
switch (team)&lt;br /&gt;
{&lt;br /&gt;
  case TEAM_T:&lt;br /&gt;
     //code...&lt;br /&gt;
  case TEAM_CT:&lt;br /&gt;
     //code...&lt;br /&gt;
  case TEAM_SPECTATOR:&lt;br /&gt;
     //code...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will generate what's called a &amp;quot;case table&amp;quot;.  Rather than worm through displaced &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; tests, the compiler generates a table of possible values, which the virtual machine knows to browse through:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE&lt;br /&gt;
  COMPARE&lt;br /&gt;
  COMPARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Don't Re-index Arrays===&lt;br /&gt;
A common practive in Small is to &amp;quot;save space&amp;quot; by re-indexing arrays.  There are a few myths behind this, such as saving memory, assuming the compiler does it for you, or readability.  Fact: none of these are true.  Observe the code below:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new players[32], num, team&lt;br /&gt;
get_players(players, num)&lt;br /&gt;
for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
{&lt;br /&gt;
   if (!is_user_connected(players[i]))&lt;br /&gt;
      continue;&lt;br /&gt;
   team = get_user_team(players[i])&lt;br /&gt;
   set_user_frags(players[i], 0)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
For this, the compiler generates code similar to:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL is_user_connected&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL get_user_team&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL set_user_frags&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
See what happened?  The compiler does not cache array indexing.  Because we've used &amp;lt;tt&amp;gt;players[i]&amp;lt;/tt&amp;gt; each time, every instance generates 4-6 (or more) instructions which load &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt;, the address of &amp;lt;tt&amp;gt;players&amp;lt;/tt&amp;gt;, computes the final location, and then grabs the data out of memory.  It is much faster to do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new player&lt;br /&gt;
for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
{&lt;br /&gt;
   player = players[i]&lt;br /&gt;
   if (!is_user_connected(player))&lt;br /&gt;
      continue;&lt;br /&gt;
   team = get_user_team(player)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Not only is this more readable, but look at how much cruft we've shaved off the compiler's generated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   STORE player&lt;br /&gt;
   CALL is_user_connected&lt;br /&gt;
   LOAD player&lt;br /&gt;
   CALL get_user_team&lt;br /&gt;
   LOAD player&lt;br /&gt;
   CALL set_user_frags&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In a large loop you can drastically reduce codesize in this manner.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Global vs Local and Variables in Loops===&lt;br /&gt;
It is important to realize that every variable in [[Pawn]] is automatically zeroed.  For global variables, they are static and permanent, thus they are zeroed when your plugin is loaded.  Variables in functions, however, must be zeroed dynamically.  This is a slow and tedious operation, and you should not only avoid relying on it when necessary, but you should keep that fact in mind when using arrays.&lt;br /&gt;
&lt;br /&gt;
[[Arrays]] in [[Pawn]] are &amp;quot;cells&amp;quot; of data.  Each cell is four or eight bytes, depending on whether your processor is 32bit or 64bit.  To create an array of 4096 cells, for example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new array[4096]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
The compiler generates code to manually zero every single one of the 16,384 bytes in that location.  Normally, this isn't too bad -- but it can be absolutely deadly in a function which is called quite often.  For example, &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt; is called on every [[server tick]] in [[AMX Mod X]].  To declare an array of that size in &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt; is highly unnecessary.  Instead, you can take advantage of the fact that not only are globals free of charge, but &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt; does not need to be re-entrant.  That is, you will never call &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt; inside of &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt;, so making the variable global will not bring up the problem of one instance of the function overwriting data from another instance of the same function.  Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new g_serverframe_array[4096]&lt;br /&gt;
public server_frame()&lt;br /&gt;
{&lt;br /&gt;
  //...code that uses g_serverframe_array&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will execute conseridably faster.  You can do this with smaller arrays too.&lt;br /&gt;
&lt;br /&gt;
Likewise, it is equally important to avoid declaring arrays inside of loops.  Consider the following block of code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
{&lt;br /&gt;
   new message[255], name[32], player&lt;br /&gt;
   player = players[i]&lt;br /&gt;
   get_user_name(player, name, 31)&lt;br /&gt;
   format(message, 254, &amp;quot;Hello, %s&amp;quot;, name)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
If there are 32 players, this loop will actually resize and zero out over 1K of memory thirty two times in a row.  Not good!  However, on the other hand, it's nice that the message is zeroed out for us each time.  &amp;lt;tt&amp;gt;Tip:&amp;lt;/tt&amp;gt; you often only need to zero out the first character of a string.  This will make the entire string empty.  The code below is much more efficient:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new message[255], name[32], player&lt;br /&gt;
for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
{&lt;br /&gt;
   player = players[i]&lt;br /&gt;
   name[0] = '\0'&lt;br /&gt;
   message[0] = '\0'&lt;br /&gt;
   get_user_name(player, name, 31)&lt;br /&gt;
   format(message, 254, &amp;quot;Hello, %s&amp;quot;, name)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This has the effect of safely making the string empty beforehand, as well as largely reducing a lot of run-time overhead.&lt;br /&gt;
&lt;br /&gt;
===Static vs Global===&lt;br /&gt;
An alternative to global variables is static variables, which are internally the same but easier to work with for programming.&lt;br /&gt;
&lt;br /&gt;
A variable declared with the keyword &amp;quot;static&amp;quot; instead of &amp;quot;new&amp;quot; operates in the same way a global does (it is created only once) but the variable is local to the function; this means the code is much easier to read, while drastically improving speed just like a global variable.  Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;stock SomeBigFunction()&lt;br /&gt;
{&lt;br /&gt;
   static gaben[255];&lt;br /&gt;
   format(gaben, &amp;quot;%L&amp;quot;, LANG_SERVER, &amp;quot;STUFF&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This has the same effect as declaring &amp;lt;tt&amp;gt;gaben&amp;lt;/tt&amp;gt; as global, except only &amp;lt;tt&amp;gt;SomeBigFunction&amp;lt;/tt&amp;gt; can use it.  &lt;br /&gt;
&lt;br /&gt;
{{qnotice|Be careful of re-entrancy!}}&lt;br /&gt;
When a variable is static, it has the same re-entrancy problems of a global variable.  That means, if your function might be called recursively, or twice in the same stack frame, you should not use static variables.  This is most often the case for API provided to other plugins or helper functions.  Triggered events are usually never called twice on the same execution chain.&lt;br /&gt;
&lt;br /&gt;
===Constant variables===&lt;br /&gt;
You can declare a variable &amp;quot;constant&amp;quot; by adding the &amp;quot;const&amp;quot; keyword before the variable name:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new const AMX_GABEN[] = &amp;quot;amx_gaben&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What this does is prevents the variable from being changed; essentially, you've locked the variable to a certain value. In this way, a constant can offer a type safe method of simplifying code, unlike a define, which is not type safe.&lt;br /&gt;
&lt;br /&gt;
In addition, constant variables are often optimized out, resulting in quicker and smaller code.&lt;br /&gt;
&lt;br /&gt;
===For Loop Comparisons===&lt;br /&gt;
A common mistake is to write code like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new string[256] = &amp;quot;something long&amp;quot;&lt;br /&gt;
for (new i=0; i&amp;lt;strlen(string); i++)&lt;br /&gt;
   //...code&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This plays off a similar principle from before: cache results.  The compiler will actually recompute your string length on each iteration of the loop.  This will have even worse effects if your string changes mid-loop.  A more sensible method is:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new string[256] = &amp;quot;something long&amp;quot;&lt;br /&gt;
new len = strlen(string)&lt;br /&gt;
for (new i=0; i&amp;lt;len; i++)&lt;br /&gt;
   //...code&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Tips and Tricks==&lt;br /&gt;
===Lookup Tables===&lt;br /&gt;
Precompute what can be precomputed.  For example, say you have a mapping of weapon indices to names:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (weapon == CSW_AK47)&lt;br /&gt;
   copy(name, len, &amp;quot;weapon_ak47&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Ignoring the fact that we have &amp;lt;tt&amp;gt;get_weapon_name&amp;lt;/tt&amp;gt; in [[AMX Mod X]], this is inefficient.  We could precompute this result in a table:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new g_WeaponNamesTable[TOTAL_WEAPONS][] = {&lt;br /&gt;
   //..0 to CSW_AK47-1&lt;br /&gt;
   &amp;quot;weapon_ak47&amp;quot;,&lt;br /&gt;
   //..CSW_AK47+1 to TOTAL_WEAPONS-1&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Perfect Hashing===&lt;br /&gt;
:TODO: explain this&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Local Strings===&lt;br /&gt;
The [[Pawn]] compiler does not optimize the DATA section, which stores all hardcoded strings and global arrays.  If you reference the same hardcoded string 500 times in your plugin, it will appear 500 different times.  If this seems bad enough, it actually does this with all strings.  For example, the empty string (&amp;quot;&amp;quot;) appears everywhere in the include files, usually used as a default parameter to many natives.  This too is copied into the data section for each unique reference.  &lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;set_cvar_string(&amp;quot;amx_gaben&amp;quot;, get_cvar_string(&amp;quot;amx_gaben&amp;quot;) + 1)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will create two copies of &amp;quot;amx_gaben&amp;quot; in the DATA section.  While this doesn't really hurt, it does increase the size of your plugin.  &lt;br /&gt;
&lt;br /&gt;
Similarly, this has the same problem:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define AMX_GABEN &amp;quot;amx_gaben&amp;quot;&lt;br /&gt;
set_cvar_string(AMX_GABEN, get_cvar_string(AMX_GABEN) + 1)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
The only way to avoid this mess is to use global variables.  As stated earlier, they're basically free storage.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new AMX_GABEN[] = &amp;quot;amx_gaben&amp;quot;&lt;br /&gt;
set_cvar_string(AMX_GABEN, get_cvar_string(AMX_GABEN) + 1)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again, while not necessary, this will reduce your plugin's size in memory and on disk.  If you're already using defines, you can make this switch easily.&lt;br /&gt;
&lt;br /&gt;
In order to prevent this from changing, you may want to declare it constant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new const AMX_GABEN[] = &amp;quot;amx_gaben&amp;quot;&lt;br /&gt;
set_cvar_string(AMX_GABEN, get_cvar_string(AMX_GABEN) + 1)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now it is a perfectly safe method of storage.&lt;br /&gt;
&lt;br /&gt;
==Faster Natives==&lt;br /&gt;
AMX Mod X replaces many of the old AMX Mod natives with faster versions.  Read below to discover them.&lt;br /&gt;
&lt;br /&gt;
===Cvar Pointers===&lt;br /&gt;
As of AMX Mod X 1.65, you can cache &amp;quot;cvar pointers&amp;quot;.  These are direct accesses to cvars, rather than named access.  This is a critical optimization which is dozens of times faster.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new g_enabled = register_cvar(&amp;quot;csdm_enabled&amp;quot;, &amp;quot;1&amp;quot;)&lt;br /&gt;
//OR&lt;br /&gt;
new g_enabled = get_cvar_pointer(&amp;quot;csdm_enabled&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
stock SetCSDM(num)&lt;br /&gt;
   set_pcvar_num(g_enabled, num)&lt;br /&gt;
&lt;br /&gt;
stock GetCSDM()&lt;br /&gt;
   return get_pcvar_num(g_enabled)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
All of the cvar* functions (except for set_cvar_string) are mapped to [get|set]_pcvar_*.  You can get a cached cvar pointer with get_cvar_pointer() or register_cvar().&lt;br /&gt;
&lt;br /&gt;
===FormatEX===&lt;br /&gt;
As of AMX Mod X 1.65, there is an ultra high-speed version of format() called formatex().  It skips copy-back checking, unlike format().  formatex() cannot be used if a source input is the same as the output buffer.  For example, these are invalid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new buffer[255]&lt;br /&gt;
formatex(buffer, 254, &amp;quot;%s&amp;quot;, buffer);&lt;br /&gt;
formatex(buffer, 254, buffer);&lt;br /&gt;
formatex(buffer, 254, &amp;quot;%d %s&amp;quot;, buffer[2]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It should be noted that format() will behave the same as formatex() if it detects that there will be no copy-back needed.  However, formatex() does not check this, and thus is slightly faster for situations where the coder is sure of its usage.&lt;br /&gt;
&lt;br /&gt;
===File Writing===&lt;br /&gt;
As of AMX Mod X 1.65, there are new natives for file writing.  Read_file and write_file are O(n^2) functions for consecutive read/writes.  fopen(), fgets(), fputs(), and fclose() are O(n) (or better) depending on how you use them.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2504</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2504"/>
		<updated>2006-01-28T15:02:35Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Integers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&lt;br /&gt;
new z = 1_000_000 // Pawn supports numbers like this. So big values are easier to read.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || false)             //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it 6 (binary 0110).&lt;br /&gt;
//This is the &amp;quot;bitwise complement&amp;quot; operator, which performs a !(not) on each bit.&lt;br /&gt;
(~(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated. &lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = {HELLO}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Pawn documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2503</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2503"/>
		<updated>2006-01-28T15:02:09Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Integers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&lt;br /&gt;
new z = 1_000_000 // Pawn supports numbers like this. So big values are easier to read.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || false)             //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it 6 (binary 0110).&lt;br /&gt;
//This is the &amp;quot;bitwise complement&amp;quot; operator, which performs a !(not) on each bit.&lt;br /&gt;
(~(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated. &lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = {HELLO}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Pawn documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2430</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2430"/>
		<updated>2006-01-21T22:03:48Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Conclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || true)              //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it to false (binary 0000).&lt;br /&gt;
(!(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5) {&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated. &lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = {HELLO}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Pawn documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2429</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2429"/>
		<updated>2006-01-21T22:01:33Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Compiler Pre-processor Directives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || true)              //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it to false (binary 0000).&lt;br /&gt;
(!(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5) {&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated. &lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = {HELLO}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Small documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2428</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2428"/>
		<updated>2006-01-21T22:00:05Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Compiler Pre-processor Directives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || true)              //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it to false (binary 0000).&lt;br /&gt;
(!(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5) {&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated. &lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = {HELLO}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change the control character( amxx std: '^' )&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma ctrlchar '\'&lt;br /&gt;
//this sets the control character to backslash( c/c++/c#/java/... std )&lt;br /&gt;
// now you have to use the \ instead of ^&lt;br /&gt;
// e.g. &amp;quot;this is ^&amp;quot;:D^&amp;quot; &amp;quot; must be now &amp;quot; this is \&amp;quot;:D\&amp;quot; &amp;quot;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Small documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2427</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2427"/>
		<updated>2006-01-21T21:52:26Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Expressions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || true)              //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it to false (binary 0000).&lt;br /&gt;
(!(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5) {&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated. &lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = {HELLO}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Small documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2426</id>
		<title>Pawn Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Pawn_Tutorial&amp;diff=2426"/>
		<updated>2006-01-21T21:46:27Z</updated>

		<summary type="html">&lt;p&gt;Greenberet: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{qnotice|This guide is rather hardcoded to [[AMX Mod X]].  It needs to be mode generic.}}&lt;br /&gt;
&lt;br /&gt;
This guide is designed to give you a more in-depth overview of the basics of programming in [[Pawn]].&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Pawn is an embeddable, (almost) typeless, easy to use scripting language that is compiled for a virtual machine. [[AMX Mod X]] uses Pawn to route scripting functions to the Half-Life engine, using the Pawn [[Virtual Machine]] and [[Metamod]] ([[Pawn]] is written in C, Metamod is written in C++). While you write Pawn scripts in a text editor, the scripts must be compiled with a &amp;quot;Compiler&amp;quot;, which produces a binary for AMX Mod X. The AMX Mod X team distributes a specially modified Pawn compiler.&lt;br /&gt;
&lt;br /&gt;
Programming scripts in Pawn is relatively easy, and does not have concepts in other languages that are unnecessary for general use, such as pointers, vectors, structs, classes, allocation, et cetera. &lt;br /&gt;
&lt;br /&gt;
==Language Paradigms==&lt;br /&gt;
Pawn was originally named &amp;quot;[[Small]]&amp;quot; to emphasize the size of the language specification.  The language sacrifices many features found in modern languages to achieve simplicity and speed, which are required for embedded uses.&lt;br /&gt;
*No typing&lt;br /&gt;
**Pawn only has one data type -- the &amp;quot;[[Cell_(Pawn)|cell]]&amp;quot;.  It is the size of the processor's integral pointer (4 bytes for 32bit processor, 8 bytes for 64bit processors).  This has two major implications - Pawn bytecode is processor specific, and pointers can fit inside a cell.&lt;br /&gt;
**[[Tagging_(Pawn)|Tagging]] - Pawn lets you create weakly statically typed &amp;quot;tags&amp;quot;, which can be associated with variables for primitive operator overloading.  For example, Pawn has no concept of floating point numbers (only integers).  Instead, operators are overloaded with the Float: tag to redirect computation to new functions.  Tag-checking is only enforced as a warning.&lt;br /&gt;
**Since Pawn only has one datatype, it does not support structs, records, objects, or anything else.&lt;br /&gt;
**Pawn &amp;lt;i&amp;gt;does&amp;lt;/i&amp;gt; support arrays of cells, which leads to C-style arrays for strings.&lt;br /&gt;
*No garbage collection&lt;br /&gt;
**Pawn has no &amp;quot;heap&amp;quot; allocation built-in.  All variables are stored on the stack or in the data section.  Therefore, no garbage collection is necessary and memory leaks are not possible from the language specification alone.&lt;br /&gt;
*Procedural&lt;br /&gt;
**Pawn is entirely comprised of single, non-nested subroutines.  There are no lambda functions, member functions, constructors, et cetera.  Functions can either be internal (within the script) or public (exposed to the VM by name, like C's &amp;quot;extern&amp;quot;).&lt;br /&gt;
*No thread-safety&lt;br /&gt;
**Pawn is targetted toward single-thread instances.&lt;br /&gt;
&lt;br /&gt;
==Implementation Features==&lt;br /&gt;
*Cross-platform compatible compiler, which outputs bytecode and debug browsing information.&lt;br /&gt;
*Cross-platform compatible Virtual Machine (VM), with support for debug browsing, halting/stopping execution, and interacting with scripts from C/C++ libraries.&lt;br /&gt;
*IA32 JIT Compiler for vastly increasing script execution time.&lt;br /&gt;
&lt;br /&gt;
Because the footprints of the VM and JIT are so small, Pawn is ideal inside games which need a simple and highly fast event system, embedded devices or applications, and realtime systems.&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Pawn is licensed under the [[ZLib/libpng_License]] license.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Variables are simple structures for holding data throughout a period of time in your script.&lt;br /&gt;
&lt;br /&gt;
==Types==&lt;br /&gt;
Small has just three data types for declaring variables. The default variable type is a regular whole number, or integer. A variable name, for backwards compatibility, should be 19 characters or less, and MUST start with a letter. It can contain the symbols A-Z, a-z, 0-9, and the underscore (&amp;quot;_&amp;quot;). It is important to note that variable names are case sensitive - &amp;quot;myvar&amp;quot;, &amp;quot;MyVaR&amp;quot;, and &amp;quot;MYVAR&amp;quot; are three separate symbols. &lt;br /&gt;
&lt;br /&gt;
===Integers===&lt;br /&gt;
The simplest data type in Pawn is an &amp;quot;integer&amp;quot;.  Integers are whole numbers.  To declare a new integer variable, use the &amp;quot;new&amp;quot; operator like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a            //Declare empty variable &amp;quot;a&amp;quot;&lt;br /&gt;
new b=5          //Declare variable &amp;quot;b&amp;quot; and set it to 5.&lt;br /&gt;
new c=5.0        //This is invalid, technically not a whole number!&lt;br /&gt;
new d=&amp;quot;hello&amp;quot;    //&amp;quot;hello&amp;quot; is not a number either, this is invalid.&lt;br /&gt;
&lt;br /&gt;
//You can also declare multiple variables on one line:&lt;br /&gt;
new e,f,g,h&lt;br /&gt;
new x=7, y=3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Floats===&lt;br /&gt;
You can also declare a variable as a &amp;quot;Float&amp;quot;, which means it can store numbers with decimal places. These are called &amp;quot;floating point&amp;quot; numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:a            //Declare empty floating point variable &amp;quot;a&amp;quot;&lt;br /&gt;
new Float:b=5.3        //This will declare a new variable &amp;quot;b&amp;quot; and assign 5.3 to it.&lt;br /&gt;
new Float:c=5          //This is valid, but the compiler will give you a warning.&lt;br /&gt;
new Float:d=&amp;quot;hello&amp;quot;    //This is invalid, &amp;quot;hello&amp;quot; is not a decimal number.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also do the following:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//float(n) is a function that takes a number n and makes it a&lt;br /&gt;
// floating point number.&lt;br /&gt;
new Float:var = float(5)&lt;br /&gt;
new Float:var2 = 5.0     &lt;br /&gt;
new Float:var3 = 1.0*5&lt;br /&gt;
new var4 = floatround(5.0)     &lt;br /&gt;
//Note: floatround(n) is a function that takes a number n and rounds it to a whole number.&lt;br /&gt;
//  this makes the assignment to a regular integer variable valid.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - Spacing does generally not matter, as long as the compiler can tell symbols apart from each other. If your spacing is REALLY bad, you will get errors or maybe even warnings. For example, &amp;quot;new var = 5&amp;quot; and &amp;quot;new var=5&amp;quot; are the same, but &amp;quot;newvar=5&amp;quot; is totally wrong.&lt;br /&gt;
&lt;br /&gt;
===Booleans===&lt;br /&gt;
The last variable type is &amp;quot;boolean&amp;quot;. It is very simple - it is either &amp;quot;true&amp;quot;, or &amp;quot;false&amp;quot;. Both &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; are predefined data structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:IsItOn        //Declares a new variable &amp;quot;IsItOn&amp;quot; which is automatically false&lt;br /&gt;
new bool:xyz=true      //Declares a new variable &amp;quot;xyz&amp;quot; set to true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
&lt;br /&gt;
Pawn features basic &amp;quot;arrays&amp;quot;. An array is a simple type of aggregate data. This means you can store multiple values in one variable! An array follows the same rules as a regular variable, and it has the same types. It simply can contain multiple values. You define an array with brackets, and how many values it can hold. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a variable called &amp;quot;Players&amp;quot; which holds 32 numbers. &lt;br /&gt;
new Players[32]&lt;br /&gt;
//You can now store values in any of the 32 &amp;quot;slots&amp;quot; this array has.  &lt;br /&gt;
// The slots are numbered from 0 to n-1, or in this case, 0 to 31.&lt;br /&gt;
//Every slot starts off as 0.&lt;br /&gt;
&lt;br /&gt;
//Set slot 0 to 5&lt;br /&gt;
Players[0] = 5&lt;br /&gt;
//Set slot 1 to whatever is in slot 0, in this case, the number 5&lt;br /&gt;
Players[1] = Players[0]&lt;br /&gt;
//This is invalid! &lt;br /&gt;
//Although there are 32 slots, they are numbered from 0 to 31.&lt;br /&gt;
//Doing this results in AMX Native Error 4 - AMX_ERR_BOUNDS&lt;br /&gt;
// or, it simply won't compile!&lt;br /&gt;
Players[32] = 15&lt;br /&gt;
//This is also totally invalid           &lt;br /&gt;
Players[-1] = 6&lt;br /&gt;
new a = 3&lt;br /&gt;
//This is also totally invalid.  &lt;br /&gt;
//a must be a constant number, so this is valid:&lt;br /&gt;
new BadArray[a]&lt;br /&gt;
const b = 3&lt;br /&gt;
new GoodArray[b]&lt;br /&gt;
//You can also use Compiler Directives (See last section)&lt;br /&gt;
&lt;br /&gt;
#define ARRAY_SIZE 3&lt;br /&gt;
new Array[ARRAY_SIZE]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays can also be declared with groups of data default, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Numbers[4] = {0,1,2,3}&lt;br /&gt;
//Note: it is important that you make sure the amount of numbers&lt;br /&gt;
// you pass and the size of the array match&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also use any data type with arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Array of floating points:&lt;br /&gt;
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}&lt;br /&gt;
//Array of booleans.  Note this sets every slot to true.&lt;br /&gt;
new bool:playerHasGun[32] = true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
&lt;br /&gt;
You have probably noticed that an important data type is missing - characters (letters and symbols). These are called &amp;quot;strings&amp;quot;, and in Pawn, they are technically numbers! A string   is an array of numbers that translate to ASCII (character) symbols. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will declare a number array &amp;quot;myString&amp;quot; that contains the data &amp;quot;Hello&amp;quot;.  &lt;br /&gt;
//It will have 6 slots, because there are 5 characters.  &lt;br /&gt;
//The last slot is reserved for the number 0, which tells the Pawn engine that it is a string.&lt;br /&gt;
new myString[] = &amp;quot;Hello&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: anything in between /* and */ is also a comment.  You cannot use /* */ inside a /* */.  The following set of commands achieves the same purpose, however, it is longer and not recommended.  This works because each character of the string &amp;quot;Hello&amp;quot; is stored in a slot in the array.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString[0] = 'H'&lt;br /&gt;
myString[1] = 'e'&lt;br /&gt;
myString[2] = 'l'&lt;br /&gt;
myString[3] = 'l'&lt;br /&gt;
myString[4] = 'o'&lt;br /&gt;
myString[5] = 0&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{qnotice|Arrays that are meant to be strings must end in a 0, or the null character.  This is so you know where the string ends.}}&lt;br /&gt;
&lt;br /&gt;
You CANNOT do this! While it may compile, it is highly dangerous as it might cause overflow errors:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new myString[6]&lt;br /&gt;
myString = &amp;quot;Hello&amp;quot;     //INVALID!&lt;br /&gt;
myString[0] = &amp;quot;Hello&amp;quot;  //INVALID!&lt;br /&gt;
//To add data to a string, you can do this:&lt;br /&gt;
new goodString[7]&lt;br /&gt;
copy(goodString, 6, &amp;quot;Hello&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we copied 6 cells of the array into an array that can hold 7.  If we were to copy 7 bytes into this array, copy() could potentially copy an extra byte for the Null character, overflowing the array.  This is called a [[buffer overflow]] and must be carefully avoided.&lt;br /&gt;
&lt;br /&gt;
More examples:&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Copy is a function that takes three parameters:&lt;br /&gt;
copy(destination[], length, source[])&lt;br /&gt;
//It copies the string inside the source array and places &lt;br /&gt;
// it into the destination array, but only copies up to length characters.&lt;br /&gt;
&lt;br /&gt;
//Lastly, to prove that a string is really an array of numbers, this is completely valid:&lt;br /&gt;
new weird[6]&lt;br /&gt;
weird[0] = 68&lt;br /&gt;
weird[1] = 65&lt;br /&gt;
weird[2] = 73&lt;br /&gt;
weird[3] = 86&lt;br /&gt;
weird[4] = 68&lt;br /&gt;
weird[5] = 0&lt;br /&gt;
//This will set the variable &amp;quot;weird&amp;quot; to the string &amp;quot;DAVID&amp;quot;.&lt;br /&gt;
//To see how letters and symbols translate into numbers, visit www.asctiitable.com &amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
&lt;br /&gt;
Pawn allows you to define your own functions. This comes in handy for removing code that is used in multiple places. Note that all functions should return a value. To do this, you use the &amp;quot;return&amp;quot; command, which immediately halts the function and returns the value of the expression passed to it. No code is executed in a function once the return is found. Here are some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is a function that takes no parameters and returns 1.&lt;br /&gt;
//When activated, it uses the (non-existant) print function.&lt;br /&gt;
show()&lt;br /&gt;
{&lt;br /&gt;
   print(&amp;quot;Hello!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   return 1   //End, return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Activate like this:&lt;br /&gt;
show()&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also declare functions to take parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares a function called &amp;quot;add_two_numbers&amp;quot;, which takes two numbers and returns the sum.&lt;br /&gt;
add_two_numbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
   new sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum  //Return the sum&lt;br /&gt;
}&lt;br /&gt;
//Then you can use your new function like this:&lt;br /&gt;
&lt;br /&gt;
new a,b&lt;br /&gt;
a = 5&lt;br /&gt;
a = 12&lt;br /&gt;
new c = add_two_numbers(a,b)&lt;br /&gt;
//c will now be equal to 17.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are not limited by what types of data parameters can accept. When you give parameters to a function, it is called &amp;quot;passing&amp;quot;. You can pass either data or a variable to a function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This defines a new function called &amp;quot;add_two_floats&amp;quot;&lt;br /&gt;
// which takes two floating points and returns the sum&lt;br /&gt;
Float:add_two_floats(Float:first, Float:second)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = first + second&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new Float:a&lt;br /&gt;
new Float:b&lt;br /&gt;
a = 5.0&lt;br /&gt;
b = 6.3&lt;br /&gt;
new Float:c&lt;br /&gt;
c = add_two_floats( a+b )&lt;br /&gt;
//c is now equal to 11.3&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can even pass arrays!  You do not have to specify the size of the array.  If you do, you must make sure you are calling the function with an array of equal size and type.&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_numbers(first, second)   //use our function from earlier&lt;br /&gt;
  &lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, that when you pass arrays through a function they are passed through what is called &amp;quot;by reference&amp;quot;. When a normal variable is passed to a function, it is copied in memory, and the copy is sent and then deleted afterwards. This is not the case with an array. Because arrays can be very large, the array is &amp;quot;referenced&amp;quot; instead of copied. This means if you change the array, afterwards it will stay changed. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will switch slots a and b inside any array passed to this function.&lt;br /&gt;
swap_slots(array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   //Note, you need to temporarily hold one of the slots before swapping them&lt;br /&gt;
   //Otherwise, you can't swap both values! This is a classic problem.&lt;br /&gt;
   //If you have a and b, setting b equal to a eliminates the original value in b.&lt;br /&gt;
   new temp&lt;br /&gt;
             &lt;br /&gt;
   temp = array[b]&lt;br /&gt;
   array[b] = array[a]&lt;br /&gt;
   array[a] = temp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new myArray[2]&lt;br /&gt;
myArray[0] = 5&lt;br /&gt;
myArray[1] = 6&lt;br /&gt;
swap_slots(myArray, 0, 1)&lt;br /&gt;
//myArray[0] is 6, myArray[1] is 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can prevent arrays from being modified by declaring them &amp;quot;constant&amp;quot;, like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;add_two_from_array(const array[], a, b)&lt;br /&gt;
{&lt;br /&gt;
   new first = array[a]&lt;br /&gt;
   new second = array[b]&lt;br /&gt;
   new sum = add_two_from_array(first, second)&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
//Note, now when you use the function, you are guaranteed that the array will not be modified.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function modifies an array passed as a constant.  It will not work.&lt;br /&gt;
&amp;lt;pawn&amp;gt;bad_function(const array[])&lt;br /&gt;
{&lt;br /&gt;
   array[0] = 0&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
&lt;br /&gt;
Expressions are just what they sound like from mathematics. They are groupings of symbols that return one piece of data. Expressions are normally comprised of parenthetical expressions, and are evaluated in a certain order (from innermost to outermost, parenthesis first, then multiplication, division, addition, subtraction, et cetera). You can put expressions anywhere. You can set variables equal to them or pass them to functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is the simplest expression.  It returns the number zero.&lt;br /&gt;
0&lt;br /&gt;
//However, to make it easier to read, this is also valid:&lt;br /&gt;
(0)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an expression is not zero or it is not false, it not only returns a value, it also returns &amp;quot;true&amp;quot;. Otherwise, it will return 0, which is also &amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Here are more mathematical expressions.  The mathematical operators are&lt;br /&gt;
// + for addition&lt;br /&gt;
// - for subtraction&lt;br /&gt;
// * for multiplication&lt;br /&gt;
// / for division&lt;br /&gt;
// % for modulus (finding the remainder of one number divided by another (5%2 is 1)&lt;br /&gt;
(5+6)                       //returns 11&lt;br /&gt;
((5*6)+3)                   //returns 33&lt;br /&gt;
((((5+3)/2)*4)-9)           //returns 5&lt;br /&gt;
((5*6) % 7)                 //returns 2&lt;br /&gt;
//Here are other expressions:&lt;br /&gt;
(true)                      //returns true&lt;br /&gt;
(5.0 + 2.3)                 //returns 7.3 as a floating point&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also extensions of these operators for direct use on variables.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5&lt;br /&gt;
new b = 6&lt;br /&gt;
//The first are the post/pre increment and decrement operators.&lt;br /&gt;
a++          //returns a+1, or 6.  This is a post increment.&lt;br /&gt;
++a          //also returns a+1, or 6.  This is a pre increment.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference between the two is subtle but important. a++ is evaluated LAST in an expression, while ++a is evaluated FIRST. This differences comes in handy with code that uses loops in certain ways. It is also important to know that the increment/decrement operators will not only return a+1, but set the variable a to a+1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;a--          //returns 4, post decrement&lt;br /&gt;
--a          //returns 4, pre decrement&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a++ essentially trims down this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
However, there is another way to write lines of code of this form:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a OP y&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Where OP is a math operator.  It can be shortened to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a OP= x&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a += 1       //This sets a to a + 1&lt;br /&gt;
a -= b       //This sets a to a - b&lt;br /&gt;
a *= 0       //This multiplies a by 0&lt;br /&gt;
a /= 2       //This divides a by 2.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, mathematical operators are not the only operators you are given. There are boolean operators to help you with logical circuits or logical decisions.&lt;br /&gt;
&lt;br /&gt;
The and operator takes in the left expression and right expression.  If both are &amp;quot;true&amp;quot;, then it returns true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This is false, because 1 returns true and 0 returns false.  &lt;br /&gt;
//Since both are not true, &amp;amp;&amp;amp; returns false.&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0)&lt;br /&gt;
(1 &amp;amp;&amp;amp; 2)                    //Both numbers are &amp;quot;true&amp;quot;, therefore the expression is true.&lt;br /&gt;
(true &amp;amp;&amp;amp; false)             //false&lt;br /&gt;
(false &amp;amp;&amp;amp; false)            //false&lt;br /&gt;
(true &amp;amp;&amp;amp; true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other important operator is &amp;quot;or&amp;quot;.  It returns true if one of two expressions are true.&lt;br /&gt;
&amp;lt;pawn&amp;gt;(1 || 0)                    //true, since one of the values is true.&lt;br /&gt;
(1 || 2)                    //true&lt;br /&gt;
(true || true)              //true&lt;br /&gt;
(false || false)            //false&lt;br /&gt;
(true || true)              //true&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are other operators as well, that you may not use as often. The &amp;quot;bitwise and&amp;quot; operator returns whether a binary bit sequence is contained in another sequence. In the technical terms, it does an &amp;quot;and (&amp;amp;&amp;amp;)&amp;quot; operation on each of the bits in both numbers. For example, say you have the number &amp;quot;9&amp;quot;, which is &amp;quot;1001&amp;quot; in binary. If you want to know if that sequence contains the number &amp;quot;8&amp;quot; (1000), you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return 8, which means 8 is indeed a bit in 9.&lt;br /&gt;
(9 &amp;amp; 8)&lt;br /&gt;
//4 (00100) is not a bit inside 16 (10000) and this will return 0.&lt;br /&gt;
(16 &amp;amp; 4)&lt;br /&gt;
//The next operator is &amp;quot;bitwise or&amp;quot; &lt;br /&gt;
//which does an &amp;quot;or (||)' operation on each of the bits in both numbers.&lt;br /&gt;
//This will take 9 (1001) and match it with 3 (0011), resulting in 1011, or 11.&lt;br /&gt;
(9 | 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two operators are also important, but not used often. They are the bitwise shift operators, &amp;lt;&amp;lt; is a left shift and &amp;gt;&amp;gt; is a right shift. They shift the bits in a number to one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This takes the number 3 (00011) and shifts it three places to binary (11000), or 24.&lt;br /&gt;
(3 &amp;lt;&amp;lt; 3)&lt;br /&gt;
//This takes the number 24 (11000) and shifts it three places to binary (00011), or 3.&lt;br /&gt;
(24 &amp;gt;&amp;gt; 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last operator is &amp;quot;bitwise not&amp;quot;. It returns the exact opposite of whatever is given to it. When used on a number, it will return each of the bits flipped (1 to 0, 0 to 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This returns false&lt;br /&gt;
(!true)&lt;br /&gt;
//This returns true&lt;br /&gt;
(!false)&lt;br /&gt;
//This takes 9 (binary 1001) and makes it 6 (binary 0110).&lt;br /&gt;
(!(9))&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
&lt;br /&gt;
Conditionals allow you to test if an expression meets a standard, and to execute code based on that decision. &lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
&lt;br /&gt;
The most important conditional is called &amp;quot;if ... then&amp;quot;. If evaluates whether a given expression is true or false. It if is true, it executes a block of code. If not, it executes a different block of code. For example:&lt;br /&gt;
&lt;br /&gt;
This is an example of the most basic if ... then statement. The first line checks to see if the expression is true. In this case, if the variable a is equal to 5, then the if statement will execute the block of code underneath it, which sets a to 6.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   a = 6&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, what happens if a does not equal 5? Then the code will not be executed. However, you can tell it to execute code if the conditions are not met. Now, if a is equal to 5, a will be set to 6. Otherwise, it will be set to 7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (a == 5) {&lt;br /&gt;
   a = 6&lt;br /&gt;
} else {&lt;br /&gt;
   a = 7&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many different operators you can use inside the if () statement. In fact, you can use any [[#Expressions|expression]] that evaluates to true (not zero) or false (zero).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This will return true if a does not equal 5&lt;br /&gt;
if (a != 5) {}&lt;br /&gt;
//Returns true if a is greater than 5&lt;br /&gt;
if (a &amp;gt; 5) {}&lt;br /&gt;
//Returns true if a is less than 5&lt;br /&gt;
if (a &amp;lt; 5) {}&lt;br /&gt;
//Returns true if a is greater than or equal to 5&lt;br /&gt;
if (a &amp;gt;= 5) {}&lt;br /&gt;
//Returns true if a is less than or equal to 5&lt;br /&gt;
if (a &amp;lt;= 5) {}&lt;br /&gt;
//Returns true because 11 is true&lt;br /&gt;
if (5+6) {}&lt;br /&gt;
//Returns true of both a and b are true&lt;br /&gt;
if (a &amp;amp;&amp;amp; b) {}&lt;br /&gt;
//Returns true if 7.5 is greater than c&lt;br /&gt;
if ( ((5*3)/2) &amp;gt; c) {}&lt;br /&gt;
//Always returns true no matter what&lt;br /&gt;
if (true) {}&lt;br /&gt;
//Never returns true&lt;br /&gt;
if (false) {}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that array comparisons have restrictions. This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;my arrayOne[3]&lt;br /&gt;
my arrayTwo[3]&lt;br /&gt;
if (arrayOne == arrayTwo) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You must do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if ((arrayOne[0] == arrayTwo[0]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[1] == arrayTwo[1]) &amp;amp;&amp;amp; &lt;br /&gt;
    (arrayOne[2] == arrayTwo[2])) {&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this would get very tedious with large arrays. You will see later on how to easily compare strings and arrays.&lt;br /&gt;
&lt;br /&gt;
The if...then model of conditional switching can be brought up to another level. Pawn provides a way for you to provide multiple levels of true and false expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of &amp;quot;if...else if&amp;quot;&lt;br /&gt;
if (a == 5) {&lt;br /&gt;
   //This code will be run if a is 5.&lt;br /&gt;
} else if (a &amp;lt; 6) {&lt;br /&gt;
   //This code will be run if a is less than 6&lt;br /&gt;
} else if (a == 7) {&lt;br /&gt;
   //This code will be run if a is 7.&lt;br /&gt;
} else {&lt;br /&gt;
   //If none of the above conditions are met, this code will be run.&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is important to note that in the above example, each code block is not &amp;quot;fall through&amp;quot;. That means each of the conditions will be checked in order, and if one is true, the code will be executed and the if statement is done. It will not execute multiple true conditions.&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
&lt;br /&gt;
Lastly, there is one last type of conditional statement. It is called a &amp;quot;switch&amp;quot; statement, and it allows you to make a nicely ordered list of conditions similar to, but not as powerful as, &amp;quot;if...else if&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Example of a switch statement&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
    case 5:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 5&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    case 6:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 6&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    case 7:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if a is equal to 7&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
    {&lt;br /&gt;
       //This code will run if all other cases fail&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Note that a switch is not &amp;quot;fall-through&amp;quot;. If a case is true, no other cases are evaluated. &lt;br /&gt;
&lt;br /&gt;
=Looping=&lt;br /&gt;
&lt;br /&gt;
Looping is essential for any language. It allows you to perform the same block of code over and over, by constructing conditions on which code should be repeated.&lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
&lt;br /&gt;
The first and most widely used loop is called a &amp;quot;for loop&amp;quot;. It takes an initial value, a condition upon which it should stop, and an incremental step. Then it executes code until it the conditions are no longer true. This lets you repeat the same block of code any number of times. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;/*A for loop has three parameters:&lt;br /&gt;
  for (initial; condition; increment)&lt;br /&gt;
  {&lt;br /&gt;
    //your code here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Before the first loop executes, it runs your initial condition.&lt;br /&gt;
  Then it begins looping your code with these steps:&lt;br /&gt;
  1.  Check if the condition is true.  If so, continue.  If not, stop.&lt;br /&gt;
  2.  Run the code.&lt;br /&gt;
  3.  Run the &amp;quot;increment&amp;quot; parameter.&lt;br /&gt;
  4.  Go to step 1.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
//Example of a for loop&lt;br /&gt;
new i&lt;br /&gt;
new sum&lt;br /&gt;
for (i=1; i&amp;lt;=10; i++)&lt;br /&gt;
{&lt;br /&gt;
   sum += i&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
#The first parameter, i=1, sets the i variable to one. This happens before the looping starts.&lt;br /&gt;
#Next, the &amp;quot;increment&amp;quot; parameter is checked. This parameter is a post-increment operator, so 1 will be added to i after the entire code block is evaluated.&lt;br /&gt;
#Then the condition is checked. Is i&amp;lt;=10? It is currently 1, so it is indeed less than or equal to 10.&lt;br /&gt;
#Since the condition is true, sum+=i is executed. This means i is added into sum.&lt;br /&gt;
#The code block has finished, and i++ increments i to 2.&lt;br /&gt;
#Now it repeats.&lt;br /&gt;
#Is i&amp;lt;=10? Yes, it is 2. Now sum+=i runs again, and now sum is equal to 3.&lt;br /&gt;
#The code block has finished, and i now increments to 3.&lt;br /&gt;
#This happens until...&lt;br /&gt;
#The increment parameter sets i to 11. The condition is no longer true, and the for loop is finished.&lt;br /&gt;
#The sum variable now holds the number 55, which is the sum of 1 through 10.&lt;br /&gt;
&lt;br /&gt;
This provides a nice way of managing arrays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Note: this provides a nice way to loop through arrays!  Observe this function below.&lt;br /&gt;
sum_of_array(myArray[], size)&lt;br /&gt;
{&lt;br /&gt;
   //Note: Make sure the user passes the size of the array, so we don't overflow it.&lt;br /&gt;
   new i, sum&lt;br /&gt;
  &lt;br /&gt;
   //This loop will start at 0 and stop right before size is reached.&lt;br /&gt;
   //If the user passes the correct size of the array, &lt;br /&gt;
   // the loop will be going from 0 to size-1&lt;br /&gt;
   // This correctly matches the numbers of slots in the array.&lt;br /&gt;
   for  (i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      //For every time this loop executes, &lt;br /&gt;
      // i will be a number from 0 to size-1&lt;br /&gt;
      //Add the value of the slot (i) in the array to sum.&lt;br /&gt;
      //Once this is finished, sum will contain &lt;br /&gt;
      // the sum of all slots in the array.&lt;br /&gt;
      sum += myArray[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
new NumberArray[4]&lt;br /&gt;
NumberArray[0] = 3&lt;br /&gt;
NumberArray[1] = 1&lt;br /&gt;
NumberArray[2] = 4&lt;br /&gt;
NumberArray[3] = 1&lt;br /&gt;
&lt;br /&gt;
new answer = sum_of_array(NumberArray, 4)&lt;br /&gt;
//answer will be 3+1+4+1, or 9&lt;br /&gt;
&lt;br /&gt;
//Here is a function to compare if one array is equal to another (i.e. a string)&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   for (i=0; i&amp;lt;size, i++)&lt;br /&gt;
   {&lt;br /&gt;
      //If a slot does not match, halt the function and return false.&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   //If the function got to this point without returning false, return true.&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
&lt;br /&gt;
The next kind of loop is also very important, and is simpler than a for loop. Called a &amp;quot;while&amp;quot; loop, it only takes one parameter: a condition. As long as the condition is true, it keeps executing code. See the above examples rewritten with while loops.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//Basic loop&lt;br /&gt;
new i=0&lt;br /&gt;
new sum&lt;br /&gt;
&lt;br /&gt;
while (++i &amp;lt;= 10)&lt;br /&gt;
{&lt;br /&gt;
   sum+=i&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sum_of_array(array[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i=0, sum&lt;br /&gt;
&lt;br /&gt;
   //Do this loop while i is less than the size.&lt;br /&gt;
   //i is incremented at the end of every loop.&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      sum += array[i]&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool:compare_arrays(array1[], array2[], size)&lt;br /&gt;
{&lt;br /&gt;
   new i&lt;br /&gt;
   while (i++ &amp;lt; size)&lt;br /&gt;
   {&lt;br /&gt;
      if (array1[i] != array2[i])&lt;br /&gt;
      {&lt;br /&gt;
         return false&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return true&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Two Dimensional Arrays==&lt;br /&gt;
&lt;br /&gt;
In Pawn it is possible to have arrays where each slot is another array. This is very useful for storing a table of data, where the first section of slots is a row and the second section of slots is a column. Two dimensional arrays are declared like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This declares an array with 50 rows and 50 columns.&lt;br /&gt;
new BigArray[50][50]&lt;br /&gt;
//this declares a floating point array with 25 rows and 10 columns.&lt;br /&gt;
new Float:BigArray[25][10]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slot in the first subset of the array becomes its own array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new BigArray[3][3]&lt;br /&gt;
BigArray[0][0] = 10&lt;br /&gt;
BigArray[0][1] = 20&lt;br /&gt;
BigArray[0][2] = 30&lt;br /&gt;
BigArray[1][0] = 40&lt;br /&gt;
BigArray[1][1] = 50&lt;br /&gt;
BigArray[1][2] = 60&lt;br /&gt;
BigArray[2][0] = 70&lt;br /&gt;
BigArray[2][1] = 80&lt;br /&gt;
BigArray[2][2] = 90&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will result in BigArray looking like this:&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
| BigArray&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 10&lt;br /&gt;
| 20&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 40&lt;br /&gt;
| 50&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 70&lt;br /&gt;
| 80&lt;br /&gt;
| 90&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that our old sum_of_array() function can still work! We can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = sum_of_array(BigArray[2], 3)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because BigArray[2] contains a second, single dimensional array, containing {7,8,9}. However, let's write a 2D sum of array function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//This function will tally up a two dimensional array.&lt;br /&gt;
sum_of_table(array[][], rows, cols)&lt;br /&gt;
{&lt;br /&gt;
   new i, j, sum&lt;br /&gt;
&lt;br /&gt;
   //Note, there is a loop inside the loop.  &lt;br /&gt;
   //This lets you go through each array inside the   &lt;br /&gt;
   // bigger array. &lt;br /&gt;
   for (i=0; i&amp;lt;rows; i++)&lt;br /&gt;
   {&lt;br /&gt;
      for (j=0; j&amp;lt;cols; j++)&lt;br /&gt;
      {&lt;br /&gt;
         sum += array[i][j]&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, it is also possible to store an array of strings using two dimensional arrays.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new StringList[3][] = {&amp;quot;Hello&amp;quot;, &amp;quot;my&amp;quot;, &amp;quot;friend&amp;quot;}&lt;br /&gt;
/*&lt;br /&gt;
  StringList[0][0] through [0][5] contains &amp;quot;Hello&amp;quot;&lt;br /&gt;
  StringList[1][0] through [1][2] contains &amp;quot;my&amp;quot;&lt;br /&gt;
  StringList[2][0] through [1][6] contains &amp;quot;friend&amp;quot;&lt;br /&gt;
*/&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table for StringList will look like:&lt;br /&gt;
StringList 	0 	1 	2 	3 	4 	5 	6&lt;br /&gt;
0 	H 	e 	l 	l 	o 	\0 	&lt;br /&gt;
1 	m 	y 	\0 				&lt;br /&gt;
2 	f 	r 	i 	e 	n 	d 	\0&lt;br /&gt;
&lt;br /&gt;
Comparing strings in multidimensional arrays is also similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (StringList[0] == &amp;quot;Hello&amp;quot;)       //INVALID&lt;br /&gt;
if (StringList[0][0] == &amp;quot;Hello&amp;quot;)    //INVALID&lt;br /&gt;
if (equali(StringList[0], &amp;quot;Hello&amp;quot;)) //Valid&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compiler Pre-processor Directives=&lt;br /&gt;
&lt;br /&gt;
Compiler directives allow you to change how your code is read. This is rather advanced and will only be run over briefly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//To bind a symbol to a value, you can do this:&lt;br /&gt;
#define SYMBOL VALUE&lt;br /&gt;
//for example:&lt;br /&gt;
&lt;br /&gt;
#define MAX_STRING 250&lt;br /&gt;
new String[MAX_STRING]&lt;br /&gt;
&lt;br /&gt;
#define HELLO &amp;quot;Hello.  This is a generic greeting.&amp;quot;&lt;br /&gt;
new Hello[MAX_STRING] = {HELLO}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use #defines to change the flow of code the compiler makes.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#if defined LINUX&lt;br /&gt;
   //This portion will be compiled if #define LINUX exists&lt;br /&gt;
   execute_command(&amp;quot;ls -l&amp;quot;)&lt;br /&gt;
#else&lt;br /&gt;
   //This portion will be compiled if #define LINUX does not exist&lt;br /&gt;
   execute_command(&amp;quot;dir&amp;quot;)&lt;br /&gt;
#endif&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also change how much memory your script uses.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma dynamic 4096&lt;br /&gt;
//This creates a 16K stack of memory (default).&lt;br /&gt;
//It is measured in blocks of 4 byte cells.&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also specify whether semicolon usage is required to terminate a line of code (by default it is not required). &lt;br /&gt;
&amp;lt;pawn&amp;gt;#pragma semicolon 1&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
&lt;br /&gt;
This guide should have given you a VERY brief introduction to basic Pawn programming. It is by no means comprehensive and it should not constitute the entirety of one's knowledge of Pawn. To read the official Small documentation and language guide, go this website: http://www.compuphase.com/pawn/pawn-lang.pdf (Note, this guide is very long and should be used as a reference. You may want to try the Small forums or the AMX Mod X forums). Continue to the next Section to see how to apply Small programming to the Half-Life and AMX Mod X engine!&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn-lang.pdf Pawn Language Reference]&lt;br /&gt;
*[http://www.compuphase.com/pawn/pawn.htm Pawn Homepage]&lt;br /&gt;
*[http://www.compuphase.com/ ITB CompuPhase]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>Greenberet</name></author>
		
	</entry>
</feed>