<?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=Asherkin</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=Asherkin"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Asherkin"/>
	<updated>2026-05-07T18:05:03Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Function_Calling_API_(SourceMod_Scripting)&amp;diff=11265</id>
		<title>Function Calling API (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Function_Calling_API_(SourceMod_Scripting)&amp;diff=11265"/>
		<updated>2022-01-06T11:45:11Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Correct void forward event type&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod provides plugins with an API for calling functions.  This API can be used to call public functions in any plugin, including public functions in the same plugin.  &lt;br /&gt;
&lt;br /&gt;
This article is split into two sections.  The first is on generic function calling, which is used for single function calls.  The second is on Forwards, which is used for calling multiple functions in one operation.&lt;br /&gt;
&lt;br /&gt;
For more information on forwards, readers should see [[Writing_Extensions#Creating_Events.2FForwards|forwards in extensions]].&lt;br /&gt;
&lt;br /&gt;
=Generic Calling=&lt;br /&gt;
There are four steps to calling a function in a plugin:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;Obtaining a &amp;quot;call Handle.&amp;quot;  This is either in the form of a function ID, tagged with &amp;lt;tt&amp;gt;Function&amp;lt;/tt&amp;gt;, or a Forward Handle, tagged with &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;Starting the call.&lt;br /&gt;
 &amp;lt;li&amp;gt;Pushing parameters in increasing order in a way that matches the function prototype.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;Ending the the call, which performs the call operation and returns the result.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For simplicity, let's consider calling a function in our own plugin.  We have the following function:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;public void OnClientDied(int attacker, int victim, const char[] weapon, bool headshot)&lt;br /&gt;
{&lt;br /&gt;
    char name[MAX_NAME_LENGTH];&lt;br /&gt;
    GetClientName(victim, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
    if (attacker != victim)&lt;br /&gt;
    {&lt;br /&gt;
        char other[MAX_NAME_LENGTH];&lt;br /&gt;
        GetClientName(attacker, other, sizeof(other));&lt;br /&gt;
        PrintToServer(&amp;quot;&amp;lt;\&amp;quot;%s\&amp;quot;&amp;gt; killed by &amp;lt;\&amp;quot;%s\&amp;quot;&amp;gt; with \&amp;quot;%s\&amp;quot; (headshot: %d)&amp;quot;, name, other, weapon, headshot);&lt;br /&gt;
    }&lt;br /&gt;
    else if (!attacker)&lt;br /&gt;
    {&lt;br /&gt;
        PrintToServer(&amp;quot;&amp;lt;\&amp;quot;%s\&amp;quot;&amp;gt; killed by \&amp;quot;world\&amp;quot; with \&amp;quot;%s\&amp;quot; (headshot: %d)&amp;quot;, name, weapon, headshot);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        PrintToServer(&amp;quot;&amp;lt;\&amp;quot;%s\&amp;quot;&amp;gt; killed by \&amp;quot;self\&amp;quot; with \&amp;quot;%s\&amp;quot; (headshot: %d)&amp;quot;, name, weapon, headshot);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An indirect way to call this function would be:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
public void EventHandler(Event event, const char[] name, bool dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
    if (StrEqual(name, &amp;quot;player_death&amp;quot;))&lt;br /&gt;
    {&lt;br /&gt;
        char weapon[64];&lt;br /&gt;
        int result;&lt;br /&gt;
&lt;br /&gt;
        event.GetString(&amp;quot;weapon&amp;quot;, weapon, sizeof(weapon));&lt;br /&gt;
&lt;br /&gt;
        /* Start function call */&lt;br /&gt;
        Call_StartFunction(null, OnClientDied);&lt;br /&gt;
&lt;br /&gt;
        /* Push parameters one at a time */&lt;br /&gt;
        Call_PushCell(GetClientOfUserId(event.GetInt(&amp;quot;attacker&amp;quot;)));&lt;br /&gt;
        Call_PushCell(GetClientOfUserId(event.GetInt(&amp;quot;userid&amp;quot;)));&lt;br /&gt;
        Call_PushString(weapon);&lt;br /&gt;
        Call_PushCell(event.GetInt(&amp;quot;headshot&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
        /* Finish the call, get the result */&lt;br /&gt;
        Call_Finish(result);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This basic example shows starting and completing a function call.  However, the real use of function calling is with forwards, which is covered in the next section.&lt;br /&gt;
&lt;br /&gt;
=Forwards=&lt;br /&gt;
Forwards are much more advantageous over single function calls.  They are expandable containers, so you can store and complete many calls with very little action.  Furthermore, they also adjust themselves when contained plugins are unloaded.  Lastly, they are type-checked; each forward's parameter types must be known in advance, and if you push a mismatching type, the call will not complete.&lt;br /&gt;
&lt;br /&gt;
Forwards must be created using the following types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_Any&amp;lt;/tt&amp;gt; - Any parameter type can be pushed&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_Cell&amp;lt;/tt&amp;gt; - A non-Float cell can be pushed&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_Float&amp;lt;/tt&amp;gt; - A Float cell can be pushed&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_String&amp;lt;/tt&amp;gt; - A string can be pushed&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_Array&amp;lt;/tt&amp;gt; - An array can be pushed&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_VarArgs&amp;lt;/tt&amp;gt; - This and all further parameters can be any type, but will be by reference.  This cannot be the first parameter type, and if it is used, it must be the last parameter type.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_CellByRef&amp;lt;/tt&amp;gt; - A non-Float cell by reference&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_FloatByRef&amp;lt;/tt&amp;gt; - A Float cell by reference&lt;br /&gt;
&lt;br /&gt;
Strings and arrays are implicitly by-reference.  When pushing variable argument parameters, if anything is pushed by-value, it will be internally automatically converted to by-reference.&lt;br /&gt;
&lt;br /&gt;
Since Forwards will call multiple functions in a row, it needs to know how to interpret the return values of functions.  There are four predefined methods:&lt;br /&gt;
*&amp;lt;tt&amp;gt;ET_Ignore&amp;lt;/tt&amp;gt; - All return values will be ignored; 0 will be returned at the end.&lt;br /&gt;
*&amp;lt;tt&amp;gt;ET_Single&amp;lt;/tt&amp;gt; - Only the last return value will be returned.&lt;br /&gt;
*&amp;lt;tt&amp;gt;ET_Event&amp;lt;/tt&amp;gt; - Function should return an &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; value (&amp;lt;tt&amp;gt;core.inc&amp;lt;/tt&amp;gt;).  &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; acts as &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;.  The highest value is returned.&lt;br /&gt;
*&amp;lt;tt&amp;gt;ET_Hook&amp;lt;/tt&amp;gt; - Function should return an &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; value.  &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; ends the forward call immediately.&lt;br /&gt;
&lt;br /&gt;
Let's write a simple example.  Our plugin, Plugin A, wants to tell other plugins when a player dies.  It has two ways of doing this, either via a ''global'' forward or a ''private'' forward.  A global forward acts upon all functions in all plugins that match a single name.  A private forward lets you explicitly manage which functions are in the container.&lt;br /&gt;
&lt;br /&gt;
==Global Forwards==&lt;br /&gt;
Global forwards are very simple to use.  After creation, they do not need to be maintained.  An example plugin below creates a global forward with the following prototype:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;forward void OnClientDied(int attacker, int victim, const char[] weapon, bool headshot);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Implementation:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;GlobalForward g_DeathForward;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    g_DeathForward = new GlobalForward(&amp;quot;OnClientDied&amp;quot;, ET_Ignore, Param_Cell, Param_Cell, Param_String, Param_Cell);&lt;br /&gt;
    HookEvent(&amp;quot;player_death&amp;quot;, EventHandler);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public APLRes AskPluginLoad2(Handle plugin, bool late, char[] error, int err_max)&lt;br /&gt;
{&lt;br /&gt;
    RegPluginLibrary(&amp;quot;my_plugin&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action EventHandler(Event event, const char[] name, bool dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
    char weapon[64];&lt;br /&gt;
    event.GetString(&amp;quot;weapon&amp;quot;, weapon, sizeof(weapon));&lt;br /&gt;
&lt;br /&gt;
    /* Start function call */&lt;br /&gt;
    Call_StartForward(g_DeathForward);&lt;br /&gt;
&lt;br /&gt;
    /* Push parameters one at a time */&lt;br /&gt;
    Call_PushCell(GetClientOfUserId(event.GetInt(&amp;quot;attacker&amp;quot;)));&lt;br /&gt;
    Call_PushCell(GetClientOfUserId(event.GetInt(&amp;quot;userid&amp;quot;)));&lt;br /&gt;
    Call_PushString(weapon);&lt;br /&gt;
    Call_PushCell(GetEventInt(event, &amp;quot;headshot&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
    /* Finish the call */&lt;br /&gt;
    Call_Finish();&lt;br /&gt;
&lt;br /&gt;
    return result;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Private Forwards==&lt;br /&gt;
Private forwards require you to manually add functions to its container.  This can leave you with much more flexibility.  Like global forwards, they automatically remove functions from unloaded plugins.  &lt;br /&gt;
&lt;br /&gt;
Usually, this is done using dynamic natives; a plugin will expose a function to add to its own forwards.  For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;typedef OnClientDiedFunc = function Action (int attacker, int victim, const char[] weapon, bool headshot);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Calls the target function when a client dies.&lt;br /&gt;
 *&lt;br /&gt;
 * @param func      OnClientDiedFunc function.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native void HookClientDeath(OnClientDiedFunc func);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this might look like:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;PrivateForward g_DeathForward;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    g_DeathForward = new PrivateForward(ET_Ignore, Param_Cell, Param_Cell, Param_String, Param_Cell);&lt;br /&gt;
&lt;br /&gt;
    CreateNative(&amp;quot;HookClientDeath&amp;quot;, Native_HookClientDeath);&lt;br /&gt;
&lt;br /&gt;
    HookEvent(&amp;quot;player_death&amp;quot;, EventHandler);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int Native_HookClientDeath(Handle plugin, int numParams)&lt;br /&gt;
{&lt;br /&gt;
    g_DeathForward.AddFunction(plugin, GetNativeFunction(1));&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the code to call the forward does not need to change at all.&lt;br /&gt;
&lt;br /&gt;
A complete implementation of a private forward may look like this:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;typedef MyFunction = function void (int client);&lt;br /&gt;
native void My_NativeEx(MyFunction func);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;PrivateForward g_hDeathFwd;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// typedef MyFunction = function void (int client);&lt;br /&gt;
// native void My_NativeEx(MyFunction func);&lt;br /&gt;
public APLRes AskPluginLoad2(Handle plugin, bool late, char[] error, int err_max)&lt;br /&gt;
{&lt;br /&gt;
    RegPluginLibrary(&amp;quot;MyPlugin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    CreateNative(&amp;quot;My_NativeEx&amp;quot;, My_Native);&lt;br /&gt;
&lt;br /&gt;
    return APLRes_Success;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    HookEvent(&amp;quot;player_death&amp;quot;, Event_Death);&lt;br /&gt;
    g_hDeathFwd = new PrivateForward(ET_Ignore, Param_Cell);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int My_Native(Handle plugin, int numParams)&lt;br /&gt;
{&lt;br /&gt;
    g_hDeathFwd.AddFunction(plugin, GetNativeFunction(1));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Event_Death(Event event, const char[] name, bool dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
    int client = GetClientOfUserId(event.GetInt(&amp;quot;userid&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
    Call_StartForward(g_hDeathFwd);&lt;br /&gt;
    Call_PushCell(client);&lt;br /&gt;
    Call_Finish();&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=11245</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=11245"/>
		<updated>2021-10-07T23:22:17Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: No such thing as an unsigned left shift&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has four types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
char key = 'A';&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
int autoNum[3] = {1, ...};              // Stores 1, 1, 1&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Enums=&lt;br /&gt;
Enums are retyped integers.  A new enum can be declared as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;enum MyEnum // the name is optional&lt;br /&gt;
{&lt;br /&gt;
  MyFirstValue, // == 0, if not explicitly assigned, the first value is zero&lt;br /&gt;
  MySecondValue, // == 1, implicitly set to the previous value plus one&lt;br /&gt;
  MyThirdValue = 1, // == 1, explicitly assign to one -- multiple names can share the same value&lt;br /&gt;
  MyFourthValue, // == 2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To allow implicit conversions of enums back to integers (that is, so functions expecting a value of type 'int' accepts it as one instead of generating a warning), the enum must either be anonymous (unnamed) or must start with a lowercase character.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Concatenation==&lt;br /&gt;
In programming, concatenation is the operation of joining character strings end-to-end. The benefit of this is to improve the readability of the source code for humans, since the compiler will continue to treat the strings as a single string. String literals can be concatenated with the &amp;lt;tt&amp;gt;...&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt; operator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char text[] = &amp;quot;This is a really long string of text that should be split over multiple lines for the sake of readability.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
char text[] = &amp;quot;This is a really long string of text that should be &amp;quot;&lt;br /&gt;
	... &amp;quot;split over multiple lines for the sake of readability.&amp;quot;; // Valid.&lt;br /&gt;
&lt;br /&gt;
char text[] = &amp;quot;This is a really long string of text that should be \&lt;br /&gt;
	split over multiple lines for the sake of readability.&amp;quot;; // Valid.&lt;br /&gt;
&lt;br /&gt;
char prefix[] = &amp;quot;What you can't do, however, &amp;quot;;&lt;br /&gt;
char moreText[] = prefix ... &amp;quot;is concatenate using a non-literal string.&amp;quot;; // Invalid, not a constant expression.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
void ChangeValue(int b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;native float FloatRound(float num);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;example[2] = 29;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;void CantChangeArray(const int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
When a function takes an array as a parameter, you can also pass any indexed array element which will be interpreted as a sub-array (slice) that begins from that index. For example,&lt;br /&gt;
if you want to get the length of a string, you can use the strlen function like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char myString[] = &amp;quot;myString&amp;quot;;&lt;br /&gt;
int length = strlen(myString); // Set length = 8&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And if you pass an indexed array element, it will be interpreted as a slice that begins from that index like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char myString[] = &amp;quot;myString&amp;quot;;&lt;br /&gt;
int length = strlen(myString[2]); // Set length = 6&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Named Parameters==&lt;br /&gt;
With functions that have many parameters with default values, you can call the function with named parameters to assign a value based on its name instead of which position it is in the argument list.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
void SomeFunctionWithDefaultParams(int a, int b = 1, int c = 2, int d = 3, int e = 4);&lt;br /&gt;
&lt;br /&gt;
// If you want to call it with a different value for `d` -- note the dotted argument assignment&lt;br /&gt;
SomeFunctionWithDefaultParams(0, .d = 14);&lt;br /&gt;
&lt;br /&gt;
// This is effectively the same, but less readable:&lt;br /&gt;
SomeFunctionWithDefaultParams(0, _, _, 14, _);&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;, &amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int[] array, int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int SumArray(const int[] array, int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int[] array, int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int[] array, int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      int B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;void Function1(int size)&lt;br /&gt;
{&lt;br /&gt;
   int[] array = new int[size];&lt;br /&gt;
 &lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;int float or char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   static int counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static int counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=11202</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=11202"/>
		<updated>2021-07-19T21:19:03Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &amp;quot;sub-arrays&amp;quot; are formally known as slices&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
char key = 'A';&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Enums=&lt;br /&gt;
Enums are retyped integers.  A new enum can be declared as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;enum MyEnum // the name is optional&lt;br /&gt;
{&lt;br /&gt;
  MyFirstValue, // == 0, if not explicitly assigned, the first value is zero&lt;br /&gt;
  MySecondValue, // == 1, implicitly set to the previous value plus one&lt;br /&gt;
  MyThirdValue = 1, // == 1, explicitly assign to one -- multiple names can share the same value&lt;br /&gt;
  MyFourthValue, // == 2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To allow implicit conversions of enums back to integers (that is, so functions expecting a value of type 'int' accepts it as one instead of generating a warning), the enum must either be anonymous (unnamed) or must start with a lowercase character.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Concatenation==&lt;br /&gt;
In programming, concatenation is the operation of joining character strings end-to-end. The benefit of this is to improve the readability of the source code for humans, since the compiler will continue to treat the strings as a single string. String literals can be concatenated with the &amp;lt;tt&amp;gt;...&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt; operator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char text[] = &amp;quot;This is a really long string of text that should be split over multiple lines for the sake of readability.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
char text[] = &amp;quot;This is a really long string of text that should be &amp;quot;&lt;br /&gt;
	... &amp;quot;split over multiple lines for the sake of readability.&amp;quot;; // Valid.&lt;br /&gt;
&lt;br /&gt;
char text[] = &amp;quot;This is a really long string of text that should be \&lt;br /&gt;
	split over multiple lines for the sake of readability.&amp;quot;; // Valid.&lt;br /&gt;
&lt;br /&gt;
char prefix[] = &amp;quot;What you can't do, however, &amp;quot;;&lt;br /&gt;
char moreText[] = prefix ... &amp;quot;is concatenate using a non-literal string.&amp;quot;; // Invalid, not a constant expression.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
void ChangeValue(int b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;native float FloatRound(float num);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;example[2] = 29;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;void CantChangeArray(const int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
When a function takes an array as a parameter, you can also pass any indexed array element which will be interpreted as a sub-array (slice) that begins from that index. For example,&lt;br /&gt;
if you want to get the length of a string, you can use the strlen function like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char myString[] = &amp;quot;myString&amp;quot;;&lt;br /&gt;
int length = strlen(myString); // Set length = 8&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And if you pass an indexed array element, it will be interpreted as a slice that begins from that index like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
char myString[] = &amp;quot;myString&amp;quot;;&lt;br /&gt;
int length = strlen(myString[2]); // Set length = 6&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Named Parameters==&lt;br /&gt;
With functions that have many parameters with default values, you can call the function with named parameters to assign a value based on its name instead of which position it is in the argument list.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
void SomeFunctionWithDefaultParams(int a, int b = 1, int c = 2, int d = 3, int e = 4);&lt;br /&gt;
&lt;br /&gt;
// If you want to call it with a different value for `d` -- note the dotted argument assignment&lt;br /&gt;
SomeFunctionWithDefaultParams(0, .d = 14);&lt;br /&gt;
&lt;br /&gt;
// This is effectively the same, but less readable:&lt;br /&gt;
SomeFunctionWithDefaultParams(0, _, _, 14, _);&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int[] array, int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int SumArray(const int[] array, int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int[] array, int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int[] array, int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      int B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;void Function1(int size)&lt;br /&gt;
{&lt;br /&gt;
   int[] array = new int[size];&lt;br /&gt;
 &lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;int float or char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   static int counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static int counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Writing_Extensions&amp;diff=11193</id>
		<title>Writing Extensions</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Writing_Extensions&amp;diff=11193"/>
		<updated>2021-05-22T17:00:33Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod's Extension System is a powerful way to greatly enhance the flexibility of your SourceMod plugins.  You can take full advantage of SourceMod's Core, using the interfaces it provides, to create C++ plugins, plugin events, plugin native functions, and shared interfaces.  Extensions can also hook into Metamod:Source.&lt;br /&gt;
&lt;br /&gt;
This article goes into the details of creating a SourceMod Extension.  Knowledge of C++ is required.&lt;br /&gt;
&lt;br /&gt;
=SDK Structure=&lt;br /&gt;
First, download the [[SourceMod SDK]] from the [https://github.com/alliedmodders/sourcemod SourceMod github], and one of the SDKs from the [https://github.com/alliedmodders/hl2sdk hl2sdk github].&lt;br /&gt;
&lt;br /&gt;
There are some scripts in the SourceMod repo to easily download all the dependencies, see the info at [[Building_SourceMod#Downloading_Source_and_Dependencies]].&lt;br /&gt;
&lt;br /&gt;
The directory structure should contain these folders:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
* hl2sdk-something - One of the HL2 SDKs&lt;br /&gt;
* sourcemod-version - The sourcemod package&lt;br /&gt;
** extensions - Sourcemod Extensions code&lt;br /&gt;
*** curl - Source code to the cURL extension&lt;br /&gt;
*** geoip - Source code to the GeoIP extension&lt;br /&gt;
*** mysql - Source code to the MySQL extension&lt;br /&gt;
** plugins - Source code to all of SourceMod's plugins&lt;br /&gt;
*** include - The include files which document plugin API&lt;br /&gt;
** public - Interface files for SourceMod's Core Interfaces&lt;br /&gt;
*** extensions  - Interfaces that are provided by extensions&lt;br /&gt;
*** '''sample_ext''' - The Sample Extension SDK&lt;br /&gt;
**** extension.cpp - Sample C++ plugin&lt;br /&gt;
**** extension.h - Sample C++ header file&lt;br /&gt;
**** Makefile - Sample C++ plugin compiler&lt;br /&gt;
**** smsdk_config.h - Sample C++ plugin settings&lt;br /&gt;
** sourcepawn - The include/interface files for SourcePawn&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Starting an Extension=&lt;br /&gt;
For simplicity, this article will assume you are using the SDK base files. Navigate to &amp;lt;code&amp;gt;extensions/public/sample_ext&amp;lt;/code&amp;gt;, and ensure that you can compile your code. If using the command line, &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; should do this, if using Visual Studio, see [[#Setting up Visual Studio|Setting up Visual Studio]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step of creating your extension is to configure it.  Open the &amp;lt;tt&amp;gt;smsdk_config.h&amp;lt;/tt&amp;gt; file and edit each of the following defines.  Use the information below to guide you.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
*SMEXT_CONF_NAME - The general name for your Extension (should be short).&lt;br /&gt;
*SMEXT_CONF_DESCRIPTION - A short description of what your extension does.&lt;br /&gt;
*SMEXT_CONF_VERSION - A version number string.  By convention, SourceMod uses the four set build number notation, so build 1.2.3.4 means:&lt;br /&gt;
**1 is the &amp;quot;Major&amp;quot; release version.&lt;br /&gt;
**2 is the &amp;quot;Minor&amp;quot; release version.&lt;br /&gt;
**3 is the &amp;quot;Maintenance&amp;quot; or &amp;quot;Revision&amp;quot; version.&lt;br /&gt;
**4 is the &amp;quot;Build,&amp;quot; usually an internal source control number.&lt;br /&gt;
*SMEXT_CONF_AUTHOR - Your name (or whoever/whatever authored the plugin).&lt;br /&gt;
*SMEXT_CONF_URL - The URL/homepage of this extension.&lt;br /&gt;
*SMEXT_CONF_LOGTAG - The logtag your extension will use for SourceMod logging.  By convention, try to keep this under ten characters or so, and to make it all caps.&lt;br /&gt;
*SMEXT_CONF_LICENSE - Right now, the SourceMod Dev Team mandates that 3rd party extensions must be under an Open Source license.  Putting a license abbreviation or very short message here is appropriate.  For more information, see [https://www.sourcemod.net/license.php the SourceMod license].&lt;br /&gt;
*SMEXT_CONF_DATESTRING - You do not need to modify this.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
If your plugin requires using SourceHook or Metamod:Source, uncomment this line:&lt;br /&gt;
&amp;lt;code&amp;gt;#define SMEXT_CONF_METAMOD&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next, you should change the name of your extension. By convention, your extension's class name should start with a capital letter.&lt;br /&gt;
* First, open &amp;lt;code&amp;gt;extension.h&amp;lt;/code&amp;gt; and change &amp;quot;Sample&amp;quot; in this line:&lt;br /&gt;
&amp;lt;cpp&amp;gt;class Sample : public SDKExtension&amp;lt;/cpp&amp;gt;&lt;br /&gt;
* Next, open &amp;lt;code&amp;gt;extension.cpp&amp;lt;/code&amp;gt; change these two lines:&lt;br /&gt;
&amp;lt;cpp&amp;gt;Sample g_Sample;&lt;br /&gt;
SMEXT_LINK(&amp;amp;g_Sample);&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Visual Studio Users==&lt;br /&gt;
Make sure you change the name of your &amp;lt;tt&amp;gt;.dll&amp;lt;/tt&amp;gt; file.  The naming convention for SourceMod extensions is &amp;lt;tt&amp;gt;name.ext.dll&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; is a short name for your extension.  You are free to change this, but it is highly recommended that you keep the &amp;lt;tt&amp;gt;.ext.dll&amp;lt;/tt&amp;gt; intact.&lt;br /&gt;
&lt;br /&gt;
You can do this by going to &amp;lt;tt&amp;gt;Project&amp;lt;/tt&amp;gt; -&amp;gt; &amp;lt;tt&amp;gt;Properties&amp;lt;/tt&amp;gt; -&amp;gt; &amp;lt;tt&amp;gt;Configuration Properties&amp;lt;/tt&amp;gt; -&amp;gt; &amp;lt;tt&amp;gt;Linker&amp;lt;/tt&amp;gt; -&amp;gt; &amp;lt;tt&amp;gt;General&amp;lt;/tt&amp;gt;.  Set the &amp;lt;tt&amp;gt;Output File&amp;lt;/tt&amp;gt; option appropriately.&lt;br /&gt;
&lt;br /&gt;
==Linux Users==&lt;br /&gt;
Simply edit the &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; and change the &amp;lt;tt&amp;gt;BINARY&amp;lt;/tt&amp;gt; line near the top.  Make sure you do not add any trailing spaces at the end of the name, or the build won't come out right.&lt;br /&gt;
&lt;br /&gt;
You should now be able to compile a blank extension!&lt;br /&gt;
&lt;br /&gt;
=Creating Native Functions=&lt;br /&gt;
''Main article: [[Natives (SourceMod Development)]]''&lt;br /&gt;
&lt;br /&gt;
Most of the time, an extension exists to add &amp;quot;native functions&amp;quot; to the plugin system.  Native functions are simply the functions that plugins can use in SourceMod.  They are coded in C++ and have a short prototype declaration in an include file.&lt;br /&gt;
&lt;br /&gt;
==Prototyping==&lt;br /&gt;
The first step to creating a native is to &amp;lt;tt&amp;gt;spec it&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;prototype&amp;lt;/tt&amp;gt; it.  This is a simple but often time consuming process, but if you get in the habit of it, your documentation will be much better.  Let's first create a very simply native.  Here is a prototype for it, which we will place in &amp;lt;tt&amp;gt;sample.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;/**&lt;br /&gt;
 * Returns the square of a number.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num	Number to square.&lt;br /&gt;
 * @return	The square of num.&lt;br /&gt;
 */&lt;br /&gt;
native int SquareNumber(num);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;native&amp;lt;/tt&amp;gt; keyword tells the compiler that this function exists in an outside source.  The comment style is similar to [http://www.stack.nl/~dimitri/doxygen/ doxygen] or [http://java.sun.com/j2se/javadoc/ Javadoc], and is preferred by the SourceMod Development Team.&lt;br /&gt;
&lt;br /&gt;
==Implementing==&lt;br /&gt;
Now that our function is documented, it's time to create it!  Each native function is bound to a C++ function.  The prototype for this function looks like:&lt;br /&gt;
&amp;lt;cpp&amp;gt;cell_t Function(IPluginContext *pContext, const cell_t *params);&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A quick explanation of these types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;cell_t&amp;lt;/tt&amp;gt; - This is a 32bit signed integer, the generic data type for Pawn.&lt;br /&gt;
*&amp;lt;tt&amp;gt;IPluginContext&amp;lt;/tt&amp;gt; - This interface provides Virtual Machine functions for retrieving or modifying memory in the plugin.&lt;br /&gt;
*&amp;lt;tt&amp;gt;params&amp;lt;/tt&amp;gt; - This is the &amp;quot;stack&amp;quot; of parameters that the plugin passed.  It is an array from [0..N] where 0 contains N. This means &amp;lt;tt&amp;gt;params[0]&amp;lt;/tt&amp;gt; contains the number of arguments passed to the native.&lt;br /&gt;
**For example, if one parameter was passed, and the parameter is 25:&lt;br /&gt;
***&amp;lt;tt&amp;gt;params[0]&amp;lt;/tt&amp;gt; == 1&lt;br /&gt;
***&amp;lt;tt&amp;gt;params[1]&amp;lt;/tt&amp;gt; == 25&lt;br /&gt;
**Even though it tells you how many parameters are passed, you do not need to verify this number.  The compiler will always pass the correct number of parameters in.  The only time you need to verify it is for backwards compatibility or variable parameter lists, which will be discussed later.&lt;br /&gt;
&lt;br /&gt;
Now, let's write our native function:&lt;br /&gt;
&amp;lt;cpp&amp;gt;cell_t SquareNumber(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	cell_t number = params[1];&lt;br /&gt;
	return number * number;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Binding==&lt;br /&gt;
Now, the final step is to bind our native.  Natives are bound in ''native lists''.  Each list must be terminated by a &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; bind.  Example:&lt;br /&gt;
&amp;lt;cpp&amp;gt;const sp_nativeinfo_t MyNatives[] = &lt;br /&gt;
{&lt;br /&gt;
	{&amp;quot;SquareNumber&amp;quot;,	SquareNumber},&lt;br /&gt;
	{NULL,			NULL},&lt;br /&gt;
};&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first column/member is a string containing the name you've assigned to the native.  The second column/member is the C++ function you're binding to.  Here, both contain the same name, but it is certainly possible to bind a function to any valid Pawn function name, and likewise, you can bind one function to more than one name.&lt;br /&gt;
&lt;br /&gt;
Lastly, you must tell Core about your native list.  There are two places that are good to do this.  Whichever you choose, you must uncomment the function in &amp;lt;tt&amp;gt;extension.h&amp;lt;/tt&amp;gt; and implement it in &amp;lt;tt&amp;gt;extension.cpp&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SDK_OnLoad&amp;lt;/tt&amp;gt; - This is called when your extension is first loaded.  If you do not require any outside interfaces, it is safe to add natives here.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SDK_OnAllLoaded&amp;lt;/tt&amp;gt; - This is called when all extensions have been loaded.  This is generally a better place to add natives.&lt;br /&gt;
&lt;br /&gt;
Let's say we choose &amp;lt;tt&amp;gt;SDK_OnAllLoaded&amp;lt;/tt&amp;gt;, we'd then have code like this:&lt;br /&gt;
&amp;lt;cpp&amp;gt;void Sample::SDK_OnAllLoaded()&lt;br /&gt;
{&lt;br /&gt;
	sharesys-&amp;gt;AddNatives(myself, MyNatives);&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
''Note: &amp;lt;tt&amp;gt;myself&amp;lt;/tt&amp;gt; is a global variable declared in the SDK.  It is a pointer that identifies your extension.''&lt;br /&gt;
&lt;br /&gt;
For more information on writing natives, see [[Natives (SourceMod Development)]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Creating Events/Forwards=&lt;br /&gt;
Events are an integral part to SourceMod.  An Event is formally called a ''Forward''.  Forwards are functions inside a plugin which are not called by the plugin itself, but are triggered from an external source.  For example, &amp;lt;tt&amp;gt;OnClientConnect&amp;lt;/tt&amp;gt; is a forward which is triggered when a player connects to a server.&lt;br /&gt;
&lt;br /&gt;
There are two major types of forwards:&lt;br /&gt;
*'''Managed''': This forward is global and has a name.  To use this forward, the function must be declared as &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; inside the user's script.  Any plugin having this public function will receive the event.&lt;br /&gt;
*'''Unmanaged''': This forward is private in nature.  For example, the &amp;lt;tt&amp;gt;HookUserMessage&amp;lt;/tt&amp;gt; native lets users specify a function to be called when a specific user message is sent.  This is done with an unmanaged forward, and adding functions to this forward is not automatic.  In general, function calls for unmanaged forwards are not public, although they can be.&lt;br /&gt;
&lt;br /&gt;
''Note: To enable the Forward interface, you must uncomment the definition &amp;lt;tt&amp;gt;SMEXT_ENABLE_FORWARDSYS&amp;lt;/tt&amp;gt; in smsdk_config.h.''&lt;br /&gt;
==Managed Forwards==&lt;br /&gt;
Let's say we want to create a forward that will be called when a player uses say chat.  For simplicity, let's assume you already have a function that tells you when a player says say chat.  We will just be creating the forward for it.&lt;br /&gt;
&lt;br /&gt;
As we did before, first let's prototype our global forward.  In our include file, we add this:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;/**&lt;br /&gt;
 * @brief Called whenever a client says something in chat.&lt;br /&gt;
 *&lt;br /&gt;
 * @param client	Index of the client.&lt;br /&gt;
 * @param text		String containing the say text.&lt;br /&gt;
 * @return 		Plugin_Handled to block text from printing, Plugin_Continue otherwise.&lt;br /&gt;
 */&lt;br /&gt;
forward Action OnPlayerSayChat(int client, const char[] text);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;forward&amp;lt;/tt&amp;gt; keyword tells the compiler that any function having this name must be declared exactly the same.  In a plugin, this would&lt;br /&gt;
&lt;br /&gt;
The next step is to declare your forward somewhere at the top of your &amp;lt;tt&amp;gt;extension.cpp&amp;lt;/tt&amp;gt; file.  This will look like:&lt;br /&gt;
&amp;lt;cpp&amp;gt;IForward *g_pSayChat = NULL&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, re-using our code from above, let's create this forward in &amp;lt;tt&amp;gt;SDK_OnAllLoaded&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;cpp&amp;gt;void Sample::SDK_OnAllLoaded()&lt;br /&gt;
{&lt;br /&gt;
	sharesys-&amp;gt;AddNatives(myself, MyNatives);&lt;br /&gt;
	g_pSayChat = forwards-&amp;gt;CreateForward(&amp;quot;OnPlayerSayChat&amp;quot;, ET_Event, 2, NULL, Param_Cell, Param_String);&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation of parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;quot;OnPlayerSayChat&amp;quot;&amp;lt;/tt&amp;gt; - The name of our forward.&lt;br /&gt;
*&amp;lt;tt&amp;gt;ET_Event&amp;lt;/tt&amp;gt; - Since forwards can execute multiple functions in multiple scripts, this is one of the ways of specifying what to do with the return value of each function.  &amp;lt;tt&amp;gt;ET_Event&amp;lt;/tt&amp;gt; means &amp;quot;return the highest value, do not allow stops.&amp;quot;  A stop refers to &amp;lt;tt&amp;gt;Pl_Stop&amp;lt;/tt&amp;gt;, which lets a plugin block the rest of the event chain.&lt;br /&gt;
*&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; - This is the number of parameters our forward will have.&lt;br /&gt;
*&amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; - Not used in our example.  This lets you pass parameters by array rather than variable arguments.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_Cell&amp;lt;/tt&amp;gt; - The first parameter is a cell (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;Param_String&amp;lt;/tt&amp;gt; - The second parameter is a string.&lt;br /&gt;
&lt;br /&gt;
Now, we write a quick function in our module to call this forward:&lt;br /&gt;
&amp;lt;cpp&amp;gt;/** Fires the say chat event in plugins.  Returns true to allow the text, false to block. */&lt;br /&gt;
bool FireChatEvent(int client, const char *text)&lt;br /&gt;
{&lt;br /&gt;
	if (!g_pSayChat)&lt;br /&gt;
	{&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	cell_t result = 0;&lt;br /&gt;
	g_pSayChat-&amp;gt;PushCell(client);&lt;br /&gt;
	g_pSayChat-&amp;gt;PushString(text);&lt;br /&gt;
	g_pSayChat-&amp;gt;Execute(&amp;amp;result);&lt;br /&gt;
	&lt;br /&gt;
	if (result == Pl_Handled)&lt;br /&gt;
	{&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return true;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, this was pretty simple.  Each parameter is &amp;quot;pushed&amp;quot; one at a time, in ascending order.  First we push the client index as a cell, then the text as a string.  Once done, we execute, and the value will be returned by reference.&lt;br /&gt;
&lt;br /&gt;
Lastly, there is a caveat.  Unlike natives, SourceMod does not automatically clean up forwards for us when are done.  We have to make sure we destroy them.  Uncomment &amp;lt;tt&amp;gt;SDK_OnUnload&amp;lt;/tt&amp;gt; from &amp;lt;tt&amp;gt;extension.h&amp;lt;/tt&amp;gt; and implement it like so:&lt;br /&gt;
&amp;lt;cpp&amp;gt;void Sample::SDK_OnUnload()&lt;br /&gt;
{&lt;br /&gt;
	forwards-&amp;gt;ReleaseForward(g_pSayChat);&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unmanaged Forwards==&lt;br /&gt;
Now things get a bit more complicated.  However, unmanaged forwards are essentially the same -- they just give you more flexibility.  Let's consider the managed example with a new twist.  We want to let users add and remove hooks from their plugins, rather than having one global forward.  The standard way to do this is with ''function IDs''.  &lt;br /&gt;
&lt;br /&gt;
Example prototype:&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;typedef SayChatHook = function Action (int client, const char[] text);&lt;br /&gt;
&lt;br /&gt;
native void AddSayChatHook(SayChatHook hook);&lt;br /&gt;
native void RemoveSayChatHook(SayChatHook hook);&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;funcenum&amp;lt;/tt&amp;gt; syntax lets you define all the valid prototypes for your hook.  In this example, the only valid method is a function declared like this (only MyHook can be changed):&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;Action MyHook(int client, const char[] text)&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
How do we make such a beast?  The first step is setting up our forward.&lt;br /&gt;
&amp;lt;cpp&amp;gt;IChangeableForward *g_pSayChat = NULL;&lt;br /&gt;
/* ... */&lt;br /&gt;
void Sample::SDK_OnAllLoaded()&lt;br /&gt;
{&lt;br /&gt;
	g_pSayChat = forwards-&amp;gt;CreateForwardEx(NULL, ET_Hook, 2, NULL, Param_Cell, Param_String); &lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice two big differences.  We now use &amp;lt;tt&amp;gt;IChangeableForward&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;IForward&amp;lt;/tt&amp;gt;, and we use &amp;lt;tt&amp;gt;CreateForwardEx&amp;lt;/tt&amp;gt; instead.  The initial first parameter specifies a name for our forward - we're going to ignore this.&lt;br /&gt;
&lt;br /&gt;
Now, we need to create our natives.  These will be fairly simple:&lt;br /&gt;
&amp;lt;cpp&amp;gt;cell_t AddSayChatHook(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	g_pSayChat-&amp;gt;AddFunction(pContext, static_cast&amp;lt;funcid_t&amp;gt;(params[1]));&lt;br /&gt;
	return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
cell_t RemoveSayChatHook(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	IPluginFunction *pFunction = pContext-&amp;gt;GetFunctionById(static_cast&amp;lt;funcid_t&amp;gt;(params[1]));&lt;br /&gt;
	g_pSayChat-&amp;gt;RemoveFunction(pFunction);&lt;br /&gt;
	return 1;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
''Note: These natives must be added -- that step is removed here and explained earlier.''&lt;br /&gt;
&lt;br /&gt;
You do not need to worry about a plugin unloading - Core will automatically remove the functions for you.  Since an &amp;lt;tt&amp;gt;IChangeableForward&amp;lt;/tt&amp;gt; is also an &amp;lt;tt&amp;gt;IForward&amp;lt;/tt&amp;gt;, the &amp;lt;tt&amp;gt;FireChatEvent&amp;lt;/tt&amp;gt; function from earlier does not need to change.  We're done!&lt;br /&gt;
&lt;br /&gt;
==Creating Interfaces==&lt;br /&gt;
Do you want your extension to share an interface?  If so, first you should create an ''interface file''.  This file should contain everything your interface needs - this way other authors can easily reference it.  Your interface must inherit the &amp;lt;tt&amp;gt;SMInterface&amp;lt;/tt&amp;gt; class.  It must also declare two global macros that uniquely identify your interface.  It must also implement two functions: &amp;lt;tt&amp;gt;GetInterfaceName&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;GetInterfaceVersion&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The two defines must start with &amp;lt;tt&amp;gt;SMINTERFACE_&amp;lt;/tt&amp;gt; and end with &amp;lt;tt&amp;gt;_NAME&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_VERSION&amp;lt;/tt&amp;gt; respectively.  The first must be a string and the second must be an unsigned integer.  This integer represents your interface's version number.  While you are free to use it however you please, by default it should be linearly increased.  If you make breaking changes or change the versioning scheme, you must overload the &amp;lt;tt&amp;gt;IsVersionCompat&amp;lt;/tt&amp;gt; function in &amp;lt;tt&amp;gt;SMInterface&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;cpp&amp;gt;#ifndef _INCLUDE_MYINTERFACE_FILE_H_&lt;br /&gt;
#define _INCLUDE_MYINTERFACE_FILE_H_&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;IShareSys.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SMINTERFACE_MYINTERFACE_NAME	&amp;quot;IMyInterface&amp;quot;&lt;br /&gt;
#define SMINTERFACE_MYINTERFACE_VERSION	1&lt;br /&gt;
&lt;br /&gt;
class IMyInterface : public SourceMod::SMInterface&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	virtual const char *GetInterfaceName()&lt;br /&gt;
	{&lt;br /&gt;
		return SMINTERFACE_MYINTERFACE_NAME;&lt;br /&gt;
	}&lt;br /&gt;
	virtual unsigned int GetInterfaceVersion()&lt;br /&gt;
	{&lt;br /&gt;
		return SMINTERFACE_MYINTERFACE_VERSION;&lt;br /&gt;
	}&lt;br /&gt;
public:&lt;br /&gt;
	/**&lt;br /&gt;
	 * @brief This function does nothing.&lt;br /&gt;
	 */&lt;br /&gt;
	virtual void DoNothingAtAll() =0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif //_INCLUDE_MYINTERFACE_FILE_H_&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice, of course, that our interface is ''pure virtual''.  This means it must be implemented in the extension.  Assuming you know C++, this should be fairly straight forward, so let's skip right to how to add this interface to the SourceMod shared system:&lt;br /&gt;
&amp;lt;cpp&amp;gt;bool Sample::SDK_OnLoad(char *error, size_t err_max, bool late)&lt;br /&gt;
{&lt;br /&gt;
	sharesys-&amp;gt;AddInterface(myself, &amp;amp;g_MyInterface);&lt;br /&gt;
	return true;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
''Note: We do this in &amp;lt;tt&amp;gt;SDK_OnLoad()&amp;lt;/tT&amp;gt; instead of &amp;lt;tt&amp;gt;SDK_OnAllLoaded()&amp;lt;/tt&amp;gt;.  Otherwise, an extension might try to search for your interface during &amp;lt;tt&amp;gt;SDK_OnAllLoaded()&amp;lt;/tt&amp;gt;, and it might fail depending on the load order.''&lt;br /&gt;
&lt;br /&gt;
That simple?  Yup!  Now other extensions can use your interface.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Using Interfaces/Other Extensions=&lt;br /&gt;
There are a variety of interfaces that are available, but not loaded by default in the Extension SDK.  These interfaces can be retrieved and used in your extension.&lt;br /&gt;
&lt;br /&gt;
==Core Interfaces==&lt;br /&gt;
If they are provided by Core, getting them is very simple.  Many interfaces can simply be uncommented in &amp;lt;tt&amp;gt;smsdk_config.h&amp;lt;/tt&amp;gt; and they will become usable.  See the &amp;quot;Available Interfaces&amp;quot; list below for the exposure list.&lt;br /&gt;
&lt;br /&gt;
Otherwise, most of the &amp;lt;tt&amp;gt;.h&amp;lt;/tt&amp;gt; interface files in the root of the &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; folder in the SDK are Core interfaces.  For example, code to use the IPluginManager interface might look like this:&lt;br /&gt;
&amp;lt;cpp&amp;gt;#include &amp;lt;IPluginSys.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IPluginManager *g_pPlugins = NULL;&lt;br /&gt;
&lt;br /&gt;
bool Sample::SDK_OnLoad(char *error, size_t err_max, bool late)&lt;br /&gt;
{&lt;br /&gt;
	SM_GET_IFACE(PLUGINSYSTEM, g_pPlugins);&lt;br /&gt;
	return true;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where did we get &amp;lt;tt&amp;gt;PLUGINSYSTEM&amp;lt;/tt&amp;gt; from?  Observe the two lines in &amp;lt;tt&amp;gt;IPluginSys.h&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;cpp&amp;gt;#define SMINTERFACE_PLUGINSYSTEM_NAME		&amp;quot;IPluginManager&amp;quot;&lt;br /&gt;
#define SMINTERFACE_PLUGINSYSTEM_VERSION	1&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;SM_GET_IFACE&amp;lt;/tt&amp;gt; macro uses the text in between the &amp;lt;tt&amp;gt;SMINTERFACE_&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;_NAME&amp;lt;/tt&amp;gt; characters.  It also uses the version for compatibility checking.  If it can't find the interface, it automatically prints to the error buffer and returns false.&lt;br /&gt;
&lt;br /&gt;
===Default Interfaces===&lt;br /&gt;
There are interfaces which are grabbed by the Extension SDK by default.  You do not need to query for them on load, or even check if they are valid or not.  They are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;IShareSys&amp;lt;/tt&amp;gt; - Exposed as &amp;lt;tt&amp;gt;sharesys&amp;lt;/tt&amp;gt;, found in &amp;lt;tt&amp;gt;IShareSys.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;HANDLESYSTEM&amp;lt;/tt&amp;gt; - Exposed as &amp;lt;tt&amp;gt;handlesys&amp;lt;/tt&amp;gt;, found in &amp;lt;tt&amp;gt;IHandleSys.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SOURCEMOD&amp;lt;/tt&amp;gt; - Exposed as &amp;lt;tt&amp;gt;g_pSM&amp;lt;/tt&amp;gt;, found in &amp;lt;tt&amp;gt;ISourceMod.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;FORWARDMANAGER&amp;lt;/tt&amp;gt; - Exposed as &amp;lt;tt&amp;gt;forwards&amp;lt;/tt&amp;gt;, found in &amp;lt;tt&amp;gt;IForwardSys.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Available Interfaces===&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_FORWARDSYS&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;forwards&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_HANDLESYS&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;handlesys&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_PLAYERHELPERS&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;playerhelpers&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_DBMANAGER&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;dbi&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_GAMECONF&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;gameconfs&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_MEMUTILS&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;memutils&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_GAMEHELPERS&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;gamehelpers&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_TIMERSYS&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;timersys&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_ENABLE_THREADER&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;threader&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==External Interfaces==&lt;br /&gt;
The situation changes if your extension requires ''another extension'', since extensions may load in a completely random order.  The first step is to mark the other extension as a dependency.  Let's say you want to use the &amp;lt;tt&amp;gt;IThreader.h&amp;lt;/tt&amp;gt; interfaces from &amp;lt;tt&amp;gt;threader.ext.dll&amp;lt;/tt&amp;gt;.  First, we declare it as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cpp&amp;gt;bool Sample::SDK_OnLoad(char *error, size_t err_max, bool late)&lt;br /&gt;
{&lt;br /&gt;
	sharesys-&amp;gt;AddDependency(myself, &amp;quot;thread.ext&amp;quot;, true, true);&lt;br /&gt;
	return true;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The two boolean parameters to &amp;lt;tt&amp;gt;AddDependency&amp;lt;/tt&amp;gt; mean, respectively: &amp;quot;try to automatically load this extension&amp;quot; and &amp;quot;this extension cannot work without the dependency.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Second, we query for the interface in &amp;lt;tt&amp;gt;SDK_OnAllLoaded&amp;lt;/tt&amp;gt;.  Since we don't know when &amp;lt;tt&amp;gt;thread.ext&amp;lt;/tt&amp;gt; will actually be loaded, we have to wait until everything is definitely loaded.&lt;br /&gt;
&amp;lt;cpp&amp;gt;IThreader *g_pThreader = NULL;&lt;br /&gt;
/* ... */&lt;br /&gt;
void Sample::SDK_OnAllLoaded()&lt;br /&gt;
{&lt;br /&gt;
	SM_GET_LATE_IFACE(THREADER, g_pThreader);&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Third, we need to find a way to fail if this interface was never found.  The way to do this is by uncommenting &amp;lt;tt&amp;gt;QueryRunning&amp;lt;/tt&amp;gt; from &amp;lt;tt&amp;gt;extension.h&amp;lt;/tt&amp;gt; and implementing it:&lt;br /&gt;
&amp;lt;cpp&amp;gt;bool Sample::QueryRunning(char *error, size_t err_max)&lt;br /&gt;
{&lt;br /&gt;
	SM_CHECK_IFACE(THREADER, g_pThreader);&lt;br /&gt;
	return true;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When SourceMod queries your extension, the macro above will either validate the pointer or return false.  If it returns false, SourceMod marks your extension as failed.&lt;br /&gt;
&lt;br /&gt;
==Caveats==&lt;br /&gt;
===NULL Interfaces===&lt;br /&gt;
There are a few ways that external interfaces can make your code complicated.  The first is simple but a common oversight.  Don't assume interfaces will be okay.  For example, say we want to create a thread once we get the &amp;lt;tt&amp;gt;IThreader&amp;lt;/tt&amp;gt; interface.  Our code should something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cpp&amp;gt;void Sample::SDK_OnAllLoaded()&lt;br /&gt;
{&lt;br /&gt;
	SM_GET_IFACE(THREADER, g_pThreader);&lt;br /&gt;
	&lt;br /&gt;
	if (QueryRunning(NULL, 0))&lt;br /&gt;
	{&lt;br /&gt;
		g_pThreader-&amp;gt;MakeThread(/* stuff */);&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we ''query ourself'' in order to find if it's safe to continue executing code.  We could also have simply checked if &amp;lt;tt&amp;gt;g_pThreader&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, but self-querying has a bonus: if your extension continues to do things like hook events or add listeners, you will be preventing your extension from entirely initializing itself while one interface is bad.  Always make sure you have sanity checks like this where needed.&lt;br /&gt;
&lt;br /&gt;
===Dynamic Unloading===&lt;br /&gt;
The second major caveat is that extensions can be dynamically unloaded.  If you specified yourself as having a dependency and that each dependency is required, you will have no problem.  Your extension will be unloaded before the interface is removed, and you can clean up memory/hooks in your &amp;lt;tt&amp;gt;SDK_OnUnload()&amp;lt;/tt&amp;gt; code.  There are two situations where this is a different story.&lt;br /&gt;
&lt;br /&gt;
====Optional Interfaces====&lt;br /&gt;
The first situation is if you are not requiring an extension that contains an interface.  Now, when the extension unloads, your extension will not be unloaded first.  This creates a small problem, as you must clean up without being unloaded.  There are two functions you can implement in your extension class to resolve this, both documented in &amp;lt;tt&amp;gt;IExtensionSys.h&amp;lt;/tt&amp;gt;:&lt;br /&gt;
*&amp;lt;tt&amp;gt;QueryInterfaceDrop&amp;lt;/tt&amp;gt; - Allows you to request unloading when a specific interface is unloaded.  This is the default behavior for all interfaces.  If you want to block this functionality, continue reading.&lt;br /&gt;
*&amp;lt;tt&amp;gt;NotifyInterfaceDrop&amp;lt;/tt&amp;gt; - This is called when an interface is dropped.  If your plugin will not be unloaded, you can use this to clean up any resources on a specific interface being removed.&lt;br /&gt;
&lt;br /&gt;
====Circular Dependencies====&lt;br /&gt;
The second situation is a bit more complicated.  It is possible for two extensions to have circular dependencies.  For example:&lt;br /&gt;
*Extension &amp;quot;A&amp;quot; requires extension &amp;quot;B.&amp;quot;&lt;br /&gt;
*Extension &amp;quot;B&amp;quot; requires extension &amp;quot;A.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If either extension is unloaded, the opposite extension is unloaded normally.  The first extension then receives the interface drop callbacks.  In this situation, it is essential that the &amp;lt;tt&amp;gt;NotifyInterfaceDrop&amp;lt;/tt&amp;gt; function be implemented and used with the circular interface.  Otherwise, you risk crashing when your extension unloads (or at the very least, leaking memory).  Since the actual drop order is undefined, it means both extensions must implement this function to be safe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Automatic Loading=&lt;br /&gt;
There are two types of automatic loading: Dynamic and Global.  Dynamic loading means your extension is only loaded when a plugin requires it.  Global loading means your extension loads no matter what.&lt;br /&gt;
&lt;br /&gt;
==Dynamic Autoloading==&lt;br /&gt;
Dynamic loading requires that you create an include file for plugins.  Plugins that include your file will automatically load your extension.  This requires implementing the &amp;lt;tt&amp;gt;Extension&amp;lt;/tt&amp;gt; structure found in &amp;lt;tt&amp;gt;core.inc&amp;lt;/tt&amp;gt;.  You must expose the structure as &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;, and the name must start with &amp;quot;&amp;lt;tt&amp;gt;__ext_&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sourcepawn&amp;gt;/**&lt;br /&gt;
 * Do not edit below this line!&lt;br /&gt;
 */&lt;br /&gt;
public Extension __ext_geoip = &lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;GeoIP&amp;quot;,&lt;br /&gt;
	file = &amp;quot;geoip.ext&amp;quot;,&lt;br /&gt;
#if defined AUTOLOAD_EXTENSIONS&lt;br /&gt;
	autoload = 1,&lt;br /&gt;
#else&lt;br /&gt;
	autoload = 0,&lt;br /&gt;
#endif&lt;br /&gt;
#if defined REQUIRE_EXTENSIONS&lt;br /&gt;
	required = 1,&lt;br /&gt;
#else&lt;br /&gt;
	required = 0,&lt;br /&gt;
#endif&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/sourcepawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanations:&lt;br /&gt;
*&amp;lt;b&amp;gt;name&amp;lt;/b&amp;gt;: The name of your module as written in &amp;lt;tt&amp;gt;SMEXT_CONF_NAME&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;file&amp;lt;/b&amp;gt;: The platform-inspecific portion of your extension's file name.&lt;br /&gt;
*&amp;lt;b&amp;gt;autoload&amp;lt;/b&amp;gt;: Specifies that your module should always dynamically autoload by default.  You can tweak this to either never autoload or always autoload (without letting the user toggle).&lt;br /&gt;
*&amp;lt;b&amp;gt;required&amp;lt;/b&amp;gt;: Specifies whether or not this extension is '''required''' by your plugin.  If for some reason your extension fails to load (or is not found), the plugin will also fail to load.  This is changeable if you wish to override the default behavior.&lt;br /&gt;
&lt;br /&gt;
You can copy and paste this example, but remember to modify the following portions:&lt;br /&gt;
*&amp;lt;b&amp;gt;__ext_geoip&amp;lt;/b&amp;gt;: Change the &amp;quot;geoip&amp;quot; portion to your own unique variable name.&lt;br /&gt;
*&amp;lt;b&amp;gt;&amp;quot;GeoIP&amp;lt;/b&amp;gt;: Change the GeoIP portion to your extension's name.  This should match the name you chose as &amp;lt;tt&amp;gt;SMEXT_CONF_NAME&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;b&amp;gt;&amp;quot;geoip.ext&amp;quot;&amp;lt;/b&amp;gt;: Change this to your extension's file name, without the .dll/.so portion.&lt;br /&gt;
&lt;br /&gt;
==Global Autoloading==&lt;br /&gt;
To have your extension always autoload, you must create a ''.autoload'' file in the &amp;lt;tt&amp;gt;extensions&amp;lt;/tt&amp;gt; folder.  For example, to have the &amp;lt;tt&amp;gt;threader.ext.dll&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;threader.ext.so&amp;lt;/tt&amp;gt; extensions autoload, you'd create the following file in &amp;lt;tt&amp;gt;extensions&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;threader.autoload&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A few notes:&lt;br /&gt;
*This only works for extensions using the .ext.&amp;lt;platform&amp;gt; convention.  SourceMod cuts off the &amp;quot;.autoload&amp;quot; portion of the file, then adds the appropriate extension just as if 'sm exts load' was used.&lt;br /&gt;
*The file does not need to contain anything, it simply needs to exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Conventions=&lt;br /&gt;
&lt;br /&gt;
==Designing API/Natives==&lt;br /&gt;
*Start interface names with the capital letter 'I'.&lt;br /&gt;
*Use a consistent naming convention.  SourceMod uses [http://msdn2.microsoft.com/en-us/library/ms229002.aspx Microsoft/Pascal] naming.  Avoid Java/Camel casing for both API and natives.&lt;br /&gt;
*When exposing interfaces, make sure your exposure defines start with &amp;lt;tt&amp;gt;SMINTERFACE_&amp;lt;/tt&amp;gt; and end with &amp;lt;tt&amp;gt;_NAME&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_VERSION&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==External Naming==&lt;br /&gt;
*Logtags (&amp;lt;tt&amp;gt;SMEXT_CONF_LOGTAG&amp;lt;/tt&amp;gt;) should be short names (under 10 characters or so) in all capital letters.&lt;br /&gt;
*Your extension file name should never have &amp;lt;tt&amp;gt;_i486&amp;lt;/tt&amp;gt; or other unnecessary platform-specific notations in its name.&lt;br /&gt;
*Your extension file name should always end in &amp;lt;tt&amp;gt;.ext.so&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;.ext.dll&amp;lt;/tt&amp;gt; depending on the platform.  The &amp;lt;tt&amp;gt;.ext.&amp;lt;/tt&amp;gt; is SourceMod convention.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Setting up Visual Studio=&lt;br /&gt;
&lt;br /&gt;
{{qnotice|It is recommended that you make a copy of the sample_ext project and modify that rather than create your own project, as it will set up most of this for you}}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample Project ==&lt;br /&gt;
&lt;br /&gt;
Instead of manually creating a project, you can make a copy of the sample_ext project and modify it.&lt;br /&gt;
&lt;br /&gt;
The sample_ext project assumes that it is located in a subdirectory inside the SourceMod public directory.  To change this, modify all references to ..\.. to $(SOURCEMOD15)\public and specify the SOURCEMOD15 variable as mentioned in the Optional Environment variables.&lt;br /&gt;
&lt;br /&gt;
The sample_ext projectuses the following environment variables to locate the various source code parts.  To set environment variables:&lt;br /&gt;
&lt;br /&gt;
'''Windows XP''': Start -&amp;gt; Settings -&amp;gt; Control Panel -&amp;gt; System -&amp;gt; Advanced -&amp;gt; Environment Variables&lt;br /&gt;
&lt;br /&gt;
'''Windows Vista/7''': Start -&amp;gt; Control Panel -&amp;gt; System -&amp;gt; Advanced system properties -&amp;gt; Advanced -&amp;gt; Environment Variables&lt;br /&gt;
&lt;br /&gt;
=== Environment Variables ===&lt;br /&gt;
&lt;br /&gt;
The environment variables used are:&lt;br /&gt;
&lt;br /&gt;
* '''MMSOURCE17''': Path to MetaMod: Source source code for version 1.7 or newer. Used to compile SourceMod itself.  &lt;br /&gt;
* '''MMSOURCE18''': Path to MetaMod: Source source code for version 1.8 or newer. Used in SourceMod 1.4 projects.  &lt;br /&gt;
* '''MMSOURCE19''': Path to MetaMod: Source source code for version 1.9 or newer. Used in SourceMod 1.5 projects.  &lt;br /&gt;
* '''HL2SDK''': Path to the Episode 1 SDK  &lt;br /&gt;
* '''HL2SDK-SWARM''': Path to the Alien Swarm SDK  &lt;br /&gt;
* '''HL2SDK-DARKM''': Path to the Dark Messiah SDK  &lt;br /&gt;
* '''HL2SDKCSGO''': Path to the Counter-Strike: Global Offensive SDK  &lt;br /&gt;
* '''HL2SDKCSS''': Path to the Counter-Strike: Source SDK  &lt;br /&gt;
* '''HL2SDKL4D''': Path to the Left 4 Dead SDK  &lt;br /&gt;
* '''HL2SDKL4D2''': Path to the Left 4 Dead 2 SDK  &lt;br /&gt;
* '''HL2SDKOB''': Path to the Orange Box SDK (not Source 2009)  &lt;br /&gt;
* '''HL2SDKOBVALVE''': Path to the Orange Box Valve / Source 2009 SDK (Half-Life 2: Deathmatch, Day of Defeat: Source, Team Fortress 2)&lt;br /&gt;
&lt;br /&gt;
Optional environment variables:&lt;br /&gt;
&lt;br /&gt;
* '''SOURCEMOD15'': Optional path to SourceMod 1.5 or newer source code&lt;br /&gt;
&lt;br /&gt;
==Manually configuring a project==&lt;br /&gt;
&lt;br /&gt;
===Paths===&lt;br /&gt;
'''Visual Studio 2003''': Tools -&amp;gt; Options -&amp;gt; Projects, VC++ Directories&lt;br /&gt;
&lt;br /&gt;
'''Visual Studio 2005''': Tools -&amp;gt; Options -&amp;gt; Projects and Solutions -&amp;gt; VC++ Directories&lt;br /&gt;
&lt;br /&gt;
====Include Paths====&lt;br /&gt;
*SourceMod only:&lt;br /&gt;
**sdk\public\extensions&lt;br /&gt;
**sdk\public\sourcepawn&lt;br /&gt;
**sdk\public&lt;br /&gt;
*SourceMM (Note that sourcemm might be 'trunk' for you):&lt;br /&gt;
**sourcemm\core&lt;br /&gt;
**sourcemm\core\sourcehook&lt;br /&gt;
*HL2SDK:&lt;br /&gt;
**game\shared&lt;br /&gt;
**public\vstdlib&lt;br /&gt;
**public\tier1&lt;br /&gt;
**public\tier0&lt;br /&gt;
**public\engine&lt;br /&gt;
**public&lt;br /&gt;
**dlls&lt;br /&gt;
&lt;br /&gt;
====Link Paths====&lt;br /&gt;
*HL2SDK:&lt;br /&gt;
**lib\public for version 2005&lt;br /&gt;
**lib-vc7\public for version 2003&lt;br /&gt;
&lt;br /&gt;
===Compiler Options===&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; These options are set by default in the sample Extension SDK.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; These options should be set for every build (Release/Debug/others).&lt;br /&gt;
&lt;br /&gt;
For VS 2005, goto Project-&amp;gt;Properties.&lt;br /&gt;
&lt;br /&gt;
*General&lt;br /&gt;
**&amp;lt;tt&amp;gt;Character Set&amp;lt;/tt&amp;gt;: '''Use Multi-Byte Character Set'''&lt;br /&gt;
*C/C++&lt;br /&gt;
**General&lt;br /&gt;
***&amp;lt;tt&amp;gt;Detect 64-bit Portability Issues&amp;lt;/tt&amp;gt;: '''No'''&lt;br /&gt;
**Preprocessor&lt;br /&gt;
***&amp;lt;tt&amp;gt;Preprocessor Defines&amp;lt;/tt&amp;gt;: Add &amp;lt;tt&amp;gt;_CRT_SECURE_NO_DEPRECATE&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_CRT_NONSTDC_NO_DEPRECATE&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SOURCEMOD_BUILD&amp;lt;/tt&amp;gt;  and &amp;lt;tt&amp;gt;WIN32&amp;lt;/tt&amp;gt;&lt;br /&gt;
**Code Generation&lt;br /&gt;
***&amp;lt;tt&amp;gt;Runtime Library&amp;lt;/tt&amp;gt;: Multi-threaded or /MT (for Release), Multi-threaded Debug or /MTd (for Debug)&lt;br /&gt;
*Linker&lt;br /&gt;
**General&lt;br /&gt;
***&amp;lt;tt&amp;gt;Output File&amp;lt;/tt&amp;gt;: Change &amp;lt;tt&amp;gt;$(ProjectName)&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;$(ProjectName).ext&amp;lt;/tt&amp;gt;, or use your own custom string.&lt;br /&gt;
**Input&lt;br /&gt;
***&amp;lt;tt&amp;gt;Additional Dependencies&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;tier0.lib tier1.lib vstdlib.lib&amp;lt;/tt&amp;gt; (for SourceMM attached extensions only)&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod]]&lt;br /&gt;
[[Category:SourceMod Development]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Multiple_or_Forked_Servers_(SourceMod)&amp;diff=11037</id>
		<title>Multiple or Forked Servers (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Multiple_or_Forked_Servers_(SourceMod)&amp;diff=11037"/>
		<updated>2020-08-05T23:12:18Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Reverted edits by Almil36 (talk) to last revision by Asherkin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod does not support running more than one server from the same SourceMod installation.  This means you cannot:&lt;br /&gt;
*Point multiple forked servers (a feature in Left 4 Dead's srcds) at one SourceMod install.&lt;br /&gt;
*Start multiple copies of the same srcds to the same SourceMod install.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that SourceMod needs to &amp;quot;own&amp;quot; certain folders.&lt;br /&gt;
*SourceMod's auto-updating feature overwrites gamedata files, and could one day overwrite other files as well.&lt;br /&gt;
*The &amp;quot;data&amp;quot; folder is considered writeable for any purpose, and can be used to store locks that live beyond process IDs.&lt;br /&gt;
&lt;br /&gt;
You can have multiple copies of SourceMod in your &amp;quot;addons&amp;quot; folder, however.  For example, you can have &amp;lt;tt&amp;gt;addons/sourcemod1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;addons/sourcemod2&amp;lt;/tt&amp;gt;.  There are two ways to make this work.&lt;br /&gt;
&lt;br /&gt;
Specify &amp;lt;tt&amp;gt;+sm_basepath&amp;lt;/tt&amp;gt; on the server command line.  For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;srcds -game tf +maxplayers 12 +sm_basepath addons/sourcemod2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are looking to save space or unify certain files that you know will not change, use symlinks.  On Linux/FreeBSD this is the &amp;lt;tt&amp;gt;ln -s&amp;lt;/tt&amp;gt; command (&amp;lt;tt&amp;gt;man ln&amp;lt;/tt&amp;gt;).  On Windows Vista or 2008 Server, this is &amp;lt;tt&amp;gt;mklink&amp;lt;/tt&amp;gt; from the command prompt.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Entity_References_(SourceMod)&amp;diff=11013</id>
		<title>Entity References (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Entity_References_(SourceMod)&amp;diff=11013"/>
		<updated>2020-05-04T13:24:11Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Reverted edits by Joinedsenses (talk) to last revision by Xerox8521&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An entity reference is a combination of a standard entity index (used for all entities in SourceMod previously) and a pseudo-unique serial number that identifies the entity. Since entities are constantly being created and destroyed a cached index doesn't guarantee the underlying entity is the same, references provide a way of verifying the same entity still exists. Generally speaking, if you have an entity index you wish to cache you should convert it to a reference first. Most Sourcemod-provided natives should be able to accept references in place of indexes (wherever the parameter asks for an entity - Not clients), and these will use the serial to check that the entity index contained in the reference is the same as when the reference was created. If you find a native that does not seem to support references in place of indexes, please file a bug report.&lt;br /&gt;
&lt;br /&gt;
SourceMod now also supports handling of logical (non-networked entities) and these use references exclusively. Natives that used to return an entity index will continue to do so in the case of networked entities (for backwards compatability) and will only return a reference for non-networked ones.&lt;br /&gt;
&lt;br /&gt;
==Converting a backwards-compat index/ref to a guaranteed reference for safely caching==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int index = GetEntPropEnt(client, Prop_Send, &amp;quot;m_hActiveWeapon&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
/* Convert our backwards-compat index/ref to a guaranteed reference */&lt;br /&gt;
int ref = EntIndexToEntRef(index);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Converting a reference back to an entity index==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int index = EntRefToEntIndex(ref);&lt;br /&gt;
&lt;br /&gt;
if (index == INVALID_ENT_REFERENCE)&lt;br /&gt;
{&lt;br /&gt;
	/* Reference wasn't valid - Entity must have been deleted */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using References to handle a logic entity==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int ent = -1;  &lt;br /&gt;
   &lt;br /&gt;
while ((ent = FindEntityByClassname(ent, &amp;quot;logic_auto&amp;quot;)) != -1)  &lt;br /&gt;
{  &lt;br /&gt;
    /**   &lt;br /&gt;
     * Get the entity index from this reference - This works on references and indexes for convenience.   &lt;br /&gt;
     * Should be a number &amp;gt;2048 since logic_auto is a non networked entity   &lt;br /&gt;
     */  &lt;br /&gt;
    int ref = EntIndexToEntRef(ent);  &lt;br /&gt;
   &lt;br /&gt;
    /* Fire an input on this entity - We use the reference version since this includes a serial check */  &lt;br /&gt;
    AcceptEntityInput(ref, &amp;quot;Kill&amp;quot;);  &lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SourceMod_Profiler&amp;diff=10884</id>
		<title>SourceMod Profiler</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SourceMod_Profiler&amp;diff=10884"/>
		<updated>2019-12-07T22:51:08Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Replace the entire page with a stub as it documents the old profiler&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod has built-in profiling support for plugins with integration into the game's &amp;quot;vprof&amp;quot; system.&lt;br /&gt;
&lt;br /&gt;
See the &amp;quot;sm prof&amp;quot; command for more details.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SSH_Keys&amp;diff=10746</id>
		<title>SSH Keys</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SSH_Keys&amp;diff=10746"/>
		<updated>2019-04-05T08:33:45Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Add note about PuTTY website.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
A private-public key pair allows one to a access remote server via SSH with a preset encryption key, rather than just a password.  Key pairs can be generated with &amp;lt;tt&amp;gt;ssh-keygen&amp;lt;/tt&amp;gt; on Linux and &amp;lt;tt&amp;gt;PuTTYGen&amp;lt;/tt&amp;gt; on Windows.  When a key pair is generated, a passphrase may be created.  If there is a passphrase set, then &amp;lt;tt&amp;gt;ssh-agent&amp;lt;/tt&amp;gt; on Linux or &amp;lt;tt&amp;gt;Pageant&amp;lt;/tt&amp;gt; on Windows can be used for logging in without needing to type the passphrase. This article explains how to use these tools in order to log in to a remote server using SSH and not typing a password.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Windows=&lt;br /&gt;
First, you should make sure you have the &amp;lt;tt&amp;gt;Pageant&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;PuTTYGen&amp;lt;/tt&amp;gt; programs downloaded. If you already have &amp;lt;tt&amp;gt;PuTTY&amp;lt;/tt&amp;gt; and you installed it via an automated installer program, then it is likely you already have these. You should be able to find them in the directory in which &amp;lt;tt&amp;gt;PuTTY&amp;lt;/tt&amp;gt; was installed. If you do not have them, you can grab both from the &amp;lt;tt&amp;gt;PuTTY&amp;lt;/tt&amp;gt; downloads page: https://www.chiark.greenend.org.uk/~sgtatham/putty/download.html. There are lots of websites, many more legitimate looking than the official site, distributing malicious copies of the &amp;lt;tt&amp;gt;PuTTY&amp;lt;/tt&amp;gt; tools due to its popularity, make sure to always download from the official website linked previously.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open &amp;lt;tt&amp;gt;PuTTYGen&amp;lt;/tt&amp;gt; first and click the button labeled &amp;quot;Generate.&amp;quot; It will then ask you to move the mouse cursor over the blank area on the program's window (in order to generate some randomness for the keys). Then it will ask you to enter a comment (which is already filled, but may be changed) and the key's passphrase twice. You may leave this passphrase blank if you never wish to enter any kind of password for accessing the server via SSH. However it might be a good idea to enter something there for extra security. When using &amp;lt;tt&amp;gt;Pageant&amp;lt;/tt&amp;gt;, you will only have to enter this passphrase once per Windows login. Your &amp;lt;tt&amp;gt;PuTTYGen&amp;lt;/tt&amp;gt; window may look like this:&lt;br /&gt;
&lt;br /&gt;
[[Image:PuTTYGen.png]]&lt;br /&gt;
&lt;br /&gt;
Click the button labeled &amp;quot;Save private key&amp;quot; and save this key somewhere on your computer, such as your &amp;lt;tt&amp;gt;My Documents&amp;lt;/tt&amp;gt; directory. Right click in the area that shows your public key and select &amp;quot;Select All&amp;quot; from the menu. Then right click again and select &amp;quot;Copy.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Next, open a terminal window (with &amp;lt;tt&amp;gt;PuTTY&amp;lt;/tt&amp;gt; or some other program) to the server that you wish to access using this key pair. Navigate to your home directory if you are not already there, and look for a directory named &amp;lt;tt&amp;gt;.ssh&amp;lt;/tt&amp;gt;. If you do not have this directory, then create it like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;cd ~&lt;br /&gt;
mkdir --mode=700 .ssh&lt;br /&gt;
cd .ssh&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now you can go into this directory and type &amp;lt;tt&amp;gt;echo&amp;lt;/tt&amp;gt;. Then right click on your terminal window. This should then paste your public key into the window. Then type a space after your public key followed by &amp;lt;tt&amp;gt;&amp;gt;&amp;gt; authorized_keys&amp;lt;/tt&amp;gt; and press the enter key. Here is an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;echo mypastedkey &amp;gt;&amp;gt; authorized_keys&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lastly, make sure your &amp;lt;tt&amp;gt;authorized_keys&amp;lt;/tt&amp;gt; file has the correct permissions, or else it will not load.  You can do this with:&lt;br /&gt;
&amp;lt;pre&amp;gt;chmod 600 authorized_keys&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you should open &amp;lt;tt&amp;gt;Pageant&amp;lt;/tt&amp;gt;. An icon for the program should appear in your system tray. Right click on this icon and select &amp;quot;Add Key&amp;quot; from the context menu.&lt;br /&gt;
&lt;br /&gt;
[[Image:Pageant_TrayMenu.png]]&lt;br /&gt;
&lt;br /&gt;
A file dialog box will appear. Find and select the private key file that you saved earlier. If you chose to use a passphrase, it will ask you to enter it once. If you did not have a passphrase, then the key will be added automatically.&lt;br /&gt;
&lt;br /&gt;
Now you may access the server via SSH in any way (such as using [[Subversion Tutorial#TortoiseSVN|TortoiseSVN]]) without having to enter a password again. If you reboot your computer, or log out of your Windows session and log back in, you only have to open &amp;lt;tt&amp;gt;Pageant&amp;lt;/tt&amp;gt; and add your key file again.&lt;br /&gt;
&lt;br /&gt;
=Linux=&lt;br /&gt;
&lt;br /&gt;
First, a private-public key pair must be created. You can do this by using &amp;lt;tt&amp;gt;ssh-keygen&amp;lt;/tt&amp;gt;, which comes with openssh (which should already be installed). Type &amp;quot;&amp;lt;tt&amp;gt;ssh-keygen -t rsa&amp;lt;/tt&amp;gt;&amp;quot;. You will be asked to type a path to the file that will be created. You can press enter here because the default is usually fine. You will then be asked for the passphrase twice. As mentioned in the Windows section above, this is optional. You may leave this passphrase blank (by pressing enter when it asks) if you wish to use the keys without having to type a password. However, it might be a good idea to use one for extra security. When using &amp;lt;tt&amp;gt;ssh-agent&amp;lt;/tt&amp;gt;, you will only have to enter this passphrase once per login.&lt;br /&gt;
&lt;br /&gt;
Here's an example of what may occur with &amp;lt;tt&amp;gt;ssh-keygen&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;damagedsoul@sente ~ $ ssh-keygen -t rsa&lt;br /&gt;
Generating public/private rsa key pair.&lt;br /&gt;
Enter file in which to save the key (/home/users/damagedsoul/.ssh/id_rsa):&lt;br /&gt;
Enter passphrase (empty for no passphrase):&lt;br /&gt;
Enter same passphrase again:&lt;br /&gt;
Your identification has been saved in /home/users/damagedsoul/.ssh/id_rsa.&lt;br /&gt;
Your public key has been saved in /home/users/damagedsoul/.ssh/id_rsa.pub.&lt;br /&gt;
The key fingerprint is:&lt;br /&gt;
69:11:bb:1f:9b:e4:52:53:e1:75:30:75:b5:d2:c1:ba damagedsoul@sente.tcwonline.org&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There should now be a file named &amp;lt;tt&amp;gt;id_rsa.pub&amp;lt;/tt&amp;gt; in the &amp;lt;tt&amp;gt;.ssh&amp;lt;/tt&amp;gt; directory of your home directory. Upload this file to the home directory of the server you wish to access using &amp;lt;tt&amp;gt;scp&amp;lt;/tt&amp;gt; or some other means. Start an SSH session with the remote server and then navigate to your home directory if you are not already there. Then you can add the contents of &amp;lt;tt&amp;gt;id_rsa.pub&amp;lt;/tt&amp;gt; to your &amp;lt;tt&amp;gt;authorized_keys&amp;lt;/tt&amp;gt; file in the &amp;lt;tt&amp;gt;.ssh&amp;lt;/tt&amp;gt; directory. If you do not have an &amp;lt;tt&amp;gt;.ssh&amp;lt;/tt&amp;gt; directory, then you will have to create it.&lt;br /&gt;
&lt;br /&gt;
Here is an example of the above information:&lt;br /&gt;
&amp;lt;pre&amp;gt;scp ~/.ssh/id_rsa.pub damagedsoul@takkun.tcwonline.org:~/&lt;br /&gt;
ssh damagedsoul@takkun.tcwonline.org&amp;lt;/pre&amp;gt;&lt;br /&gt;
These next commands are then executed on the remote server:&lt;br /&gt;
&amp;lt;pre&amp;gt;cd ~&lt;br /&gt;
mkdir --mode=700 .ssh&lt;br /&gt;
cat id_rsa.pub &amp;gt;&amp;gt; .ssh/authorized_keys&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now exit from the remote server's SSH session. You now need to run &amp;lt;tt&amp;gt;ssh-agent&amp;lt;/tt&amp;gt;. However, if you have a blank passphrase, the following steps are not necessary and you may begin logging in to the remote server without a password.&lt;br /&gt;
&lt;br /&gt;
If you did enter a passphrase, then execute the following commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;eval `ssh-agent -s`&lt;br /&gt;
ssh-add&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It would also probably be a good idea to add a command to kill all &amp;lt;tt&amp;gt;ssh-agent&amp;lt;/tt&amp;gt; processes to your shell's logout script (for example &amp;lt;tt&amp;gt;~/.bash_logout&amp;lt;/tt&amp;gt;) or else you may leave behind some stray processes.&lt;br /&gt;
&amp;lt;pre&amp;gt;echo killall ssh-agent &amp;gt;&amp;gt; ~/.bash_logout&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may now access the remote server via SSH in any way (such as using [[Subversion Tutorial|svn]]) without having to enter a password again. If you reboot or log out and log back in, you only have to run &amp;lt;tt&amp;gt;ssh-agent&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ssh-add&amp;lt;/tt&amp;gt; again.&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10695</id>
		<title>Menus Step By Step (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10695"/>
		<updated>2018-12-21T18:16:40Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Remove SetMenuTitle note, it causes confusion.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod [[Menu API (SourceMod)|Menu API]] is fairly useful for displaying an information panel, a menu, or a vote to users.  This document talks specifically about menus and how to create one.&lt;br /&gt;
&lt;br /&gt;
== The working menu example ==&lt;br /&gt;
&lt;br /&gt;
This is the working code example that we'll be talking about in the upcoming sections.  If you need to, you can come back and look at it as you read the rest of this page.&lt;br /&gt;
&lt;br /&gt;
We will be using PrintToServer to print text to the server console as we run through the events.&lt;br /&gt;
&lt;br /&gt;
Usage of the [[Translations (SourceMod Scripting)|Translations]] system is highly recommended and will be used in this example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define CHOICE1 &amp;quot;#choice1&amp;quot;&lt;br /&gt;
#define CHOICE2 &amp;quot;#choice2&amp;quot;&lt;br /&gt;
#define CHOICE3 &amp;quot;#choice3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	switch(action)&lt;br /&gt;
	{&lt;br /&gt;
		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Menu_Test1(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&lt;br /&gt;
	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&lt;br /&gt;
	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE3, &amp;quot;Choice 3&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.Display(client, 20);&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The translation file that goes with it... addons/sourcemod/translations/menu_test.phrases.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Choice 3&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Choice Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	&amp;quot;Menu Title&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Menu Title Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step by Step ==&lt;br /&gt;
&lt;br /&gt;
=== OnPluginStart ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This block is here to register the command /menu_test1 so that this menu can be tested.&lt;br /&gt;
&lt;br /&gt;
This block is beyond the scope of this page.  See: [[Introduction to SourceMod Plugins#Plugin Structure|Plugin Structure]] for OnPluginStart, [[Translations (SourceMod Scripting)|Translations]] for LoadTranslations, and [[Commands_(SourceMod_Scripting)|Commands]] for RegConsoleCmd.&lt;br /&gt;
&lt;br /&gt;
=== Menu_Test1 ===&lt;br /&gt;
&lt;br /&gt;
Menu_Test1 is a ConCmd, which is beyond the scope of this page.  See: [[Commands (SourceMod Scripting)|Commands]] for more details on that.  We're going to be talking about what's in it.&lt;br /&gt;
&lt;br /&gt;
==== Menu ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Menu takes two arguments.&lt;br /&gt;
&lt;br /&gt;
The first is a function that matches the [https://sm.alliedmods.net/new-api/menus/MenuHandler MenuHandler] callback signature.&lt;br /&gt;
&lt;br /&gt;
The second is a bitmask of which MenuAction events we are going to handle in our MenuHandler.  There are 7 that apply to standard menus: &lt;br /&gt;
* MenuAction_Start - Called once when a menu is displayed&lt;br /&gt;
* MenuAction_Display - Called once for each client a menu is displayed to&lt;br /&gt;
* MenuAction_Select - Called when a client makes a selection from the menu that isn't Previous, Next, Back, or Exit.&lt;br /&gt;
* MenuAction_Cancel - Called when a client closes a menu or it is closed on them&lt;br /&gt;
* MenuAction_End - Called once when all clients have closed the menu&lt;br /&gt;
* MenuAction_DrawItem - Called once for each item for each user a menu is displayed to. Can change the menu item style.&lt;br /&gt;
* MenuAction_DisplayIitem. - Called once for each item for each user a menu is displayed to. Can change the menu item text.&lt;br /&gt;
&lt;br /&gt;
These will be discussed in more detail in the MenuHandler1 section.&lt;br /&gt;
&lt;br /&gt;
Of those 7, 3 are called whether you specify them or not: MenuAction_Select, MenuAction_Cancel, and MenuAction_End.&lt;br /&gt;
&lt;br /&gt;
MENU_ACTIONS_DEFAULT sets just the 3 required fields, while MENU_ACTIONS_ALL specifies all 10 actions (including the 3 vote actions).&lt;br /&gt;
&lt;br /&gt;
To specify just a few of them, you can do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	Menu menu = new Menu(MenuHandler1, MenuAction_Start|MenuAction_Select|MenuAction_Cancel|MenuAction_End);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== menu.SetTitle ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sets the menu's title.  This example uses the translation system and the server's default language.  This isn't strictly necessary as we will set the menu title again later.&lt;br /&gt;
&lt;br /&gt;
==== menu.AddItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE3, &amp;quot;Choice 3&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A menu isn't useful without something in it!&lt;br /&gt;
menu.AddItem has 2 required arguments and one optional argument.&lt;br /&gt;
&lt;br /&gt;
The 2 required arguments are:&lt;br /&gt;
&lt;br /&gt;
The Info string, and the Display string.&lt;br /&gt;
&lt;br /&gt;
The Info String is a string that is used to uniquely identify this menu item.  It is never displayed to the user, but is used in various callbacks.&lt;br /&gt;
&lt;br /&gt;
The Display String is the default text to be used for this item on the menu.  It can be changed via the menu's MenuAction_DisplayItem callback.&lt;br /&gt;
&lt;br /&gt;
The optional argument is the menu's item draw style.  It can be one of these values:&lt;br /&gt;
* ITEMDRAW_DEFAULT - Displays text as normal.&lt;br /&gt;
* ITEMDRAW_DISABLED - Item is displayed and has a number, but can't be selected.&lt;br /&gt;
* ITEMDRAW_RAWLINE - Item is displayed, but doesn't have a number assigned to it and thus can't be selected&lt;br /&gt;
* ITEMDRAW_NOTEXT - Draws an item with no text.  Not very useful.&lt;br /&gt;
* ITEMDRAW_SPACER - Item is blank, but has a number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_IGNORE - Item is blank with no number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_CONTROL - Don't use this one.  It's used for the items SourceMod automatically adds.&lt;br /&gt;
&lt;br /&gt;
Be aware that if your CreateMenu second argument includes MenuAction_DrawItem or MENU_ACTIONS_ALL and you don't actually implement the MenuAction_DrawItem callback (or implement it and don't return the current item's style if you don't change it), your style here will be completely ignored.&lt;br /&gt;
&lt;br /&gt;
==== menu.ExitButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.ExitButton = false;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defaults to true.&lt;br /&gt;
&lt;br /&gt;
It set to false, the menu won't have an exit button.&lt;br /&gt;
&lt;br /&gt;
==== menu.ExitBackButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.ExitBackButton = false;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(This isn't in the code above, but it should be mentioned) &lt;br /&gt;
&lt;br /&gt;
Defaults to false.&lt;br /&gt;
&lt;br /&gt;
Should only be used if the menu is a submenu, with the menu set up to check the cancel reason to see if the ExitBack action was used.&lt;br /&gt;
&lt;br /&gt;
If set to true, replaces the Exit item with the Back item.  The Back item still cancels the menu, but has a separate cancel reason.&lt;br /&gt;
&lt;br /&gt;
This can be used to dynamically set if a menu is being called as its own menu or as a submenu.&lt;br /&gt;
&lt;br /&gt;
==== menu.Display ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.Display(client, 20);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DisplayMenu takes 2 arguments:&lt;br /&gt;
&lt;br /&gt;
A Menu handle, a client index, and the amount of time in seconds to show the menu.&lt;br /&gt;
&lt;br /&gt;
If you want the menu to show forever, pass MENU_TIME_FOREVER as the third argument.&lt;br /&gt;
&lt;br /&gt;
=== MenuHandler1 ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MenuHandler1 is a function whose signature matches the MenuHandler callback.  It can be named something other than MenuHandler1. It must always be public and it will always have these arguments: Handle, MenuAction, cell, and cell in that order.&lt;br /&gt;
&lt;br /&gt;
The Handle argument is always the menu that called the handler.&lt;br /&gt;
&lt;br /&gt;
The MenuAction argument is always one of 7 actions for a standard menu.  They are:  MenuAction_Start, MenuAction_Display, MenuAction_Select, MenuAction_Cancel, MenuAction_End, MenuAction_DrawItem, and MenuAction_DisplayIitem.  We will discuss each of these as we reach their code.&lt;br /&gt;
&lt;br /&gt;
The two cell arguments meaning depend on the MenuAction argument. '''A common mistake is to assume param1 is the client.''' This is incorrect for MenuAction_Start, MenuAction_End, MenuAction_VoteEnd, MenuAction_VoteStart, and MenuAction_VoteCancel.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Start ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: not set&lt;br /&gt;
* param2: not set&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Start doesn't set param1 and param2.  It is fired when the menu is displayed to one or more users using DisplayMenu, DisplayMenuAtItem, VoteMenu, or VoteMenuToAll.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Display ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuPanel Handle&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Display is called once for each user a menu is displayed to.  param1 is the client, param2 is the MenuPanel handle.&lt;br /&gt;
&lt;br /&gt;
SetPanelTitle is used to change the menu's title based on the language of the user viewing it using the Translations system.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Select ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Select is called when a user selects a non-control item on the menu (something added using AddMenuItem). param1 is the client, param2 is the menu position of the item the client selected.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Cancel ====&lt;br /&gt;
&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Cancel is called whenever a user closes a menu or it is closed for them for another reason.  param1 is the client, param2 is the close reason.&lt;br /&gt;
&lt;br /&gt;
The close reasons you can receive are:&lt;br /&gt;
&lt;br /&gt;
* MenuCancel_Disconnected - The client got disconnected from the server.&lt;br /&gt;
* MenuCancel_Interrupted - Another menu opened, automatically closing our menu.&lt;br /&gt;
* MenuCancel_Exit - The client selected Exit. Not called if SetMenuExitBack was set to true. Not called if SetMenuExit was set to false.&lt;br /&gt;
* MenuCancel_NoDisplay - Our menu never displayed to the client for whatever reason.&lt;br /&gt;
* MenuCancel_Timeout - The menu timed out. Not called if the menu time was MENU_TIME_FOREVER.&lt;br /&gt;
* MenuCancel_ExitBack - The client selected Back. Only called if SetMenuExitBack has been called and set to true before the menu was sent. Not called if SetMenuExit was set to false.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_End ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: MenuEnd reason&lt;br /&gt;
* param2: If param1 is MenuEnd_Cancelled, the MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_End is called when ''all'' clients have closed a menu or vote.  For menus that are not going to be redisplayed, it is required that you call CloseHandle on the menu here.&lt;br /&gt;
&lt;br /&gt;
The parameters are rarely used in MenuAction_End.  param1 is the menu end reason. param2 depends on param1.&lt;br /&gt;
&lt;br /&gt;
The end reasons you can receive for normal menus are:&lt;br /&gt;
&lt;br /&gt;
* MenuEnd_Selected - The menu closed because an item was selected (MenuAction_Select was fired)&lt;br /&gt;
* MenuEnd_Cancelled - The menu was cancelled (MenuAction_Cancel was fired), cancel reason is in param2; cancel reason can be any of the ones listed in MenuAction_Cancel except MenuCancel_Exit or MenuCancel_ExitBack&lt;br /&gt;
* MenuEnd_Exit - The menu was exited via the Exit item (MenuAction_Cancel was fired with param2 set to MenuCancel_Exit)&lt;br /&gt;
* MenuEnd_ExitBack - The menu was exited via the ExitBack item (MenuAction_Cancel was fired with param 2 set to MenuCancel_ExitBack)&lt;br /&gt;
&lt;br /&gt;
Note: You do '''not''' have the client index during this callback, so it's far too late to do anything useful with this information.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DrawItem ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: new ITEMDRAW properties or style from GetMenuItem.  Since 0 is ITEMDRAW_DEFAULT, returning 0 clears all styles for this item.&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its draw style here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string and menu style.&lt;br /&gt;
&lt;br /&gt;
You should return the style you want the menu item to have.  In our example, if client 1 is viewing the menu, we want CHOICE3 to be disabled.&lt;br /&gt;
&lt;br /&gt;
the return value is a bitfield, so to apply multiple styles, you do something like this:&lt;br /&gt;
&lt;br /&gt;
		return ITEMDRAW_NOTEXT | ITEMDRAW_SPACER;&lt;br /&gt;
&lt;br /&gt;
'''Failing to return the current item's style if you don't change the style is a programmer error.'''&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DisplayItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: return value from RedrawMenuItem or 0 for no change&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its text here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
This callback is intended for use with the Translation system.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
Once we have the info string, we compare our item to it and apply the appropriate translation string.&lt;br /&gt;
&lt;br /&gt;
If we change an item, we have to call RedrawMenuItem and return the value it returns.  If we do not change an item, we must return 0.&lt;br /&gt;
&lt;br /&gt;
==== return ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	return 0;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you handle MenuAction_DrawItem or MenuAction_DisplayItem, you will get the following warning if you fail to return 0 after the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;warning 209: function &amp;quot;MenuHandler1&amp;quot; should return a value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is because MenuAction_DrawItem and MenuAction_DisplayItem have return values, while the other actions only return 0.&lt;br /&gt;
&lt;br /&gt;
== The End ==&lt;br /&gt;
Hopefully this walk through a simple menu helped you understand why each call is being made where.  Menus have some options that we didn't explore here, such as disabling pagination (which is enabled by default).  You may want to refer to the main Menu documentation for more details.&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User_talk:Asherkin&amp;diff=10230</id>
		<title>User talk:Asherkin</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User_talk:Asherkin&amp;diff=10230"/>
		<updated>2016-11-30T16:45:32Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Reverted edits by TheY4Kman (talk) to last revision by Asherkin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Lowercase_title}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10176</id>
		<title>Introduction to SourcePawn 1.7</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_1.7&amp;diff=10176"/>
		<updated>2016-06-27T21:22:18Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide is designed to give you a very basic overview to fundamentals of scripting in SourcePawn. [[Pawn]] is a &amp;quot;scripting&amp;quot; language used to embed functionality in other programs. That means it is not a standalone language, like C++ or Java, and its details will differ based on the application. SourcePawn is the version of Pawn used in [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
This guide does not tell you how to write SourceMod plugins; it is intended as an overview of the syntax and semantics of the language instead. Read the separate article, [[Introduction to SourceMod Plugins]] for SourceMod API specifics. &lt;br /&gt;
&lt;br /&gt;
=Non-Programmer Intro=&lt;br /&gt;
This section is intended for non-programmers. If you're still confused, you may want to pick up a book on another language, such as PHP, Python, or Java, to get a better idea of what programming is like.&lt;br /&gt;
&lt;br /&gt;
==Symbols/Keywords==&lt;br /&gt;
A symbol is a series of letters, numbers, and/or underscores, that uniquely represents something. Symbols are case-sensitive, and usually start with a letter.&lt;br /&gt;
&lt;br /&gt;
There are a few reserved symbols that have special meaning. For example, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; are special constructs in the language that will explained later. They cannot be used as symbol names.&lt;br /&gt;
&lt;br /&gt;
==Variables==&lt;br /&gt;
There a few important constructs you should know before you begin to script. The first is a '''variable'''. A variable is a symbol, or name, that holds data. For example, the variable &amp;quot;a&amp;quot; could hold the number &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, et cetera. Since a variable holds data, it also allocates the memory needed to store that data.&lt;br /&gt;
&lt;br /&gt;
In addition to a name, variables have a '''type'''. A type tells the program how to interpret the data, and how much memory the data will use. Pawn has three types of data that are most commonly used:&lt;br /&gt;
* Integers, using the &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; type. Integer types may store a whole number from -2147483648 to 2147483647.&lt;br /&gt;
* Floats, using the &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; type. Float types may store fractional numbers in a huge range, though they are not as precise as integers.&lt;br /&gt;
* Characters, using the &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; type. Character types store one byte of character information, typically an [http://www.asciitable.com/ ASCII] character.&lt;br /&gt;
* Booleans, using the &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; type. Booleans store either true or false.&lt;br /&gt;
&lt;br /&gt;
Example of creating variables and assigning values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
The next important concept is '''functions'''. Functions are symbols or names that perform an action. When you invoke, or call them, they carry out a specific sequence of code and then return a result. There are a few types of functions, but every function is activated the same way. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // Calls the &amp;quot;show&amp;quot; function, and gives it the number 56.&lt;br /&gt;
enable();     // Calls the &amp;quot;enable&amp;quot; function with no values.&lt;br /&gt;
bool visible = show(a);    //Calls the &amp;quot;show&amp;quot; function, stores its result in a variable.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every piece of data passed to a function is called a '''parameter'''. A function can have any number of parameters (there is a &amp;quot;reasonable&amp;quot; limit of 32 in SourceMod). Parameters will be explained further in the article.&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
Note any text that appears after a &amp;quot;//&amp;quot; is considered a &amp;quot;comment&amp;quot; and is not actual code. There are two comment styles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Double slash, everything following on that line is ignored.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Multi-line comment, everything in between the asterisks is ignored. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Block Coding==&lt;br /&gt;
The next concept is block coding. You can group code into &amp;quot;blocks&amp;quot; separated by { and }. This effectively makes one large block of code act as one statement. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block coding using braces is used everywhere in programming. Blocks of code can be nested within each other. It is a good idea to adapt a consistent and readable indentation style early on to prevent spaghetti-looking code.&lt;br /&gt;
&lt;br /&gt;
=Language Paradigms=&lt;br /&gt;
Pawn may seem similar to other languages, like C, but it has fundamental differences. It is not important that you immediately understand these differences, but they may be helpful if you're familiar with another language already.&lt;br /&gt;
*'''Pawn is sort of typed.''' Before SourceMod 1.7, Pawn did not have types. Older code and older natives will reflect this by using tags and the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; keyword. As of SourceMod 1.7, we recommend that all code use types. For more information see [[SourcePawn Transitional Syntax]].&lt;br /&gt;
*'''Pawn is not garbage collected.''' Pawn, as a language, has no built-in memory allocation, and thus has no garbage. If a function allocates memory, you may be responsible for freeing it.&lt;br /&gt;
*'''Pawn is not object oriented.''' Pawn does not have structs or objects. As of SourceMod 1.7, it has limited sugaring for treating some data types as objects, but users cannot create their own objects or classes.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe. &lt;br /&gt;
*'''Pawn is compiled.''' Pawn is compiled to an intermediate, machine-independent code, which is stored in a &amp;quot;.smx&amp;quot; file. When loading .smx files, SourceMod translates this code to machine code for the platform and CPU it's running on.&lt;br /&gt;
&lt;br /&gt;
Early language design decisions were made by ITB CompuPhase. It is designed for low-level embedded devices and is thus very small and very fast.&lt;br /&gt;
&lt;br /&gt;
=Variables=&lt;br /&gt;
Pawn currently supports the following basic variable types:&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - true or false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - an 8-bit ASCII character.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - a 32-bit signed integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - a 32-bit IEEE-754 floating point number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - the base type of a SourceMod object&lt;br /&gt;
&lt;br /&gt;
Other types may exist when defined in include files - for example, enums create new types for named integers, and many types derive from &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Strings, currently, are 0-terminated arrays of &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;s. They're described a little further ahead.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Below we include some examples of variable declarations, both valid and invalid. Keep in mind that SourcePawn has recently added new syntax, and that's what's documented below. Older code may use older declaration syntax, which is no longer supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Invalid variable usage:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // Type mismatch. 5.0 is a float.&lt;br /&gt;
float b = 5;         // Type mismatch. 5 is an integer.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a variable is not assigned upon declaration, it will be set to 0. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // Set to 0&lt;br /&gt;
float b;      // Set to 0.0&lt;br /&gt;
bool c;       // Set to false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignment==&lt;br /&gt;
Variables can be re-assigned data after they are created. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a list. Arrays are useful for storing multiple pieces of data in one variable, or mapping one type of data to another.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
An array is declared using brackets. Some examples of arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // Stores 32 integers.&lt;br /&gt;
float origin[3];     // Stores 3 floating point numbers&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, arrays are initialized to 0. You can assign them different default values, however:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // Stores 1, 2, 3, 4, 5.&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // Stores 1.0, 2.0, 3.0.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can leave out the array size if you're going to pre-assign data to it. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The compiler will automatically deduce that you intended an array of size 5.&lt;br /&gt;
&lt;br /&gt;
When array is declared with brackets after its name, Pawn considers that array to have a '''fixed size'''. The size of a fixed-size array is always known. Some arrays can be '''dynamically sized''', by putting the brackets before the name. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates an array of size &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt;, which could be anything, so the size of the array is not known until the array is allocated.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Using an array is just like using a normal variable. The only difference is the array must be '''indexed'''. Indexing an array means choosing the element which you wish to use.&lt;br /&gt;
&lt;br /&gt;
For example, here is an example of the above code using indexes:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the '''index''' is what's in between the brackets. The index always starts from 0. That is, if an array has N elements, its valid indexes are from 0 to N-1. Accessing the data at these indexes works like a normal variable.&lt;br /&gt;
&lt;br /&gt;
Using an incorrect index will cause an error. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look correct, but 5 is not a valid index. The highest valid index is 4.&lt;br /&gt;
&lt;br /&gt;
You can use any expression as an index. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // Set a = 1&lt;br /&gt;
numbers[a] = 4;          // Set numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; // Set numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expressions will be discussed in depth later in the article.&lt;br /&gt;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a construct for storing text (or even raw binary data). A string is just an array of characters, except that the final character must be 0 (called the null terminator). Without a null terminator, Pawn would not know where to stop reading the string. All strings are [http://en.wikipedia.org/wiki/UTF-8 UTF-8] in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
In general, you must have an idea of how large a string will be before you store it. SourcePawn does not yet have the capability of pre-determining storage space for strings.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are usually declared as arrays. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are equivalent to doing:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although strings are rarely initialized in this manner, it is very important to remember the concept of the null terminator, which signals the end of a string. The compiler, and most SourceMod functions will automatically null-terminate for you, so it is mainly important when manipulating strings directly.&lt;br /&gt;
&lt;br /&gt;
Note that a string is enclosed in double-quotes, but a character is enclosed in single quotes.&lt;br /&gt;
&lt;br /&gt;
==Characters==&lt;br /&gt;
A character of text can be used in either a String or a cell. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Set clam to 'D'&lt;br /&gt;
text[0] = 'A';      //Change the 'C' to 'A', it is now 'Arab'&lt;br /&gt;
clam = text[0];     //Set clam to 'A'&lt;br /&gt;
text[1] = clam;     //Change the 'r' to 'A', is is now 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you can't do is mix character arrays with strings. The internal storage is different. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // Invalid.&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // Valid, but NOT A STRING.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Functions=&lt;br /&gt;
Functions, as stated before, are isolated blocks of code that perform an action. They can be invoked, or '''called''', with '''parameters''' that give specific options.&lt;br /&gt;
&lt;br /&gt;
There are two types of ways functions are called:&lt;br /&gt;
*'''direct call''' - You specifically call a function in your code.&lt;br /&gt;
*'''callback''' - The application calls a function in your code, as if it were an event trigger.&lt;br /&gt;
&lt;br /&gt;
There are six types of functions:&lt;br /&gt;
*'''native''': A direct, internal function provided by the application.&lt;br /&gt;
*'''public''': A callback function that is visible to the application and other scripts.&lt;br /&gt;
*'''normal''': A normal function that only you can call.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': A normal function provided by an include file. If unused, it won't be compiled.&lt;br /&gt;
*'''forward''': This function is a global event provided by the application. If you implement it, it will be a callback.&lt;br /&gt;
&lt;br /&gt;
All code in Pawn must exist in functions. This is in contrast to languages like PHP, Perl, and Python which let you write global code. That is because Pawn is a callback-based language: it responds to actions from a parent application, and functions must be written to handle those actions. Although our examples often contain free-floating code, this is purely for demonstration purposes. Free-floating code in our examples implies the code is part of some function.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Unlike variables, functions do not need to be declared before you use them. Functions have two pieces, the '''signature''' and the '''body'''. The signature contains the name of your function and the parameters it will accept. The body is the contents of its code.&lt;br /&gt;
&lt;br /&gt;
Example of a function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple function. The prototype is this line:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - Return value type (integer).&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Name of the function.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - First parameter, an integer.&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - Second parameter, an integer.&lt;br /&gt;
&lt;br /&gt;
The body is a block of code. It creates a new variable, called &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, and assigns it the value of the two parameters added together (more on expressions later). The important thing to notice is the &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; statement, which tells the function to end and return a value to the caller of the function. All functions return something on completion, unless they return a special type called &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input, and it can return any non-array type.&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that cells are passed '''by value'''. That is, their value cannot be changed by the function. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would not change the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. That is because a copy of the value in &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is passed instead of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; itself. &lt;br /&gt;
&lt;br /&gt;
More examples of functions will be provided throughout the article.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Public functions are used to implement callbacks. You should not create a public function unless it is specifically implementing a callback. For example, here are two callbacks from &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement and receive these two events, you would write functions as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''public''' keyword signals to the parent application that it should attach the function to the appropriate forwarded event.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by SourceMod. You can call them as if they were a normal function. For example, SourceMod has the following function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be called like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded will be 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Array Parameters==&lt;br /&gt;
You can pass arrays or Strings as parameters. It is important to note that these are passed '''by reference'''. That is, rather than making a copy of the data, the data is referenced directly. There is a simple way of explaining this more concretely.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function sets the given index in the array to a given value. When it is run on our example array, it changes index 2 to from the value 3 to 29. I.e.:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note two important things here. First, arrays are not copied when they are passed to functions - they are passed ''by reference'', so the view of the array is consistent at all times. Second, the brackets changed position in our function signature. This is because our function accepts an array of any size, and since we don't know the size, we must use the dynamic array syntax.&lt;br /&gt;
&lt;br /&gt;
To prevent an array from being modified in a function, you can mark it as &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. This will raise an error on code that attempts to modify it. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Won't compile&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is a good idea to use &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; in array parameters if you know the array won't be modified; this can prevent coding mistakes.&lt;br /&gt;
&lt;br /&gt;
=Expressions=&lt;br /&gt;
Expressions are exactly the same as they are in mathematics. They are groups of operators/symbols which evaluate to one piece of data. They are often parenthetical (comprised of parenthesis). They contain a strict &amp;quot;order of operations.&amp;quot;  They can contain variables, functions, numbers, and expressions themselves can be nested inside other expressions, or even passed as parameters.&lt;br /&gt;
&lt;br /&gt;
The simplest expression is a single number. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Returns the number 0&lt;br /&gt;
(0); //Returns the number 0 as well&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although expressions can return any value, they are also said to either return ''zero or non-zero''. In that sense, ''zero'' is ''false'', and ''non-zero'' is ''true''. For example, -1 is '''true''' in Pawn, since it is non-zero. Do not assume negative numbers are false.&lt;br /&gt;
&lt;br /&gt;
The order of operations for expressions is similar to C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Here are some example expressions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Evaluates to 11&lt;br /&gt;
5 * 6 + 3;               //Evaluates to 33&lt;br /&gt;
5 * (6 + 3);             //Evaluates to 45&lt;br /&gt;
5.0 + 2.3;               //Evaluates to 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, evaluates to 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Evaluates to -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted, expressions can contain variables, or even functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //Evaluates to 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  String manipulation routines may be found in the string.inc file located in the include subdirectory. They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Operators==&lt;br /&gt;
There are a few extra helpful operators in Pawn. The first set simplifies self-aggregation expressions. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is true of the following operators in Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additionally, there are increment/decrement operators:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Can be simplified as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an advanced note, the ++ or -- can come before the variable (pre-increment, pre-decrement) or after the variable (post-increment, post-decrement). The difference is in how the rest of the expression containing them sees their result.&lt;br /&gt;
&lt;br /&gt;
* ''Pre:'' The variable is incremented before evaluation, and the rest of the expression sees the new value.&lt;br /&gt;
* ''Post:'' The variable is incremented after evaluation, and the rest of the expression sees the old value.&lt;br /&gt;
&lt;br /&gt;
In other words, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; while &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; evaluates to the value of &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. In both cases &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is incremented by &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In (1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''old'' value ''before'' it is incremented to &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;, but in (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is assigned &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;'s ''int'' value ''after'' it is incremented to &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Comparison Operators==&lt;br /&gt;
There are six operators for comparing two values numerically, and the result is either true (non-zero) or false (zero):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - True if a and b have the same value.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - True if a and b have different values.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - True if a is greater than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - True if a is greater than or equal to b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - True if a is less than b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - True if a is less than or equal to b&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Evaluates to true because 1 is not equal to 3.&lt;br /&gt;
(3 + 3 == 6);     //Evaluates to true because 3+3 is 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Evaluates to false because 3 is less than 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays or strings. That is, you cannot compare either using &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
These truth values can be combined using three boolean operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - True if both a and b are true. False if a or b (or both) is false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - True if a or b (or both) is true. False if both a and b are false.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - True if a is false. False if a is true.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Evaluates to true because the expression 1 is true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Evaluates to false because the expression 0 is false&lt;br /&gt;
(!1 || 0);        //Evaluates to false because !1 is false.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Left/Right Values==&lt;br /&gt;
Two important concepts are left-hand and right-hand values, or l-values and r-values. An l-value is what appears on the left-hand side of a variable assignment, and an r-value is what appears on the right side of a variable assignment.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; is an l-value and &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is an r-value.&lt;br /&gt;
&lt;br /&gt;
The rules:&lt;br /&gt;
*'''Expressions are never l-values'''.&lt;br /&gt;
*'''Variables are both l-values and r-values'''.&lt;br /&gt;
&lt;br /&gt;
=Conditionals=&lt;br /&gt;
Conditional statements let you only run code if a certain condition is matched.&lt;br /&gt;
&lt;br /&gt;
==If Statements==&lt;br /&gt;
If statements test one or more conditions. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if the expression was true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They can be extended to handle more cases as well:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Code  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also handle the case of no expression being matched. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Code that will run if no expressions were true */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch Statements==&lt;br /&gt;
Switch statements are restricted if statements. They test one expression for a series of possible values. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* code */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Code */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* will run if no case matched */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike some other languages, switches are not fall-through. That is, multiple cases will never be run. When a case matches its code is executed, and the switch is then immediately terminated.&lt;br /&gt;
&lt;br /&gt;
=Loops=&lt;br /&gt;
Loops allow you to conveniently repeat a block of code while a given condition remains true. &lt;br /&gt;
&lt;br /&gt;
==For Loops==&lt;br /&gt;
For loops are loops which have four parts:&lt;br /&gt;
*The '''initialization''' statement - run once before the first loop.&lt;br /&gt;
*The '''condition''' statement - checks whether the next loop should run, including the first one. The loop terminates when this expression evaluates to false.&lt;br /&gt;
*The '''iteration''' statement - run after each loop.&lt;br /&gt;
*The '''body''' block - run each time the '''condition''' statement evaluates to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* initialization */ ; /* condition */ ; /* iteration */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A simple example is a function to sum an array:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down:&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - Creates a new variable for the loop, sets it to 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Only runs the loop if &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. This ensures that the loop stops reading at a certain point. In this case, we don't want to read invalid indexes in the array.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Increments &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; by one after each loop. This ensures that the loop doesn't run forever; eventually &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; will become too big and the loop will end.&lt;br /&gt;
&lt;br /&gt;
Thus, the &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; function will loop through each valid index of the array, each time adding that value of the array into a sum. For loops are very common for processing arrays like this.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While loops are less common than for loops but are actually the simplest possible loop. They have only two parts:&lt;br /&gt;
*The '''condition''' statement - checked before each loop. The loop terminates when it evaluates to false.&lt;br /&gt;
*The '''body''' block - run each time through the loop.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue. Every for loop can be rewritten as a while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* initialization */&lt;br /&gt;
while ( /* condition */ )&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
   /* iteration */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the previous for loop rewritten as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also '''do...while''' loops which are even less common. These are the same as while loops except the condition check is AFTER each loop, rather than before. This means the loop is always run at least once. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* body */&lt;br /&gt;
}&lt;br /&gt;
while ( /* condition */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Loop Control==&lt;br /&gt;
There are two cases in which you want to selectively control a loop:&lt;br /&gt;
*'''skipping''' one iteration of the loop but continuing as normal, or;&lt;br /&gt;
*'''breaking''' the loop entirely before it's finished.&lt;br /&gt;
&lt;br /&gt;
Let's say you have a function which takes in an array and searches for a matching number. You want it to stop once the number is found:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Returns the array index where the value is, or -1 if not found.&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int array[], int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Certainly, this function could simply &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; instead, but the example shows how &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; will terminate the loop.&lt;br /&gt;
&lt;br /&gt;
Similarly, the &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; keyword skips an iteration of a loop. For example, let's say we wanted to sum all even numbers:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Skip the rest of this loop iteration */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&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;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code. That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''. They can be seen by any function. However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level. Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked. Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself. Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in. That is, a variable at global scope is visible globally to all functions. A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function. The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      int B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block. That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within). As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1(int size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0. Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;int float or char&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope. It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   static int counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again. It does not exist on the stack. That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function. Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant. &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables. As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static int counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=10093</id>
		<title>Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=10093"/>
		<updated>2015-12-28T01:10:04Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Removed /* Client and Entity Indexes */ section due to being mostly wrong.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic introduction to writing a [[SourceMod]] plugin.  If you are not familiar with the SourcePawn language, it is recommended that you at least briefly read the [[Introduction to SourcePawn]] article.&lt;br /&gt;
&lt;br /&gt;
For information on compiling plugins, see [[Compiling SourceMod Plugins]]. You can use [http://www.crimsoneditor.com/ Crimson Editor], [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ Pawn Studio] or any other text editor you're comfortable with to write plugins.&lt;br /&gt;
&lt;br /&gt;
=Starting from scratch=&lt;br /&gt;
Open your favorite text editor and create a new empty file. When you have an empty file you can just start writing code using the core language, however, you will not be able to use any of SourceMod features because the compiler does not now about them. This is done deliberately so it is possible to use SourcePawn outside of SourceMod. But since we are writing a SourceMod plugin, it is a good idea to enable access to SourceMod features first. This it done using &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; directive. It tells compiler to &amp;quot;paste&amp;quot; the code from another file into yours.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
How does this work? First of all, note that we enclosed file name into angle brackets. Angle brackets tell the compiler to look in the default include directory. By default, it is '''scripting/include'''. You can open it right now and see a lot of inc files there. Those are SourceMod include files that describe various functions, tags and other features available for SourceMod plugins. The files are plain-text and you are encouraged to read them. You will notice however, that there's not much code in there, certainly not enough to implement all the great features of SourceMod, so where are they? They are implemented inside a SourceMod core which is written in C++ and is compiled into binary files which end up in '''bin''' directory. So how does your SourcePawn code and SM core link together if compiler doesn't know about existence of the latter? SourceMod include files are written specially, so they say that the implementation of functions is ''somewhere else''. Compiler understands that and generate a special code that says that this function call is going outside. When SourceMod loads your plugin, it inspects these bits of code and substitutes it's own internal functions instead. This is called [http://en.wikipedia.org/wiki/Dynamic_linking dynamic linking].&lt;br /&gt;
&lt;br /&gt;
=Setting up plugin info=&lt;br /&gt;
Now that we got access to SourceMod features, it is time to setup the information that will be displayed via &amp;lt;tt&amp;gt;sm plugins list&amp;lt;/tt&amp;gt; command. No one likes unnamed plugins. To do that we are going to look inside '''sourcemod.inc''' file and see the format that information should be declared. It's always helpful to look inside SM include files to find out information you don't know. There is also an [http://docs.sourcemod.net/api/ API documentation] but it can be outdated and it only has SM core files so if your plugin are going to use any third party extension or another plugin, you will have to study inc files. So, open '''sourcemod.inc''' and scroll down a bit until you see this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Plugin public information.&lt;br /&gt;
 */&lt;br /&gt;
struct Plugin&lt;br /&gt;
{&lt;br /&gt;
   public const char[] name;		/**&amp;lt; Plugin Name */&lt;br /&gt;
   public const char[] description;	/**&amp;lt; Plugin Description */&lt;br /&gt;
   public const char[] author;		/**&amp;lt; Plugin Author */&lt;br /&gt;
   public const char[] version;		/**&amp;lt; Plugin Version */&lt;br /&gt;
   public const char[] url;			/**&amp;lt; Plugin URL */&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
and this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Declare this as a struct in your plugin to expose its information.&lt;br /&gt;
 * Example:&lt;br /&gt;
 *&lt;br /&gt;
 * public Plugin myinfo =&lt;br /&gt;
 * {&lt;br /&gt;
 *    name = &amp;quot;My Plugin&amp;quot;,&lt;br /&gt;
 *    //etc&lt;br /&gt;
 * };&lt;br /&gt;
 */&lt;br /&gt;
public Plugin myinfo;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It tells us that we need to create a global public variable &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; which must be of type &amp;lt;tt&amp;gt;Plugin&amp;lt;/tt&amp;gt; which is a struct with 5 fields which themselves are strings. It may sound complicated for a beginner but it's easy. Let's go ahead and create one:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Plugin myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; keyword means that SourceMod will be able to directly access our variable. &amp;lt;tt&amp;gt;Plugin:&amp;lt;/tt&amp;gt; defines a type of our variable. &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; is, obviously, a name of our variable as required by SourceMod. You see that we initialize it right away. This is preferred way to do when filling out plugin info.&lt;br /&gt;
&lt;br /&gt;
After that the full code of your plugin should look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Getting code to run=&lt;br /&gt;
We already include SourceMod features and filled up or plugin info. We now have a perfectly well formed plugin which can be compiled and loaded by SourceMod. However, there is one problem - it does nothing. You might be tempted to just start writing a code after &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; declaration just to see that it will not compile. SourcePawn, unlike other scripting languages like Lua, does not allow a code to be outside of functions. After reading that, you may probably want to just define some function, name it &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; probably, compile and load a plugin and see that your code never gets called. So how do we make SourceMod call our code? For this exact reason we have forwards. Forwards are function prototypes declared by one party that can be implemented by another party as a [http://en.wikipedia.org/wiki/Callback_%28computer_programming%29 callback]. When a first party starts a forward call, all parties that have matching callbacks receive the call. SourceMod declares a plenty of interesting forwards that we can implement. As you can see, forwards are the only way to get our code executed, keep that in mind. So let's implement &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt; forward. As you may have guessed, it is called when our plugin starts. To do that, we'll have to look up the declaration of &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt;. It is declared inside '''sourcemod.inc''', a file we are already familiar with, let's find it:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Called when the plugin is fully initialized and all known external references &lt;br /&gt;
 * are resolved. This is only called once in the lifetime of the plugin, and is &lt;br /&gt;
 * paired with OnPluginEnd().&lt;br /&gt;
 *&lt;br /&gt;
 * If any run-time error is thrown during this callback, the plugin will be marked &lt;br /&gt;
 * as failed.&lt;br /&gt;
 *&lt;br /&gt;
 * It is not necessary to close any handles or remove hooks in this function.  &lt;br /&gt;
 * SourceMod guarantees that plugin shutdown automatically and correctly releases &lt;br /&gt;
 * all resources.&lt;br /&gt;
 *&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
forward void OnPluginStart();&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Empty parentheses tells us that no arguments are passed inside this forward, &amp;lt;tt&amp;gt;@noreturn&amp;lt;/tt&amp;gt; inside documentation tells us that we don't have to return anything, pretty simple forward. So how to write a correct callback for it? Firstly, our callback must have the same name, so it's &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt;, secondly, our callback should have the same number of arguments, none in this case, and lastly, SourceMod needs to be able to call our callback so it needs to be &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. So the implementation looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we can write code inside curly braces and it will be executed when our plugin starts. Let's output &amp;lt;tt&amp;gt;&amp;quot;Hello world!&amp;quot;&amp;lt;/tt&amp;gt; to server console. To do that we are going to use &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt; function. It is declared inside '''console.inc''', however, we don't need to manually include '''console.inc''' because it is included automatically as part of '''sourcemod.inc'''.&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sends a message to the server console.&lt;br /&gt;
 *&lt;br /&gt;
 * @param format		Formatting rules.&lt;br /&gt;
 * @param ...			Variable number of format parameters.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native int PrintToServer(const char[] format, any ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
As you can see, this is a native function. It is implemented inside SM core. Judging by it's arguments, we can see that it is a [[Format_Class_Functions_%28SourceMod_Scripting%29|format class function]]. However, we don't need any formatting right now, so let's just pass &amp;lt;tt&amp;gt;&amp;quot;Hello world!&amp;quot;&amp;lt;/tt&amp;gt; string as an only argument:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
That's it! The full code of your plugin should look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Compile and load your plugin on your server and see for yourself that the message is displayed in server console.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
Pawn requires '''include files''', much like C requires header files.  Include files list all of the structures, functions, callbacks, and tags that are available.  There are three types of include files:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; and anything it includes.  These are all provided by SourceMod's Core.&lt;br /&gt;
*'''Extension''' - adds a dependency against a certain extension.&lt;br /&gt;
*'''Plugin''' - adds a dependency against a certain plugin.&lt;br /&gt;
&lt;br /&gt;
Include files are loaded using the &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; compiler directive.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [https://sm.alliedmods.net/new-api/console/RegAdminCmd RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [https://sm.alliedmods.net/new-api/console/ConCmd Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Command_MySlap(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it! This is because you're not returning Plugin_Handled in your callback. Since you haven't,  SourceMod believes you didn't want the Source Engine to know the command was registered, and it handles it so. The reason SourceMod expects your function to return Plugin_Handled is because of the Action tag you put in your function's prototype. The Action tag specifies that Command_MySlap must return one of four things. See the [https://sm.alliedmods.net/new-api/core/Action Action] enumeration in the sourcemod API to learn more about these return types and when to use them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action Command_MySlap(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything. This is because returning &amp;quot;Plugin_Handled&amp;quot; in a command callback will prevent the engine from processing the command. The engine will never even see that the command was run. This is what you will want to do if you are registering a completely new command through SourceMod.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [https://sm.alliedmods.net/new-api/console/GetCmdArg GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [https://sm.alliedmods.net/new-api/helpers/FindTarget FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [https://sm.alliedmods.net/new-api/sdktools_functions/SlapPlayer SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [https://sm.alliedmods.net/new-api/console/ReplyToCommand ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Command_MySlap(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	char arg1[32], arg2[32];&lt;br /&gt;
	int damage;&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	int target = FindTarget(client, arg1);&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	char name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [https://sm.alliedmods.net/new-api/sourcemod/AutoExecConfig AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;ConVar sm_myslap_damage = null;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Command_MySlap(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	char arg1[32], arg2[32];&lt;br /&gt;
	int damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [https://sm.alliedmods.net/new-api/logging/LogAction LogAction()] and [https://sm.alliedmods.net/new-api/console/ShowActivity2 ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	char name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [https://sm.alliedmods.net/new-api/commandfilters/ProcessTargetString ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ConVar sm_myslap_damage = null;&lt;br /&gt;
&lt;br /&gt;
public Plugin myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;);&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Command_MySlap(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	char arg1[32], arg2[32];&lt;br /&gt;
	int damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	char target_name[MAX_TARGET_LENGTH];&lt;br /&gt;
	int target_list[MAXPLAYERS], target_count;&lt;br /&gt;
	bool tn_is_ml;&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (int i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage);&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage);&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;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They almost always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   int victim_id = event.GetInt(&amp;quot;userid&amp;quot;);&lt;br /&gt;
   int attacker_id = event.GetInt(&amp;quot;attacker&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   int victim = GetClientOfUserId(victim_id);&lt;br /&gt;
   int attacker = GetClientOfUserId(attacker_id);&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/sourcemod/AskPluginLoad2 AskPluginLoad2()] - Called once, immediately after the plugin is loaded from the disk.  This function can be used to stop a plugin from loading and return a custom error message; return APLRes_Failure and use strcopy on to replace the error string.  All CreateNative and RegPluginLibrary calls should be done here.  &lt;br /&gt;
*[https://sm.alliedmods.net/new-api/sourcemod/OnPluginStart OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/sourcemod/OnAllPluginsLoaded OnAllPluginsLoaded()] - Called once, after all non-late loaded plugins have called OnPluginStart.  &lt;br /&gt;
*[https://sm.alliedmods.net/new-api/sourcemod/OnMapStart OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/sourcemod/OnConfigsExecuted OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/sourcemod/OnMapEnd OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/sourcemod/OnPluginEnd OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/clients/OnClientConnect OnClientConnect()] - Called when a player initiates a connection.  You can block a player from connecting by returning Plugin_Stop and setting rejectmsg to an error message.&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/clients/OnClientConnected OnClientConnected()] - Called after a player connects. Signifies that the player is in-game and IsClientConnected() will return true. '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/clients/OnClientAuthorized OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between OnClientConnected and OnClientPreAdminCheck/OnClientDisconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/clients/OnClientPutInServer OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/clients/OnClientPostAdminCheck OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/clients/OnClientDisconnect OnClientDisconnect()] - Called when a player's disconnection starts.  '''This is paired to OnClientConnected().'''&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/clients/OnClientDisconnect_Post OnClientDisconnect_Post()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnected().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
If you only want to detect when a client initially connects or leaves your server, hook the [[Generic Source Server Events#player_connect|player_connect]] or [[Generic Source Server Events#player_disconnect|player_disconnect]] events respectively.&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Category:SourceMod_Scripting&amp;diff=9968</id>
		<title>Category:SourceMod Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Category:SourceMod_Scripting&amp;diff=9968"/>
		<updated>2015-08-13T18:52:56Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This category contains articles about scripting for SourceMod with SourcePawn.&lt;br /&gt;
&lt;br /&gt;
===Introductions===&lt;br /&gt;
*[[Introduction to SourcePawn 1.7]] - Learning language syntax.&lt;br /&gt;
*[[Introduction to SourceMod Plugins]] - Writing your &amp;quot;first plugin.&amp;quot;&lt;br /&gt;
*[http://docs.sourcemod.net/api API Reference] - Searchable scripting API reference.&lt;br /&gt;
&lt;br /&gt;
===Basic API===&lt;br /&gt;
*[[AutoConfigs (SourceMod Scripting)|AutoConfigs]] - Automatic .cfg creation for cvars.&lt;br /&gt;
*[[Commands (SourceMod Scripting)|Commands]] - Console commands/input.&lt;br /&gt;
*[[ConVars (SourceMod Scripting)|ConVars]] - Console variables (cvars).&lt;br /&gt;
*[[Events (SourceMod Scripting)|Events]] - Half-Life 2 Game Events.&lt;br /&gt;
*[[KeyValues (SourceMod Scripting)|KeyValues]] - KeyValues file parsing/writing.&lt;br /&gt;
*[[Menu API (SourceMod)|Menus]] - Building and drawing menus.&lt;br /&gt;
*[[SQL (SourceMod Scripting)|SQL]] - Using databases (MySQL, SQLite).&lt;br /&gt;
*[[Timers (SourceMod Scripting)|Timers]] - Timed callbacks.&lt;br /&gt;
*[[DataPacks|DataPacks]] -  A good way to store asynchronous data.&lt;br /&gt;
*[[Translations (SourceMod Scripting)|Translations]] - Internationalization.&lt;br /&gt;
*[[Entity References (SourceMod)|Entity References]] - A safe way of storing entities.&lt;br /&gt;
&lt;br /&gt;
===Advanced API===&lt;br /&gt;
*[[Admin API (SourceMod)|Administration API]] - Using the Admin Cache.&lt;br /&gt;
*[[Admin Menu (SourceMod Scripting)|Admin Menu API]] - Attaching to the Admin Menu.&lt;br /&gt;
*[[Creating Natives (SourceMod Scripting)|Creating Natives]] - Exposing API to other plugins.&lt;br /&gt;
*[[Function Calling API (SourceMod Scripting)|Function Calling API]] - Calling external functions.&lt;br /&gt;
*[[Optional Requirements (SourceMod Scripting)|Optional Requirements]] - Managing dependencies.&lt;br /&gt;
*[[SDKTools (SourceMod Scripting)|SDKTools]] - Using the powerful SDK abstraction layer.&lt;br /&gt;
*[[TempEnts (SourceMod SDKTools)|Temporary Entities]] - Using temporary entities.&lt;br /&gt;
&lt;br /&gt;
===Information===&lt;br /&gt;
*[[Format Class Functions (SourceMod Scripting)|Format Class Functions]] - All about text formatting.&lt;br /&gt;
*[[Handles (SourceMod Scripting)|Handles]] - Overview of Handles and some common types.&lt;br /&gt;
*[[Optimizing Plugins (SourceMod Scripting)|Optimizing Plugins]] - Optimization hints.&lt;br /&gt;
*[[Tags (Scripting)|Tags]] - All about tags.&lt;br /&gt;
*[[Vectors Explained (Scripting)|Vectors Explained]] - Explanation of Vector types.&lt;br /&gt;
&lt;br /&gt;
===Resources===&lt;br /&gt;
*[https://sm.alliedmods.net/new-api/ API Reference] - Searchable scripting API reference.&lt;br /&gt;
*[[Entity Properties]] - Explanation of Source entity properties.&lt;br /&gt;
*[[Game Events (Source)|Game Events]] - Game events listings for popular mods.&lt;br /&gt;
*[[Mod TempEnt List (Source)|Temp Entity Lists]] - Temporary entities for popular mods.&lt;br /&gt;
*[[SourceMod Profiler]] - Performance tracking and optimizing.&lt;br /&gt;
*[[Vice_keys]] - Decryption keys for ctx files&lt;br /&gt;
*[[Weapon Names(Source)]] - Weapon Names / weapon entity names&lt;br /&gt;
[[Category:SourceMod]]&lt;br /&gt;
[[Category:SourceMod Development]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Required_Versions_(SourceMod&amp;diff=9723</id>
		<title>Required Versions (SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Required_Versions_(SourceMod&amp;diff=9723"/>
		<updated>2014-11-01T12:24:35Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Redirected page to Required Versions (SourceMod)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Required Versions (SourceMod)]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Required_Versions_(SourceMod&amp;diff=9722</id>
		<title>Required Versions (SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Required_Versions_(SourceMod&amp;diff=9722"/>
		<updated>2014-11-01T12:24:15Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Redirected page to Creating Required Versions (SourceMod)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Creating Required Versions (SourceMod)]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Template:Pr&amp;diff=9686</id>
		<title>Template:Pr</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Template:Pr&amp;diff=9686"/>
		<updated>2014-08-18T08:26:16Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Removed trailing slash from links.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/alliedmodders/sourcemod/pull/{{{1}}} PR {{{1}}}]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=9596</id>
		<title>Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=9596"/>
		<updated>2014-06-15T13:26:59Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Reverted edits by Castile (talk) to last revision by Powerlord&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic introduction to writing a [[SourceMod]] plugin.  If you are not familiar with the SourcePawn language, it is recommended that you at least briefly read the [[Introduction to SourcePawn]] article.&lt;br /&gt;
&lt;br /&gt;
For information on compiling plugins, see [[Compiling SourceMod Plugins]]. You can use [http://www.crimsoneditor.com/ Crimson Editor], [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ Pawn Studio] or any other text editor you're comfortable with to write plugins.&lt;br /&gt;
&lt;br /&gt;
=Starting from scratch=&lt;br /&gt;
Open your favorite text editor and create a new empty file. When you have an empty file you can just start writing code using the core language, however, you will not be able to use any of SourceMod features because the compiler does not now about them. This is done deliberately so it is possible to use SourcePawn outside of SourceMod. But since we are writing a SourceMod plugin, it is a good idea to enable access to SourceMod features first. This it done using &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; directive. It tells compiler to &amp;quot;paste&amp;quot; the code from another file into yours.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
How does this work? First of all, note that we enclosed file name into angle brackets. Angle brackets tell the compiler to look in the default include directory. By default, it is '''scripting/include'''. You can open it right now and see a lot of inc files there. Those are SourceMod include files that describe various functions, tags and other features available for SourceMod plugins. The files are plain-text and you are encouraged to read them. You will notice however, that there's not much code in there, certainly not enough to implement all the great features of SourceMod, so where are they? They are implemented inside a SourceMod core which is written in C++ and is compiled into binary files which end up in '''bin''' directory. So how does your SourcePawn code and SM core link together if compiler doesn't know about existence of the latter? SourceMod include files are written specially, so they say that the implementation of functions is ''somewhere else''. Compiler understands that and generate a special code that says that this function call is going outside. When SourceMod loads your plugin, it inspects these bits of code and substitutes it's own internal functions instead. This is called [http://en.wikipedia.org/wiki/Dynamic_linking dynamic linking].&lt;br /&gt;
&lt;br /&gt;
=Setting up plugin info=&lt;br /&gt;
Now that we got access to SourceMod features, it is time to setup the information that will be displayed via &amp;lt;tt&amp;gt;sm plugins list&amp;lt;/tt&amp;gt; command. No one likes unnamed plugins. To do that we are going to look inside '''sourcemod.inc''' file and see the format that information should be declared. It's always helpful to look inside SM include files to find out information you don't know. There is also an [http://docs.sourcemod.net/api/ API documentation] but it can be outdated and it only has SM core files so if your plugin are going to use any third party extension or another plugin, you will have to study inc files. So, open '''sourcemod.inc''' and scroll down a bit until you see this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Plugin public information.&lt;br /&gt;
 */&lt;br /&gt;
struct Plugin&lt;br /&gt;
{&lt;br /&gt;
   const String:name[],			/**&amp;lt; Plugin Name */&lt;br /&gt;
   const String:description[],	/**&amp;lt; Plugin Description */&lt;br /&gt;
   const String:author[],		/**&amp;lt; Plugin Author */&lt;br /&gt;
   const String:version[],		/**&amp;lt; Plugin Version */&lt;br /&gt;
   const String:url[],			/**&amp;lt; Plugin URL */&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
and this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Declare this as a struct in your plugin to expose its information.&lt;br /&gt;
 * Example:&lt;br /&gt;
 *&lt;br /&gt;
 * public Plugin:myinfo =&lt;br /&gt;
 * {&lt;br /&gt;
 *    name = &amp;quot;My Plugin&amp;quot;,&lt;br /&gt;
 *    //etc&lt;br /&gt;
 * };&lt;br /&gt;
 */&lt;br /&gt;
public Plugin:myinfo;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It tells us that we need to create a global public variable &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; which must be of type &amp;lt;tt&amp;gt;Plugin&amp;lt;/tt&amp;gt; which is a struct with 5 fields which themselves are strings. It may sound complicated for a beginner but it's easy. Let's go ahead and create one:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; keyword means that SourceMod will be able to directly access our variable. &amp;lt;tt&amp;gt;Plugin:&amp;lt;/tt&amp;gt; defines a type of our variable. &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; is, obviously, a name of our variable as required by SourceMod. You see that we initialize it right away. This is preferred way to do when filling out plugin info.&lt;br /&gt;
&lt;br /&gt;
After that the full code of your plugin should look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Getting code to run=&lt;br /&gt;
We already include SourceMod features and filled up or plugin info. We now have a perfectly well formed plugin which can be compiled and loaded by SourceMod. However, there is one problem - it does nothing. You might be tempted to just start writing a code after &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; declaration just to see that it will not compile. SourcePawn, unlike other scripting languages like Lua, does not allow a code to be outside of functions. After reading that, you may probably want to just define some function, name it &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; probably, compile and load a plugin and see that your code never gets called. So how do we make SourceMod call our code? For this exact reason we have forwards. Forwards are function prototypes declared by one party that can be implemented by another party as a [http://en.wikipedia.org/wiki/Callback_%28computer_programming%29 callback]. When a first party starts a forward call, all parties that have matching callbacks receive the call. SourceMod declares a plenty of interesting forwards that we can implement. As you can see, forwards are the only way to get our code executed, keep that in mind. So let's implement &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt; forward. As you may have guessed, it is called when our plugin starts. To do that, we'll have to look up the declaration of &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt;. It is declared inside '''sourcemod.inc''', a file we are already familiar with, let's find it:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Called when the plugin is fully initialized and all known external references &lt;br /&gt;
 * are resolved. This is only called once in the lifetime of the plugin, and is &lt;br /&gt;
 * paired with OnPluginEnd().&lt;br /&gt;
 *&lt;br /&gt;
 * If any run-time error is thrown during this callback, the plugin will be marked &lt;br /&gt;
 * as failed.&lt;br /&gt;
 *&lt;br /&gt;
 * It is not necessary to close any handles or remove hooks in this function.  &lt;br /&gt;
 * SourceMod guarantees that plugin shutdown automatically and correctly releases &lt;br /&gt;
 * all resources.&lt;br /&gt;
 *&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
forward OnPluginStart();&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Empty parentheses tells us that no arguments are passed inside this forward, &amp;lt;tt&amp;gt;@noreturn&amp;lt;/tt&amp;gt; inside documentation tells us that we don't have to return anything, pretty simple forward. So how to write a correct callback for it? Firstly, our callback must have the same name, so it's &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt;, secondly, our callback should have the same number of arguments, none in this case, and lastly, SourceMod needs to be able to call our callback so it needs to be &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. So the implementation looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we can write code inside curly braces and it will be executed when our plugin starts. Let's output &amp;lt;tt&amp;gt;&amp;quot;Hello world!&amp;quot;&amp;lt;/tt&amp;gt; to server console. To do that we are going to use &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt; function. It is declared inside '''console.inc''', however, we don't need to manually include '''console.inc''' because it is included automatically as part of '''sourcemod.inc'''.&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sends a message to the server console.&lt;br /&gt;
 *&lt;br /&gt;
 * @param format		Formatting rules.&lt;br /&gt;
 * @param ...			Variable number of format parameters.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native PrintToServer(const String:format[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
As you can see, this is a native function. It is implemented inside SM core. Judging by it's arguments, we can see that it is a [[Format_Class_Functions_%28SourceMod_Scripting%29|format class function]]. However, we don't need any formatting right now, so let's just pass &amp;lt;tt&amp;gt;&amp;quot;Hello world!&amp;quot;&amp;lt;/tt&amp;gt; string as an only argument:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
That's it! The full code of your plugin should look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Compile and load your plugin on your server and see for yourself that the message is displayed in server console.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
Pawn requires '''include files''', much like C requires header files.  Include files list all of the structures, functions, callbacks, and tags that are available.  There are three types of include files:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; and anything it includes.  These are all provided by SourceMod's Core.&lt;br /&gt;
*'''Extension''' - adds a dependency against a certain extension.&lt;br /&gt;
*'''Plugin''' - adds a dependency against a certain plugin.&lt;br /&gt;
&lt;br /&gt;
Include files are loaded using the &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; compiler directive.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=771&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  Any command that you type in the console, even if it's registered by SourceMod, will be sent to the engine to be processed. Because we have not had SourceMod block this functionality yet, the engine replies with &amp;quot;Unknown command&amp;quot; because it is not a valid engine command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything. This is because returning &amp;quot;Plugin_Handled&amp;quot; in a command callback will prevent the engine from processing the command. The engine will never even see that the command was run. This is what you will want to do if you are registering a completely new command through SourceMod.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage;&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1);&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;);&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH];&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count;&lt;br /&gt;
	new bool:tn_is_ml;&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage);&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage);&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Although SourceMod fires the OnClientConnected and OnClientDisconnected callbacks every map change, the server tracks players across map changes and does not change their userids or client indexes.  To see if a client really connected or disconnected, hook the  [[Generic Source Server Events#player_connect|player_connect]] and [[Generic Source Server Events#player_disconnect|player_disconnect]] events instead.&lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They almost always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;);&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id);&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id);&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=940&amp;amp; AskPluginLoad2()] - Called once, immediately after the plugin is loaded from the disk.  This function can be used to stop a plugin from loading and return a custom error message; return APLRes_Failure and use strcopy on to replace the error string.  All CreateNative and RegPluginLibrary calls should be done here.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=583&amp;amp; OnAllPluginsLoaded()] - Called once, after all non-late loaded plugins have called OnPluginStart.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  You can block a player from connecting by returning Plugin_Stop and setting rejectmsg to an error message.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=916&amp;amp; OnClientConnected()] - Called after a player connects. Signifies that the player is in-game and IsClientConnected() will return true. '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between OnClientConnected and OnClientPreAdminCheck/OnClientDisconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection starts.  '''This is paired to OnClientConnected().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=391&amp;amp; OnClientDisconnect_Post()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnected().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
If you only want to detect when a client initially connects or leaves your server, hook the [[Generic Source Server Events#player_connect|player_connect]] or [[Generic Source Server Events#player_disconnect|player_disconnect]] events respectively.&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=9595</id>
		<title>Scripting FAQ (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=9595"/>
		<updated>2014-06-15T13:25:43Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Undo revision 8701 by Impact123 (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Yak.gif]]&lt;br /&gt;
yak wuz heer&lt;br /&gt;
&lt;br /&gt;
=How do I learn SourcePawn?=&lt;br /&gt;
A good start is on the [[Introduction to SourcePawn]] page, which will teach you the SourcePawn language. Then go through the [[Introduction to SourceMod Plugins]], which will teach you how to write your first plug-in.&lt;br /&gt;
&lt;br /&gt;
=Where can I find all the SourcePawn functions and other information?=&lt;br /&gt;
All SourceMod plug-ins have this line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line instructs the compiler to retrieve the file &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; from the &amp;lt;tt&amp;gt;sourcemod/scripting/include&amp;lt;/tt&amp;gt; folder. Every function, variable, and definition can be found in the &amp;lt;tt&amp;gt;.inc&amp;lt;/tt&amp;gt; files inside the &amp;lt;tt&amp;gt;sourcemod/scripting/include&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
But searching through all those files can be quite tedious. Thankfully, the honourable [https://forums.alliedmods.net/member.php?u=9443 Nican] created an API reference viewable on the web, complete with searching and commenting: [http://docs.sourcemod.net/api/ http://docs.sourcemod.net/api/]&lt;br /&gt;
&lt;br /&gt;
Also, if you are in the SourceMod IRC channel ([irc://irc.gamesurge.net/sourcemod #sourcemod on GameSurge]), you can use the &amp;lt;tt&amp;gt;!api&amp;lt;/tt&amp;gt; command to search [https://forums.alliedmods.net/member.php?u=9443 Nican's] API reference:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;theY4Kman&amp;gt; !api Netclass&lt;br /&gt;
&amp;lt;yakbot&amp;gt; theY4Kman: GetEntityNetClass(edict, String:clsname[], maxlength): Retrieves an entity's networkable serverclass name. This is not the same as the classname and is used for networkable state changes. (http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=66)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I find the classname of an entity? (e.g., &amp;quot;&amp;lt;tt&amp;gt;weapon_knife&amp;lt;/tt&amp;gt;&amp;quot; or &amp;quot;&amp;lt;tt&amp;gt;prop_physics&amp;lt;/tt&amp;gt;&amp;quot;)=&lt;br /&gt;
The classname of an entity (not to be confused with a netclass such as &amp;lt;tt&amp;gt;CCSPlayer&amp;lt;/tt&amp;gt;) is a unique identifier. It's the most well known of entity names. To find it, use the function [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=65 GetEdictClassname()]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:classname[128];&lt;br /&gt;
GetEdictClassname(myentity, classname, sizeof(classname));&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;myentity classname: %s&amp;quot;, classname);&lt;br /&gt;
// myentity classname: weapon_knife&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I block regular commands, such as &amp;lt;tt&amp;gt;kill&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt;?=&lt;br /&gt;
As of version 1.3, the recommended way to hook and block commands is with [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=949 AddCommandListener()]. Previously, using [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=470 RegConsoleCmd()] with the command name was the only way to hook commands, but this creates a whole new command for the command dispatch to check every time any command is executed. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=949 AddCommandListener()] creates only a lightweight hook, processed only when the specific command is executed.&lt;br /&gt;
&lt;br /&gt;
Here's how to use it to block the &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    AddCommandListener(SayCallback, &amp;quot;say&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:SayCallback(client, const String:command[], argc)&lt;br /&gt;
{&lt;br /&gt;
    Return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I hook +commands, such as &amp;lt;tt&amp;gt;+zoom&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;+attack&amp;lt;/tt&amp;gt;?=&lt;br /&gt;
Unlike regular commands, &amp;lt;tt&amp;gt;+commands&amp;lt;/tt&amp;gt; are handled on the client's computer, then sent to the server in a more compressed fashion. This means [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=949 AddCommandListener()] cannot be used to hook &amp;lt;tt&amp;gt;+commands&amp;lt;/tt&amp;gt;. As of version 1.3, the recommended solution is to use the global forward [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=937 OnPlayerRunCmd()]. This forward is fired every time a player uses a movement button. To detect or block a &amp;lt;tt&amp;gt;+command&amp;lt;/tt&amp;gt;, you'll first have to find out its proper &amp;lt;tt&amp;gt;IN_&amp;lt;/tt&amp;gt; constant (see &amp;lt;tt&amp;gt;[http://docs.sourcemod.net/api/index.php?fastload=file&amp;amp;id=47&amp;amp;file=&amp;amp; entity_prop_stocks.inc]&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Here's how to use it to block crouching when attacking:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:OnPlayerRunCmd(client, &amp;amp;buttons, &amp;amp;impulse, Float:vel[3], Float:angles[3], &amp;amp;weapon)&lt;br /&gt;
{&lt;br /&gt;
    // Check if the player is attacking (+attack)&lt;br /&gt;
    if ((buttons &amp;amp; IN_ATTACK) == IN_ATTACK)&lt;br /&gt;
    {&lt;br /&gt;
        // If so, block their crouching (+duck)&lt;br /&gt;
        buttons &amp;amp;= ~IN_DUCK;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // We must return Plugin_Continue to let the changes be processed.&lt;br /&gt;
    // Otherwise, we can return Plugin_Handled to block the commands&lt;br /&gt;
    return Plugin_Continue;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I get rid of loose indentation warnings?=&lt;br /&gt;
&amp;lt;pre&amp;gt;myplugin.sp(#) : warning 217: loose indentation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Loose indentation warnings arise when indentation in your code is inconsistent. This usually means using both tabs and spaces as indentation. However, it can also mean a different amount of spaces or tabs are being used. Therefore, to correct it, use just one type of indentation. Because different editors have different settings for the size of tab stops, it is recommended you use 4 spaces to indent.&lt;br /&gt;
&lt;br /&gt;
Good:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    new myvar = 5;&lt;br /&gt;
    if (myvar == (2 + 3))&lt;br /&gt;
        PrintToServer(&amp;quot;myvar is %d&amp;quot;, myvar);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bad:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	new myvar = 5;&lt;br /&gt;
    if (myvar == (2 + 3))&lt;br /&gt;
		PrintToServer(&amp;quot;myvar is %d&amp;quot;, myvar);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=How do I get rid of tag mismatch warnings?=&lt;br /&gt;
Though every variable in SourcePawn is one cell (4 bytes), with the exception of strings, there are many different ways to interpret what's inside a cell. To signify a cell's contents, tags are used. The most common are &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; (the default tag: a vanilla cell. This tag is implied when no other tag is specified.), &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;String&amp;lt;/tt&amp;gt;. See [[Introduction to SourcePawn#Variables_2]] for more information.&lt;br /&gt;
&lt;br /&gt;
Functions wear these tags on their parameters so you can tell what needs to be passed to the function:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function calls for '''&amp;lt;tt&amp;gt;entity&amp;lt;/tt&amp;gt;''', a cell with the implied tag '''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;'''''; '''&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;''', with the developer-defined tag '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;'''''; '''&amp;lt;tt&amp;gt;prop&amp;lt;/tt&amp;gt;''', with the built-in tag '''''&amp;lt;tt&amp;gt;String&amp;lt;/tt&amp;gt;'''''; and '''&amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;''', with the built-in tag '''''&amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;'''''.&lt;br /&gt;
To call this function, then, you must pass values with the specified tags. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;SetEntPropFloat(1234, Prop_Send, &amp;quot;m_fNumber&amp;quot;, 1.0);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This calls the function correctly: &amp;lt;tt&amp;gt;1234&amp;lt;/tt&amp;gt; is a regular cell ('''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;'''''), &amp;lt;tt&amp;gt;Prop_Send&amp;lt;/tt&amp;gt; is a variable defined in the enum '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;''''' in [http://docs.sourcemod.net/api/index.php?fastload=file&amp;amp;id=4&amp;amp;file=&amp;amp; entity.inc], &amp;lt;tt&amp;gt;&amp;quot;m_fNumber&amp;quot;&amp;lt;/tt&amp;gt; is a '''''&amp;lt;tt&amp;gt;String&amp;lt;/tt&amp;gt;''''', and &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt; is a '''''&amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;'''''. For a nonexample:&lt;br /&gt;
&amp;lt;pawn&amp;gt;SetEntPropFloat(1234.0, 1, &amp;quot;m_fNumber&amp;quot;, 1337);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is incorrect! &amp;lt;tt&amp;gt;1234.0&amp;lt;/tt&amp;gt; is a '''''&amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;''''' that should be a regular cell ('''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;'''''); &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; is a regular cell ('''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;''''') that should be a '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;'''''; and &amp;lt;tt&amp;gt;1337&amp;lt;/tt&amp;gt; is a regular cell ('''''&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;''''') that should be a '''''&amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt;'''''. This call will generate a tag mismatch warning. To correct it, simply use a value with the correct tag. Most of the time, tags that are not built-in (such as '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;''''') can be found in the same file where a function uses them (you can find '''''&amp;lt;tt&amp;gt;PropType&amp;lt;/tt&amp;gt;''''' in [http://docs.sourcemod.net/api/index.php?fastload=file&amp;amp;id=4&amp;amp;file=&amp;amp; entity.inc]).&lt;br /&gt;
&lt;br /&gt;
=How do I add color to my messages?=&lt;br /&gt;
Though the actual colors will vary depending on the mod, you can add color to any chat message using the characters &amp;lt;tt&amp;gt;0x01&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;0x08&amp;lt;/tt&amp;gt;. For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChatAll (&amp;quot;\x01 1 .. \x02 2 .. \x03 3 .. \x04 4 .. \x05 5 .. \x06 6 .. \x07 7 .. \x08 8&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example output from Left 4 Dead:&lt;br /&gt;
&lt;br /&gt;
[[Image:Left_4_Dead_Colors.png]]&lt;br /&gt;
&lt;br /&gt;
With a little experimenting, you can learn the colors for a mod. However, the meaning behind the colors is generally as follows:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt style=&amp;quot;color: blue;&amp;quot;&amp;gt;0x01&amp;lt;/tt&amp;gt; = Normal color&lt;br /&gt;
* &amp;lt;tt style=&amp;quot;color: blue;&amp;quot;&amp;gt;0x02&amp;lt;/tt&amp;gt; = Use team color to the end of a player's name. When used, it can be the only color used, and it must be at the start of the message.&lt;br /&gt;
* &amp;lt;tt style=&amp;quot;color: blue;&amp;quot;&amp;gt;0x03&amp;lt;/tt&amp;gt; = Team color&lt;br /&gt;
* &amp;lt;tt style=&amp;quot;color: blue;&amp;quot;&amp;gt;0x04&amp;lt;/tt&amp;gt; = Location color&lt;br /&gt;
&lt;br /&gt;
This data comes from Counter-Strike: Source.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, to use players' team colors, you must use UserMessages, because there is no way for the current SourceMod functions to know which team color to use. Here's an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:hBf;&lt;br /&gt;
hBf = StartMessageOne(&amp;quot;SayText2&amp;quot;, player_to); // To send the message to all players, use StartMessageAll(&amp;quot;SayText2&amp;quot;);&lt;br /&gt;
if (hBf != INVALID_HANDLE)&lt;br /&gt;
{&lt;br /&gt;
    BfWriteByte(hBf, player_from); &lt;br /&gt;
    BfWriteByte(hBf, 0); &lt;br /&gt;
    BfWriteString(hBf, &amp;quot;&amp;lt;\x03player_from team color\x01&amp;gt; My message&amp;quot;);&lt;br /&gt;
    EndMessage();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;player_to&amp;lt;/tt&amp;gt; is the client index to send the message to (or use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=132&amp;amp; StartMessageAll()] instead of [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=133&amp;amp; StartMessageOne()] to send the message to all players). &amp;lt;tt&amp;gt;player_from&amp;lt;/tt&amp;gt; is the client index of the player whose team color will be utilized in the message. The message will now look like this (assuming &amp;lt;tt&amp;gt;player_from&amp;lt;/tt&amp;gt; is on the RED team):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#AA0&amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:#F00&amp;quot;&amp;gt;player_from team color&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:#AA0&amp;quot;&amp;gt;&amp;amp;gt; My message&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There's another catch, however: this is only known to work in CS:S and TF2. For other mods, your mileage may vary.&lt;br /&gt;
&lt;br /&gt;
==Color Libraries==&lt;br /&gt;
There are a few libraries that can handle colors for you, so you don't have to muck with UserMessages:&lt;br /&gt;
&lt;br /&gt;
===exvel's Colors===&lt;br /&gt;
This is a simple include file, allowing easy control over chat coloring. You can grab it [http://forums.alliedmods.net/showthread.php?t=96831 on the forums].  Instead of hex codes, colors are denoted with tags, such as &amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{default}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{green}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;, or &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{blue}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Here's some example usage. Note that this code assumes client 1 is in game and on the &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;BLU&amp;lt;/span&amp;gt; team:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;colors&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    CPrintToChatAll(&amp;quot;{green}Hello {red}World! {default}Test 1 concluded.&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    new client_on_blu_team = 1;&lt;br /&gt;
    CPrintToChatAllEx(client_on_blu_team, &amp;quot;{teamcolor}BLU team {default}says {green}hi!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;Hello &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #F00;&amp;quot;&amp;gt;World! &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;Test 1 concluded.&amp;lt;/span&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;BLU team &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;says &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;hi!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that to use a team color, there needs to be at least one player on that team. Otherwise, it will default to &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{green}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===SMLib===&lt;br /&gt;
[http://forums.alliedmods.net/showthread.php?p=1398699 SMLib] is a huge collection of stock functions to keep plug-in developers from reinventing the wheel. It includes a [http://forums.alliedmods.net/showthread.php?p=1398702#post1398702 colors API] very similar to [[#exvel's Colors|exvel's]]. The benefits of SMLib are it supports shorthand color names, such as &amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{N}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt; and &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;{G}&amp;lt;/tt&amp;gt;&amp;lt;/span&amp;gt;, and all colors are supported in its &amp;lt;tt&amp;gt;Client_PrintToChat()&amp;lt;/tt&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
Here's how to print the same thing as the above example with SMLib. Note that this code also assumes client 1 is in game and on the &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;BLU&amp;lt;/span&amp;gt; team:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;smlib&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
    Client_PrintToChatAll(&amp;quot;{G}Hello {R}World! {N}Test 1 concluded.&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    new client_on_blu_team = 1;&lt;br /&gt;
    Client_PrintToChatAll(client_on_blu_team, &amp;quot;{T}BLU team {N}says {G}hi!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;Hello &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #F00;&amp;quot;&amp;gt;World! &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;Test 1 concluded.&amp;lt;/span&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: #00F;&amp;quot;&amp;gt;BLU team &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #AA0;&amp;quot;&amp;gt;says &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color: #0F0;&amp;quot;&amp;gt;hi!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Why do I get an &amp;quot;unknown symbol&amp;quot; error when using an SDKTools native?=&lt;br /&gt;
None of SourceMod's or SDKTools's functions are built into SourcePawn. Therefore, every time you use one of their functions, SourcePawn needs to know how to call the function. Normally, this is done using includes. Just like you would #include &amp;lt;sourcemod&amp;gt; to use SourceMod's functions, you need to:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
to use an SDKTools native.&lt;br /&gt;
&lt;br /&gt;
=Why is Source telling me my command is an &amp;quot;Unknown command&amp;quot;?=&lt;br /&gt;
This is because you're not returning &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt; in your callback. If you don't, SourceMod believes you didn't want the Source Engine to know the command was registered, and it handles it so.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:MyCommand(client, args)&lt;br /&gt;
{&lt;br /&gt;
    // Do something...&lt;br /&gt;
    &lt;br /&gt;
    return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9572</id>
		<title>Installing Metamod:Source</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9572"/>
		<updated>2014-05-21T02:36:16Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: /* Custom VDF File */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will guide you through a [[Metamod:Source]] installation.&lt;br /&gt;
&lt;br /&gt;
=Normal Installation=&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[http://www.metamodsource.net/ Download] Metamod:Source.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Extract the package to your game folder.  For example, for Counter-Strike:Source, you would have &amp;lt;tt&amp;gt;cstrike/addons/metamod&amp;lt;/tt&amp;gt; after extracting.  If you are uploading to FTP, extract the files locally before transferring to your server's game folder.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Restart your server.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Type &amp;quot;meta version&amp;quot; in your server console (or RCON).  You should see a line like: &amp;quot;Loaded As: Valve Server Plugin.&amp;quot;  If the command is not recognized, see the sections below.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Custom VDF File==&lt;br /&gt;
Metamod:Source 1.10.0 and later include a &amp;lt;tt&amp;gt;metamod.vdf&amp;lt;/tt&amp;gt; file for easier installation on most games. If you have trouble getting it to load, [http://www.metamodsource.net/?go=vdf go here] to generate a VDF file specific to your game. This file should be placed into your server's &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
Known setups that require this step:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Left 4 Dead 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;3rd party mods using the Source SDK Base.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Listen servers (created with the in-game &amp;quot;Create Server&amp;quot; option) for non-english game clients.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=GameInfo=&lt;br /&gt;
'''Note: This is normally not needed - if you do not understand what this, do NOT do this unless instructed to. The above instructions are sufficient to install Metamod:Source for 99% of servers.'''&lt;br /&gt;
&lt;br /&gt;
Metamod:Source 1.4.2 and lower used an older method for loading itself.  The advantage of this method was that Metamod:Source could be loaded before the actual game mod, which gave it a small amount of extra functionality.  This functionality was never used by plugin developers, and Steam updates kept overwriting &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; files, so we switched to a different loading mechanism.&lt;br /&gt;
&lt;br /&gt;
However this loading mechanism may still be desirable if you run into backwards compatibility issues, or you have a plugin which takes advantage of the early-loading mechanism.  If this is your case, here are the &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; directions below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the file in the mod folder called &amp;quot;gameinfo.txt&amp;quot;. You will see a few lines at the bottom like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SearchPaths&lt;br /&gt;
{&lt;br /&gt;
	Game				|gameinfo_path|. &lt;br /&gt;
	Game				cstrike&lt;br /&gt;
	Game				hl2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add a line after the &amp;quot;{&amp;quot; sign but before all of the &amp;quot;Game&amp;quot; entries that looks like this:&amp;lt;pre&amp;gt;GameBin				|gameinfo_path|addons/metamod/bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If you're using Windows, you may need to use a backwards slash (\) instead.&lt;br /&gt;
&amp;lt;li&amp;gt;You're done! To test whether it worked, restart your game server and type &amp;quot;meta version&amp;quot; in the server console.  You should see a line that says &amp;quot;Loaded as: GameDLL (gameinfo.txt).&amp;quot;  If it doesn't recognize the command, the installation probably failed.  If the &amp;quot;Loaded as:&amp;quot; line says something else, &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; was probably not modified correctly.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For more information or documentation, see [[:Category:Metamod:Source Documentation]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; loading method is supported as a legacy feature only.  The patcher tool is no longer provided.  You can mark &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; if you absolutely want to protect it from being overwritten.&lt;br /&gt;
&lt;br /&gt;
We will continue to make sure Metamod:Source can load via this method for as long as the Source Engine allows it.  However, we will concentrate more on supporting the new loading mechanism for general use.&lt;br /&gt;
&lt;br /&gt;
[[Category:Metamod:Source Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9039</id>
		<title>Installing Metamod:Source</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9039"/>
		<updated>2013-08-30T17:53:38Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: /* Normal Installation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will guide you through a [[Metamod:Source]] installation.&lt;br /&gt;
&lt;br /&gt;
=Normal Installation=&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[http://www.metamodsource.net/ Download] Metamod:Source.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Extract the package to your game folder.  For example, for Counter-Strike:Source, you would have &amp;lt;tt&amp;gt;cstrike/addons/metamod&amp;lt;/tt&amp;gt; after extracting.  If you are uploading to FTP, extract the files locally before transferring to your server's game folder.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Restart your server.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Type &amp;quot;meta version&amp;quot; in your server console (or RCON).  You should see a line like: &amp;quot;Loaded As: Valve Server Plugin.&amp;quot;  If the command is not recognized, see the sections below.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Custom VDF File==&lt;br /&gt;
Metamod:Source 1.10.0 and later include a &amp;lt;tt&amp;gt;metamod.vdf&amp;lt;/tt&amp;gt; file for easier installation on most games. If you have trouble getting it to load, [http://www.metamodsource.net/?go=vdf go here] to generate a VDF file specific to your game. This file should be placed into your server's &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
Known setups that require this step:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;3rd party mods using the Source SDK Base.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Listen servers (created with the in-game &amp;quot;Create Server&amp;quot; option) for non-english game clients.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=GameInfo=&lt;br /&gt;
'''Note: This is normally not needed - if you do not understand what this, do NOT do this unless instructed to. The above instructions are sufficient to install Metamod:Source for 99% of servers.'''&lt;br /&gt;
&lt;br /&gt;
Metamod:Source 1.4.2 and lower used an older method for loading itself.  The advantage of this method was that Metamod:Source could be loaded before the actual game mod, which gave it a small amount of extra functionality.  This functionality was never used by plugin developers, and Steam updates kept overwriting &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; files, so we switched to a different loading mechanism.&lt;br /&gt;
&lt;br /&gt;
However this loading mechanism may still be desirable if you run into backwards compatibility issues, or you have a plugin which takes advantage of the early-loading mechanism.  If this is your case, here are the &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; directions below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the file in the mod folder called &amp;quot;gameinfo.txt&amp;quot;. You will see a few lines at the bottom like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SearchPaths&lt;br /&gt;
{&lt;br /&gt;
	Game				|gameinfo_path|. &lt;br /&gt;
	Game				cstrike&lt;br /&gt;
	Game				hl2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add a line after the &amp;quot;{&amp;quot; sign but before all of the &amp;quot;Game&amp;quot; entries that looks like this:&amp;lt;pre&amp;gt;GameBin				|gameinfo_path|addons/metamod/bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If you're using Windows, you may need to use a backwards slash (\) instead.&lt;br /&gt;
&amp;lt;li&amp;gt;You're done! To test whether it worked, restart your game server and type &amp;quot;meta version&amp;quot; in the server console.  You should see a line that says &amp;quot;Loaded as: GameDLL (gameinfo.txt).&amp;quot;  If it doesn't recognize the command, the installation probably failed.  If the &amp;quot;Loaded as:&amp;quot; line says something else, &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; was probably not modified correctly.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For more information or documentation, see [[:Category:Metamod:Source Documentation]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; loading method is supported as a legacy feature only.  The patcher tool is no longer provided.  You can mark &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; if you absolutely want to protect it from being overwritten.&lt;br /&gt;
&lt;br /&gt;
We will continue to make sure Metamod:Source can load via this method for as long as the Source Engine allows it.  However, we will concentrate more on supporting the new loading mechanism for general use.&lt;br /&gt;
&lt;br /&gt;
[[Category:Metamod:Source Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9038</id>
		<title>Installing Metamod:Source</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9038"/>
		<updated>2013-08-30T17:52:25Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: /* Custom VDF File */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will guide you through a [[Metamod:Source]] installation.&lt;br /&gt;
&lt;br /&gt;
=Normal Installation=&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[http://www.metamodsource.net/ Download] Metamod:Source.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Extract the package to your game folder.  For example, for Counter-Strike:Source, you would have &amp;lt;tt&amp;gt;cstrike/addons/metamod&amp;lt;/tt&amp;gt; after extracting.  If you are uploading to FTP, extract the files locally before transferring to your server's game folder.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Restart your server.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Type &amp;quot;meta version&amp;quot; in your server console (or RCON).  You should see a line like: &amp;quot;Loaded As: Valve Server Plugin.&amp;quot;  If the command is not recognized, see the [[Installing Metamod:Source#Troubleshooting|Troubleshooting]] section below.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Custom VDF File==&lt;br /&gt;
Metamod:Source 1.10.0 and later include a &amp;lt;tt&amp;gt;metamod.vdf&amp;lt;/tt&amp;gt; file for easier installation on most games. If you have trouble getting it to load, [http://www.metamodsource.net/?go=vdf go here] to generate a VDF file specific to your game. This file should be placed into your server's &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
Known setups that require this step:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;3rd party mods using the Source SDK Base.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Listen servers (created with the in-game &amp;quot;Create Server&amp;quot; option) for non-english game clients.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=GameInfo=&lt;br /&gt;
'''Note: This is normally not needed - if you do not understand what this, do NOT do this unless instructed to. The above instructions are sufficient to install Metamod:Source for 99% of servers.'''&lt;br /&gt;
&lt;br /&gt;
Metamod:Source 1.4.2 and lower used an older method for loading itself.  The advantage of this method was that Metamod:Source could be loaded before the actual game mod, which gave it a small amount of extra functionality.  This functionality was never used by plugin developers, and Steam updates kept overwriting &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; files, so we switched to a different loading mechanism.&lt;br /&gt;
&lt;br /&gt;
However this loading mechanism may still be desirable if you run into backwards compatibility issues, or you have a plugin which takes advantage of the early-loading mechanism.  If this is your case, here are the &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; directions below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the file in the mod folder called &amp;quot;gameinfo.txt&amp;quot;. You will see a few lines at the bottom like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SearchPaths&lt;br /&gt;
{&lt;br /&gt;
	Game				|gameinfo_path|. &lt;br /&gt;
	Game				cstrike&lt;br /&gt;
	Game				hl2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add a line after the &amp;quot;{&amp;quot; sign but before all of the &amp;quot;Game&amp;quot; entries that looks like this:&amp;lt;pre&amp;gt;GameBin				|gameinfo_path|addons/metamod/bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If you're using Windows, you may need to use a backwards slash (\) instead.&lt;br /&gt;
&amp;lt;li&amp;gt;You're done! To test whether it worked, restart your game server and type &amp;quot;meta version&amp;quot; in the server console.  You should see a line that says &amp;quot;Loaded as: GameDLL (gameinfo.txt).&amp;quot;  If it doesn't recognize the command, the installation probably failed.  If the &amp;quot;Loaded as:&amp;quot; line says something else, &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; was probably not modified correctly.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For more information or documentation, see [[:Category:Metamod:Source Documentation]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; loading method is supported as a legacy feature only.  The patcher tool is no longer provided.  You can mark &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; if you absolutely want to protect it from being overwritten.&lt;br /&gt;
&lt;br /&gt;
We will continue to make sure Metamod:Source can load via this method for as long as the Source Engine allows it.  However, we will concentrate more on supporting the new loading mechanism for general use.&lt;br /&gt;
&lt;br /&gt;
[[Category:Metamod:Source Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SourceMod_1.5.0_Release_Notes&amp;diff=9027</id>
		<title>SourceMod 1.5.0 Release Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SourceMod_1.5.0_Release_Notes&amp;diff=9027"/>
		<updated>2013-08-26T14:41:27Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
SourceMod 1.5.0 is a major update with many new features and bug fixes.&lt;br /&gt;
&lt;br /&gt;
=Overview for Admins=&lt;br /&gt;
&lt;br /&gt;
*'''New Game Support''' - SourceMod, including base plugins and the CStrike extension now fully support &amp;lt;span style=&amp;quot;text-decoration:underline&amp;quot;&amp;gt;Counter-Strike: Global Offensive&amp;lt;/span&amp;gt;.&lt;br /&gt;
*Updated gamedata for many games and mods.&lt;br /&gt;
*The popular SDKHooks extension is now shipped with SourceMod.&lt;br /&gt;
*Lots of stability fixes.&lt;br /&gt;
*Better localization support.&lt;br /&gt;
&lt;br /&gt;
=Overview for Developers=&lt;br /&gt;
&lt;br /&gt;
A full list of API additions and changes is available.&lt;br /&gt;
*Many new functions added.&lt;br /&gt;
*Some existing functions made more useful.&lt;br /&gt;
*Large scale documentation cleanup and fixing of functionality to match documenation or vice versa in cases.&lt;br /&gt;
&lt;br /&gt;
*Too much to name here. For overview of all sourcepawn and SM extension API changes and additions, please see [[SourceMod_1.5.0_API_Changes]]&lt;br /&gt;
&lt;br /&gt;
=Compatibility Issues=&lt;br /&gt;
&lt;br /&gt;
In almost all cases, SourceMod 1.5.0 is fully backward compatible with the 1.4.x releases. The following are the few places where this is not the case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''BfRead* and BfWrite natives not available on CS:GO''':&lt;br /&gt;
&lt;br /&gt;
CS:GO has a completely new usermessage system for which there is no direct way to force compatibility through the existing bitbuf read/write natives. To read or write usermessage parameters in CS:GO, you need to use the new Pb natives.&lt;br /&gt;
&lt;br /&gt;
There is also a new &amp;lt;tt&amp;gt;GetUserMessageType&amp;lt;/tt&amp;gt; native to check which one of the two usermessage types that the running game uses.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[SourceMod_1.5.0_API_Changes#Protobuf]] and [[SourceMod_1.5.0_API_Changes#UserMessages]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GuessSDKVersion deprecated, GetEngineVersion added'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;GuessSDKVersion&amp;lt;/tt&amp;gt; will continue to function as-is for now, but will be removed in a later version. Additionally, a compile-time warning will be thrown. It has been superseded by the new &amp;lt;tt&amp;gt;GetEngineVersion&amp;lt;/tt&amp;gt; native which will give clearer results and is more extendable for the future.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[SourceMod_1.5.0_API_Changes#HalfLife]]&lt;br /&gt;
&lt;br /&gt;
'''TF2_GetResourceEntity, TF2_GetPlayerResourceData, and TF2_SetPlayerResourceData deprecated'''&lt;br /&gt;
&lt;br /&gt;
These natives will continue to function as-is for now, but will generate a compile-time warning and be removed in a later version.&lt;br /&gt;
&lt;br /&gt;
Calls to them should be replaced with calls to the new &amp;lt;tt&amp;gt;GetPlayerResourceEntity&amp;lt;/tt&amp;gt; and the GetEntProp* and SetEntProp* natives.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[SourceMod_1.5.0_API_Changes#TF2]]&lt;br /&gt;
&lt;br /&gt;
=Translations=&lt;br /&gt;
SourceMod 1.5 comes with the following languages translated, thanks to [http://www.sourcemod.net/translator/?go=translate&amp;amp;op=status community translators]:&lt;br /&gt;
*Arabic&lt;br /&gt;
*Brazilian Portuguese&lt;br /&gt;
*Bulgarian&lt;br /&gt;
*Chinese (Simplified)&lt;br /&gt;
*Chinese (Traditional)&lt;br /&gt;
*Czech&lt;br /&gt;
*Danish&lt;br /&gt;
*Dutch&lt;br /&gt;
*English&lt;br /&gt;
*Finnish&lt;br /&gt;
*French&lt;br /&gt;
*German&lt;br /&gt;
*Greek&lt;br /&gt;
*Hebrew&lt;br /&gt;
*Hungarian&lt;br /&gt;
*Italian&lt;br /&gt;
*Japanese&lt;br /&gt;
*Korean&lt;br /&gt;
*Latvian&lt;br /&gt;
*Lithuanian&lt;br /&gt;
*Norwegian&lt;br /&gt;
*Polish&lt;br /&gt;
*Portuguese&lt;br /&gt;
*Romanian&lt;br /&gt;
*Russian&lt;br /&gt;
*Slovak&lt;br /&gt;
*Spanish&lt;br /&gt;
*Swedish&lt;br /&gt;
*Thai&lt;br /&gt;
*Turkish&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Changelog=&lt;br /&gt;
&lt;br /&gt;
===User Changes===&lt;br /&gt;
&lt;br /&gt;
*Added support for Counter-Strike: Global Offensive ({{bz|5299}}, {{bz|5579}}).&lt;br /&gt;
*Split CS:S, TF2, DoD:S, HL2:DM, and ND to separate binaries ({{bz|5370}}, {{bz|5813}}).&lt;br /&gt;
*Added support for runoff voting in mapchooser ({{bz|4218}}).&lt;br /&gt;
*Added option to require Steam validation before granting admin access ({{bz|4837}}) ({{user|49537|VoiDeD}}).&lt;br /&gt;
*Added localization support for many more core and base plugin messages ({{bz|5120}}, {{bz|5146}}).&lt;br /&gt;
*Added the ability to override RegConsoleCommand-created commands ({{bz|5199}}).&lt;br /&gt;
*Added support for &amp;quot;fuzzy&amp;quot; (partial) map names in map-related natives and cmds for L4D and later ({{bz|5599}}).&lt;br /&gt;
*Updated Reserved Slots to use max humans as max count ({{bz|5444}}).&lt;br /&gt;
*Added support for custom maxitems on radio menus ({{bz|5371}}).&lt;br /&gt;
*Improved console config editing ({{bz|5470}}).&lt;br /&gt;
*Increased map name buffer sizes in mapchooser to better account for nested maps ({{bz|5609}}) ({{user|41418|Peace-Maker}}).&lt;br /&gt;
*Fixed JIT conflicts with SELinux ({{bz|5581}}).&lt;br /&gt;
*Added logged error when PlayerRunCommand offset lookup fails ({{bz|5535}}) ({{user|6136|GoD-Tony}}).&lt;br /&gt;
*Fixed double print when sending psay to self ({{bz|5649}}) ({{user|41418|Peace-Maker}}).&lt;br /&gt;
*Fixed check against uninitialized string in extension loader ({{bz|5546}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Fixed possible runtime errors in basetriggers for not-ingame clients ({{bz|5191}}) ({{user|41418|Peace-Maker}}).&lt;br /&gt;
*Check all possible mapcycle paths on newer orangebox games ({{bz|5719}}).&lt;br /&gt;
*Fixed ReadMapList not seeing maps in all valve search paths ({{bz|5715}}) ({{user|49537|VoiDeD}}).&lt;br /&gt;
*Fixed typo in too-many-params native error message ({{user|41418|Peace-Maker}}).&lt;br /&gt;
*Fixed various issues in clientprefs ({{bz|5538}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Removed debug printout from PerformGravity ({{bz|5679}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Fixed broken translating in some plugins and natives ({{bz|5612}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Fixed issues with COMMAND_FILTER_NO_BOTS and @bots multi-target.&lt;br /&gt;
*Fixed crash in SDKHooks when throwing bad ent type error on logical ent ({{user|57030|KyleS}}).&lt;br /&gt;
&lt;br /&gt;
===Developer Changes===&lt;br /&gt;
&lt;br /&gt;
*Added support for CS:GO to the CStrike extension ({{bz|5299}}) ({{user|26021|Drifter}}).&lt;br /&gt;
*Added support for new protobuf usermessages used in newer games ({{bz|5579}}, {{bz|5588}}, {{bz|5590}}, {{bz|5633}}).&lt;br /&gt;
*Added latest SDKHooks version as first-party extension.&lt;br /&gt;
*Updated SQLite to version 3.7.15.1 ({{bz|5235}}).&lt;br /&gt;
*Added natives for changing team score and mvp stars on CSS/CSGO ({{bz|5295}}) ({{user|26021|Drifter}}).&lt;br /&gt;
*Added global pre and post forwards for client chat ({{bz|5394}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Added TF2_CanPlayerTeleport forward to the TF2 game extension ({{bz|5283}}) ({{user|49537|VoiDeD}}).&lt;br /&gt;
*Added GetEntityAddress native ({{bz|5269}}) ({{user|71533|ProdigySim}}).&lt;br /&gt;
*Added more parameters to PlayerRunCommand forward ({{bz|5346}}) ({{user|6136|GoD-Tony}}).&lt;br /&gt;
*Added forwards to basecomm plugin ({{bz|5466}}) ({{user|26021|Drifter}}).&lt;br /&gt;
*Added symbol lookup support to gamedata on Windows ({{bz|5511}}) ({{user|6136|GoD-Tony}}).&lt;br /&gt;
*Exposed GetLanguageInfo in ITranslator interface ({{bz|5249}}) ({{user|49537|VoiDeD}}).&lt;br /&gt;
*Increase maximum .sp line length to 4095 characters. ({{bz|5347}}) ({{user|28227|theY4Kman}}).&lt;br /&gt;
*Improved netprop dump output ({{bz|5471}}).&lt;br /&gt;
*Added int64 typename to netprop dumps ({{bz|5655}}).&lt;br /&gt;
*Added GetMaxHumanPlayers native exposing IServerGameClients func ({{bz|5551}}).&lt;br /&gt;
*Added WeaponIDToAlias native to CStrike extension ({{bz|5460}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Fixed OnLibraryAdded/Removed not being called in all plugins ({{bz|5431}}).&lt;br /&gt;
*Made thread worker processing limits configurable at runtime ({{bz|5326}}).&lt;br /&gt;
*Added support in TF2 ext for detection of player conds &amp;gt;= 64 ({{bz|5565}}).&lt;br /&gt;
*Updated button defines in entity_prop_stocks ({{bz|5564}}).&lt;br /&gt;
*Added GetPlayerResourceEntity to SDKTools to replace old, semi-broken TF2-only version ({{bz|5491}}).&lt;br /&gt;
*Exposed third parameter of TF2's AddCond in TF2_AddCondition ({{bz|5641}}) ({{user|84304|FlaminSarge}}).&lt;br /&gt;
*Added GetSteamAccountID function to IPlayerHelpers and native for sp ({{bz|5548}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Added ISDKHooks interface with entity listeners ({{bz|5602}}) ({{user|6136|GoD-Tony}}).&lt;br /&gt;
*Added file upload support to webternet extension.&lt;br /&gt;
*Added more alternative names for TFClass_Heavy ({{bz|5338}}) ({{user|59521|Afronanny}}).&lt;br /&gt;
*Throw error instead of crash when calling SetTeamScore between maps ({{bz|5718}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Fixed clients not being marked as in kick queue in some cases ({{bz|5746}}) ({{user|193987|SystematicMania}}).&lt;br /&gt;
*Made compile.sh set working dir to own dir ({{bz|5710}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Added CS_IsValidWeaponID native and validity checks to other natives ({{bz|5566}}) ({{user|26021|Drifter}}).&lt;br /&gt;
*Numerous code documentation fixups ({{bz|5720}}) ({{user|34668|Tsunami}}).&lt;br /&gt;
*Fixed cmd listener callback return behavior to match func doc ({{bz|5882}}).&lt;br /&gt;
&lt;br /&gt;
===Internal Changes===&lt;br /&gt;
&lt;br /&gt;
*Fixed handle misuse in clientprefs plugin ({{bz|5805}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Removed call to getchar() in debug build of compiler ({{bz|5626}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Fixed instability issues with cloned handles ({{bz|5245}}, {{bz|5240}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Changed extension unload order to avoid exposing finalization window ({{bz|5556}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Fixed typo in TF2 ext asm.c causing accidental assignment instead of compare.&lt;br /&gt;
*Call OnPluginEnd before finalizer hooks have run ({{bz|4519}}).&lt;br /&gt;
*Fixed potential for reading out of library bounds in MemoryUtils::FindPattern.&lt;br /&gt;
*Overhauled versioning information ({{bz|5453}}).&lt;br /&gt;
*Changed from RemoveEdict to using the Kill input for TF2_RemoveWeapon.&lt;br /&gt;
*Fixed accidental assignment in each of SDKTools and sp compiler ({{bz|5745}}) ({{user|57030|KyleS}}).&lt;br /&gt;
*Fixed potential deadlock in HandleSystem::TryAndFreeSomeHandles ({{bz|5665}}) ({{user|57030|KyleS}}).&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=9026</id>
		<title>Installing SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=9026"/>
		<updated>2013-08-26T02:17:07Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: /* Prerequisites */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages|Installing_SourceMod}}&lt;br /&gt;
&lt;br /&gt;
Installing SourceMod is very simple, and it can be added with almost no configuration changes.&lt;br /&gt;
&lt;br /&gt;
=Prerequisites=&lt;br /&gt;
A GUI Web Browser to retrieve Metamod and SourceMod compressed archives.&lt;br /&gt;
A tool to copy archive to your dedicated server host.&lt;br /&gt;
&lt;br /&gt;
SourceMod requires [[Metamod:Source]] 1.9.0 or higher (it is recommended that the latest version is used). [http://www.metamodsource.net/ Click here] to visit the Metamod:Source homepage. Instructions to install SourceMM manually can be found [[Installing Metamod:Source|here]].&lt;br /&gt;
&lt;br /&gt;
SourceMod will run on almost any mod built using the Source SDK.&lt;br /&gt;
&lt;br /&gt;
=Uploading/Installing=&lt;br /&gt;
==Local Server==&lt;br /&gt;
To install SourceMod locally, simply extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat, et cetera).&lt;br /&gt;
[http://www.sourcemod.net/downloads.php Download Here]&lt;br /&gt;
&lt;br /&gt;
==Remote Server==&lt;br /&gt;
To install SourceMod remotely, first extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your local computer (for example, your Desktop).  You will see an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  &lt;br /&gt;
&lt;br /&gt;
Using a tool such as [http://www.google.com/search?q=FTP FTP], locate your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike:Source, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat:Source, et cetera).  Underneath this folder, you should have an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder (if not, Metamod:Source is probably not installed).  From your local &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder, upload the entire contents to your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  When done, your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder should have a &amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
If you have trouble with these steps, you need to get acquainted with FTP and server management.  However, you can also ask your server provider for help.  Some providers also have web interfaces for managing your server.&lt;br /&gt;
&lt;br /&gt;
Alternatively, if you copied the tar.gz to your srcds directory, execute the following from the cstrike sub directory:&lt;br /&gt;
tar -xzf ../sourcemod-1.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
=Checking the Install=&lt;br /&gt;
Your folder layout should look like:&lt;br /&gt;
*&amp;lt;tt&amp;gt;[mod]&amp;lt;/tt&amp;gt; - Your mod's folder&lt;br /&gt;
**&amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt;&lt;br /&gt;
***&amp;lt;tt&amp;gt;metamod&amp;lt;/tt&amp;gt; - Metamod:Source&lt;br /&gt;
***&amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; - SourceMod&lt;br /&gt;
&lt;br /&gt;
Once SourceMod is uploaded/copied and configured with Metamod:Source, restart your server completely.  If it is local, shut it down and restart it.  If it is remote, you may need to ask your server provider for help.  However, it is often safe to issue a &amp;quot;quit&amp;quot; command via [[rcon]], since most providers will automatically restart your server.&lt;br /&gt;
&lt;br /&gt;
First, in your [[server console]] (not client console), type:&lt;br /&gt;
&amp;lt;pre&amp;gt;meta list&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the install worked, you will see something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
    [01] SourceMod (1.1.0.2489) by AlliedModders LLC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should then be able to use the SourceMod root console command, which can be invoked with simply:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;] sm version&lt;br /&gt;
 SourceMod Version Information:&lt;br /&gt;
    SourceMod Version: 1.1.0.2489&lt;br /&gt;
    SourcePawn Engine: SourcePawn 1.1, jit-x86 (build 1.1.0-svn)&lt;br /&gt;
    SourcePawn API: v1 = 4, v2 = 2&lt;br /&gt;
    Compiled on: Sep  5 2008 02:02:12&lt;br /&gt;
    http://www.sourcemod.net/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lastly, assuming you have already setup your administration user, you can test the in game menu by joining the server, and in the client console type the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_admin&amp;lt;/pre&amp;gt;&lt;br /&gt;
You should see a menu popup with all you options.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
If the install failed, you will generally see one of four symptoms.  &lt;br /&gt;
&lt;br /&gt;
==Metamod reports NOFILE or FAILED==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
  [01] &amp;lt;NOFILE&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most likely, either the files are not located in the correct place, or the file could not be loaded.  For more information, use the following command (except use the correct list number):&lt;br /&gt;
&amp;lt;pre&amp;gt;meta info 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Metamod lists no plugins==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 0 plugins:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several causes of this error.&lt;br /&gt;
&lt;br /&gt;
# The most common cause is that sourcemod.vdf can't be located in the addons/metamod folder.  Verify that sourcemod.vdf is present in this folder.&lt;br /&gt;
# If sourcemod.vdf is present, make sure you are using the correct build of Sourcemod (zip = windows, tar.gz = linux).&lt;br /&gt;
&lt;br /&gt;
==Metamod says nothing==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; has no reply at all, Metamod:Source is not properly installed. [[Installing Metamod:Source|This wiki page]] may provide you with clues on how to solve this problem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Category:Metamod:Source_Documentation&amp;diff=9025</id>
		<title>Category:Metamod:Source Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Category:Metamod:Source_Documentation&amp;diff=9025"/>
		<updated>2013-08-26T02:07:27Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&amp;lt;b&amp;gt;Installation and Setup&amp;lt;/b&amp;gt;&lt;br /&gt;
**[[Installing Metamod:Source]]&lt;br /&gt;
**[[Configuring Metamod:Source]]&lt;br /&gt;
*&amp;lt;b&amp;gt;Usage&amp;lt;/b&amp;gt;&lt;br /&gt;
**[[Console Commands (Metamod:Source)|Console Commands]]&lt;br /&gt;
**[[:Category:Metamod:Source Development|Development]]&lt;br /&gt;
*&amp;lt;b&amp;gt;Information&amp;lt;/b&amp;gt;&lt;br /&gt;
**[[Gameinfo Deprecation]]&lt;br /&gt;
**[[Metamod:Source VDF Files]]&lt;br /&gt;
**[[Supported Games (Metamod:Source)|Supported Games]]&lt;br /&gt;
**[[Frequently Asked Questions (Metamod:Source)|FAQ]]&lt;br /&gt;
**[[Open Source Plugins for Metamod:Source|Open Source Plugins]]&lt;br /&gt;
*&amp;lt;b&amp;gt;Development&amp;lt;/b&amp;gt;&lt;br /&gt;
**[[:Category:Metamod:Source Development|Metamod:Source Development]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=9024</id>
		<title>Installing SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=9024"/>
		<updated>2013-08-26T02:05:01Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages|Installing_SourceMod}}&lt;br /&gt;
&lt;br /&gt;
Installing SourceMod is very simple, and it can be added with almost no configuration changes.&lt;br /&gt;
&lt;br /&gt;
=Prerequisites=&lt;br /&gt;
A GUI Web Browser to retrieve Metamod and SourceMod compressed archives.&lt;br /&gt;
A tool to copy archive to your dedicated server host.&lt;br /&gt;
&lt;br /&gt;
SourceMod requires [[Metamod:Source]] 1.8.0 or higher (it is recommended that the latest version is used). [http://www.metamodsource.net/ Click here] to visit the Metamod:Source homepage. Instructions to install SourceMM manually can be found [[Installing Metamod:Source|here]].&lt;br /&gt;
&lt;br /&gt;
SourceMod will run on almost any mod built using the Source SDK.&lt;br /&gt;
&lt;br /&gt;
=Uploading/Installing=&lt;br /&gt;
==Local Server==&lt;br /&gt;
To install SourceMod locally, simply extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat, et cetera).&lt;br /&gt;
[http://www.sourcemod.net/downloads.php Download Here]&lt;br /&gt;
&lt;br /&gt;
==Remote Server==&lt;br /&gt;
To install SourceMod remotely, first extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your local computer (for example, your Desktop).  You will see an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  &lt;br /&gt;
&lt;br /&gt;
Using a tool such as [http://www.google.com/search?q=FTP FTP], locate your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike:Source, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat:Source, et cetera).  Underneath this folder, you should have an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder (if not, Metamod:Source is probably not installed).  From your local &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder, upload the entire contents to your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  When done, your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder should have a &amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
If you have trouble with these steps, you need to get acquainted with FTP and server management.  However, you can also ask your server provider for help.  Some providers also have web interfaces for managing your server.&lt;br /&gt;
&lt;br /&gt;
Alternatively, if you copied the tar.gz to your srcds directory, execute the following from the cstrike sub directory:&lt;br /&gt;
tar -xzf ../sourcemod-1.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
=Checking the Install=&lt;br /&gt;
Your folder layout should look like:&lt;br /&gt;
*&amp;lt;tt&amp;gt;[mod]&amp;lt;/tt&amp;gt; - Your mod's folder&lt;br /&gt;
**&amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt;&lt;br /&gt;
***&amp;lt;tt&amp;gt;metamod&amp;lt;/tt&amp;gt; - Metamod:Source&lt;br /&gt;
***&amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; - SourceMod&lt;br /&gt;
&lt;br /&gt;
Once SourceMod is uploaded/copied and configured with Metamod:Source, restart your server completely.  If it is local, shut it down and restart it.  If it is remote, you may need to ask your server provider for help.  However, it is often safe to issue a &amp;quot;quit&amp;quot; command via [[rcon]], since most providers will automatically restart your server.&lt;br /&gt;
&lt;br /&gt;
First, in your [[server console]] (not client console), type:&lt;br /&gt;
&amp;lt;pre&amp;gt;meta list&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the install worked, you will see something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
    [01] SourceMod (1.1.0.2489) by AlliedModders LLC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should then be able to use the SourceMod root console command, which can be invoked with simply:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;] sm version&lt;br /&gt;
 SourceMod Version Information:&lt;br /&gt;
    SourceMod Version: 1.1.0.2489&lt;br /&gt;
    SourcePawn Engine: SourcePawn 1.1, jit-x86 (build 1.1.0-svn)&lt;br /&gt;
    SourcePawn API: v1 = 4, v2 = 2&lt;br /&gt;
    Compiled on: Sep  5 2008 02:02:12&lt;br /&gt;
    http://www.sourcemod.net/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lastly, assuming you have already setup your administration user, you can test the in game menu by joining the server, and in the client console type the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_admin&amp;lt;/pre&amp;gt;&lt;br /&gt;
You should see a menu popup with all you options.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
If the install failed, you will generally see one of four symptoms.  &lt;br /&gt;
&lt;br /&gt;
==Metamod reports NOFILE or FAILED==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
  [01] &amp;lt;NOFILE&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most likely, either the files are not located in the correct place, or the file could not be loaded.  For more information, use the following command (except use the correct list number):&lt;br /&gt;
&amp;lt;pre&amp;gt;meta info 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Metamod lists no plugins==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 0 plugins:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several causes of this error.&lt;br /&gt;
&lt;br /&gt;
# The most common cause is that sourcemod.vdf can't be located in the addons/metamod folder.  Verify that sourcemod.vdf is present in this folder.&lt;br /&gt;
# If sourcemod.vdf is present, make sure you are using the correct build of Sourcemod (zip = windows, tar.gz = linux).&lt;br /&gt;
&lt;br /&gt;
==Metamod says nothing==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; has no reply at all, Metamod:Source is not properly installed. [[Installing Metamod:Source|This wiki page]] may provide you with clues on how to solve this problem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod_(simple)&amp;diff=9023</id>
		<title>Installing SourceMod (simple)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod_(simple)&amp;diff=9023"/>
		<updated>2013-08-26T02:03:51Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{outdated|directions=Please refer to the detailed guides for [[Installing Metamod:Source]] and [[Installing SourceMod]] respectively.}}&lt;br /&gt;
&lt;br /&gt;
The below is a simplified install guide and does not provide full issue and install feedback in order to remain simple. In most cases this guide should be sufficient, however in case you experience unusual behaviour, a detailed install guide is available [[Installing_SourceMod|here]].&lt;br /&gt;
&lt;br /&gt;
==Your Server==&lt;br /&gt;
SourceMod is a server addon. If you want to install SourceMod, it needs to be installed on the server.&amp;lt;br&amp;gt;&lt;br /&gt;
There are two kinds of servers: listen and dedicated.&lt;br /&gt;
[[File:Sourcededicatedserver.jpg|thumb|right|The Source dedicated server is located in the ''Tools'' category on Steam.]]&lt;br /&gt;
* A listen server is the server you host when using the in-game &amp;quot;create server&amp;quot; feature. '''NOTE:''' as of recent, SourceMod cannot run on a listen server by default. It is '''not''' recommended to use a listen server.&lt;br /&gt;
* A dedicated server is run using the ''Source Multiplayer Dedicated Server'', located in the ''Tools'' category on Steam.&lt;br /&gt;
Note: If you are installing SourceMod on a server not located near you, you should use the [[Installing_SourceMod|detailed install guide]].&lt;br /&gt;
&lt;br /&gt;
==Finding the root folder==&lt;br /&gt;
SourceMod is installed on the server for a specific game. The game could be Counter Strike:Source, Team Fortress 2 or many other.&amp;lt;br&amp;gt;&lt;br /&gt;
Each game has its own folder on your server if installed. Each folder has a unique name with the game's initials.&amp;lt;br&amp;gt;&lt;br /&gt;
A list of initials is included below.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
! Game !! Initials&lt;br /&gt;
|-&lt;br /&gt;
| Counter Strike:Source   || cstrike&lt;br /&gt;
|-&lt;br /&gt;
| Day of Defeat:Source   || dod&lt;br /&gt;
|-&lt;br /&gt;
| Team Fortress 2   || tf&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The root folder of your game is located in:&amp;lt;br&amp;gt;&lt;br /&gt;
Steam/steamapps/'''&amp;lt;accountname&amp;gt;'''/source 2007 dedicated server/'''&amp;lt;initials&amp;gt;'''/&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
''Note: Replace &amp;lt;accountname&amp;gt; with your Steam account name and &amp;lt;initials&amp;gt; with the proper initials listed above.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''Example:''' Steam/steamapps/'''gaben'''/source 2007 dedicated server/'''tf'''/&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Now that you have found your game's root folder, we can begin installing.&lt;br /&gt;
&lt;br /&gt;
==Installing Metamod:Source==&lt;br /&gt;
SourceMod runs using Metamod:Source. You will need to install Metamod in order for SourceMod to work.&lt;br /&gt;
* [http://www.metamodsource.net Download Metamod]. The download link is located on the left side of the webpage. Make sure to pick the proper operation system (Windows on a Windows server, Linux on a Linux server, and so on).&lt;br /&gt;
* Put the content of the zip into your game's root folder. You should now have an &amp;quot;addons&amp;quot; folder in your game's root folder.&lt;br /&gt;
* In order for the game to recognise Metamod, you need a vdf file. [http://www.metamodsource.net/?go=vdf Click here] and select the game you wish to install Metamod for, then click the generate button.&lt;br /&gt;
* Once the metamod.vdf file has downloaded, copy it into your &amp;quot;addons&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
You have now successfully installed Metamod!&lt;br /&gt;
&lt;br /&gt;
==Installing SourceMod==&lt;br /&gt;
Once you have installed Metamod:Source, there will be an &amp;quot;addons&amp;quot; folder in your server's game root.&amp;lt;br&amp;gt;&lt;br /&gt;
* [http://www.sourcemod.net/downloads.php Download SourceMod] (make sure to pick the proper operation system).&lt;br /&gt;
* Place the content of the zip into your server's game root.&lt;br /&gt;
&lt;br /&gt;
You have now successfully installed SourceMod!&lt;br /&gt;
&lt;br /&gt;
==Confirmation==&lt;br /&gt;
Before we end the guide, let's make sure everything is working.&lt;br /&gt;
* Start your server (or restart it if it was already running).&lt;br /&gt;
* Type 'meta version' into the server's console. If it does not recognise the command, then you have made a mistake in installing Metamod and we recommend that you follow the [[Installing_Metamod:Source|detailed guide]].&lt;br /&gt;
* Type 'sm version' into the server's console. If it does not recognise the command, then you have made a mistake in installing Sourcemod and we recommend that you follow the [[Installing_SourceMod|detailed guide]].&lt;br /&gt;
&lt;br /&gt;
If everything was successful then you're done!&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=9022</id>
		<title>Installing SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=9022"/>
		<updated>2013-08-26T02:02:04Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages|Installing_SourceMod}}&lt;br /&gt;
&lt;br /&gt;
Installing SourceMod is very simple, and it can be added with almost no configuration changes.&lt;br /&gt;
&lt;br /&gt;
=Prerequisites=&lt;br /&gt;
A GUI Web Browser to retrieve Metamod and SourceMod compressed archives.&lt;br /&gt;
A tool to copy archive to your dedicated server host.&lt;br /&gt;
&lt;br /&gt;
SourceMod requires [[Metamod:Source]] 1.8.0 or higher (it is recommended that the latest version is used). [http://www.metamodsource.net/ Click here] to visit the Metamod:Source homepage. Instructions to install SourceMM manually can be found [[Installing Metamod:Source|here]].&lt;br /&gt;
&lt;br /&gt;
SourceMod will run on almost any mod built using the Source SDK.&lt;br /&gt;
&lt;br /&gt;
=Uploading/Installing=&lt;br /&gt;
==Local Server==&lt;br /&gt;
To install SourceMod locally, simply extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat, et cetera).&lt;br /&gt;
[http://www.sourcemod.net/downloads.php Download Here]&lt;br /&gt;
&lt;br /&gt;
==Remote Server==&lt;br /&gt;
To install SourceMod remotely, first extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your local computer (for example, your Desktop).  You will see an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  &lt;br /&gt;
&lt;br /&gt;
Using a tool such as [http://www.google.com/search?q=FTP FTP], locate your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike:Source, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat:Source, et cetera).  Underneath this folder, you should have an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder (if not, Metamod:Source is probably not installed).  From your local &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder, upload the entire contents to your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  When done, your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder should have a &amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
If you have trouble with these steps, you need to get acquainted with FTP and server management.  However, you can also ask your server provider for help.  Some providers also have web interfaces for managing your server.&lt;br /&gt;
&lt;br /&gt;
Alternatively, if you copied the tar.gz to your srcds directory, execute the following from the cstrike sub directory:&lt;br /&gt;
tar -xzf ../sourcemod-1.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
=Checking the Install=&lt;br /&gt;
Your folder layout should look like:&lt;br /&gt;
*&amp;lt;tt&amp;gt;[mod]&amp;lt;/tt&amp;gt; - Your mod's folder&lt;br /&gt;
**&amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt;&lt;br /&gt;
***&amp;lt;tt&amp;gt;metamod&amp;lt;/tt&amp;gt; - Metamod:Source&lt;br /&gt;
***&amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; - SourceMod&lt;br /&gt;
&lt;br /&gt;
Once SourceMod is uploaded/copied and configured with Metamod:Source, restart your server completely.  If it is local, shut it down and restart it.  If it is remote, you may need to ask your server provider for help.  However, it is often safe to issue a &amp;quot;quit&amp;quot; command via [[rcon]], since most providers will automatically restart your server.&lt;br /&gt;
&lt;br /&gt;
First, in your [[server console]] (not client console), type:&lt;br /&gt;
&amp;lt;pre&amp;gt;meta list&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the install worked, you will see something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
    [01] SourceMod (1.1.0.2489) by AlliedModders LLC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should then be able to use the SourceMod root console command, which can be invoked with simply:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;] sm version&lt;br /&gt;
 SourceMod Version Information:&lt;br /&gt;
    SourceMod Version: 1.1.0.2489&lt;br /&gt;
    SourcePawn Engine: SourcePawn 1.1, jit-x86 (build 1.1.0-svn)&lt;br /&gt;
    SourcePawn API: v1 = 4, v2 = 2&lt;br /&gt;
    Compiled on: Sep  5 2008 02:02:12&lt;br /&gt;
    http://www.sourcemod.net/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lastly, assuming you have already setup your administration user, you can test the in game menu by joining the server, and in the client console type the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_admin&amp;lt;/pre&amp;gt;&lt;br /&gt;
You should see a menu popup with all you options.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
If the install failed, you will generally see one of four symptoms.  &lt;br /&gt;
&lt;br /&gt;
==Metamod reports NOFILE or FAILED==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
  [01] &amp;lt;NOFILE&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most likely, either the files are not located in the correct place, or the file could not be loaded.  For more information, use the following command (except use the correct list number):&lt;br /&gt;
&amp;lt;pre&amp;gt;meta info 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Metamod lists no plugins==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 0 plugins:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several causes of this error.&lt;br /&gt;
&lt;br /&gt;
# The most common cause is that sourcemod.vdf can't be located in the addons/metamod folder.  Verify that sourcemod.vdf is present in this folder.&lt;br /&gt;
# If sourcemod.vdf is present, make sure you are using the correct build of Sourcemod (zip = windows, tar.gz = linux).&lt;br /&gt;
&lt;br /&gt;
==Metamod says nothing==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; has no reply at all, Metamod:Source is not properly installed. [http://wiki.alliedmods.net/index.php/Installing_SourceMM This wiki page] may provide you with clues on how to solve this problem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9021</id>
		<title>Template:Outdated</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9021"/>
		<updated>2013-08-26T02:01:03Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;{{nmbox&lt;br /&gt;
 | image = [[Image:Gnome globe current event.png|42px]]&lt;br /&gt;
 | text  = '''This article's factual accuracy may be compromised due to out-of-date information.'''&amp;lt;br&amp;gt;It is strongly suggested that you do not follow any instructions that may appear on this page.{{#if:{{{directions|}}}|&amp;lt;br&amp;gt;'''{{{directions|}}}'''|}}&lt;br /&gt;
}}&amp;lt;includeonly&amp;gt;[[Category:Outdated]]&amp;lt;/includeonly&amp;gt;&amp;lt;/center&amp;gt;&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9020</id>
		<title>Template:Outdated</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9020"/>
		<updated>2013-08-26T02:00:38Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;{{nmbox&lt;br /&gt;
 | image = [[Image:Gnome globe current event.png|42px]]&lt;br /&gt;
 | text  = '''This article's factual accuracy may be compromised due to out-of-date information'''&amp;lt;br&amp;gt;It is strongly suggested that you do not follow any instructions that may appear on this page.{{#if:{{{directions|}}}|&amp;lt;br&amp;gt;'''{{{directions|}}}'''|}}&lt;br /&gt;
}}&amp;lt;includeonly&amp;gt;[[Category:Outdated]]&amp;lt;/includeonly&amp;gt;&amp;lt;/center&amp;gt;&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9019</id>
		<title>Template:Outdated</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9019"/>
		<updated>2013-08-26T01:59:53Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;{{nmbox&lt;br /&gt;
 | image = [[Image:Gnome globe current event.png|42px]]&lt;br /&gt;
 | text  = '''This article's factual accuracy may be compromised due to out-of-date information'''&amp;lt;br&amp;gt;It is strongly suggested that you do not follow any instructions that may appear on this page.{{#if:{{{directions|}}}|&amp;lt;br&amp;gt;{{{directions|}}}|}}&lt;br /&gt;
}}&amp;lt;includeonly&amp;gt;[[Category:Outdated]]&amp;lt;/includeonly&amp;gt;&amp;lt;/center&amp;gt;&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=9018</id>
		<title>Installing SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=9018"/>
		<updated>2013-08-26T01:57:28Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages|Installing_SourceMod}}&lt;br /&gt;
&lt;br /&gt;
Installing SourceMod is very simple, and it can be added with almost no configuration changes.&lt;br /&gt;
&lt;br /&gt;
=Prerequisites=&lt;br /&gt;
A GUI Web Browser to retrieve Metamod and SourceMod compressed archives.&lt;br /&gt;
A tool to copy archive to your dedicated server host.&lt;br /&gt;
&lt;br /&gt;
SourceMod requires [[Metamod:Source]] 1.8.0 or higher (it is recommended that the latest version is used). [http://www.metamodsource.net/ Click here] to visit the Metamod:Source homepage. Instructions to install SourceMM manually can be found [http://wiki.alliedmods.net/index.php/Installing_Metamod:Source here].&lt;br /&gt;
&lt;br /&gt;
SourceMod will run on almost any mod built using the Source SDK.&lt;br /&gt;
&lt;br /&gt;
=Uploading/Installing=&lt;br /&gt;
==Local Server==&lt;br /&gt;
To install SourceMod locally, simply extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat, et cetera).&lt;br /&gt;
[http://www.sourcemod.net/downloads.php Download Here]&lt;br /&gt;
&lt;br /&gt;
==Remote Server==&lt;br /&gt;
To install SourceMod remotely, first extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your local computer (for example, your Desktop).  You will see an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  &lt;br /&gt;
&lt;br /&gt;
Using a tool such as [http://www.google.com/search?q=FTP FTP], locate your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike:Source, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat:Source, et cetera).  Underneath this folder, you should have an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder (if not, Metamod:Source is probably not installed).  From your local &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder, upload the entire contents to your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  When done, your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder should have a &amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
If you have trouble with these steps, you need to get acquainted with FTP and server management.  However, you can also ask your server provider for help.  Some providers also have web interfaces for managing your server.&lt;br /&gt;
&lt;br /&gt;
Alternatively, if you copied the tar.gz to your srcds directory, execute the following from the cstrike sub directory:&lt;br /&gt;
tar -xzf ../sourcemod-1.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
=Checking the Install=&lt;br /&gt;
Your folder layout should look like:&lt;br /&gt;
*&amp;lt;tt&amp;gt;[mod]&amp;lt;/tt&amp;gt; - Your mod's folder&lt;br /&gt;
**&amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt;&lt;br /&gt;
***&amp;lt;tt&amp;gt;metamod&amp;lt;/tt&amp;gt; - Metamod:Source&lt;br /&gt;
***&amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; - SourceMod&lt;br /&gt;
&lt;br /&gt;
Once SourceMod is uploaded/copied and configured with Metamod:Source, restart your server completely.  If it is local, shut it down and restart it.  If it is remote, you may need to ask your server provider for help.  However, it is often safe to issue a &amp;quot;quit&amp;quot; command via [[rcon]], since most providers will automatically restart your server.&lt;br /&gt;
&lt;br /&gt;
First, in your [[server console]] (not client console), type:&lt;br /&gt;
&amp;lt;pre&amp;gt;meta list&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the install worked, you will see something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
    [01] SourceMod (1.1.0.2489) by AlliedModders LLC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should then be able to use the SourceMod root console command, which can be invoked with simply:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;] sm version&lt;br /&gt;
 SourceMod Version Information:&lt;br /&gt;
    SourceMod Version: 1.1.0.2489&lt;br /&gt;
    SourcePawn Engine: SourcePawn 1.1, jit-x86 (build 1.1.0-svn)&lt;br /&gt;
    SourcePawn API: v1 = 4, v2 = 2&lt;br /&gt;
    Compiled on: Sep  5 2008 02:02:12&lt;br /&gt;
    http://www.sourcemod.net/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lastly, assuming you have already setup your administration user, you can test the in game menu by joining the server, and in the client console type the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_admin&amp;lt;/pre&amp;gt;&lt;br /&gt;
You should see a menu popup with all you options.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
If the install failed, you will generally see one of four symptoms.  &lt;br /&gt;
&lt;br /&gt;
==Metamod reports NOFILE or FAILED==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
  [01] &amp;lt;NOFILE&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most likely, either the files are not located in the correct place, or the file could not be loaded.  For more information, use the following command (except use the correct list number):&lt;br /&gt;
&amp;lt;pre&amp;gt;meta info 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Metamod lists no plugins==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 0 plugins:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several causes of this error.&lt;br /&gt;
&lt;br /&gt;
# The most common cause is that sourcemod.vdf can't be located in the addons/metamod folder.  Verify that sourcemod.vdf is present in this folder.&lt;br /&gt;
# If sourcemod.vdf is present, make sure you are using the correct build of Sourcemod (zip = windows, tar.gz = linux).&lt;br /&gt;
&lt;br /&gt;
==Metamod says nothing==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; has no reply at all, Metamod:Source is not properly installed. [http://wiki.alliedmods.net/index.php/Installing_SourceMM This wiki page] may provide you with clues on how to solve this problem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod/ko&amp;diff=9017</id>
		<title>Installing SourceMod/ko</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod/ko&amp;diff=9017"/>
		<updated>2013-08-26T01:55:44Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{outdated|directions=Please refer to the english language version.}}&lt;br /&gt;
&lt;br /&gt;
{{Languages|Installing_SourceMod}}&lt;br /&gt;
&lt;br /&gt;
소스모드를 설치하는 것은 아주 간단합니다. 그리고 설정을 바꿀 필요도 거의 없습니다.&lt;br /&gt;
&amp;lt;br&amp;gt;'''아래는 자세한 설치 안내이고, 중요한 정보와 설치 피드팩을 제공합니다. 그러나, 이 페이지의 설명을 이해하는 데 어려움을 겪고있다면, 간단한 설치 안내서가 [[Installing_SourceMod_(simple)|여기]]에 있습니다.'''&lt;br /&gt;
&lt;br /&gt;
=필요한 것들=&lt;br /&gt;
메타모드와 소스모드의 파일을 받기 위해서 GUI 웹브라우저가 필요합니다&lt;br /&gt;
당신의 데디케이트 서버 호스트에 파일들을 복사할 도구가 필요합니다&lt;br /&gt;
&lt;br /&gt;
소스모드는 [[Metamod:Source|메타모드:소스]] 1.8.0 이나 더 높은 버전이 필요합니다&lt;br /&gt;
메타모드:소스의 홈페이지에 방문하려면 [http://www.metamodsource.net/ 이곳]을 클릭하세요&lt;br /&gt;
메타모드:소스를 설치를 위한 설명은 [[Installing_Metamod:Source|여기]]에 있습니다.&lt;br /&gt;
&lt;br /&gt;
소스모드는 Source SDK를 사용해서 만들어진 어떤 모드에서도 작동합니다. 또한, Source Engine을 사용해 만들어진 &amp;quot;더 쉽(The Ship)&amp;quot;도 지원합니다.&lt;br /&gt;
&lt;br /&gt;
=업그레이드/설치=&lt;br /&gt;
==로컬 서버==&lt;br /&gt;
소스모드를 로컬 서버에 설치하려면, 단순히 &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt;(윈도우즈) 또는 &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt;(리눅스) 패키지를 당신의 모드 폴더 (예를 들어 카운터스트라이크:소스라면 &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt;, 데이 오브 디피트:소스 라면 &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; 등...)에 압축 해제하세요. [http://www.sourcemod.net/downloads.php 여기]에서 다운로드하세요. &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; 폴더가 보일 것입니다.&lt;br /&gt;
&lt;br /&gt;
[http://www.google.com/search?q=FTP FTP] 같은 도구를 써서, 당신의 모드 폴더(예를 들어 카운터스트라이크:소스라면 &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt;, 데이 오브 디피트:소스 라면 &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; 등...)를 찾으세요. 그리고 그 폴더 아래에, &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; 폴더가 있어야 합니다.(없다면, 메타모드:소스가 설치되지 않은 것입니다.) 당신의 로컬 &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; 폴더에서 목표로 하는 원격 &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; 폴더로 모든 내용물을 업로드하세요. 다 끝나면, 원격 &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; 폴더는 &amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; 폴더를 가지고 있을 것입니다.&lt;br /&gt;
&lt;br /&gt;
이러한 단계를 수행하는 데 어려움을 겪는다면, FTP나 서버 관리에 보다 익숙해져야 합니다. 그러나 당신의 서버 제공자에게 도움을 요청할 수 있을 것입니다. 몇몇 서버 제공자들은 당신의 서버를 관리하기 위한 웹 인터페이스를 제공해 줄 것입니다.&lt;br /&gt;
&lt;br /&gt;
만약 당신이 tar.gz 파일을 srcds 디렉토리에 복사했다면, 하위의 cstrike 디렉토리에서 다음을 실행하세요 : &lt;br /&gt;
tar -xzf ../sourcemod-1.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
=설치 확인=&lt;br /&gt;
이제 폴더 구조가 다음과 같을 것입니다:&lt;br /&gt;
*&amp;lt;tt&amp;gt;[모드]&amp;lt;/tt&amp;gt; - 모드의 폴더&lt;br /&gt;
**&amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt;&lt;br /&gt;
***&amp;lt;tt&amp;gt;metamod&amp;lt;/tt&amp;gt; - 메타모드:소스&lt;br /&gt;
***&amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; - 소스모드&lt;br /&gt;
&lt;br /&gt;
일단 소스모드가 업로드/복사 되고, 메타모드:소스와 설정이 끝나면, 당신의 서버를 완전히 재시작하세요. 로컬 서버라면, 종료한 뒤 재시작하고, 원격 서버라면 서버 제공자에게 문의해야 합니다. 경우에 따라 [[rcon]] 명령으로 &amp;quot;quit&amp;quot; 명령을 실행하는 것도 안전한데, 대개의 서버 제공자들이 당신의 서버를 다시 실행시켜 줄 것이기 때문입니다.&lt;br /&gt;
&lt;br /&gt;
먼저, [[server console|서버 콘솔]](클라이언트 콘솔이 아님) 에 다음을 입력하세요:&lt;br /&gt;
&amp;lt;pre&amp;gt;meta list&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
설치가 제대로 됬다면, 다음과 같은 것을 볼 것입니다:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
    [01] SourceMod (1.1.0.2489) by AlliedModders LLC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 소스모드의 주 콘솔 명령을 사용할 수 있습니다. 단순히 아래와 같이 실행합니다:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
예제:&lt;br /&gt;
&amp;lt;pre&amp;gt;] sm version&lt;br /&gt;
 SourceMod Version Information:&lt;br /&gt;
    SourceMod Version: 1.1.0.2489&lt;br /&gt;
    SourcePawn Engine: SourcePawn 1.1, jit-x86 (build 1.1.0-svn)&lt;br /&gt;
    SourcePawn API: v1 = 4, v2 = 2&lt;br /&gt;
    Compiled on: Sep  5 2008 02:02:12&lt;br /&gt;
    http://www.sourcemod.net/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
마지막으로, 당신이 이미 관리자 설정을 끝마쳤다고 가정한다면, 이제 서버에 접속해서 클라이언트 콘솔에 다음을 입력해서 인게임 메뉴를 시험해 볼 수 있습니다:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_admin&amp;lt;/pre&amp;gt;&lt;br /&gt;
이것으로 옵션이 있는 메뉴를 볼 수 있어야 합니다.&lt;br /&gt;
&lt;br /&gt;
=문제 해결=&lt;br /&gt;
설치에 실패했다면, 일반적으로 네가지 증상을 살펴보아야 합니다.  &lt;br /&gt;
&lt;br /&gt;
==메타모드가 NOFILE 혹은 FAILED 를 보고한다==&lt;br /&gt;
&amp;quot;meta list&amp;quot; 를 입력했을 때 다음과 같은 응답을 한다면:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
-Id- Name                  Version     Author           Status  &lt;br /&gt;
[01] -                     -           -                NOFILE  &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
대개의 경우 파일들이 올바른 위치에 없거나, 파일이 로드될 수 없는 것입니다. 자세한 정보를 위해서는 다음의 명령어를 사용하세요 (단, 올바를 줄번호를 사용해야 합니다):&lt;br /&gt;
&amp;lt;pre&amp;gt;meta list 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==메타모드가 아무 플러그인도 보여주지 않는다==&lt;br /&gt;
만약 &amp;quot;meta list&amp;quot; 다음과 같은 응답을 한다면:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
-Id- Name                  Version     Author           Status  &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
소스모드를 &amp;lt;tt&amp;gt;addons/metamod/metaplugins.ini&amp;lt;/tt&amp;gt; 파일에 더하는 것을 잊었거나, 혹은 그것이 당신의 문제를 해결해주지 못한다면, 올바른 소스모드의 빌드를 사용하는지 확인하십시오(zip = 윈도우즈, tar = 리눅스)&lt;br /&gt;
&lt;br /&gt;
==메타모드가 아무 응답도 하지 않는다==&lt;br /&gt;
만약 &amp;quot;meta list&amp;quot; 가 전혀 응답하지 않는다면, 메타모드:소스가 설치되지 않은 것입니다.&lt;br /&gt;
[[Installing_SourceMM|이 위키 페이지]] 가 아마도 이 문제를 해결할 단서를 제공해 줄 것입니다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9016</id>
		<title>Installing Metamod:Source</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9016"/>
		<updated>2013-08-26T01:54:22Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will guide you through a [[Metamod:Source]] installation.&lt;br /&gt;
&lt;br /&gt;
=Normal Installation=&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[http://www.metamodsource.net/ Download] Metamod:Source.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Extract the package to your game folder.  For example, for Counter-Strike:Source, you would have &amp;lt;tt&amp;gt;cstrike/addons/metamod&amp;lt;/tt&amp;gt; after extracting.  If you are uploading to FTP, extract the files locally before transferring to your server's game folder.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Restart your server.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Type &amp;quot;meta version&amp;quot; in your server console (or RCON).  You should see a line like: &amp;quot;Loaded As: Valve Server Plugin.&amp;quot;  If the command is not recognized, see the [[Installing Metamod:Source#Troubleshooting|Troubleshooting]] section below.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Custom VDF File==&lt;br /&gt;
Metamod:Source 1.10.0 and later include a &amp;lt;tt&amp;gt;metamod.vdf&amp;lt;/tt&amp;gt; file for easier installation on most games. If you have trouble getting it to load, [http://www.metamodsource.net/?go=vdf go here] to generate a VDF file specific to your game. This file should be placed into your server's &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
Known setups that require this step:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Games on the Episode 1 or older engines.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Listen servers (created with the in-game &amp;quot;Create Server&amp;quot; option) for non-english game clients.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=GameInfo=&lt;br /&gt;
'''Note: This is normally not needed - if you do not understand what this, do NOT do this unless instructed to. The above instructions are sufficient to install Metamod:Source for 99% of servers.'''&lt;br /&gt;
&lt;br /&gt;
Metamod:Source 1.4.2 and lower used an older method for loading itself.  The advantage of this method was that Metamod:Source could be loaded before the actual game mod, which gave it a small amount of extra functionality.  This functionality was never used by plugin developers, and Steam updates kept overwriting &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; files, so we switched to a different loading mechanism.&lt;br /&gt;
&lt;br /&gt;
However this loading mechanism may still be desirable if you run into backwards compatibility issues, or you have a plugin which takes advantage of the early-loading mechanism.  If this is your case, here are the &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; directions below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the file in the mod folder called &amp;quot;gameinfo.txt&amp;quot;. You will see a few lines at the bottom like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SearchPaths&lt;br /&gt;
{&lt;br /&gt;
	Game				|gameinfo_path|. &lt;br /&gt;
	Game				cstrike&lt;br /&gt;
	Game				hl2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add a line after the &amp;quot;{&amp;quot; sign but before all of the &amp;quot;Game&amp;quot; entries that looks like this:&amp;lt;pre&amp;gt;GameBin				|gameinfo_path|addons/metamod/bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If you're using Windows, you may need to use a backwards slash (\) instead.&lt;br /&gt;
&amp;lt;li&amp;gt;You're done! To test whether it worked, restart your game server and type &amp;quot;meta version&amp;quot; in the server console.  You should see a line that says &amp;quot;Loaded as: GameDLL (gameinfo.txt).&amp;quot;  If it doesn't recognize the command, the installation probably failed.  If the &amp;quot;Loaded as:&amp;quot; line says something else, &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; was probably not modified correctly.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For more information or documentation, see [[:Category:Metamod:Source Documentation]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; loading method is supported as a legacy feature only.  The patcher tool is no longer provided.  You can mark &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; if you absolutely want to protect it from being overwritten.&lt;br /&gt;
&lt;br /&gt;
We will continue to make sure Metamod:Source can load via this method for as long as the Source Engine allows it.  However, we will concentrate more on supporting the new loading mechanism for general use.&lt;br /&gt;
&lt;br /&gt;
[[Category:Metamod:Source Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Category:Outdated&amp;diff=9015</id>
		<title>Category:Outdated</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Category:Outdated&amp;diff=9015"/>
		<updated>2013-08-26T01:53:24Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Created page with &amp;quot;Pages in this category have been marked as containing outdated information, they should be updated, or references to them should be removed if the information is no longer rel...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pages in this category have been marked as containing outdated information, they should be updated, or references to them should be removed if the information is no longer relevant in any way.&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod_(simple)&amp;diff=9014</id>
		<title>Installing SourceMod (simple)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod_(simple)&amp;diff=9014"/>
		<updated>2013-08-26T01:52:18Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{outdated}}&lt;br /&gt;
&lt;br /&gt;
The below is a simplified install guide and does not provide full issue and install feedback in order to remain simple. In most cases this guide should be sufficient, however in case you experience unusual behaviour, a detailed install guide is available [[Installing_SourceMod|here]].&lt;br /&gt;
&lt;br /&gt;
==Your Server==&lt;br /&gt;
SourceMod is a server addon. If you want to install SourceMod, it needs to be installed on the server.&amp;lt;br&amp;gt;&lt;br /&gt;
There are two kinds of servers: listen and dedicated.&lt;br /&gt;
[[File:Sourcededicatedserver.jpg|thumb|right|The Source dedicated server is located in the ''Tools'' category on Steam.]]&lt;br /&gt;
* A listen server is the server you host when using the in-game &amp;quot;create server&amp;quot; feature. '''NOTE:''' as of recent, SourceMod cannot run on a listen server by default. It is '''not''' recommended to use a listen server.&lt;br /&gt;
* A dedicated server is run using the ''Source Multiplayer Dedicated Server'', located in the ''Tools'' category on Steam.&lt;br /&gt;
Note: If you are installing SourceMod on a server not located near you, you should use the [[Installing_SourceMod|detailed install guide]].&lt;br /&gt;
&lt;br /&gt;
==Finding the root folder==&lt;br /&gt;
SourceMod is installed on the server for a specific game. The game could be Counter Strike:Source, Team Fortress 2 or many other.&amp;lt;br&amp;gt;&lt;br /&gt;
Each game has its own folder on your server if installed. Each folder has a unique name with the game's initials.&amp;lt;br&amp;gt;&lt;br /&gt;
A list of initials is included below.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
! Game !! Initials&lt;br /&gt;
|-&lt;br /&gt;
| Counter Strike:Source   || cstrike&lt;br /&gt;
|-&lt;br /&gt;
| Day of Defeat:Source   || dod&lt;br /&gt;
|-&lt;br /&gt;
| Team Fortress 2   || tf&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The root folder of your game is located in:&amp;lt;br&amp;gt;&lt;br /&gt;
Steam/steamapps/'''&amp;lt;accountname&amp;gt;'''/source 2007 dedicated server/'''&amp;lt;initials&amp;gt;'''/&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
''Note: Replace &amp;lt;accountname&amp;gt; with your Steam account name and &amp;lt;initials&amp;gt; with the proper initials listed above.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''Example:''' Steam/steamapps/'''gaben'''/source 2007 dedicated server/'''tf'''/&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Now that you have found your game's root folder, we can begin installing.&lt;br /&gt;
&lt;br /&gt;
==Installing Metamod:Source==&lt;br /&gt;
SourceMod runs using Metamod:Source. You will need to install Metamod in order for SourceMod to work.&lt;br /&gt;
* [http://www.metamodsource.net Download Metamod]. The download link is located on the left side of the webpage. Make sure to pick the proper operation system (Windows on a Windows server, Linux on a Linux server, and so on).&lt;br /&gt;
* Put the content of the zip into your game's root folder. You should now have an &amp;quot;addons&amp;quot; folder in your game's root folder.&lt;br /&gt;
* In order for the game to recognise Metamod, you need a vdf file. [http://www.metamodsource.net/?go=vdf Click here] and select the game you wish to install Metamod for, then click the generate button.&lt;br /&gt;
* Once the metamod.vdf file has downloaded, copy it into your &amp;quot;addons&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
You have now successfully installed Metamod!&lt;br /&gt;
&lt;br /&gt;
==Installing SourceMod==&lt;br /&gt;
Once you have installed Metamod:Source, there will be an &amp;quot;addons&amp;quot; folder in your server's game root.&amp;lt;br&amp;gt;&lt;br /&gt;
* [http://www.sourcemod.net/downloads.php Download SourceMod] (make sure to pick the proper operation system).&lt;br /&gt;
* Place the content of the zip into your server's game root.&lt;br /&gt;
&lt;br /&gt;
You have now successfully installed SourceMod!&lt;br /&gt;
&lt;br /&gt;
==Confirmation==&lt;br /&gt;
Before we end the guide, let's make sure everything is working.&lt;br /&gt;
* Start your server (or restart it if it was already running).&lt;br /&gt;
* Type 'meta version' into the server's console. If it does not recognise the command, then you have made a mistake in installing Metamod and we recommend that you follow the [[Installing_Metamod:Source|detailed guide]].&lt;br /&gt;
* Type 'sm version' into the server's console. If it does not recognise the command, then you have made a mistake in installing Sourcemod and we recommend that you follow the [[Installing_SourceMod|detailed guide]].&lt;br /&gt;
&lt;br /&gt;
If everything was successful then you're done!&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9013</id>
		<title>Template:Outdated</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9013"/>
		<updated>2013-08-26T01:51:53Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;{{nmbox&lt;br /&gt;
 | image = [[Image:Gnome globe current event.png|42px]]&lt;br /&gt;
 | text  = '''This article's factual accuracy may be compromised due to out-of-date information'''&amp;lt;br&amp;gt;It is strongly suggested that you do not follow any instructions that may appear on this page.&lt;br /&gt;
}}&amp;lt;includeonly&amp;gt;[[Category:Outdated]]&amp;lt;/includeonly&amp;gt;&amp;lt;/center&amp;gt;&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9012</id>
		<title>Template:Outdated</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9012"/>
		<updated>2013-08-26T01:48:26Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;{{nmbox&lt;br /&gt;
 | image = [[Image:Gnome globe current event.png|42px]]&lt;br /&gt;
 | text  = '''This article's factual accuracy may be compromised due to out-of-date information'''&amp;lt;br&amp;gt;It is strongly suggested that you do not follow any instructions that may appear on this page.&lt;br /&gt;
}}&amp;lt;/center&amp;gt;&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Template:Nmbox&amp;diff=9011</id>
		<title>Template:Nmbox</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Template:Nmbox&amp;diff=9011"/>
		<updated>2013-08-26T01:47:41Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;table class=&amp;quot;nmbox&amp;quot; style=&amp;quot;border:1px solid #AAAAAA; border-collapse:collapse; clear:both; font-size:85%; margin: 0.25em 0;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background: #EEF3E2&amp;quot;&amp;gt;&lt;br /&gt;
{{#if:{{{image|}}}{{{header|}}}&lt;br /&gt;
| &amp;lt;th class=&amp;quot;mbox-image&amp;quot; style=&amp;quot;white-space: nowrap; padding: 4px 1em; border-right: 1px solid #aaaaaa;&amp;quot;&amp;gt;{{{image|}}} {{{header|}}}&amp;lt;/th&amp;gt;&lt;br /&gt;
| &amp;lt;td class=&amp;quot;mbox-empty-cell&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;   &amp;lt;!-- No image. Cell with some width or padding necessary for text cell to have 100% width. --&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;td class=&amp;quot;mbox-text&amp;quot; style=&amp;quot;background: #F6F9ED; padding: 4px 1em&amp;quot;&amp;gt;{{{text|}}}&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9010</id>
		<title>Template:Outdated</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Template:Outdated&amp;diff=9010"/>
		<updated>2013-08-26T01:46:32Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Created page with &amp;quot;{{nmbox  | image = 42px  | text  = '''This article's factual accuracy may be compromised due to out-of-date information'''&amp;lt;br&amp;gt;It is str...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{nmbox&lt;br /&gt;
 | image = [[Image:Gnome globe current event.png|42px]]&lt;br /&gt;
 | text  = '''This article's factual accuracy may be compromised due to out-of-date information'''&amp;lt;br&amp;gt;It is strongly suggested that you do not follow any instructions that may appear on this page.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=File:Gnome_globe_current_event.png&amp;diff=9009</id>
		<title>File:Gnome globe current event.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=File:Gnome_globe_current_event.png&amp;diff=9009"/>
		<updated>2013-08-26T01:42:52Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9008</id>
		<title>Installing Metamod:Source</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_Metamod:Source&amp;diff=9008"/>
		<updated>2013-08-26T01:27:55Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Updated install instructions for 1.10.0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article will guide you through a [[Metamod:Source]] installation.  Use this guide if you wish to install Metamod:Source manually, or for some reason you cannot (or will not) use the automated installer.&lt;br /&gt;
&amp;lt;br&amp;gt;'''The below is a detailed install guide and provides excellent issue and install feedback. However, if you're having troubles understanding the page and its instructions, [[Installing_SourceMod_(simple)|a simplified install guide is available here]].'''&lt;br /&gt;
&lt;br /&gt;
=Normal Installation=&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[http://www.metamodsource.net/ Download] Metamod:Source.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Extract the package to your game folder.  For example, for Counter-Strike:Source, you would have &amp;lt;tt&amp;gt;cstrike/addons/metamod&amp;lt;/tt&amp;gt; after extracting.  If you are uploading to FTP, extract the files locally before transferring to your server's game folder.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Restart your server.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Type &amp;quot;meta version&amp;quot; in your server console (or RCON).  You should see a line like: &amp;quot;Loaded As: Valve Server Plugin.&amp;quot;  If the command is not recognized, see the [[Installing Metamod:Source#Troubleshooting|Troubleshooting]] section below.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Custom VDF File==&lt;br /&gt;
Metamod:Source 1.10.0 and later include a &amp;lt;tt&amp;gt;metamod.vdf&amp;lt;/tt&amp;gt; file for easier installation on most games. If you have trouble getting it to load, [http://www.metamodsource.net/?go=vdf go here] to generate a VDF file specific to your game. This file should be placed into your server's &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
Known setups that require this step:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Games on the Episode 1 or older engines.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Listen servers (created with the in-game &amp;quot;Create Server&amp;quot; option) for non-english game clients.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=GameInfo=&lt;br /&gt;
'''Note: This is normally not needed - if you do not understand what this, do NOT do this unless instructed to. The above instructions are sufficient to install Metamod:Source for 99% of servers.'''&lt;br /&gt;
&lt;br /&gt;
Metamod:Source 1.4.2 and lower used an older method for loading itself.  The advantage of this method was that Metamod:Source could be loaded before the actual game mod, which gave it a small amount of extra functionality.  This functionality was never used by plugin developers, and Steam updates kept overwriting &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; files, so we switched to a different loading mechanism.&lt;br /&gt;
&lt;br /&gt;
However this loading mechanism may still be desirable if you run into backwards compatibility issues, or you have a plugin which takes advantage of the early-loading mechanism.  If this is your case, here are the &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; directions below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the file in the mod folder called &amp;quot;gameinfo.txt&amp;quot;. You will see a few lines at the bottom like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SearchPaths&lt;br /&gt;
{&lt;br /&gt;
	Game				|gameinfo_path|. &lt;br /&gt;
	Game				cstrike&lt;br /&gt;
	Game				hl2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add a line after the &amp;quot;{&amp;quot; sign but before all of the &amp;quot;Game&amp;quot; entries that looks like this:&amp;lt;pre&amp;gt;GameBin				|gameinfo_path|addons/metamod/bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If you're using Windows, you may need to use a backwards slash (\) instead.&lt;br /&gt;
&amp;lt;li&amp;gt;You're done! To test whether it worked, restart your game server and type &amp;quot;meta version&amp;quot; in the server console.  You should see a line that says &amp;quot;Loaded as: GameDLL (gameinfo.txt).&amp;quot;  If it doesn't recognize the command, the installation probably failed.  If the &amp;quot;Loaded as:&amp;quot; line says something else, &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; was probably not modified correctly.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For more information or documentation, see [[:Category:Metamod:Source Documentation]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; loading method is supported as a legacy feature only.  The patcher tool is no longer provided.  You can mark &amp;lt;tt&amp;gt;gameinfo.txt&amp;lt;/tt&amp;gt; if you absolutely want to protect it from being overwritten.&lt;br /&gt;
&lt;br /&gt;
We will continue to make sure Metamod:Source can load via this method for as long as the Source Engine allows it.  However, we will concentrate more on supporting the new loading mechanism for general use.&lt;br /&gt;
&lt;br /&gt;
[[Category:Metamod:Source Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=8963</id>
		<title>Installing SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=8963"/>
		<updated>2013-07-07T12:45:58Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: /* Metamod lists no plugins */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages|Installing_SourceMod}}&lt;br /&gt;
&lt;br /&gt;
Installing SourceMod is very simple, and it can be added with almost no configuration changes.&lt;br /&gt;
&amp;lt;br&amp;gt;'''The below is a detailed install guide and provides excellent issue and install feedback. However, if you're having troubles understanding the page and its instructions, [[Installing_SourceMod_(simple)|a simplified install guide is available here]].'''&lt;br /&gt;
&lt;br /&gt;
=Prerequisites=&lt;br /&gt;
A GUI Web Browser to retrieve Metamod and SourceMod compressed archives.&lt;br /&gt;
A tool to copy archive to your dedicated server host.&lt;br /&gt;
&lt;br /&gt;
SourceMod requires [[Metamod:Source]] 1.8.0 or higher. [http://www.metamodsource.net/ Click here] to visit the Metamod:Source homepage. Instructions to install SourceMM manually can be found [http://wiki.alliedmods.net/index.php/Installing_Metamod:Source here].&lt;br /&gt;
&lt;br /&gt;
SourceMod will run on any mod built using the Source SDK.  It also supports &amp;quot;The Ship,&amp;quot; which uses the Source engine.&lt;br /&gt;
&lt;br /&gt;
=Uploading/Installing=&lt;br /&gt;
==Local Server==&lt;br /&gt;
To install SourceMod locally, simply extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat, et cetera).&lt;br /&gt;
[http://www.sourcemod.net/downloads.php Download Here]&lt;br /&gt;
&lt;br /&gt;
==Remote Server==&lt;br /&gt;
To install SourceMod remotely, first extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your local computer (for example, your Desktop).  You will see an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  &lt;br /&gt;
&lt;br /&gt;
Using a tool such as [http://www.google.com/search?q=FTP FTP], locate your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike:Source, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat:Source, et cetera).  Underneath this folder, you should have an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder (if not, Metamod:Source is probably not installed).  From your local &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder, upload the entire contents to your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  When done, your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder should have a &amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
If you have trouble with these steps, you need to get acquainted with FTP and server management.  However, you can also ask your server provider for help.  Some providers also have web interfaces for managing your server.&lt;br /&gt;
&lt;br /&gt;
Alternatively, if you copied the tar.gz to your srcds directory, execute the following from the cstrike sub directory:&lt;br /&gt;
tar -xzf ../sourcemod-1.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
=Checking the Install=&lt;br /&gt;
Your folder layout should look like:&lt;br /&gt;
*&amp;lt;tt&amp;gt;[mod]&amp;lt;/tt&amp;gt; - Your mod's folder&lt;br /&gt;
**&amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt;&lt;br /&gt;
***&amp;lt;tt&amp;gt;metamod&amp;lt;/tt&amp;gt; - Metamod:Source&lt;br /&gt;
***&amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; - SourceMod&lt;br /&gt;
&lt;br /&gt;
Once SourceMod is uploaded/copied and configured with Metamod:Source, restart your server completely.  If it is local, shut it down and restart it.  If it is remote, you may need to ask your server provider for help.  However, it is often safe to issue a &amp;quot;quit&amp;quot; command via [[rcon]], since most providers will automatically restart your server.&lt;br /&gt;
&lt;br /&gt;
First, in your [[server console]] (not client console), type:&lt;br /&gt;
&amp;lt;pre&amp;gt;meta list&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the install worked, you will see something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
    [01] SourceMod (1.1.0.2489) by AlliedModders LLC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should then be able to use the SourceMod root console command, which can be invoked with simply:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;] sm version&lt;br /&gt;
 SourceMod Version Information:&lt;br /&gt;
    SourceMod Version: 1.1.0.2489&lt;br /&gt;
    SourcePawn Engine: SourcePawn 1.1, jit-x86 (build 1.1.0-svn)&lt;br /&gt;
    SourcePawn API: v1 = 4, v2 = 2&lt;br /&gt;
    Compiled on: Sep  5 2008 02:02:12&lt;br /&gt;
    http://www.sourcemod.net/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lastly, assuming you have already setup your administration user, you can test the in game menu by joining the server, and in the client console type the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_admin&amp;lt;/pre&amp;gt;&lt;br /&gt;
You should see a menu popup with all you options.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
If the install failed, you will generally see one of four symptoms.  &lt;br /&gt;
&lt;br /&gt;
==Metamod reports NOFILE or FAILED==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
  [01] &amp;lt;NOFILE&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most likely, either the files are not located in the correct place, or the file could not be loaded.  For more information, use the following command (except use the correct list number):&lt;br /&gt;
&amp;lt;pre&amp;gt;meta info 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Metamod lists no plugins==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 0 plugins:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several causes of this error.&lt;br /&gt;
&lt;br /&gt;
# The most common cause is that sourcemod.vdf can't be located in the addons/metamod folder.  Verify that sourcemod.vdf is present in this folder.&lt;br /&gt;
# If sourcemod.vdf is present, make sure you are using the correct build of Sourcemod (zip = windows, tar.gz = linux).&lt;br /&gt;
&lt;br /&gt;
==Metamod says nothing==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; has no reply at all, Metamod:Source is not properly installed. [http://wiki.alliedmods.net/index.php/Installing_SourceMM This wiki page] may provide you with clues on how to solve this problem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=8962</id>
		<title>Installing SourceMod</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Installing_SourceMod&amp;diff=8962"/>
		<updated>2013-07-07T12:44:12Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: /* Metamod reports NOFILE or FAILED */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages|Installing_SourceMod}}&lt;br /&gt;
&lt;br /&gt;
Installing SourceMod is very simple, and it can be added with almost no configuration changes.&lt;br /&gt;
&amp;lt;br&amp;gt;'''The below is a detailed install guide and provides excellent issue and install feedback. However, if you're having troubles understanding the page and its instructions, [[Installing_SourceMod_(simple)|a simplified install guide is available here]].'''&lt;br /&gt;
&lt;br /&gt;
=Prerequisites=&lt;br /&gt;
A GUI Web Browser to retrieve Metamod and SourceMod compressed archives.&lt;br /&gt;
A tool to copy archive to your dedicated server host.&lt;br /&gt;
&lt;br /&gt;
SourceMod requires [[Metamod:Source]] 1.8.0 or higher. [http://www.metamodsource.net/ Click here] to visit the Metamod:Source homepage. Instructions to install SourceMM manually can be found [http://wiki.alliedmods.net/index.php/Installing_Metamod:Source here].&lt;br /&gt;
&lt;br /&gt;
SourceMod will run on any mod built using the Source SDK.  It also supports &amp;quot;The Ship,&amp;quot; which uses the Source engine.&lt;br /&gt;
&lt;br /&gt;
=Uploading/Installing=&lt;br /&gt;
==Local Server==&lt;br /&gt;
To install SourceMod locally, simply extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat, et cetera).&lt;br /&gt;
[http://www.sourcemod.net/downloads.php Download Here]&lt;br /&gt;
&lt;br /&gt;
==Remote Server==&lt;br /&gt;
To install SourceMod remotely, first extract the &amp;lt;tt&amp;gt;.zip&amp;lt;/tt&amp;gt; (Windows) or &amp;lt;tt&amp;gt;.tar.gz&amp;lt;/tt&amp;gt; (Linux) package to your local computer (for example, your Desktop).  You will see an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  &lt;br /&gt;
&lt;br /&gt;
Using a tool such as [http://www.google.com/search?q=FTP FTP], locate your mod folder (i.e. &amp;lt;tt&amp;gt;cstrike&amp;lt;/tt&amp;gt; for Counter-Strike:Source, &amp;lt;tt&amp;gt;dod&amp;lt;/tt&amp;gt; for Day of Defeat:Source, et cetera).  Underneath this folder, you should have an &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder (if not, Metamod:Source is probably not installed).  From your local &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder, upload the entire contents to your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder.  When done, your remote &amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt; folder should have a &amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
If you have trouble with these steps, you need to get acquainted with FTP and server management.  However, you can also ask your server provider for help.  Some providers also have web interfaces for managing your server.&lt;br /&gt;
&lt;br /&gt;
Alternatively, if you copied the tar.gz to your srcds directory, execute the following from the cstrike sub directory:&lt;br /&gt;
tar -xzf ../sourcemod-1.1.0.tar.gz&lt;br /&gt;
&lt;br /&gt;
=Checking the Install=&lt;br /&gt;
Your folder layout should look like:&lt;br /&gt;
*&amp;lt;tt&amp;gt;[mod]&amp;lt;/tt&amp;gt; - Your mod's folder&lt;br /&gt;
**&amp;lt;tt&amp;gt;addons&amp;lt;/tt&amp;gt;&lt;br /&gt;
***&amp;lt;tt&amp;gt;metamod&amp;lt;/tt&amp;gt; - Metamod:Source&lt;br /&gt;
***&amp;lt;tt&amp;gt;sourcemod&amp;lt;/tt&amp;gt; - SourceMod&lt;br /&gt;
&lt;br /&gt;
Once SourceMod is uploaded/copied and configured with Metamod:Source, restart your server completely.  If it is local, shut it down and restart it.  If it is remote, you may need to ask your server provider for help.  However, it is often safe to issue a &amp;quot;quit&amp;quot; command via [[rcon]], since most providers will automatically restart your server.&lt;br /&gt;
&lt;br /&gt;
First, in your [[server console]] (not client console), type:&lt;br /&gt;
&amp;lt;pre&amp;gt;meta list&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the install worked, you will see something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
    [01] SourceMod (1.1.0.2489) by AlliedModders LLC&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should then be able to use the SourceMod root console command, which can be invoked with simply:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;] sm version&lt;br /&gt;
 SourceMod Version Information:&lt;br /&gt;
    SourceMod Version: 1.1.0.2489&lt;br /&gt;
    SourcePawn Engine: SourcePawn 1.1, jit-x86 (build 1.1.0-svn)&lt;br /&gt;
    SourcePawn API: v1 = 4, v2 = 2&lt;br /&gt;
    Compiled on: Sep  5 2008 02:02:12&lt;br /&gt;
    http://www.sourcemod.net/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lastly, assuming you have already setup your administration user, you can test the in game menu by joining the server, and in the client console type the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_admin&amp;lt;/pre&amp;gt;&lt;br /&gt;
You should see a menu popup with all you options.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
If the install failed, you will generally see one of four symptoms.  &lt;br /&gt;
&lt;br /&gt;
==Metamod reports NOFILE or FAILED==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 1 plugin:&lt;br /&gt;
  [01] &amp;lt;NOFILE&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most likely, either the files are not located in the correct place, or the file could not be loaded.  For more information, use the following command (except use the correct list number):&lt;br /&gt;
&amp;lt;pre&amp;gt;meta info 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Metamod lists no plugins==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; replies with something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;] meta list&lt;br /&gt;
Listing 0 plugins:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several causes of this error.&lt;br /&gt;
&lt;br /&gt;
# The most common cause is that sourcemod.vdf can't be located in the addons/metamod folder.  Verify that sourcemod.vdf is present in this folder.&lt;br /&gt;
# If sourcemod.vdf is present, make sure you are using the correct build of Sourcemod (zip = windows, tar.gz = linux).&lt;br /&gt;
# If the game was recently updated, it may be using a newer filesystem interface causing MetaMod to disable VDF loading.  Try switching to a [http://www.sourcemm.net/snapshots snapshot build] or manually add sourcemod to MetaMod's addons/metamod/metaplugins.ini&lt;br /&gt;
&lt;br /&gt;
==Metamod says nothing==&lt;br /&gt;
If &amp;quot;meta list&amp;quot; has no reply at all, Metamod:Source is not properly installed. [http://wiki.alliedmods.net/index.php/Installing_SourceMM This wiki page] may provide you with clues on how to solve this problem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Spcomp_(Emscripten)&amp;diff=8919</id>
		<title>Spcomp (Emscripten)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Spcomp_(Emscripten)&amp;diff=8919"/>
		<updated>2013-05-02T20:38:02Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Lowercase_title}}&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;sourcepawn/compiler&amp;lt;/tt&amp;gt;, clone Emscripten to &amp;lt;tt&amp;gt;./emscripten&amp;lt;/tt&amp;gt; and copy &amp;lt;tt&amp;gt;../../plugins/include&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;./include&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Make sure you run the tests from https://github.com/kripken/emscripten/wiki/Tutorial.&lt;br /&gt;
&lt;br /&gt;
You need to compile the LZMA encoder for compression to work:&lt;br /&gt;
 cd ./emscripten/third_party/lzma.js&lt;br /&gt;
 ./doit.sh&lt;br /&gt;
 cd ../../../&lt;br /&gt;
&lt;br /&gt;
 emscripten/emcc -O0 --closure 0 -DNDEBUG -fno-strict-aliasing -I . -I ../../public/ -I ../../public/sourcepawn/ \&lt;br /&gt;
 -D_GNU_SOURCE -Wall -DLINUX -DHAVE_STDINT_H -DAMX_ANSIONLY -Dstricmp=strcasecmp -m32 -fno-exceptions -fno-rtti \&lt;br /&gt;
 binreloc.c libpawnc.c lstring.c memfile.c pawncc.c sc1.c sc2.c sc3.c sc4.c sc5.c sc6.c sc7.c scexpand.c sci18n.c sclist.c \&lt;br /&gt;
 scmemfil.c scstate.c sctracker.c scvars.c sp_file.c sp_symhash.c zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/deflate.c \&lt;br /&gt;
 zlib/gzio.c zlib/infback.c zlib/inffast.c zlib/inflate.c zlib/inftrees.c zlib/trees.c zlib/uncompr.c zlib/zutil.c \&lt;br /&gt;
 --compression emscripten/third_party/lzma.js/lzma-native,emscripten/third_party/lzma.js/lzma-decoder.js,LZMA.decompress \&lt;br /&gt;
 -o spcomp.html --preload-file include -Wno-format -Wno-parentheses -Wno-unused -Wno-sometimes-uninitialized -funroll-loops \&lt;br /&gt;
 -ldl -lm -lgcc -s UNALIGNED_MEMORY=1&lt;br /&gt;
&lt;br /&gt;
Enabling optimisations currently breaks emcc, leave them disabled.&lt;br /&gt;
&lt;br /&gt;
UPDATE: Due to a small patch to spcomp, optimisation is now possible. You can also enable the closure compiler if you're writing your own frontend.&lt;br /&gt;
&lt;br /&gt;
 emscripten/emcc -O3 --closure 0 -DNDEBUG -fno-strict-aliasing -I . -I ../../public/ -I ../../public/sourcepawn/ \&lt;br /&gt;
 -D_GNU_SOURCE -Wall -DLINUX -DHAVE_STDINT_H -DAMX_ANSIONLY -Dstricmp=strcasecmp -m32 -fno-exceptions -fno-rtti \&lt;br /&gt;
 binreloc.c libpawnc.c lstring.c memfile.c pawncc.c sc1.c sc2.c sc3.c sc4.c sc5.c sc6.c sc7.c scexpand.c sci18n.c sclist.c \&lt;br /&gt;
 scmemfil.c scstate.c sctracker.c scvars.c sp_file.c sp_symhash.c zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/deflate.c \&lt;br /&gt;
 zlib/gzio.c zlib/infback.c zlib/inffast.c zlib/inflate.c zlib/inftrees.c zlib/trees.c zlib/uncompr.c zlib/zutil.c \&lt;br /&gt;
 --compression emscripten/third_party/lzma.js/lzma-native,emscripten/third_party/lzma.js/lzma-decoder.js,LZMA.decompress \&lt;br /&gt;
 -o spcomp.html --preload-file include -Wno-format -Wno-parentheses -Wno-unused -Wno-sometimes-uninitialized -funroll-loops \&lt;br /&gt;
 -ldl -lm -lgcc&lt;br /&gt;
&lt;br /&gt;
spcomp won't be able to find the include folder automatically, make sure you invoke it with &amp;lt;tt&amp;gt;-iinclude&amp;lt;/tt&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Spcomp_(Emscripten)&amp;diff=8906</id>
		<title>Spcomp (Emscripten)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Spcomp_(Emscripten)&amp;diff=8906"/>
		<updated>2013-04-05T06:19:12Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Created page with &amp;quot;{{Lowercase_title}}  In &amp;lt;tt&amp;gt;sourcepawn/compiler&amp;lt;/tt&amp;gt;, clone Emscripten to &amp;lt;tt&amp;gt;./emscripten&amp;lt;/tt&amp;gt; and copy &amp;lt;tt&amp;gt;../../plugins/include&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;./include&amp;lt;/tt&amp;gt;.  Make sure you r...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Lowercase_title}}&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;sourcepawn/compiler&amp;lt;/tt&amp;gt;, clone Emscripten to &amp;lt;tt&amp;gt;./emscripten&amp;lt;/tt&amp;gt; and copy &amp;lt;tt&amp;gt;../../plugins/include&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;./include&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Make sure you run the tests from https://github.com/kripken/emscripten/wiki/Tutorial.&lt;br /&gt;
&lt;br /&gt;
You need to compile the LZMA encoder for compression to work:&lt;br /&gt;
 cd ./emscripten/third_party/lzma.js&lt;br /&gt;
 ./doit.sh&lt;br /&gt;
 cd ../../../&lt;br /&gt;
&lt;br /&gt;
 emscripten/emcc -O0 --closure 0 -DNDEBUG -fno-strict-aliasing -I . -I ../../public/ -I ../../public/sourcepawn/ \&lt;br /&gt;
 -D_GNU_SOURCE -Wall -DLINUX -DHAVE_STDINT_H -DAMX_ANSIONLY -Dstricmp=strcasecmp -m32 -fno-exceptions -fno-rtti \&lt;br /&gt;
 binreloc.c libpawnc.c lstring.c memfile.c pawncc.c sc1.c sc2.c sc3.c sc4.c sc5.c sc6.c sc7.c scexpand.c sci18n.c sclist.c \&lt;br /&gt;
 scmemfil.c scstate.c sctracker.c scvars.c sp_file.c sp_symhash.c zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/deflate.c \&lt;br /&gt;
 zlib/gzio.c zlib/infback.c zlib/inffast.c zlib/inflate.c zlib/inftrees.c zlib/trees.c zlib/uncompr.c zlib/zutil.c \&lt;br /&gt;
 --compression emscripten/third_party/lzma.js/lzma-native,emscripten/third_party/lzma.js/lzma-decoder.js,LZMA.decompress \&lt;br /&gt;
 -o spcomp.html --preload-file include -Wno-format -Wno-parentheses -Wno-unused -Wno-sometimes-uninitialized -funroll-loops \&lt;br /&gt;
 -ldl -lm -lgcc -s UNALIGNED_MEMORY=1&lt;br /&gt;
&lt;br /&gt;
Enabling optimisations currently breaks emcc, leave them disabled.&lt;br /&gt;
&lt;br /&gt;
spcomp won't be able to find the include folder automatically, make sure you invoke it with &amp;lt;tt&amp;gt;-iinclude&amp;lt;/tt&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8883</id>
		<title>Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8883"/>
		<updated>2013-03-17T16:13:02Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Moved incomplete new tutorial to talk page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic introduction to writing a [[SourceMod]] plugin.  If you are not familiar with the SourcePawn language, it is recommended that you at least briefly read the [[Introduction to SourcePawn]] article.&lt;br /&gt;
&lt;br /&gt;
For information on compiling plugins, see [[Compiling SourceMod Plugins]]. You can use [http://www.crimsoneditor.com/ Crimson Editor], [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ Pawn Studio] or any other text editor you're comfortable with to write plugins.&lt;br /&gt;
&lt;br /&gt;
=Starting from scratch=&lt;br /&gt;
Open your favorite text editor and create a new empty file. When you have an empty file you can just start writing code using the core language, however, you will not be able to use any of SourceMod features because the compiler does not now about them. This is done deliberately so it is possible to use SourcePawn outside of SourceMod. But since we are writing a SourceMod plugin, it is a good idea to enable access to SourceMod features first. This it done using &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; directive. It tells compiler to &amp;quot;paste&amp;quot; the code from another file into yours.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
How does this work? First of all, note that we enclosed file name into angle brackets. Angle brackets tell the compiler to look in the default include directory. By default, it is '''scripting/include'''. You can open it right now and see a lot of inc files there. Those are SourceMod include files that describe various functions, tags and other features available for SourceMod plugins. The files are plain-text and you are encouraged to read them. You will notice however, that there's not much code in there, certainly not enough to implement all the great features of SourceMod, so where are they? They are implemented inside a SourceMod core which is written in C++ and is compiled into binary files which end up in '''bin''' directory. So how does your SourcePawn code and SM core link together if compiler doesn't know about existence of the latter? SourceMod include files are written specially, so they say that the implementation of functions is ''somewhere else''. Compiler understands that and generate a special code that says that this function call is going outside. When SourceMod loads your plugin, it inspects these bits of code and substitutes it's own internal functions instead. This is called [http://en.wikipedia.org/wiki/Dynamic_linking dynamic linking].&lt;br /&gt;
&lt;br /&gt;
=Setting up plugin info=&lt;br /&gt;
Now that we got access to SourceMod features, it is time to setup the information that will be displayed via &amp;lt;tt&amp;gt;sm plugins list&amp;lt;/tt&amp;gt; command. No one likes unnamed plugins. To do that we are going to look inside '''sourcemod.inc''' file and see the format that information should be declared. It's always helpful to look inside SM include files to find out information you don't know. There is also an [http://docs.sourcemod.net/api/ API documentation] but it can be outdated and it only has SM core files so if your plugin are going to use any third party extension or another plugin, you will have to study inc files. So, open '''sourcemod.inc''' and scroll down a bit until you see this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Plugin public information.&lt;br /&gt;
 */&lt;br /&gt;
struct Plugin&lt;br /&gt;
{&lt;br /&gt;
   const String:name[],			/**&amp;lt; Plugin Name */&lt;br /&gt;
   const String:description[],	/**&amp;lt; Plugin Description */&lt;br /&gt;
   const String:author[],		/**&amp;lt; Plugin Author */&lt;br /&gt;
   const String:version[],		/**&amp;lt; Plugin Version */&lt;br /&gt;
   const String:url[],			/**&amp;lt; Plugin URL */&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
and this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Declare this as a struct in your plugin to expose its information.&lt;br /&gt;
 * Example:&lt;br /&gt;
 *&lt;br /&gt;
 * public Plugin:myinfo =&lt;br /&gt;
 * {&lt;br /&gt;
 *    name = &amp;quot;My Plugin&amp;quot;,&lt;br /&gt;
 *    //etc&lt;br /&gt;
 * };&lt;br /&gt;
 */&lt;br /&gt;
public Plugin:myinfo;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It tells us that we need to create a global public variable &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; which must be of type &amp;lt;tt&amp;gt;Plugin&amp;lt;/tt&amp;gt; which is a struct with 5 fields which themselves are strings. It may sound complicated for a beginner but it's easy. Let's go ahead and create one:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; keyword means that SourceMod will be able to directly access our variable. &amp;lt;tt&amp;gt;Plugin:&amp;lt;/tt&amp;gt; defines a type of our variable. &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; is, obviously, a name of our variable as required by SourceMod. You see that we initialize it right away. This is preferred way to do when filling out plugin info.&lt;br /&gt;
&lt;br /&gt;
After that the full code of your plugin should look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Getting code to run=&lt;br /&gt;
We already include SourceMod features and filled up or plugin info. We now have a perfectly well formed plugin which can be compiled and loaded by SourceMod. However, there is one problem - it does nothing. You might be tempted to just start writing a code after &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; declaration just to see that it will not compile. SourcePawn, unlike other scripting languages like Lua, does not allow a code to be outside of functions. After reading that, you may probably want to just define some function, name it &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; probably, compile and load a plugin and see that your code never gets called. So how do we make SourceMod call our code? For this exact reason we have forwards. Forwards are function prototypes declared by one party that can be implemented by another party as a [http://en.wikipedia.org/wiki/Callback_%28computer_programming%29 callback]. When a first party starts a forward call, all parties that have matching callbacks receive the call. SourceMod declares a plenty of interesting forwards that we can implement. As you can see, forwards are the only way to get our code executed, keep that in mind. So let's implement &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt; forward. As you may have guessed, it is called when our plugin starts. To do that, we'll have to look up the declaration of &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt;. It is declared inside '''sourcemod.inc''', a file we are already familiar with, let's find it:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Called when the plugin is fully initialized and all known external references &lt;br /&gt;
 * are resolved. This is only called once in the lifetime of the plugin, and is &lt;br /&gt;
 * paired with OnPluginEnd().&lt;br /&gt;
 *&lt;br /&gt;
 * If any run-time error is thrown during this callback, the plugin will be marked &lt;br /&gt;
 * as failed.&lt;br /&gt;
 *&lt;br /&gt;
 * It is not necessary to close any handles or remove hooks in this function.  &lt;br /&gt;
 * SourceMod guarantees that plugin shutdown automatically and correctly releases &lt;br /&gt;
 * all resources.&lt;br /&gt;
 *&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
forward OnPluginStart();&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Empty parentheses tells us that no arguments are passed inside this forward, &amp;lt;tt&amp;gt;@noreturn&amp;lt;/tt&amp;gt; inside documentation tells us that we don't have to return anything, pretty simple forward. So how to write a correct callback for it? Firstly, our callback must have the same name, so it's &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt;, secondly, our callback should have the same number of arguments, none in this case, and lastly, SourceMod needs to be able to call our callback so it needs to be &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. So the implementation looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we can write code inside curly braces and it will be executed when our plugin starts. Let's output &amp;lt;tt&amp;gt;&amp;quot;Hello world!&amp;quot;&amp;lt;/tt&amp;gt; to server console. To do that we are going to use &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt; function. It is declared inside '''console.inc''', however, we don't need to manually include '''console.inc''' because it is included automatically as part of '''sourcemod.inc'''.&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sends a message to the server console.&lt;br /&gt;
 *&lt;br /&gt;
 * @param format		Formatting rules.&lt;br /&gt;
 * @param ...			Variable number of format parameters.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native PrintToServer(const String:format[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
As you can see, this is a native function. It is implemented inside SM core. Judging by it's arguments, we can see that it is a [[Format_Class_Functions_%28SourceMod_Scripting%29|format class function]]. However, we don't need any formatting right now, so let's just pass &amp;lt;tt&amp;gt;&amp;quot;Hello world!&amp;quot;&amp;lt;/tt&amp;gt; string as an only argument:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
That's it! The full code of your plugin should look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Compile and load your plugin on your server and see for yourself that the message is displayed in server console.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
Pawn requires '''include files''', much like C requires header files.  Include files list all of the structures, functions, callbacks, and tags that are available.  There are three types of include files:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; and anything it includes.  These are all provided by SourceMod's Core.&lt;br /&gt;
*'''Extension''' - adds a dependency against a certain extension.&lt;br /&gt;
*'''Plugin''' - adds a dependency against a certain plugin.&lt;br /&gt;
&lt;br /&gt;
Include files are loaded using the &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; compiler directive.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=771&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  Any command that you type in the console, even if it's registered by SourceMod, will be sent to the engine to be processed. Because we have not had SourceMod block this functionality yet, the engine replies with &amp;quot;Unknown command&amp;quot; because it is not a valid engine command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything. This is because returning &amp;quot;Plugin_Handled&amp;quot; in a command callback will prevent the engine from processing the command. The engine will never even see that the command was run. This is what you will want to do if you are registering a completely new command through SourceMod.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage;&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1);&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;);&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH];&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count;&lt;br /&gt;
	new bool:tn_is_ml;&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage);&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage);&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They almost always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;);&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id);&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id);&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=940&amp;amp; AskPluginLoad2()] - Called once, immediately after the plugin is loaded from the disk.  This function can be used to stop a plugin from loading and return a custom error message; return APLRes_Failure and use strcopy on to replace the error string.  All CreateNative and RegPluginLibrary calls should be done here.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=583&amp;amp; OnAllPluginsLoaded()] - Called once, after all non-late loaded plugins have called OnPluginStart.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  You can block a player from connecting by returning Plugin_Stop and setting rejectmsg to an error message.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=916&amp;amp; OnClientConnected()] - Called after a player connects. Signifies that the player is in-game and IsClientConnected() will return true. '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between OnClientConnected and OnClientPreAdminCheck/OnClientDisconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection starts.  '''This is paired to OnClientConnected().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=391&amp;amp; OnClientDisconnect_Post()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnected().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Talk:Introduction_to_SourceMod_Plugins&amp;diff=8882</id>
		<title>Talk:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Talk:Introduction_to_SourceMod_Plugins&amp;diff=8882"/>
		<updated>2013-03-17T16:12:18Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Created page with &amp;quot; ----  &amp;lt;div class=&amp;quot;info&amp;quot;&amp;gt;Below is FaTony's WIP rewrite of the command tutorial, it's been remove from the main page as it's incomplete and more confusing for new users&amp;lt;br&amp;gt;--~~...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;info&amp;quot;&amp;gt;Below is FaTony's WIP rewrite of the command tutorial, it's been remove from the main page as it's incomplete and more confusing for new users&amp;lt;br&amp;gt;--[[User:Asherkin|Asherkin]] ([[User talk:Asherkin|talk]]) 11:12, 17 March 2013 (CDT)&amp;lt;/div&amp;gt;&lt;br /&gt;
=Creating client command=&lt;br /&gt;
So far we have learned how to set up our plugin and run some code. But our plugin still doesn't do anything useful. Let's add a console command to allow clients to see their kills/deaths ratio. For demonstration purposes, we are going to start with very naive implementation that a beginner could write, then we'll look at the common bugs it contains, fix them and add more advanced features. In the end we'll have a mature feature-rich implementation and experience that will prevent us from making simple mistakes in the future.&lt;br /&gt;
&lt;br /&gt;
==Naive implementation==&lt;br /&gt;
First, we need to register our console command. &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt; is a good place to do that. In order to register our console command, we need to use &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt; function, it is declared inside '''console.inc''', here's how it's declared:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Creates a console command, or hooks an already existing one.&lt;br /&gt;
 *&lt;br /&gt;
 * Console commands are case sensitive.  However, if the command already exists in the game, &lt;br /&gt;
 * the a client may enter the command in any case.  SourceMod corrects for this automatically, &lt;br /&gt;
 * and you should only hook the &amp;quot;real&amp;quot; version of the command.&lt;br /&gt;
 *&lt;br /&gt;
 * @param cmd			Name of the command to hook or create.&lt;br /&gt;
 * @param callback		A function to use as a callback for when the command is invoked.&lt;br /&gt;
 * @param description	Optional description to use for command creation.&lt;br /&gt;
 * @param flags			Optional flags to use for command creation.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 * @error				Command name is the same as an existing convar.&lt;br /&gt;
 */&lt;br /&gt;
native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]=&amp;quot;&amp;quot;, flags=0);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This native looks a bit more complicated than the previous one, so let's go through each argument step by step. First one is the name of our command, we'll use &amp;lt;tt&amp;gt;&amp;quot;sm_kdr&amp;quot;&amp;lt;/tt&amp;gt;. Second one is a callback, but it has unknown tag &amp;lt;tt&amp;gt;ConCmd&amp;lt;/tt&amp;gt;. In order to correctly call &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt; we need to find how &amp;lt;tt&amp;gt;ConCmd&amp;lt;/tt&amp;gt; is declared. Thankfully, we don't need to look hard, it's declared right above &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Called when a generic console command is invoked.&lt;br /&gt;
 *&lt;br /&gt;
 * @param client		Index of the client, or 0 from the server.&lt;br /&gt;
 * @param args			Number of arguments that were in the argument string.&lt;br /&gt;
 * @return				An Action value.  Not handling the command&lt;br /&gt;
 *						means that Source will report it as &amp;quot;not found.&amp;quot;&lt;br /&gt;
 */&lt;br /&gt;
functag public Action:ConCmd(client, args);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This is a function tag. What does it mean? It means that we need to define our own function that will have the same prototype (number of arguments, their tags and return tag) as the one of function tag. However, in this case, we don't need to (and can't) use the same name as in tag, that would result in error. We need to use our own name, let's use &amp;lt;tt&amp;gt;Command_KDR&amp;lt;/tt&amp;gt;. Function tags doesn't require to use the same argument names as specified in declaration, but it's a good idea to use them, because they usually have the most meaning. So, all in all, it leads us to the following definition:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_KDR(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now, if you've been following carefully, you should see that we have another unknown tag here - &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt;. Let's look how it's declared ('''core.inc'''):&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Specifies what to do after a hook completes.&lt;br /&gt;
 */&lt;br /&gt;
enum Action&lt;br /&gt;
{&lt;br /&gt;
	Plugin_Continue = 0,	/**&amp;lt; Continue with the original action */&lt;br /&gt;
	Plugin_Changed = 1,		/**&amp;lt; Inputs or outputs have been overridden with new values */&lt;br /&gt;
	Plugin_Handled = 3,		/**&amp;lt; Handle the action at the end (don't call it) */&lt;br /&gt;
	Plugin_Stop = 4,		/**&amp;lt; Immediately stop the hook chain and handle the original */&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
It's an enumeration tag and in our callback it's up to us to decide which value to return. As you probably understood from reading all the info, SourceMod console commands are implemented as hooks between client and original server code. If we don't return anything and &amp;quot;let it slide&amp;quot; or return &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;, the original command from client will reach the server and, since it's highly unlikely that there is &amp;lt;tt&amp;gt;sm_kdr&amp;lt;/tt&amp;gt; command in the game, the message &amp;lt;tt&amp;gt;Unknown command &amp;quot;sm_kdr&amp;quot;&amp;lt;/tt&amp;gt; will be printed to client's console. We don't want that, so let's modify our callback to return &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_KDR(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
It's a very common mistake to forget to return &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt; so our naive implementation is going to be not so naive after all! Now, after we finally understood how &amp;lt;tt&amp;gt;ConCmd&amp;lt;/tt&amp;gt; tag works, it's time to move to the next argument of &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt;. It is a string that will act like a description of our command. However, notice the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; after argument name, it indicates that this argument is optional, we can skip it and empty string (&amp;lt;tt&amp;gt;&amp;quot;&amp;quot;&amp;lt;/tt&amp;gt;) will be used. And the last argument is flags and it's also optional. Command flags are used to change behavior of command, but for now default behavior is ok. Now we know the meaning of all arguments, let's make a call.&lt;br /&gt;
&amp;lt;pawn&amp;gt;RegConsoleCmd(&amp;quot;sm_kdr&amp;quot;, Command_KDR, &amp;quot;Displays the client their kills/deaths ratio.&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Notice that we skipped flags because we want default behavior. Now let's see how the full command-related code looks like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;sm_kdr&amp;quot;, Command_KDR, &amp;quot;Displays the client their kills/deaths ratio.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_KDR(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Why did we choose &amp;lt;tt&amp;gt;sm_kdr&amp;lt;/tt&amp;gt; as the name of our command? It's handy because it will create convenient [[Commands_%28SourceMod_Scripting%29#Chat_Triggers|chat triggers]]. The skeleton of our command is ready, it is time to write the actual code for calculating KDR and displaying it to client. Notice that the first argument of our &amp;lt;tt&amp;gt;Command_KDR&amp;lt;/tt&amp;gt; callback is &amp;lt;tt&amp;gt;client&amp;lt;/tt&amp;gt;. When our callback is called, it will hold the index of client who called our command. We'll use this to find necessary information about client and to display that information back. First, let's find the number of kills, we'll use &amp;lt;tt&amp;gt;GetClientFrags&amp;lt;/tt&amp;gt; function for that, it's declared in '''clients.inc''':&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Returns the client's frag count.&lt;br /&gt;
 *&lt;br /&gt;
 * @param client		Player's index.&lt;br /&gt;
 * @return				Frag count.&lt;br /&gt;
 * @error				Invalid client index, client not in game, or no mod support.&lt;br /&gt;
 */&lt;br /&gt;
native GetClientFrags(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
It takes one argument - the client index and returns the number of frags. For the only argument of &amp;lt;tt&amp;gt;GetClientFrags&amp;lt;/tt&amp;gt; we'll use &amp;lt;tt&amp;gt;client&amp;lt;/tt&amp;gt; argument of our callback and we also need to store the return value so we'll create a local variable for that:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new kills = GetClientFrags(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
By this time, it is assumed that you've learned how to read include files and find necessary information, so only links to online SourceMod API will be provided. Next, we need to find the number of client deaths, we'll use &amp;lt;tt&amp;gt;[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=431&amp;amp; GetClientDeaths]&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new deaths = GetClientDeaths(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now that we have both kills and deaths, let's find the ratio. Remember that by default all variables in SourcePawn act like integers, but we need the fractional part in this case. Another very important thing to remember is that a result of integer division is also an integer. So we need to convert both kills and deaths to floating point values and store the result in a floating point variable. &amp;lt;tt&amp;gt;[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=705&amp;amp; float]&amp;lt;/tt&amp;gt; function does the conversion.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:ratio = float(kills) / float(deaths);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
And now we only need to display the ratio, since our command can be called either via console or chat, it is good idea to display our info accordingly, so we'll use &amp;lt;tt&amp;gt;[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand]&amp;lt;/tt&amp;gt;. It's another [[Format_Class_Functions_(SourceMod_Scripting)|format class function]] and now we need to apply some formatting. In a nutshell, we pass the string which acts as a template for text and &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; sign and one-letter type identifier (which is called format specifier) for variable values to put inside that template. After that, we must pass the number of arguments that correspond to the number of format specifiers in our format string. Since we have a floating point number, the format specifier will be &amp;lt;tt&amp;gt;%f&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;ReplyToCommand(client, &amp;quot;Your KDR is: %f.&amp;quot;, ratio);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
That's it! Now let's see the full code of our naive implementation:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;sm_kdr&amp;quot;, Command_KDR, &amp;quot;Displays the client their kills/deaths ratio.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_KDR(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new kills = GetClientFrags(client);&lt;br /&gt;
	new deaths = GetClientDeaths(client);&lt;br /&gt;
	new Float:ratio = float(kills) / float(deaths);&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;Your KDR is: %f.&amp;quot;, ratio);&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Compile and test this plugin and notice that something is wrong. We'll talk about it in the next section.&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=MediaWiki:Common.css&amp;diff=8881</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=MediaWiki:Common.css&amp;diff=8881"/>
		<updated>2013-03-17T16:11:08Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
div.info {&lt;br /&gt;
	background-color:#FFFFFF;&lt;br /&gt;
	padding-left:6px;&lt;br /&gt;
	padding-bottom:2px;&lt;br /&gt;
	padding-top:2px;&lt;br /&gt;
	background-position: 8px center;&lt;br /&gt;
	font-family: Arial, Helvetica, sans-serif;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	color: #003399;&lt;br /&gt;
	border-top-width: 1px;&lt;br /&gt;
	border-right-width: 1px;&lt;br /&gt;
	border-bottom-width: 1px;&lt;br /&gt;
	border-left-width: 10px;&lt;br /&gt;
	border-top-style: solid;&lt;br /&gt;
	border-right-style: solid;&lt;br /&gt;
	border-bottom-style: solid;&lt;br /&gt;
	border-left-style: solid;&lt;br /&gt;
	border-top-color: #aaa;&lt;br /&gt;
	border-right-color: #aaa;&lt;br /&gt;
	border-bottom-color: #aaa;&lt;br /&gt;
	border-left-color: #1e90ff;&lt;br /&gt;
	letter-spacing: 0.1em;&lt;br /&gt;
	word-spacing:0.1em;&lt;br /&gt;
	min-height:50px;&lt;br /&gt;
	margin-left:10px;&lt;br /&gt;
	margin-right:10px;&lt;br /&gt;
	vertical-align:middle;&lt;br /&gt;
	}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=MediaWiki:Common.css&amp;diff=8880</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=MediaWiki:Common.css&amp;diff=8880"/>
		<updated>2013-03-17T16:07:50Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: Created page with &amp;quot;/* CSS placed here will be applied to all skins */ div.info { 	background-color:#FFFFFF; 	padding-left:70px; 	padding-bottom:2px; 	padding-top:2px; 	background-position: 8px c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
div.info {&lt;br /&gt;
	background-color:#FFFFFF;&lt;br /&gt;
	padding-left:70px;&lt;br /&gt;
	padding-bottom:2px;&lt;br /&gt;
	padding-top:2px;&lt;br /&gt;
	background-position: 8px center;&lt;br /&gt;
	font-family: Arial, Helvetica, sans-serif;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	color: #003399;&lt;br /&gt;
	border-top-width: 1px;&lt;br /&gt;
	border-right-width: 1px;&lt;br /&gt;
	border-bottom-width: 1px;&lt;br /&gt;
	border-left-width: 10px;&lt;br /&gt;
	border-top-style: solid;&lt;br /&gt;
	border-right-style: solid;&lt;br /&gt;
	border-bottom-style: solid;&lt;br /&gt;
	border-left-style: solid;&lt;br /&gt;
	border-top-color: #aaa;&lt;br /&gt;
	border-right-color: #aaa;&lt;br /&gt;
	border-bottom-color: #aaa;&lt;br /&gt;
	border-left-color: #1e90ff;&lt;br /&gt;
	letter-spacing: 0.1em;&lt;br /&gt;
	word-spacing:0.1em;&lt;br /&gt;
	min-height:50px;&lt;br /&gt;
	background-repeat: no-repeat;&lt;br /&gt;
	background-image:url(../Info.png);&lt;br /&gt;
	margin-left:10px;&lt;br /&gt;
	margin-right:10px;&lt;br /&gt;
	vertical-align:middle;&lt;br /&gt;
	}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8879</id>
		<title>Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8879"/>
		<updated>2013-03-17T15:56:32Z</updated>

		<summary type="html">&lt;p&gt;Asherkin: /* Declaration */ Fixed link to ConCmd&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic introduction to writing a [[SourceMod]] plugin.  If you are not familiar with the SourcePawn language, it is recommended that you at least briefly read the [[Introduction to SourcePawn]] article.&lt;br /&gt;
&lt;br /&gt;
For information on compiling plugins, see [[Compiling SourceMod Plugins]]. You can use [http://www.crimsoneditor.com/ Crimson Editor], [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ Pawn Studio] or any other text editor you're comfortable with to write plugins.&lt;br /&gt;
&lt;br /&gt;
=Starting from scratch=&lt;br /&gt;
Open your favorite text editor and create a new empty file. When you have an empty file you can just start writing code using the core language, however, you will not be able to use any of SourceMod features because the compiler does not now about them. This is done deliberately so it is possible to use SourcePawn outside of SourceMod. But since we are writing a SourceMod plugin, it is a good idea to enable access to SourceMod features first. This it done using &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; directive. It tells compiler to &amp;quot;paste&amp;quot; the code from another file into yours.&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
How does this work? First of all, note that we enclosed file name into angle brackets. Angle brackets tell the compiler to look in the default include directory. By default, it is '''scripting/include'''. You can open it right now and see a lot of inc files there. Those are SourceMod include files that describe various functions, tags and other features available for SourceMod plugins. The files are plain-text and you are encouraged to read them. You will notice however, that there's not much code in there, certainly not enough to implement all the great features of SourceMod, so where are they? They are implemented inside a SourceMod core which is written in C++ and is compiled into binary files which end up in '''bin''' directory. So how does your SourcePawn code and SM core link together if compiler doesn't know about existence of the latter? SourceMod include files are written specially, so they say that the implementation of functions is ''somewhere else''. Compiler understands that and generate a special code that says that this function call is going outside. When SourceMod loads your plugin, it inspects these bits of code and substitutes it's own internal functions instead. This is called [http://en.wikipedia.org/wiki/Dynamic_linking dynamic linking].&lt;br /&gt;
&lt;br /&gt;
=Setting up plugin info=&lt;br /&gt;
Now that we got access to SourceMod features, it is time to setup the information that will be displayed via &amp;lt;tt&amp;gt;sm plugins list&amp;lt;/tt&amp;gt; command. No one likes unnamed plugins. To do that we are going to look inside '''sourcemod.inc''' file and see the format that information should be declared. It's always helpful to look inside SM include files to find out information you don't know. There is also an [http://docs.sourcemod.net/api/ API documentation] but it can be outdated and it only has SM core files so if your plugin are going to use any third party extension or another plugin, you will have to study inc files. So, open '''sourcemod.inc''' and scroll down a bit until you see this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Plugin public information.&lt;br /&gt;
 */&lt;br /&gt;
struct Plugin&lt;br /&gt;
{&lt;br /&gt;
   const String:name[],			/**&amp;lt; Plugin Name */&lt;br /&gt;
   const String:description[],	/**&amp;lt; Plugin Description */&lt;br /&gt;
   const String:author[],		/**&amp;lt; Plugin Author */&lt;br /&gt;
   const String:version[],		/**&amp;lt; Plugin Version */&lt;br /&gt;
   const String:url[],			/**&amp;lt; Plugin URL */&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
and this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Declare this as a struct in your plugin to expose its information.&lt;br /&gt;
 * Example:&lt;br /&gt;
 *&lt;br /&gt;
 * public Plugin:myinfo =&lt;br /&gt;
 * {&lt;br /&gt;
 *    name = &amp;quot;My Plugin&amp;quot;,&lt;br /&gt;
 *    //etc&lt;br /&gt;
 * };&lt;br /&gt;
 */&lt;br /&gt;
public Plugin:myinfo;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It tells us that we need to create a global public variable &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; which must be of type &amp;lt;tt&amp;gt;Plugin&amp;lt;/tt&amp;gt; which is a struct with 5 fields which themselves are strings. It may sound complicated for a beginner but it's easy. Let's go ahead and create one:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; keyword means that SourceMod will be able to directly access our variable. &amp;lt;tt&amp;gt;Plugin:&amp;lt;/tt&amp;gt; defines a type of our variable. &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; is, obviously, a name of our variable as required by SourceMod. You see that we initialize it right away. This is preferred way to do when filling out plugin info.&lt;br /&gt;
&lt;br /&gt;
After that the full code of your plugin should look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Getting code to run=&lt;br /&gt;
We already include SourceMod features and filled up or plugin info. We now have a perfectly well formed plugin which can be compiled and loaded by SourceMod. However, there is one problem - it does nothing. You might be tempted to just start writing a code after &amp;lt;tt&amp;gt;myinfo&amp;lt;/tt&amp;gt; declaration just to see that it will not compile. SourcePawn, unlike other scripting languages like Lua, does not allow a code to be outside of functions. After reading that, you may probably want to just define some function, name it &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; probably, compile and load a plugin and see that your code never gets called. So how do we make SourceMod call our code? For this exact reason we have forwards. Forwards are function prototypes declared by one party that can be implemented by another party as a [http://en.wikipedia.org/wiki/Callback_%28computer_programming%29 callback]. When a first party starts a forward call, all parties that have matching callbacks receive the call. SourceMod declares a plenty of interesting forwards that we can implement. As you can see, forwards are the only way to get our code executed, keep that in mind. So let's implement &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt; forward. As you may have guessed, it is called when our plugin starts. To do that, we'll have to look up the declaration of &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt;. It is declared inside '''sourcemod.inc''', a file we are already familiar with, let's find it:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Called when the plugin is fully initialized and all known external references &lt;br /&gt;
 * are resolved. This is only called once in the lifetime of the plugin, and is &lt;br /&gt;
 * paired with OnPluginEnd().&lt;br /&gt;
 *&lt;br /&gt;
 * If any run-time error is thrown during this callback, the plugin will be marked &lt;br /&gt;
 * as failed.&lt;br /&gt;
 *&lt;br /&gt;
 * It is not necessary to close any handles or remove hooks in this function.  &lt;br /&gt;
 * SourceMod guarantees that plugin shutdown automatically and correctly releases &lt;br /&gt;
 * all resources.&lt;br /&gt;
 *&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
forward OnPluginStart();&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Empty parentheses tells us that no arguments are passed inside this forward, &amp;lt;tt&amp;gt;@noreturn&amp;lt;/tt&amp;gt; inside documentation tells us that we don't have to return anything, pretty simple forward. So how to write a correct callback for it? Firstly, our callback must have the same name, so it's &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt;, secondly, our callback should have the same number of arguments, none in this case, and lastly, SourceMod needs to be able to call our callback so it needs to be &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. So the implementation looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we can write code inside curly braces and it will be executed when our plugin starts. Let's output &amp;lt;tt&amp;gt;&amp;quot;Hello world!&amp;quot;&amp;lt;/tt&amp;gt; to server console. To do that we are going to use &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt; function. It is declared inside '''console.inc''', however, we don't need to manually include '''console.inc''' because it is included automatically as part of '''sourcemod.inc'''.&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sends a message to the server console.&lt;br /&gt;
 *&lt;br /&gt;
 * @param format		Formatting rules.&lt;br /&gt;
 * @param ...			Variable number of format parameters.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native PrintToServer(const String:format[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
As you can see, this is a native function. It is implemented inside SM core. Judging by it's arguments, we can see that it is a [[Format_Class_Functions_%28SourceMod_Scripting%29|format class function]]. However, we don't need any formatting right now, so let's just pass &amp;lt;tt&amp;gt;&amp;quot;Hello world!&amp;quot;&amp;lt;/tt&amp;gt; string as an only argument:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
That's it! The full code of your plugin should look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Hello world!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Compile and load your plugin on your server and see for yourself that the message is displayed in server console.&lt;br /&gt;
&lt;br /&gt;
=Creating client command=&lt;br /&gt;
So far we have learned how to set up our plugin and run some code. But our plugin still doesn't do anything useful. Let's add a console command to allow clients to see their kills/deaths ratio. For demonstration purposes, we are going to start with very naive implementation that a beginner could write, then we'll look at the common bugs it contains, fix them and add more advanced features. In the end we'll have a mature feature-rich implementation and experience that will prevent us from making simple mistakes in the future.&lt;br /&gt;
&lt;br /&gt;
==Naive implementation==&lt;br /&gt;
First, we need to register our console command. &amp;lt;tt&amp;gt;OnPluginStart&amp;lt;/tt&amp;gt; is a good place to do that. In order to register our console command, we need to use &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt; function, it is declared inside '''console.inc''', here's how it's declared:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Creates a console command, or hooks an already existing one.&lt;br /&gt;
 *&lt;br /&gt;
 * Console commands are case sensitive.  However, if the command already exists in the game, &lt;br /&gt;
 * the a client may enter the command in any case.  SourceMod corrects for this automatically, &lt;br /&gt;
 * and you should only hook the &amp;quot;real&amp;quot; version of the command.&lt;br /&gt;
 *&lt;br /&gt;
 * @param cmd			Name of the command to hook or create.&lt;br /&gt;
 * @param callback		A function to use as a callback for when the command is invoked.&lt;br /&gt;
 * @param description	Optional description to use for command creation.&lt;br /&gt;
 * @param flags			Optional flags to use for command creation.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 * @error				Command name is the same as an existing convar.&lt;br /&gt;
 */&lt;br /&gt;
native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]=&amp;quot;&amp;quot;, flags=0);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This native looks a bit more complicated than the previous one, so let's go through each argument step by step. First one is the name of our command, we'll use &amp;lt;tt&amp;gt;&amp;quot;sm_kdr&amp;quot;&amp;lt;/tt&amp;gt;. Second one is a callback, but it has unknown tag &amp;lt;tt&amp;gt;ConCmd&amp;lt;/tt&amp;gt;. In order to correctly call &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt; we need to find how &amp;lt;tt&amp;gt;ConCmd&amp;lt;/tt&amp;gt; is declared. Thankfully, we don't need to look hard, it's declared right above &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Called when a generic console command is invoked.&lt;br /&gt;
 *&lt;br /&gt;
 * @param client		Index of the client, or 0 from the server.&lt;br /&gt;
 * @param args			Number of arguments that were in the argument string.&lt;br /&gt;
 * @return				An Action value.  Not handling the command&lt;br /&gt;
 *						means that Source will report it as &amp;quot;not found.&amp;quot;&lt;br /&gt;
 */&lt;br /&gt;
functag public Action:ConCmd(client, args);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This is a function tag. What does it mean? It means that we need to define our own function that will have the same prototype (number of arguments, their tags and return tag) as the one of function tag. However, in this case, we don't need to (and can't) use the same name as in tag, that would result in error. We need to use our own name, let's use &amp;lt;tt&amp;gt;Command_KDR&amp;lt;/tt&amp;gt;. Function tags doesn't require to use the same argument names as specified in declaration, but it's a good idea to use them, because they usually have the most meaning. So, all in all, it leads us to the following definition:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_KDR(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now, if you've been following carefully, you should see that we have another unknown tag here - &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt;. Let's look how it's declared ('''core.inc'''):&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Specifies what to do after a hook completes.&lt;br /&gt;
 */&lt;br /&gt;
enum Action&lt;br /&gt;
{&lt;br /&gt;
	Plugin_Continue = 0,	/**&amp;lt; Continue with the original action */&lt;br /&gt;
	Plugin_Changed = 1,		/**&amp;lt; Inputs or outputs have been overridden with new values */&lt;br /&gt;
	Plugin_Handled = 3,		/**&amp;lt; Handle the action at the end (don't call it) */&lt;br /&gt;
	Plugin_Stop = 4,		/**&amp;lt; Immediately stop the hook chain and handle the original */&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
It's an enumeration tag and in our callback it's up to us to decide which value to return. As you probably understood from reading all the info, SourceMod console commands are implemented as hooks between client and original server code. If we don't return anything and &amp;quot;let it slide&amp;quot; or return &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;, the original command from client will reach the server and, since it's highly unlikely that there is &amp;lt;tt&amp;gt;sm_kdr&amp;lt;/tt&amp;gt; command in the game, the message &amp;lt;tt&amp;gt;Unknown command &amp;quot;sm_kdr&amp;quot;&amp;lt;/tt&amp;gt; will be printed to client's console. We don't want that, so let's modify our callback to return &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_KDR(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
It's a very common mistake to forget to return &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt; so our naive implementation is going to be not so naive after all! Now, after we finally understood how &amp;lt;tt&amp;gt;ConCmd&amp;lt;/tt&amp;gt; tag works, it's time to move to the next argument of &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt;. It is a string that will act like a description of our command. However, notice the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; after argument name, it indicates that this argument is optional, we can skip it and empty string (&amp;lt;tt&amp;gt;&amp;quot;&amp;quot;&amp;lt;/tt&amp;gt;) will be used. And the last argument is flags and it's also optional. Command flags are used to change behavior of command, but for now default behavior is ok. Now we know the meaning of all arguments, let's make a call.&lt;br /&gt;
&amp;lt;pawn&amp;gt;RegConsoleCmd(&amp;quot;sm_kdr&amp;quot;, Command_KDR, &amp;quot;Displays the client their kills/deaths ratio.&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Notice that we skipped flags because we want default behavior. Now let's see how the full command-related code looks like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;sm_kdr&amp;quot;, Command_KDR, &amp;quot;Displays the client their kills/deaths ratio.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_KDR(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Why did we choose &amp;lt;tt&amp;gt;sm_kdr&amp;lt;/tt&amp;gt; as the name of our command? It's handy because it will create convenient [[Commands_%28SourceMod_Scripting%29#Chat_Triggers|chat triggers]]. The skeleton of our command is ready, it is time to write the actual code for calculating KDR and displaying it to client. Notice that the first argument of our &amp;lt;tt&amp;gt;Command_KDR&amp;lt;/tt&amp;gt; callback is &amp;lt;tt&amp;gt;client&amp;lt;/tt&amp;gt;. When our callback is called, it will hold the index of client who called our command. We'll use this to find necessary information about client and to display that information back. First, let's find the number of kills, we'll use &amp;lt;tt&amp;gt;GetClientFrags&amp;lt;/tt&amp;gt; function for that, it's declared in '''clients.inc''':&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Returns the client's frag count.&lt;br /&gt;
 *&lt;br /&gt;
 * @param client		Player's index.&lt;br /&gt;
 * @return				Frag count.&lt;br /&gt;
 * @error				Invalid client index, client not in game, or no mod support.&lt;br /&gt;
 */&lt;br /&gt;
native GetClientFrags(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
It takes one argument - the client index and returns the number of frags. For the only argument of &amp;lt;tt&amp;gt;GetClientFrags&amp;lt;/tt&amp;gt; we'll use &amp;lt;tt&amp;gt;client&amp;lt;/tt&amp;gt; argument of our callback and we also need to store the return value so we'll create a local variable for that:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new kills = GetClientFrags(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
By this time, it is assumed that you've learned how to read include files and find necessary information, so only links to online SourceMod API will be provided. Next, we need to find the number of client deaths, we'll use &amp;lt;tt&amp;gt;[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=431&amp;amp; GetClientDeaths]&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new deaths = GetClientDeaths(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now that we have both kills and deaths, let's find the ratio. Remember that by default all variables in SourcePawn act like integers, but we need the fractional part in this case. Another very important thing to remember is that a result of integer division is also an integer. So we need to convert both kills and deaths to floating point values and store the result in a floating point variable. &amp;lt;tt&amp;gt;[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=705&amp;amp; float]&amp;lt;/tt&amp;gt; function does the conversion.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:ratio = float(kills) / float(deaths);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
And now we only need to display the ratio, since our command can be called either via console or chat, it is good idea to display our info accordingly, so we'll use &amp;lt;tt&amp;gt;[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand]&amp;lt;/tt&amp;gt;. It's another [[Format_Class_Functions_(SourceMod_Scripting)|format class function]] and now we need to apply some formatting. In a nutshell, we pass the string which acts as a template for text and &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; sign and one-letter type identifier (which is called format specifier) for variable values to put inside that template. After that, we must pass the number of arguments that correspond to the number of format specifiers in our format string. Since we have a floating point number, the format specifier will be &amp;lt;tt&amp;gt;%f&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;ReplyToCommand(client, &amp;quot;Your KDR is: %f.&amp;quot;, ratio);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
That's it! Now let's see the full code of our naive implementation:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;sm_kdr&amp;quot;, Command_KDR, &amp;quot;Displays the client their kills/deaths ratio.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_KDR(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new kills = GetClientFrags(client);&lt;br /&gt;
	new deaths = GetClientDeaths(client);&lt;br /&gt;
	new Float:ratio = float(kills) / float(deaths);&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;Your KDR is: %f.&amp;quot;, ratio);&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Compile and test this plugin and notice that something is wrong. We'll talk about it in the next section.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
Pawn requires '''include files''', much like C requires header files.  Include files list all of the structures, functions, callbacks, and tags that are available.  There are three types of include files:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; and anything it includes.  These are all provided by SourceMod's Core.&lt;br /&gt;
*'''Extension''' - adds a dependency against a certain extension.&lt;br /&gt;
*'''Plugin''' - adds a dependency against a certain plugin.&lt;br /&gt;
&lt;br /&gt;
Include files are loaded using the &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; compiler directive.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=771&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  Any command that you type in the console, even if it's registered by SourceMod, will be sent to the engine to be processed. Because we have not had SourceMod block this functionality yet, the engine replies with &amp;quot;Unknown command&amp;quot; because it is not a valid engine command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything. This is because returning &amp;quot;Plugin_Handled&amp;quot; in a command callback will prevent the engine from processing the command. The engine will never even see that the command was run. This is what you will want to do if you are registering a completely new command through SourceMod.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage;&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1);&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;);&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH];&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count;&lt;br /&gt;
	new bool:tn_is_ml;&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage);&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage);&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They almost always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;);&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id);&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id);&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=940&amp;amp; AskPluginLoad2()] - Called once, immediately after the plugin is loaded from the disk.  This function can be used to stop a plugin from loading and return a custom error message; return APLRes_Failure and use strcopy on to replace the error string.  All CreateNative and RegPluginLibrary calls should be done here.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=583&amp;amp; OnAllPluginsLoaded()] - Called once, after all non-late loaded plugins have called OnPluginStart.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  You can block a player from connecting by returning Plugin_Stop and setting rejectmsg to an error message.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=916&amp;amp; OnClientConnected()] - Called after a player connects. Signifies that the player is in-game and IsClientConnected() will return true. '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between OnClientConnected and OnClientPreAdminCheck/OnClientDisconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection starts.  '''This is paired to OnClientConnected().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=391&amp;amp; OnClientDisconnect_Post()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnected().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Asherkin</name></author>
		
	</entry>
</feed>