<?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=TheY4Kman</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=TheY4Kman"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/TheY4Kman"/>
	<updated>2026-04-15T04:50:32Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User_talk:Asherkin&amp;diff=10177</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=10177"/>
		<updated>2016-07-01T18:24:18Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Lowercase_title}}&lt;br /&gt;
&lt;br /&gt;
asherkin smells like old babies.&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=8826</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=8826"/>
		<updated>2013-01-24T14:52:01Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: &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)&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>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=8629</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=8629"/>
		<updated>2012-08-13T02:43:33Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: yak yak yak yak yak yak yak yak yak yak yak&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>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=File:Yak.gif&amp;diff=8628</id>
		<title>File:Yak.gif</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=File:Yak.gif&amp;diff=8628"/>
		<updated>2012-08-13T02:42:52Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: yak wuz heer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;yak wuz heer&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=8627</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=8627"/>
		<updated>2012-08-13T02:15:11Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* How do I find the classname of an entity? (e.g., &amp;quot;weapon_knife&amp;quot; or &amp;quot;prop_physics&amp;quot;) */ Added netclass example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=8626</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=8626"/>
		<updated>2012-08-13T02:13:25Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Added color question&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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) 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>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=File:Left_4_Dead_Colors.png&amp;diff=8625</id>
		<title>File:Left 4 Dead Colors.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=File:Left_4_Dead_Colors.png&amp;diff=8625"/>
		<updated>2012-08-13T01:12:13Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Output of `PrintToChatAll (&amp;quot;\x01 1 .. \x02 2 .. \x03 3 .. \x04 4 .. \x05 5 .. \x06 6 .. \x07 7 .. \x08 8&amp;quot;);` in Left 4 Dead.

Image courtesy of antihacker (http://forums.alliedmods.net/member.php?u=47979).&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Output of `PrintToChatAll (&amp;quot;\x01 1 .. \x02 2 .. \x03 3 .. \x04 4 .. \x05 5 .. \x06 6 .. \x07 7 .. \x08 8&amp;quot;);` in Left 4 Dead.&lt;br /&gt;
&lt;br /&gt;
Image courtesy of antihacker (http://forums.alliedmods.net/member.php?u=47979).&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=8624</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=8624"/>
		<updated>2012-08-13T00:37:49Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Added SDKTools &amp;quot;unknown symbol&amp;quot; and &amp;quot;Unknown command&amp;quot; questions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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) 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;
=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>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=8623</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=8623"/>
		<updated>2012-08-13T00:34:12Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Added tag mismatch warning question&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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) 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;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Scripting_FAQ_(SourceMod)&amp;diff=8622</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=8622"/>
		<updated>2012-08-13T00:21:44Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Started porting Yak's FAQ's&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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) 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;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SourceMod_Profiler&amp;diff=8438</id>
		<title>SourceMod Profiler</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SourceMod_Profiler&amp;diff=8438"/>
		<updated>2012-04-10T13:59:32Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* Interpreting Results */ LINKIFYING MOFO&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod profiler is a built-in tool for measuring the performance of SourceMod natives and plugins.  &lt;br /&gt;
&lt;br /&gt;
It is currently an &amp;quot;alpha&amp;quot; addition.  While it was tested to work, there may be cases where it breaks.  Do not use it in a production environment -- it is intended as a tool for developers.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
The SourceMod Profiler tracks &amp;quot;profilable items.&amp;quot;  These items are:&lt;br /&gt;
* Native calls from plugins.&lt;br /&gt;
* Callbacks into plugins.&lt;br /&gt;
* Internal function calls in plugins.&lt;br /&gt;
&lt;br /&gt;
The following statistics are tracked for each item:&lt;br /&gt;
* Number calls.&lt;br /&gt;
* Total time spent in all calls.&lt;br /&gt;
* Minimum time spent in any call.&lt;br /&gt;
* Maximum time spent in any call.&lt;br /&gt;
&lt;br /&gt;
These statistics can be used to gauge how well your plugin is performing.  It can also be used to tweak and optimize your code where necessary.&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
==Configuration==&lt;br /&gt;
The profiler can only be enabled in &amp;lt;tt&amp;gt;configs/plugin_settings.cfg&amp;lt;/tt&amp;gt;.  You can enable it on any number of plugins at a time.  However, it is a good idea to only profile what you need.&lt;br /&gt;
&lt;br /&gt;
The profiler can be configured with the &amp;quot;profile&amp;quot; option key in an &amp;quot;Options&amp;quot; section.  The value should be a bits added up:&lt;br /&gt;
* 1 - Profile natives.&lt;br /&gt;
* 2 - Profile callbacks.&lt;br /&gt;
* 4 - Profile functions (implies 2).&lt;br /&gt;
&lt;br /&gt;
Example for profiling &amp;quot;adminhelp&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;quot;adminhelp&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;pause&amp;quot;			&amp;quot;no&amp;quot;&lt;br /&gt;
		&amp;quot;lifetime&amp;quot;		&amp;quot;mapsync&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;Options&amp;quot;&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;debug&amp;quot;		&amp;quot;no&amp;quot;&lt;br /&gt;
			&amp;quot;profile&amp;quot;	&amp;quot;7&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that one can also use the &amp;quot;*&amp;quot; wildcard (as seen in the default config) in place of a plugin name in order to change the settings of all loaded plugins.&lt;br /&gt;
&lt;br /&gt;
==Getting Results==&lt;br /&gt;
You can use &amp;quot;sm profiler flush&amp;quot; in your console to dump and reset the profiler statistics.  The output will be written to an XML file in your &amp;lt;tt&amp;gt;sourcemod/logs&amp;lt;/tt&amp;gt; folder.  For example: &amp;lt;tt&amp;gt;addons/sourcemod/logs/profile_1204422886.xml&amp;lt;/tt&amp;gt; (note that a timestamp is included).&lt;br /&gt;
&lt;br /&gt;
There is no way to stop the profiler entirely save from editing &amp;lt;tt&amp;gt;plugin_settings.cfg&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Interpreting Results=&lt;br /&gt;
[[image:Sm_profiler.PNG|thumb|right|300px|Profiler Screenshot]]&lt;br /&gt;
The easiest way to interpret the results is to use the &amp;lt;tt&amp;gt;[http://www.sourcemod.net/profviewer.exe profviewer.exe]&amp;lt;/tt&amp;gt; tool available on [http://www.sourcemod.net/downloads.php SourceMod's downloads page].  It requires the [http://www.microsoft.com/downloads/details.aspx?FamilyID=0856EACB-4362-4B0D-8EDD-AAB15C5E04F5&amp;amp;displaylang=en .NET 2.0 Framework].  You can open profiler .xml files with this tool and sort the various result metrics (descending order only).&lt;br /&gt;
&lt;br /&gt;
*All times are in seconds.  The &amp;quot;min&amp;quot; and &amp;quot;max&amp;quot; times are single measurements.  The &amp;quot;average&amp;quot; time is the total time spent divided by the number of calls.  &lt;br /&gt;
*Function names are displayed as raw names for natives, or &amp;quot;a!b&amp;quot; for plugins, where &amp;quot;a&amp;quot; is the plugin filename and &amp;quot;b&amp;quot; is the function name.&lt;br /&gt;
&lt;br /&gt;
It is important to note how the time values are actually computed.  You may find the results to be deceiving otherwise.  Take the following list of events:&lt;br /&gt;
*Core calls &amp;lt;tt&amp;gt;OnClientCommand&amp;lt;/tt&amp;gt; in plugin &amp;lt;tt&amp;gt;a.smx&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;a.smx!OnClientCommand&amp;lt;/tt&amp;gt; calls &amp;lt;tt&amp;gt;a.smx!StrEqual&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;a.smx!StrEqual&amp;lt;/tt&amp;gt; calls &amp;lt;tt&amp;gt;strcmp()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SourceMod computes each item's time by adding in its children's time.  For example, the time &amp;lt;tt&amp;gt;t(a.smx!OnClientCommand)&amp;lt;/tt&amp;gt; will be equal to:&lt;br /&gt;
&amp;lt;pre&amp;gt;t(a.smx!OnClientCommand) + t(a.smx!StrEqual) + t(strcmp)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise, the time of &amp;lt;tt&amp;gt;StrEqual&amp;lt;/tt&amp;gt; will be equal to:&lt;br /&gt;
&amp;lt;pre&amp;gt;t(a.smx!StrEqual) + t(strcmp)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This has two major implications:&lt;br /&gt;
*'''You cannot profile recursive functions'''.  The data will be nonsensical.  Use &amp;lt;tt&amp;gt;profiler.inc&amp;lt;/tt&amp;gt; for manually timing recursive calls.&lt;br /&gt;
*The time of re-entrant functions may be deceiving.  For example, &amp;lt;tt&amp;gt;DisplayMenu()&amp;lt;/tt&amp;gt; may appear very slow, but that's because it may fire dozens of callbacks.  Similarly, the custom sorting natives' time will include their callbacks' time.  That doesn't necessarily mean the natives themselves are slow, but that they are slow because of the callbacks they are invoking.&lt;br /&gt;
&lt;br /&gt;
''Note: The profiler does not include its own internal operations when timing items.  There is a small margin of error, however.''&lt;br /&gt;
&lt;br /&gt;
In general, you should not go insane trying to optimize unless there is a good reason.  For example, an &amp;lt;tt&amp;gt;OnGameFrame&amp;lt;/tt&amp;gt; callback may be called 200 times per minute, and thus if its average time exceeds reasonable values (say, a dozen milliseconds) then you may want to consider optimizing it.  However, if you see that a particular call to &amp;lt;tt&amp;gt;LoadTranslations()&amp;lt;/tt&amp;gt; is taking 150ms, you shouldn't worry too much - that function only gets called on load.&lt;br /&gt;
&lt;br /&gt;
Use your judgment when interpreting the results, and don't go crazy.  If you need advice, post on the forums.&lt;br /&gt;
&lt;br /&gt;
=File Format=&lt;br /&gt;
The file format is XML.  The contents are fairly self-explanatory, as there are only three elements.  Sample parsers are included in the SourceMod source code tree:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;tools/csharp&amp;lt;/tt&amp;gt; - Source code for the profviewer.exe program.  &amp;lt;tt&amp;gt;ProfReport.cs&amp;lt;/tt&amp;gt; implements the parser.&lt;br /&gt;
*&amp;lt;tt&amp;gt;php/ProfFileParser.class.php&amp;lt;/tt&amp;gt; - Source code for a PHP parser.  Requires PHP5 and libexpat (XML) support.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Writing_Extensions&amp;diff=8109</id>
		<title>Writing Extensions</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Writing_Extensions&amp;diff=8109"/>
		<updated>2011-06-18T10:38:55Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* Implementing */ Being more explicit&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 [[SourceMod]] website.  The directory structure looks like this:&lt;br /&gt;
*&amp;lt;tt&amp;gt;extensions&amp;lt;/tt&amp;gt;&lt;br /&gt;
**&amp;lt;tt&amp;gt;geoip/&amp;lt;/tt&amp;gt; - Source code to the GeoIP extension&lt;br /&gt;
**&amp;lt;tt&amp;gt;mysql/&amp;lt;/tt&amp;gt; - Source code to the MySQL extension&lt;br /&gt;
**&amp;lt;tt&amp;gt;threader/&amp;lt;/tt&amp;gt; - Source code to the Threader extension&lt;br /&gt;
*&amp;lt;tt&amp;gt;plugins/&amp;lt;/tt&amp;gt; - Source code to all of SourceMod's plugins&lt;br /&gt;
**&amp;lt;tt&amp;gt;include/&amp;lt;/tt&amp;gt; - The include files which document plugin API&lt;br /&gt;
*&amp;lt;tt&amp;gt;public/&amp;lt;/tt&amp;gt; - Interface files for SourceMod's Core Interfaces&lt;br /&gt;
**&amp;lt;tt&amp;gt;extensions/&amp;lt;/tt&amp;gt; - Interfaces that are provided by extensions&lt;br /&gt;
**&amp;lt;tt&amp;gt;sample_ext/&amp;lt;/tt&amp;gt; - The Sample Extension SDK&lt;br /&gt;
**&amp;lt;tt&amp;gt;sourcepawn&amp;lt;/tt&amp;gt; - The include/interface files for SourcePawn&lt;br /&gt;
*&amp;lt;tt&amp;gt;sourcepawn/&amp;lt;/tt&amp;gt;&lt;br /&gt;
**&amp;lt;tt&amp;gt;compiler/&amp;lt;/tt&amp;gt; - The SourcePawn Compiler&lt;br /&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.  These are:&lt;br /&gt;
*&amp;lt;tt&amp;gt;sdk/smsdk_config.h&amp;lt;/tt&amp;gt; - Configuration settings (we will be editing this)&lt;br /&gt;
*&amp;lt;tt&amp;gt;sdk/smsdk_ext.h&amp;lt;/tt&amp;gt; - Header for SDK wrappers (usually never needs to be edited)&lt;br /&gt;
**''Note: Sometimes, this may be updated by the SourceMod Dev Team.  Using a newest version is recommended.'&lt;br /&gt;
*&amp;lt;tt&amp;gt;sdk/smsdk_ext.cpp&amp;lt;/tt&amp;gt; - Source for SDK wrappers (usually never needs to be edited)&lt;br /&gt;
**''Note: Sometimes, this may be updated by the SourceMod Dev Team.  Using a newest version is recommended.'&lt;br /&gt;
*&amp;lt;tt&amp;gt;extension.h&amp;lt;/tt&amp;gt; - User file for main extension header&lt;br /&gt;
*&amp;lt;tt&amp;gt;extension.cpp&amp;lt;/tt&amp;gt; - User file for main extension code&lt;br /&gt;
&lt;br /&gt;
''The &amp;lt;tt&amp;gt;extension.*&amp;lt;/tt&amp;gt; files are not technically part of the SDK.  However, they are provided to give users a starting point and some documentation.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note:''' For help setting up Visual Studio, please 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;tt&amp;gt;SMEXT_CONF_NAME&amp;lt;/tt&amp;gt; - The general name for your Extension (should be short).&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_CONF_DESCRIPTION&amp;lt;/tt&amp;gt; - A short description of what your extension does.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_CONF_VERSION&amp;lt;/tt&amp;gt; - A version number string.  By convention, SourceMod uses the four set build number notation.  I.e. for 1.2.3.4:&lt;br /&gt;
**&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; is the &amp;quot;Major&amp;quot; release version.&lt;br /&gt;
**&amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; is the &amp;quot;Minor&amp;quot; release version.&lt;br /&gt;
**&amp;lt;tt&amp;gt;3&amp;lt;/tt&amp;gt; is the &amp;quot;Maintenance&amp;quot; or &amp;quot;Revision&amp;quot; version.&lt;br /&gt;
**&amp;lt;tt&amp;gt;4&amp;lt;/tt&amp;gt; is the &amp;quot;Build,&amp;quot; usually an internal source control number.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_CONF_AUTHOR&amp;lt;/tt&amp;gt; - Your name (or whoever/whatever authored the plugin).&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_CONF_URL&amp;lt;/tt&amp;gt; - The URL/homepage of this extension.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_CONF_LOGTAG&amp;lt;/tt&amp;gt; - 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;
*&amp;lt;tt&amp;gt;SMEXT_CONF_LICENSE&amp;lt;/tt&amp;gt; - 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 [[SourceMod License]].&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_CONF_DATESTRING&amp;lt;/tt&amp;gt; - You do not need to modify this.&lt;br /&gt;
*&amp;lt;tt&amp;gt;SMEXT_CONF_METAMOD&amp;lt;/tt&amp;gt; - If your plugin requires using SourceHook or Metamod:Source, uncomment this line.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next, you may want to change the name of the default class that &amp;lt;tt&amp;gt;extension.h&amp;lt;/tt&amp;gt; declares.  To do this...&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;Open &amp;lt;tt&amp;gt;extension.h&amp;lt;/tt&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;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open &amp;lt;tt&amp;gt;extension.cpp&amp;lt;/tt&amp;gt; and change the two lines to correspond to your new class name.  You can also change the global singleton that's declared, although you cannot remove the &amp;lt;tt&amp;gt;SMEXT_LINK&amp;lt;/tt&amp;gt; line (this lets SourceMod load your extension).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&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;
&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;pawn&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 SquareNumber(num);&amp;lt;/pawn&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;pawn&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 		Pl_Handled to block text from printing, Pl_Continue otherwise.&lt;br /&gt;
 */&lt;br /&gt;
forward ResultType:OnPlayerSayChat(client, const String:text[]);&amp;lt;/pawn&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;pawn&amp;gt;funcenum SayChatHook&lt;br /&gt;
{&lt;br /&gt;
	forward(client, const String:text[]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
native AddSayChatHook(SayChatHook:hook);&lt;br /&gt;
native RemoveSayChatHook(SayChatHook:hook);&amp;lt;/pawn&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;pawn&amp;gt;MyHook(client, const String:text[])&amp;lt;/pawn&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;pawn&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;/pawn&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;
&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 on &amp;quot;.ext.dll&amp;quot; or &amp;quot;.ext.so&amp;quot; which will not work on custom files.&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;
==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>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_(legacy_syntax)&amp;diff=7422</id>
		<title>Introduction to SourcePawn (legacy syntax)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_(legacy_syntax)&amp;diff=7422"/>
		<updated>2009-09-28T20:38:54Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* Notes */ decl can initialize strings&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;
&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 (unlike PHP, where sometimes they are not).  Symbols do not start with any special character, though they must 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.  Variables are created for storage space throughout a program.  Variables must be declared before being used, using the &amp;quot;new&amp;quot; keyword.  Data is assigned to variables using the equal sign (=).  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In SourcePawn, variables have two types, which will be explained in more detail further on.&lt;br /&gt;
*Cells (arbitrary numerical data), as shown above.&lt;br /&gt;
*Strings (a series of text characters)&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.  That means when you activate them, they carry out a specific sequence of code.  There are a few types of functions, but every function is activated the same way.  &amp;quot;Calling a function&amp;quot; is the term for invoking a function's action.  Function calls are constructed like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;function(&amp;lt;parameters&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Activates &amp;quot;show&amp;quot; function, and gives the number 56 to it&lt;br /&gt;
show();     //Activates &amp;quot;show&amp;quot; function with no data, blank&lt;br /&gt;
show(a);    //Activates &amp;quot;show&amp;quot; function, gives a variable's contents as data&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;
&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 not typed.'''  Pawn only has one data type, the '''cell'''.  This will be explained in detail later.  [Below it says that there are two types: cell and string.]&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 is procedural, and relies on subroutines.  It also does not have C structs.&lt;br /&gt;
*'''Pawn is not functional.''' Pawn is procedural, and does not support lambda functions or late binding or anything else you might find in a very high-level language, like Python or Ruby.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn is not interpreted.''' Well, it &amp;quot;sort of&amp;quot; is.  It gets interpreted at a very low level.  You must run your code through a compiler, which produces a binary.  This binary will work on any platform that the host application uses.  This speeds up loading time and lets you check errors easier.&lt;br /&gt;
&lt;br /&gt;
These 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;
In Pawn there are two variable types: the '''cell''' and the '''String'''.  A cell can store 32 bits of numerical data.  A String is a sequential/flat list of UTF-8 text characters.&lt;br /&gt;
&lt;br /&gt;
A '''cell''' has no inherent type, however, cells can be '''tagged'''.  A tag lets you enforce where certain cells can be used.  The default tags are:&lt;br /&gt;
*(nothing), or '''_''' - No tag.  Usually used for whole numbers ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - Used for floating point (fractional) numbers.&lt;br /&gt;
*'''bool''' - Used for storing either '''true''' or '''false'''.&lt;br /&gt;
&lt;br /&gt;
Strings are different and will be explained in the next sections.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Examples of different valid variable declarations:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Works because 0 is 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;
new a = 5.0;         //Tag mismatch.  5.0 is tagged as Float&lt;br /&gt;
new Float:b = 5;     //Tag mismatch.  5 is not tagged.&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;
new a;        //Set to 0&lt;br /&gt;
new Float:b;  //Set to 0.0&lt;br /&gt;
new 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;new a, Float:b, 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 sequential list.  Arrays are useful for storing multiple pieces of data in one variable, and often greatly simplify many tasks.  &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;
new players[32];     //Stores 32 cells (numbers)&lt;br /&gt;
new 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;
new numbers[5] = {1, 2, 3, 4, 5};       //Stores 1, 2, 3, 4, 5 in the cells.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Stores 1.0, 2.0, 3.0 in the cells.&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;
new 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;
==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;
new numbers[5], 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;
To use an incorrect index will cause an error.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new 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;new 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 convenient method of storing text.  The characters are stored in an array.  The string is terminated by a '''null terminator''', or a 0.  Without a null terminator, Pawn would not know where to stop reading the string.  All strings are UTF-8 in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
Notice that Strings are a combination of arrays and cells.  Unlike other languages, this means you must know how much space a string will use in advance.  That is, strings are not dynamic.  They can only grow to the space you allocate for them.&lt;br /&gt;
&lt;br /&gt;
''Note for experts:  They're not actually cells.  SourcePawn uses 8-bit storage for String arrays as an optimization.  This is what makes String a type and not a tag.''&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are declared almost equivalently to arrays.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String: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;
new String:message[7], String: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;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new 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;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Invalid, needs String: type&lt;br /&gt;
new 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;
&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 five 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;
*'''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 '''prototype''' and the '''body'''.  The prototype 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;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&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;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&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;first&amp;lt;/tt&amp;gt; - Name of the first parameter, which is a simple cell.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Name of the second parameter, which is a simple cell.&lt;br /&gt;
&lt;br /&gt;
The body is a simple 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 a cell'' upon completion.  That means, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will assign the number 9 to sum.  The function adds the two inputs, and the sum is given as the '''return value'''.  If a function has no return statement or does not place a value in the return statement, it returns 0 by default.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input.  It can return any cell, but not arrays or strings.  Example:  &lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Note that if in the above function, you returned a non-Float, you would get a tag mismatch.''&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new 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;new 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 OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(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 OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(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 exposes the function publicly, and allows the parent application to directly call the function.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by the application.  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 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;new num = FloatRound(5.2);     //Results in num = 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;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, 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;
This is only possible because the array can be directly modified.  To prevent an array from being modified, 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;CantChangeArray(const array[], index, 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 7&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;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Evaluates to 90&lt;br /&gt;
new 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;new 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;new 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;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new 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 ''new'' 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;
new 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;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new 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;new 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;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new 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;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new 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;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new 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;
&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;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new 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;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new 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;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new 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;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new 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;
&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;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new 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;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is valid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; '''ONLY''' with strings:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, any other tag will fail to compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl Float:blah[512] = {1.0};&amp;lt;/pawn&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;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static 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;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static 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>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:TheY4Kman/Plug-in_Search_API&amp;diff=7023</id>
		<title>User:TheY4Kman/Plug-in Search API</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:TheY4Kman/Plug-in_Search_API&amp;diff=7023"/>
		<updated>2009-03-15T07:41:08Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* How To Search */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''WORK IN PROGRESS!'''&lt;br /&gt;
&lt;br /&gt;
The plug-in search API exposes the plug-ins database through the JSON format.&lt;br /&gt;
&lt;br /&gt;
==How To Search==&lt;br /&gt;
Criteria for searching is specified in GET variables in the URL. For example, http://users.alliedmods.net/~they4kman/plugin_search.php?approved=yes&amp;amp;author=theY4Kman will retrieve all the approved plug-ins by theY4Kman. Here's the rest of the search criteria available:&lt;br /&gt;
&lt;br /&gt;
*'''title''': the title of the plug-in, e.g. &amp;quot;Triggers&amp;quot;&lt;br /&gt;
*'''author''': the username of the author, e.g. &amp;quot;theY4Kman&amp;quot;&lt;br /&gt;
*'''description''': the description provided by the author&lt;br /&gt;
*'''category''': the type of plug-in, e.g. &amp;quot;General Purpose&amp;quot;, &amp;quot;All&amp;quot;, &amp;quot;Administration&amp;quot;, etc.&lt;br /&gt;
*'''pluginid''': the ID of a plug-in ('''note''': this is NOT the thread ID)&lt;br /&gt;
*'''postid''': the ID of the plug-in's thread ('''note''': this IS the thread ID)&lt;br /&gt;
*'''authorid''': the forum user ID of the author&lt;br /&gt;
*'''mod''': the short name of a mod. For example, &amp;quot;cstrike&amp;quot; to search for Counter-Strike: Source games.&lt;br /&gt;
*'''approved''': whether the plug-in has been approved or not. '1', 'yes', and 'true' will filter out all non-approved plug-ins, whereas '0', 'no', and 'false' will filter out all approved plug-ins. Don't use this variable at all to see both approved and unapproved plug-ins.&lt;br /&gt;
&lt;br /&gt;
All of the criteria (save for ''approved'') support MySQL wildcards. '''%''' (percent sign) will accept any range of text, and '''_''' (underscore) will accept one character. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;http://users.alliedmods.net/~they4kman/plugin_search.php?approved=yes&amp;amp;title=sawce%rukia&amp;lt;/pre&amp;gt;&lt;br /&gt;
Will accept plug-in titles with any of these values:&lt;br /&gt;
*sawce loves rukia&lt;br /&gt;
*sawce is rukia&lt;br /&gt;
*sawce LOOOVES rukia&lt;br /&gt;
*sawcerukia&lt;br /&gt;
*sawce and rukia&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://users.alliedmods.net/~they4kman/plugin_search.php?approved=yes&amp;amp;title=sawce_&amp;lt;/pre&amp;gt;&lt;br /&gt;
Will accept any of these:&lt;br /&gt;
*sawces&lt;br /&gt;
*sawce!&lt;br /&gt;
*sawce.&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
The query http://users.alliedmods.net/~they4kman/plugin_search.php?author=theY4Kman&amp;amp;title=Triggers will find theY4Kman's Triggers plug-in, which will result in the following output (whitespace added for human readability):&lt;br /&gt;
&amp;lt;pre&amp;gt;[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;pluginid&amp;quot;:&amp;quot;285&amp;quot;,&lt;br /&gt;
    &amp;quot;author&amp;quot;:&amp;quot;theY4Kman&amp;quot;,&lt;br /&gt;
    &amp;quot;postid&amp;quot;:&amp;quot;585758&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;:&amp;quot;Triggers&amp;quot;,&lt;br /&gt;
    &amp;quot;category&amp;quot;:&amp;quot;General Purpose&amp;quot;,&lt;br /&gt;
    &amp;quot;mod_url&amp;quot;:&amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;description&amp;quot;:&amp;quot;Adds commandlist.txt functionality (From Mani) to SourceMod&amp;quot;,&lt;br /&gt;
    &amp;quot;authorid&amp;quot;:&amp;quot;28227&amp;quot;,&lt;br /&gt;
    &amp;quot;mod_short&amp;quot;:&amp;quot;any&amp;quot;,&lt;br /&gt;
    &amp;quot;mod_full&amp;quot;:&amp;quot;Any&amp;quot;,&lt;br /&gt;
    &amp;quot;approved&amp;quot;:&amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;:[]&lt;br /&gt;
  }&lt;br /&gt;
]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''pluginid''': the ID of the plug-in&lt;br /&gt;
*'''author''': the username of the author&lt;br /&gt;
*'''postid''': the thread ID of the plug-in. Use ''forums.alliedmods.net/showthread.php?t='''postid''''' to get the full URL to the thread.&lt;br /&gt;
*'''title''': the title of the plug-in&lt;br /&gt;
*'''category''': the type of plug-in&lt;br /&gt;
*'''mod_url''': a link to the webpage for the mod this plug-in was built for. For example, if the plug-in was meant for Counter-Strike: Source, the ''mod_url'' will be &amp;quot;http://www.steamgames.com/v/index.php?area=game&amp;amp;AppId=240&amp;quot;&lt;br /&gt;
*'''description''': self-explanitory&lt;br /&gt;
*'''authorid''': the forum user ID of the author. Use ''forums.alliedmods.net/member.php?u='''authorid''''' to get the full URL of the author.&lt;br /&gt;
*'''mod_short''': the short name of the mod this plug-in was built for. For example, if the plug-in was meant for Counter-Strike: Source, ''mod_short'' will be &amp;quot;cstrike&amp;quot;&lt;br /&gt;
*'''mod_full''': the full name of the mod. For example, if the plug-in was meant for Counter-Strike: Source, ''mod_full'' will be &amp;quot;Counter-Strike: Source&amp;quot;&lt;br /&gt;
*'''approved''': whether the plug-in was approved. '1' if it was, '0' if it wasn't.&lt;br /&gt;
*'''dependencies''': this is a list of plug-in IDs that the plug-in depends on. At the time of writing, extension dependencies have not been implemented, and plug-in dependencies are rare, so this list is not very useful.&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:TheY4Kman/Plug-in_Search_API&amp;diff=7020</id>
		<title>User:TheY4Kman/Plug-in Search API</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:TheY4Kman/Plug-in_Search_API&amp;diff=7020"/>
		<updated>2009-03-14T23:55:37Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''WORK IN PROGRESS!'''&lt;br /&gt;
&lt;br /&gt;
The plug-in search API exposes the plug-ins database through the JSON format.&lt;br /&gt;
&lt;br /&gt;
==How To Search==&lt;br /&gt;
Criteria for searching is specified in GET variables in the URL. For example, http://users.alliedmods.net/~they4kman/plugin_search.php?approved=yes&amp;amp;author=theY4Kman will retrieve all the plug-ins by theY4Kman. Here's the rest of the search criteria available:&lt;br /&gt;
&lt;br /&gt;
*'''title''': the title of the plug-in, e.g. &amp;quot;Triggers&amp;quot;&lt;br /&gt;
*'''author''': the username of the author, e.g. &amp;quot;theY4Kman&amp;quot;&lt;br /&gt;
*'''description''': the description provided by the author&lt;br /&gt;
*'''category''': the type of plug-in, e.g. &amp;quot;General Purpose&amp;quot;, &amp;quot;All&amp;quot;, &amp;quot;Administration&amp;quot;, etc.&lt;br /&gt;
*'''pluginid''': the ID of a plug-in ('''note''': this is NOT the thread ID)&lt;br /&gt;
*'''postid''': the ID of the plug-in's thread ('''note''': this IS the thread ID)&lt;br /&gt;
*'''authorid''': the forum user ID of the author&lt;br /&gt;
*'''mod''': the short name of a mod. For example, &amp;quot;cstrike&amp;quot; to search for Counter-Strike: Source games.&lt;br /&gt;
*'''approved''': whether the plug-in has been approved or not. '1', 'yes', and 'true' will filter out all non-approved plug-ins, whereas '0', 'no', and 'false' will filter out all approved plug-ins. Don't use this variable at all to see both approved and unapproved plug-ins.&lt;br /&gt;
&lt;br /&gt;
All of the criteria (save for ''approved'') support MySQL wildcards. '''%''' (percent sign) will accept any range of text, and '''_''' (underscore) will accept one character. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;http://users.alliedmods.net/~they4kman/plugin_search.php?approved=yes&amp;amp;title=sawce%rukia&amp;lt;/pre&amp;gt;&lt;br /&gt;
Will accept plug-in titles with any of these values:&lt;br /&gt;
*sawce loves rukia&lt;br /&gt;
*sawce is rukia&lt;br /&gt;
*sawce LOOOVES rukia&lt;br /&gt;
*sawcerukia&lt;br /&gt;
*sawce and rukia&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://users.alliedmods.net/~they4kman/plugin_search.php?approved=yes&amp;amp;title=sawce_&amp;lt;/pre&amp;gt;&lt;br /&gt;
Will accept any of these:&lt;br /&gt;
*sawces&lt;br /&gt;
*sawce!&lt;br /&gt;
*sawce.&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
The query http://users.alliedmods.net/~they4kman/plugin_search.php?author=theY4Kman&amp;amp;title=Triggers will find theY4Kman's Triggers plug-in, which will result in the following output (whitespace added for human readability):&lt;br /&gt;
&amp;lt;pre&amp;gt;[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;pluginid&amp;quot;:&amp;quot;285&amp;quot;,&lt;br /&gt;
    &amp;quot;author&amp;quot;:&amp;quot;theY4Kman&amp;quot;,&lt;br /&gt;
    &amp;quot;postid&amp;quot;:&amp;quot;585758&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;:&amp;quot;Triggers&amp;quot;,&lt;br /&gt;
    &amp;quot;category&amp;quot;:&amp;quot;General Purpose&amp;quot;,&lt;br /&gt;
    &amp;quot;mod_url&amp;quot;:&amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;description&amp;quot;:&amp;quot;Adds commandlist.txt functionality (From Mani) to SourceMod&amp;quot;,&lt;br /&gt;
    &amp;quot;authorid&amp;quot;:&amp;quot;28227&amp;quot;,&lt;br /&gt;
    &amp;quot;mod_short&amp;quot;:&amp;quot;any&amp;quot;,&lt;br /&gt;
    &amp;quot;mod_full&amp;quot;:&amp;quot;Any&amp;quot;,&lt;br /&gt;
    &amp;quot;approved&amp;quot;:&amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;:[]&lt;br /&gt;
  }&lt;br /&gt;
]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''pluginid''': the ID of the plug-in&lt;br /&gt;
*'''author''': the username of the author&lt;br /&gt;
*'''postid''': the thread ID of the plug-in. Use ''forums.alliedmods.net/showthread.php?t='''postid''''' to get the full URL to the thread.&lt;br /&gt;
*'''title''': the title of the plug-in&lt;br /&gt;
*'''category''': the type of plug-in&lt;br /&gt;
*'''mod_url''': a link to the webpage for the mod this plug-in was built for. For example, if the plug-in was meant for Counter-Strike: Source, the ''mod_url'' will be &amp;quot;http://www.steamgames.com/v/index.php?area=game&amp;amp;AppId=240&amp;quot;&lt;br /&gt;
*'''description''': self-explanitory&lt;br /&gt;
*'''authorid''': the forum user ID of the author. Use ''forums.alliedmods.net/member.php?u='''authorid''''' to get the full URL of the author.&lt;br /&gt;
*'''mod_short''': the short name of the mod this plug-in was built for. For example, if the plug-in was meant for Counter-Strike: Source, ''mod_short'' will be &amp;quot;cstrike&amp;quot;&lt;br /&gt;
*'''mod_full''': the full name of the mod. For example, if the plug-in was meant for Counter-Strike: Source, ''mod_full'' will be &amp;quot;Counter-Strike: Source&amp;quot;&lt;br /&gt;
*'''approved''': whether the plug-in was approved. '1' if it was, '0' if it wasn't.&lt;br /&gt;
*'''dependencies''': this is a list of plug-in IDs that the plug-in depends on. At the time of writing, extension dependencies have not been implemented, and plug-in dependencies are rare, so this list is not very useful.&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:TheY4Kman/Plug-in_Search_API&amp;diff=7019</id>
		<title>User:TheY4Kman/Plug-in Search API</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:TheY4Kman/Plug-in_Search_API&amp;diff=7019"/>
		<updated>2009-03-14T22:56:31Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* How To Use It */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''WORK IN PROGRESS!'''&lt;br /&gt;
The plug-in search API exposes the plug-ins database through the JSON format.&lt;br /&gt;
&lt;br /&gt;
==How To Use It==&lt;br /&gt;
Criteria for searching is specified in GET variables in the URL. For example, http://users.alliedmods.net/~they4kman/plugin_search.php?approved=yes&amp;amp;author=theY4Kman will retrieve all the plug-ins by theY4Kman.&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:TheY4Kman/Plug-in_Search_API&amp;diff=6985</id>
		<title>User:TheY4Kman/Plug-in Search API</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:TheY4Kman/Plug-in_Search_API&amp;diff=6985"/>
		<updated>2009-03-02T05:31:24Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: New page: '''WORK IN PROGRESS!''' The plug-in search API exposes the plug-ins database through the JSON format.  ==How To Use It== Criteria for searching is specified in GET variables in the URL. Fo...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''WORK IN PROGRESS!'''&lt;br /&gt;
The plug-in search API exposes the plug-ins database through the JSON format.&lt;br /&gt;
&lt;br /&gt;
==How To Use It==&lt;br /&gt;
Criteria for searching is specified in GET variables in the URL. For example: http://users.alliedmods.net/~they4kman/plugin_search.php?approved=yes&amp;amp;author=theY4Kman will retrieve all the plug-ins by the&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Gabe_Newell&amp;diff=6859</id>
		<title>Gabe Newell</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Gabe_Newell&amp;diff=6859"/>
		<updated>2009-01-26T23:19:59Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VALVe_Software]]&lt;br /&gt;
[[Category:People]]&lt;br /&gt;
[[Image:Gabe Newell.jpg|thumb|300px|Gabe Newell, laying down the law.]]&lt;br /&gt;
{{Gaben|C’mon, people, you can’t show the player a really big bomb and not let them blow it up.|[[Half-Life 1]]}}&lt;br /&gt;
&lt;br /&gt;
{{Gaben|Yes.|[[turning into cows when eating grass]]}}&lt;br /&gt;
&lt;br /&gt;
{{Gaben|this extents the original player_death by a new fields|Counter-Strike:Source modevents.res}}&lt;br /&gt;
&lt;br /&gt;
{{Gaben|Uh, no. And whoever is winding people up with this rumor, please stop giving out my home phone number. |rights on a half-life movie}}&lt;br /&gt;
&lt;br /&gt;
{{Gaben| We at Valve have always thought of ourselves as being part of a community, and I can't imagine a better group of people to &amp;lt;s&amp;gt;help us take care of these problems than this community&amp;lt;/s&amp;gt; screw over with obnoxious advertising.|[http://www.shacknews.com/onearticle.x/28619 HL2 Source Leak]}}&lt;br /&gt;
&lt;br /&gt;
[[Image:Gaben_Portal_Cake.jpg|thumb|300px|Gabe Newell, reaching for the &amp;lt;strike&amp;gt;stars&amp;lt;/strike&amp;gt; cake]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=File:Gaben_Portal_Cake.jpg&amp;diff=6858</id>
		<title>File:Gaben Portal Cake.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=File:Gaben_Portal_Cake.jpg&amp;diff=6858"/>
		<updated>2009-01-26T23:13:38Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Gaben tries and tries, but alas, he may never reach the cake.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Gaben tries and tries, but alas, he may never reach the cake.&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Entity_Properties&amp;diff=5808</id>
		<title>Entity Properties</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Entity_Properties&amp;diff=5808"/>
		<updated>2008-05-14T20:22:24Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: s/encapsulates/encapsulate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article is a brief introduction into Half-Life 2 entity properties.  &lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
'''In layman's terms:'''&lt;br /&gt;
Entity properties are named variables attached to entities.  Each variable is located at a specific offset from the entity.  For example, CS:S player entities have a variable called &amp;quot;m_iAccount&amp;quot; which is offset 3,608 bytes from every player in memory.  These variables, as well as their offsets, are enumerable at run-time.  They are not the same as KeyValues inputs, which are designed to accept information from maps.  Entity properties are the raw, internal data that comprises an entity.&lt;br /&gt;
&lt;br /&gt;
'''In C++ terms:'''&lt;br /&gt;
Entity properties are named, retrievable properties that represent a certain data structure specific to an entity instance.  They are usually tied to variables of CBaseEntity and its derivatives.  Each named property is tied to, among other pieces of information, an offset from the &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; pointer of the entity.  This means that server-side developers can easily decompose entity information, because the variable names and offsets are enumerable. &lt;br /&gt;
&lt;br /&gt;
The information here is intended for server-side plugin developers who are learning, programming, or reverse engineering a mod that does not nicely expose API for modifying entities.  Mod developers should use the [http://developer.valvesoftware.com/ Valve Wiki].&lt;br /&gt;
&lt;br /&gt;
There are two main property types for Source entities:&lt;br /&gt;
*&amp;lt;b&amp;gt;SendProps&amp;lt;/b&amp;gt;: These are properties designed for networking.  Changes are mirrored to clients via the Source engine and RecvProps.&lt;br /&gt;
*&amp;lt;b&amp;gt;DataMaps&amp;lt;/b&amp;gt;: These are properties designed for saving and restoring an entity.  Unlike SendProps, they are not necessarily networkable, and they are more mod specific.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Network Properties=&lt;br /&gt;
Network properties deal with properties that must be transmitted over the network.  There are four pieces to this:&lt;br /&gt;
*Network variables, which handle marking offsets in memory as changed.&lt;br /&gt;
*Send properties, which describe how the memory/data at the offset should be networked.&lt;br /&gt;
*Send tables, also called data tables, which contain lists of send properties.&lt;br /&gt;
*Server classes, which contain all of the send tables an entity needs for networking.&lt;br /&gt;
&lt;br /&gt;
Since correct networking is crucial to client/server communication, the send table hierarchy must be the same between the server and the client.  Otherwise, the client will not be able to connect to the server.  &lt;br /&gt;
&lt;br /&gt;
==Network Variables==&lt;br /&gt;
The purpose of network variables is to notify the engine of which entities, and which offsets in those entities, need to be re-transmitted over the network because they have changed.&lt;br /&gt;
&lt;br /&gt;
'''Important Headers''': &amp;lt;tt&amp;gt;public/networkvar.h&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;public/edict.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Network variables are simple, operator-overloading macros, which box the original value type.  This is to detect state changes.  When m_fOnTarget is changed via normal means (for example, using C++ operators and not something like &amp;lt;tt&amp;gt;memcpy&amp;lt;/tt&amp;gt;), it will trigger a function called &amp;lt;tt&amp;gt;NetworkStateChanged()&amp;lt;/tt&amp;gt; in the entity.  This state change can be global (resends the entire entity) or offset specific (only transmits as many bits as needed).&lt;br /&gt;
&lt;br /&gt;
The order of operations is usually similar to:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;Code, like the following, is executed:&lt;br /&gt;
  &amp;lt;cpp&amp;gt;m_fOnTarget = false;&amp;lt;/cpp&amp;gt;&lt;br /&gt;
 &amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;This assignment triggers &amp;lt;tt&amp;gt;::NetworkStateChanged(address)&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;CBaseEntity&amp;lt;/tt&amp;gt; or its derived class.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;This calls &amp;lt;tt&amp;gt;CServerNetworkProperty::NetworkStateChanged(offset_from_this)&amp;lt;/tt&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;This calls &amp;lt;tt&amp;gt;edict_t::StateChanged(offset_from_baseent)&amp;lt;/tt&amp;gt; (entities are tied to edicts)&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;If the entity has had more than 19 offsets changed, or more than 100 entities have changed, the entire entity is marked for retransmission.  &amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;Otherwise, its changed offset is added to the global change offset table.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of a network variable being declared looks like below, from &amp;lt;tt&amp;gt;dlls/player.cpp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;cpp&amp;gt;	CNetworkVar( bool, m_fOnTarget );		//Is the crosshair on a target?&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Send Properties==&lt;br /&gt;
While network properties are for notifying the engine of changes, send properties tell the engine exactly how to deal with those changes.  &lt;br /&gt;
&lt;br /&gt;
'''Important Headers''': &amp;lt;tt&amp;gt;public/dt_send.h&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;public/dt_shared.h&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;public/dt_common.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send properties enumerate the following pieces of information about each network offset:&lt;br /&gt;
*A &amp;lt;tt&amp;gt;SendPropType&amp;lt;/tt&amp;gt; value (Int, Float, Vector, String, Array, or Data Table).&lt;br /&gt;
*The number of bits to transmit.&lt;br /&gt;
*The name of the property (usually, the same as the variable name).&lt;br /&gt;
*Transmission flags (such as, whether it is signed or unsigned).&lt;br /&gt;
*The offset from the CBaseEntity pointer at which this variable lives.&lt;br /&gt;
&lt;br /&gt;
An example of a SendProp being declared looks like below, from &amp;lt;tt&amp;gt;dlls/player.cpp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;cpp&amp;gt;SendPropInt ( SENDINFO( m_fOnTarget ), 2, SPROP_UNSIGNED ),&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This declares an unsigned send property that only transmits two bits.&lt;br /&gt;
&lt;br /&gt;
==Send Tables==&lt;br /&gt;
Send tables, also called ''data tables'', encapsulate a set of related send properties.  Send tables can be nested; if there is a send property that includes a send table, the tables will effectively be merged.&lt;br /&gt;
&lt;br /&gt;
'''Important Headers''': &amp;lt;tt&amp;gt;public/dt_send.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send tables have explicit names.  For example the following line from &amp;lt;tt&amp;gt;dlls/player.cpp&amp;lt;/tt&amp;gt; begins a send table named &amp;lt;tt&amp;gt;DT_PlayerState&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;cpp&amp;gt;BEGIN_SEND_TABLE_NOBASE(CPlayerState, DT_PlayerState)&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This particular send table is then linked into &amp;lt;tt&amp;gt;DT_BasePlayer&amp;lt;/tt&amp;gt; via: &lt;br /&gt;
&amp;lt;cpp&amp;gt;SendPropDataTable(SENDINFO_DT(pl), &amp;amp;REFERENCE_SEND_TABLE(DT_PlayerState), SendProxy_DataTableToDataTable),&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Server Classes==&lt;br /&gt;
Server classes are at the highest level of the networking chain.  Each server class has:&lt;br /&gt;
*A unique name (a &amp;lt;tt&amp;gt;ClassName&amp;lt;/tt&amp;gt; as opposed to an entity's &amp;lt;tt&amp;gt;Classname&amp;lt;/tt&amp;gt;).&lt;br /&gt;
*A root send table.&lt;br /&gt;
*A pointer to the next server class in the chain.&lt;br /&gt;
&lt;br /&gt;
'''Important Headers''': &amp;lt;tt&amp;gt;public/server_class.h&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While server classes are not related, they are globally linked via a constructor - this is simply to make development easier.  The engine retrieves the first server class pointer via &amp;lt;tt&amp;gt;IServerGameDLL::GetAllServerClasses()&amp;lt;/tt&amp;gt;.  Using this pointer, the engine can find every single server class, and thus all send tables in the tree, and likewise, all send properties in each table.&lt;br /&gt;
&lt;br /&gt;
Usually, each major CBaseEntity derivation contains a server class.  For example, for Counter-Strike:Source, there is a &amp;lt;tt&amp;gt;CCSPlayer&amp;lt;/tt&amp;gt; server class.  Its major hierarchy looks roughly like:&lt;br /&gt;
*CCSPlayer&lt;br /&gt;
**DT_CSPlayer&lt;br /&gt;
***DT_BasePlayer&lt;br /&gt;
****DT_BaseCombatCharacter&lt;br /&gt;
*****DT_BaseFlex&lt;br /&gt;
******DT_BaseAnimatingOverlay&lt;br /&gt;
*******DT_BaseAnimating&lt;br /&gt;
********DT_BaseEntity&lt;br /&gt;
&lt;br /&gt;
Although this is a recursive tree, the properties themselves are all linear.  This means, that all send properties under CCSPlayer are all offsets to anything matching a CCSPlayer.  &lt;br /&gt;
&lt;br /&gt;
Because server classes can be enumerated without the instantiation of a given object/entity, send property lookup can be resolved at load time.  Even if it needs to be done at run-time, it can be easily optimized given this linear structure.&lt;br /&gt;
&lt;br /&gt;
=Data Maps=&lt;br /&gt;
Data maps are properties which are enumerated for save/restore mechanisms.  They are less complicated than send properties, but more mod-specific. &lt;br /&gt;
&lt;br /&gt;
'''Important Headers''': &amp;lt;tt&amp;gt;public/datamap.h&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Data maps are encapsulated in a structure called &amp;lt;tt&amp;gt;datamap_t&amp;lt;/tt&amp;gt;.  This structure contains the following information:&lt;br /&gt;
*An array of &amp;lt;tt&amp;gt;typedescription_t&amp;lt;/tt&amp;gt; structures.&lt;br /&gt;
*A string name.&lt;br /&gt;
*A link to a parent data map, if any.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;typedescription_t&amp;lt;/tt&amp;gt; structure declares one property.  It contains:&lt;br /&gt;
*A &amp;lt;tt&amp;gt;fieldtype_t&amp;lt;/tt&amp;gt; data type, which has types such as &amp;lt;tt&amp;gt;FIELD_INTEGER&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;FIELD_STRING&amp;lt;/tt&amp;gt;&lt;br /&gt;
*A field name, which will usually be the same as the variable name.&lt;br /&gt;
*An offset from the entity pointer to where this data lives.&lt;br /&gt;
&lt;br /&gt;
Data maps can be recursive trees like send tables, since a field can contain another data map.  However, there is no known or documented method of easily extracting all data maps.  This means that lookup can only be done once an instance to a given entity is known, relying on &amp;lt;tt&amp;gt;CBaseEntity::GetDataDescMap&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
However, CBaseEntity is ultimately mod specific.  Even if it's rare that its position in the virtual table will change, care should be taken to ensure cross-mod compatibility.  It is incorrect to assume that calling this function will result in the same behaviour on every mod.&lt;br /&gt;
&lt;br /&gt;
An example of a data map being declared can be found in &amp;lt;tt&amp;gt;dlls/player.cpp&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;cpp&amp;gt;BEGIN_SIMPLE_DATADESC( CPlayerState )&lt;br /&gt;
	// DEFINE_FIELD( netname, FIELD_STRING ),  // Don't stomp player name with what's in save/restore&lt;br /&gt;
	DEFINE_FIELD( v_angle, FIELD_VECTOR ),&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Enumeration=&lt;br /&gt;
==Server Classes==&lt;br /&gt;
Server classes are easily enumerable.  Here is an example function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cpp&amp;gt;/**&lt;br /&gt;
 * Searches for a named Server Class.&lt;br /&gt;
 *&lt;br /&gt;
 * @param name		Name of the top-level server class.&lt;br /&gt;
 * @return 		Server class matching the name, or NULL if none found.&lt;br /&gt;
 */&lt;br /&gt;
ServerClass *UTIL_FindServerClass(const char *name)&lt;br /&gt;
{&lt;br /&gt;
	ServerClass *pClass = server-&amp;gt;GetAllServerClasses();&lt;br /&gt;
	while (pClass)&lt;br /&gt;
	{&lt;br /&gt;
		if (strcmp(pClass-&amp;gt;m_pNetworkName, name) == 0)&lt;br /&gt;
		{&lt;br /&gt;
			return pClass;&lt;br /&gt;
		}&lt;br /&gt;
		pClass = pClass-&amp;gt;m_pNext;&lt;br /&gt;
	}&lt;br /&gt;
	return NULL;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Send Properties==&lt;br /&gt;
Full send table enumeration requires recursion.  An example function below recurses through all properties and sub-table properties of a table.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cpp&amp;gt;/**&lt;br /&gt;
 * Recursively looks through a send table for a given named property.&lt;br /&gt;
 *&lt;br /&gt;
 * @param pTable	Send table to browse.&lt;br /&gt;
 * @param name		Property to search for.&lt;br /&gt;
 * @return 		SendProp pointer on success, NULL on failure.&lt;br /&gt;
 */&lt;br /&gt;
SendProp *UTIL_FindSendProp(SendTable *pTable, const char *name)&lt;br /&gt;
{&lt;br /&gt;
	int count = pTable-&amp;gt;GetNumProps();&lt;br /&gt;
	SendTable *pTable;&lt;br /&gt;
	SendProp *pProp;&lt;br /&gt;
	for (int i=0; i&amp;lt;count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		pProp = pTable-&amp;gt;GetProp(i);&lt;br /&gt;
		if (strcmp(pProp-&amp;gt;GetName(), name) == 0)&lt;br /&gt;
		{&lt;br /&gt;
			return pProp;&lt;br /&gt;
		}&lt;br /&gt;
		if (pProp-&amp;gt;GetDataTable())&lt;br /&gt;
		{&lt;br /&gt;
			if ((pProp=UTIL_FindSendProp(pProp-&amp;gt;GetDataTable(), name)) != NULL)&lt;br /&gt;
			{&lt;br /&gt;
				return pProp;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return NULL;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example usage of both of these functions might look like:&lt;br /&gt;
&amp;lt;cpp&amp;gt;/**&lt;br /&gt;
 * Sets a player's health.&lt;br /&gt;
 *&lt;br /&gt;
 * @param edict		Player's edict.&lt;br /&gt;
 * @param health	Health to set.&lt;br /&gt;
 */&lt;br /&gt;
void SetPlayerHealth(edict_t *edict, int health)&lt;br /&gt;
{&lt;br /&gt;
	static unsigned int offset = 0;&lt;br /&gt;
	&lt;br /&gt;
	if (!offset)&lt;br /&gt;
	{&lt;br /&gt;
		ServerClass *sc = UTIL_FindServerClass(&amp;quot;CBasePlayer&amp;quot;);&lt;br /&gt;
		SendProp *pProp = UTIL_FindSendProp(sc-&amp;gt;m_pTable, &amp;quot;m_iHealth&amp;quot;);&lt;br /&gt;
		offset = pProp-&amp;gt;GetOffset();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	IServerUnknown *pUnknown = (IServerUnknown *)edict-&amp;gt;GetUnknown();&lt;br /&gt;
	if (!pUnknown)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	CBaseEntity *pEntity = pUnknown-&amp;gt;GetBaseEntity();&lt;br /&gt;
	*(int *)((char *)pEntity + offset) = health;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Datamap Properties==&lt;br /&gt;
Here is an example of a function for searching datamaps for a given property.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cpp&amp;gt;/**&lt;br /&gt;
 * Finds a named offset in a datamap.&lt;br /&gt;
 *&lt;br /&gt;
 * @param pMap		Datamap to search.&lt;br /&gt;
 * @param name		Name of the property to find.&lt;br /&gt;
 * @return		Offset of a data map property, or 0 if not found.&lt;br /&gt;
 */&lt;br /&gt;
unsigned int UTIL_FindInDataMap(datamap_t *pMap, const char *name)&lt;br /&gt;
{&lt;br /&gt;
	while (pMap)&lt;br /&gt;
	{&lt;br /&gt;
		for (int i=0; i&amp;lt;pMap-&amp;gt;dataNumFields; i++)&lt;br /&gt;
		{&lt;br /&gt;
			if (pMap-&amp;gt;dataDesc[i].fieldName == NULL)&lt;br /&gt;
			{&lt;br /&gt;
				continue;&lt;br /&gt;
			}&lt;br /&gt;
			if (strcmp(name, pMap-&amp;gt;dataDesc[i].fieldName) == 0)&lt;br /&gt;
			{&lt;br /&gt;
				return pMap-&amp;gt;dataDesc[i].fieldOffset[TD_OFFSET_NORMAL];&lt;br /&gt;
			}&lt;br /&gt;
			if (pMap-&amp;gt;dataDesc[i].td)&lt;br /&gt;
			{&lt;br /&gt;
				unsigned int offset;&lt;br /&gt;
				if ((offset=UTIL_FindInDataMap(pMap-&amp;gt;dataDesc[i].td, name)) != 0)&lt;br /&gt;
				{&lt;br /&gt;
					return offset;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		pMap = pMap-&amp;gt;baseMap;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 0; &lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we can rewrite the &amp;lt;tt&amp;gt;SetPlayerHealth&amp;lt;/tt&amp;gt; function using data maps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cpp&amp;gt;/**&lt;br /&gt;
 * Sets a player's health.&lt;br /&gt;
 *&lt;br /&gt;
 * @param edict		Player's edict.&lt;br /&gt;
 * @param health	Health to set.&lt;br /&gt;
 */&lt;br /&gt;
void SetPlayerHealth(edict_t *edict, int health)&lt;br /&gt;
{&lt;br /&gt;
	static unsigned int offset = 0;&lt;br /&gt;
&lt;br /&gt;
	IServerUnknown *pUnknown = (IServerUnknown *)edict-&amp;gt;GetUnknown();&lt;br /&gt;
	if (!pUnknown)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	CBaseEntity *pEntity = pUnknown-&amp;gt;GetBaseEntity();&lt;br /&gt;
	&lt;br /&gt;
	if (!offset)&lt;br /&gt;
	{&lt;br /&gt;
		offset = UTIL_FindInDataMap(pEntity-&amp;gt;GetDataDescMap(), &amp;quot;m_iHealth&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	*(int *)((char *)pEntity + offset) = health;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=SourceMod Commands=&lt;br /&gt;
SDKTools provides two commands for dumping netprops:&lt;br /&gt;
*&amp;lt;tt&amp;gt;sm_dump_netprops &amp;amp;lt;file&amp;amp;gt;&amp;lt;/tt&amp;gt; - Dumps network properties to a named text file (in the mod folder).&lt;br /&gt;
*&amp;lt;tt&amp;gt;sm_dump_netprops_xml &amp;amp;lt;file&amp;amp;gt;&amp;lt;/tt&amp;gt; - Dumps network properties to a named text file in XML format (in the mod folder).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.bailopan.net/table_dump.txt Sample CS:S Network Property Dump]&lt;br /&gt;
*[http://www.bailopan.net/tf_netprops.txt Sample TF Network Property Dump]&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_(legacy_syntax)&amp;diff=5801</id>
		<title>Introduction to SourcePawn (legacy syntax)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_(legacy_syntax)&amp;diff=5801"/>
		<updated>2008-05-10T21:17:00Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: More semi-colons!&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;
&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 (unlike PHP, where sometimes they are not).  Symbols do not start with any special character, though they must 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.  Variables are created for storage space throughout a program.  Variables must be declared before being used, using the &amp;quot;new&amp;quot; keyword.  Data is assigned to variables using the equal sign (=).  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In SourcePawn, variables have two types, which will be explained in more detail further on.&lt;br /&gt;
*Cells (arbitrary numerical data), as shown above.&lt;br /&gt;
*Strings (a series of text characters)&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.  That means when you activate them, they carry out a specific sequence of code.  There are a few types of functions, but every function is activated the same way.  &amp;quot;Calling a function&amp;quot; is the term for invoking a function's action.  Function calls are constructed like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;function(&amp;lt;parameters&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Activates &amp;quot;show&amp;quot; function, and gives the number 56 to it&lt;br /&gt;
show();     //Activates &amp;quot;show&amp;quot; function with no data, blank&lt;br /&gt;
show(a);    //Activates &amp;quot;show&amp;quot; function, gives a variable's contents as data&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;
&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 not typed.'''  Pawn only has one data type, the '''cell'''.  This will be explained in detail later.&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 is procedural, and relies on subroutines.  It also does not have C structs.&lt;br /&gt;
*'''Pawn is not functional.''' Pawn is procedural, and does not support lambda functions or late binding or anything else you might find in a very high-level language, like Python or Ruby.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn is not interpreted.''' Well, it &amp;quot;sort of&amp;quot; is.  It gets interpreted at a very low level.  You must run your code through a compiler, which produces a binary.  This binary will work on any platform that the host application uses.  This speeds up loading time and lets you check errors easier.&lt;br /&gt;
&lt;br /&gt;
These languages 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;
&lt;br /&gt;
=Variables=&lt;br /&gt;
In Pawn there are two variable types: the '''cell''' and the '''String'''.  A cell can store 32 bits of numerical data.  A String is a sequential/flat list of UTF-8 text characters.&lt;br /&gt;
&lt;br /&gt;
A '''cell''' has no inherent type, however, cells can be '''tagged'''.  A tag lets you enforce where certain cells can be used.  The default tags are:&lt;br /&gt;
*(nothing), or '''_''' - No tag.  Usually used for whole numbers ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - Used for floating point (fractional) numbers.&lt;br /&gt;
*'''bool''' - Used for storing either '''true''' or '''false'''.&lt;br /&gt;
&lt;br /&gt;
Strings are different and will be explained in the next sections.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Examples of different valid variable declarations:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Works because 0 is 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;
new a = 5.0;         //Tag mismatch.  5.0 is tagged as Float&lt;br /&gt;
new Float:b = 5;     //Tag mismatch.  5 is not tagged.&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;
new a;        //Set to 0&lt;br /&gt;
new Float:b;  //Set to 0.0&lt;br /&gt;
new 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;new a, Float:b, 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;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a sequential list.  Arrays are useful for storing multiple pieces of data in one variable, and often greatly simplify many tasks.  &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;
new players[32];     //Stores 32 cells (numbers)&lt;br /&gt;
new 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;
new numbers[5] = {1, 2, 3, 4, 5};       //Stores 1, 2, 3, 4, 5 in the cells.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Stores 1.0, 2.0, 3.0 in the cells.&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;
new 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;
==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;
new numbers[5], 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;
To use an incorrect index will cause an error.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new 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;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Set a = 1&lt;br /&gt;
numbers[a] = 4;          //Set numbers[1] = 3&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;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a convenient method of storing text.  The characters are stored in an array.  The string is terminated by a '''null terminator''', or a 0.  Without a null terminator, Pawn would not know where to stop reading the string.  All strings are UTF-8 in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
Notice that Strings are a combination of arrays and cells.  Unlike other languages, this means you must know how much space a string will use in advance.  That is, strings are not dynamic.  They can only grow to the space you allocate for them.&lt;br /&gt;
&lt;br /&gt;
''Note for experts:  They're not actually cells.  SourcePawn uses 8-bit storage for String arrays as an optimization.  This is what makes String a type and not a tag.''&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are declared almost equivalently to arrays.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String: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;
new String:message[7], String: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;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new 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;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Invalid, needs String: type&lt;br /&gt;
new 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;
&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 five 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;
*'''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 contrast to languages like PHP, Perl, or 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 built 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 '''prototype''' and the '''body'''.  The prototype 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;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&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;AddTwoNumbers(first, second);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&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;first&amp;lt;/tt&amp;gt; - Name of the first parameter, which is a simple cell.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Name of the second parameter, which is a simple cell.&lt;br /&gt;
&lt;br /&gt;
The body is a simple 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.  All functions ''return a cell'' upon completion.  That means, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will assign the number 9 to sum.  The function adds the two inputs, and the sum is given as the '''return value'''.  If a function has no return statement, or does not place a value in the return statement, it returns 0 by default.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input.  It can return any cell, but not arrays or strings.  Example:  &lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Note that if in the above function, you returned a non-Float, you would get a tag mismatch.''&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new 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;new 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 OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(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 OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(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 exposes the function publicly, and allows the parent application to directly call the function.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by the application.  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 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;new num = FloatRound(5.0);     //Results in num = 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;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, 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;
This is only possible because the array can be directly modified.  To prevent an array from being modified, 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;CantChangeArray(const array[], index, 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;
&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 7&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;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Evaluates to 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&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;new 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;new 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 be before the variable (preincrement, predecrement) or after the variable (postincrement, postdecrement).  The difference is in the order of execution.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;&lt;br /&gt;
new c = ++a;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; will be equal to 5, after which &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; will be incremented to 6.  But then &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; will be incremented to 7, and &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; will receive the value of 7.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
As noted earlier, expressions can either be true or false depending on if they're non-zero or zero.  This is especially useful with truth operators.  There are five important truth operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; - Tests whether two expressions are both true.&lt;br /&gt;
*&amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; - Tests whether one of two expressions is true.&lt;br /&gt;
*&amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; - Flips the truth value of an expression.&lt;br /&gt;
*&amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; - Tests whether two expressions are numerically equivalent.&lt;br /&gt;
*&amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; - Tests whether two expressions are numerically inequivalent.&lt;br /&gt;
&lt;br /&gt;
There are also some mathematical truth operators (L is left hand, R is right hand):&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt; - True if L is greater than R&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; - True if L is greater than or equal to R&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt; - True if L is less than R&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; - True if L is less than or equal to R&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;
(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;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays.  That is, you cannot compare strings or arrays using &amp;lt;tt&amp;gt;==&amp;lt;/tt&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;
new 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 ran.  If a single case matches, its code is ran, and the switch is then immediately terminated.&lt;br /&gt;
&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 properties:&lt;br /&gt;
*The '''begin''' statement, which is ran before the first loop occurs.&lt;br /&gt;
*The '''condition''' statement, which checks whether the next loop should run.&lt;br /&gt;
*The '''iterator''' statement, which is ran after each loop runs.&lt;br /&gt;
*The code block itself, which is what's run every loop.&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;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new 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;new 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.  It only has two properties:&lt;br /&gt;
*The '''condition''', which is checked before each loop.&lt;br /&gt;
*The '''code''', which is what's run each loop.&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue.  Here is an example of the previous for loop as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new 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;
   /* Code */&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;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new 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;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new 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;
&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;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new 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;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new 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;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new 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;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new 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;
&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;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new 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;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&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;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static 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;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static 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;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_(legacy_syntax)&amp;diff=5800</id>
		<title>Introduction to SourcePawn (legacy syntax)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourcePawn_(legacy_syntax)&amp;diff=5800"/>
		<updated>2008-05-10T21:15:38Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Fixed some spelling errors, and added semi-colons&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;
&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 (unlike PHP, where sometimes they are not).  Symbols do not start with any special character, though they must 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.  Variables are created for storage space throughout a program.  Variables must be declared before being used, using the &amp;quot;new&amp;quot; keyword.  Data is assigned to variables using the equal sign (=).  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a,b,c,d&lt;br /&gt;
&lt;br /&gt;
a=5&lt;br /&gt;
b=16&lt;br /&gt;
c=0&lt;br /&gt;
d=500&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In SourcePawn, variables have two types, which will be explained in more detail further on.&lt;br /&gt;
*Cells (arbitrary numerical data), as shown above.&lt;br /&gt;
*Strings (a series of text characters)&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.  That means when you activate them, they carry out a specific sequence of code.  There are a few types of functions, but every function is activated the same way.  &amp;quot;Calling a function&amp;quot; is the term for invoking a function's action.  Function calls are constructed like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;function(&amp;lt;parameters&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56)   //Activates &amp;quot;show&amp;quot; function, and gives the number 56 to it&lt;br /&gt;
show()     //Activates &amp;quot;show&amp;quot; function with no data, blank&lt;br /&gt;
show(a)    //Activates &amp;quot;show&amp;quot; function, gives a variable's contents as data&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;
&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 not typed.'''  Pawn only has one data type, the '''cell'''.  This will be explained in detail later.&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 is procedural, and relies on subroutines.  It also does not have C structs.&lt;br /&gt;
*'''Pawn is not functional.''' Pawn is procedural, and does not support lambda functions or late binding or anything else you might find in a very high-level language, like Python or Ruby.&lt;br /&gt;
*'''Pawn is single-threaded.''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn is not interpreted.''' Well, it &amp;quot;sort of&amp;quot; is.  It gets interpreted at a very low level.  You must run your code through a compiler, which produces a binary.  This binary will work on any platform that the host application uses.  This speeds up loading time and lets you check errors easier.&lt;br /&gt;
&lt;br /&gt;
These languages 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;
&lt;br /&gt;
=Variables=&lt;br /&gt;
In Pawn there are two variable types: the '''cell''' and the '''String'''.  A cell can store 32 bits of numerical data.  A String is a sequential/flat list of UTF-8 text characters.&lt;br /&gt;
&lt;br /&gt;
A '''cell''' has no inherent type, however, cells can be '''tagged'''.  A tag lets you enforce where certain cells can be used.  The default tags are:&lt;br /&gt;
*(nothing), or '''_''' - No tag.  Usually used for whole numbers ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - Used for floating point (fractional) numbers.&lt;br /&gt;
*'''bool''' - Used for storing either '''true''' or '''false'''.&lt;br /&gt;
&lt;br /&gt;
Strings are different and will be explained in the next sections.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
Examples of different valid variable declarations:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Works because 0 is 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;
new a = 5.0;         //Tag mismatch.  5.0 is tagged as Float&lt;br /&gt;
new Float:b = 5;     //Tag mismatch.  5 is not tagged.&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;
new a;        //Set to 0&lt;br /&gt;
new Float:b;  //Set to 0.0&lt;br /&gt;
new 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;new a, Float:b, 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;
&lt;br /&gt;
=Arrays=&lt;br /&gt;
An array is a sequence of data in a sequential list.  Arrays are useful for storing multiple pieces of data in one variable, and often greatly simplify many tasks.  &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;
new players[32];     //Stores 32 cells (numbers)&lt;br /&gt;
new 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;
new numbers[5] = {1, 2, 3, 4, 5};       //Stores 1, 2, 3, 4, 5 in the cells.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Stores 1.0, 2.0, 3.0 in the cells.&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;
new 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;
==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;
new numbers[5], 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;
To use an incorrect index will cause an error.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new 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;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Set a = 1&lt;br /&gt;
numbers[a] = 4;          //Set numbers[1] = 3&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;
&lt;br /&gt;
=Strings=&lt;br /&gt;
Strings are a convenient method of storing text.  The characters are stored in an array.  The string is terminated by a '''null terminator''', or a 0.  Without a null terminator, Pawn would not know where to stop reading the string.  All strings are UTF-8 in SourcePawn.&lt;br /&gt;
&lt;br /&gt;
Notice that Strings are a combination of arrays and cells.  Unlike other languages, this means you must know how much space a string will use in advance.  That is, strings are not dynamic.  They can only grow to the space you allocate for them.&lt;br /&gt;
&lt;br /&gt;
''Note for experts:  They're not actually cells.  SourcePawn uses 8-bit storage for String arrays as an optimization.  This is what makes String a type and not a tag.''&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Strings are declared almost equivalently to arrays.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String: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;
new String:message[7], String: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;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new 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;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Invalid, needs String: type&lt;br /&gt;
new 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;
&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 five 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;
*'''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 contrast to languages like PHP, Perl, or 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 built 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 '''prototype''' and the '''body'''.  The prototype 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;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&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;AddTwoNumbers(first, second);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Broken down, it means:&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;first&amp;lt;/tt&amp;gt; - Name of the first parameter, which is a simple cell.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Name of the second parameter, which is a simple cell.&lt;br /&gt;
&lt;br /&gt;
The body is a simple 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.  All functions ''return a cell'' upon completion.  That means, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will assign the number 9 to sum.  The function adds the two inputs, and the sum is given as the '''return value'''.  If a function has no return statement, or does not place a value in the return statement, it returns 0 by default.&lt;br /&gt;
&lt;br /&gt;
A function can accept any type of input.  It can return any cell, but not arrays or strings.  Example:  &lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Note that if in the above function, you returned a non-Float, you would get a tag mismatch.''&lt;br /&gt;
&lt;br /&gt;
You can, of course, pass variables to functions:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new 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;new 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 OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(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 OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Code here */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(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 exposes the function publicly, and allows the parent application to directly call the function.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives are builtin functions provided by the application.  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 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;new num = FloatRound(5.0);     //Results in num = 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;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, 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;
This is only possible because the array can be directly modified.  To prevent an array from being modified, 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;CantChangeArray(const array[], index, 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;
&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 7&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;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Evaluates to 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&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;new 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;new 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 be before the variable (preincrement, predecrement) or after the variable (postincrement, postdecrement).  The difference is in the order of execution.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;&lt;br /&gt;
new c = ++a;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; will be equal to 5, after which &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; will be incremented to 6.  But then &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; will be incremented to 7, and &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; will receive the value of 7.&lt;br /&gt;
&lt;br /&gt;
==Truth Operators==&lt;br /&gt;
As noted earlier, expressions can either be true or false depending on if they're non-zero or zero.  This is especially useful with truth operators.  There are five important truth operators:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; - Tests whether two expressions are both true.&lt;br /&gt;
*&amp;lt;tt&amp;gt;||&amp;lt;/tt&amp;gt; - Tests whether one of two expressions is true.&lt;br /&gt;
*&amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; - Flips the truth value of an expression.&lt;br /&gt;
*&amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; - Tests whether two expressions are numerically equivalent.&lt;br /&gt;
*&amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; - Tests whether two expressions are numerically inequivalent.&lt;br /&gt;
&lt;br /&gt;
There are also some mathematical truth operators (L is left hand, R is right hand):&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt; - True if L is greater than R&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt; - True if L is greater than or equal to R&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt; - True if L is less than R&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt; - True if L is less than or equal to R&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;
(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;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these operators do not work on arrays.  That is, you cannot compare strings or arrays using &amp;lt;tt&amp;gt;==&amp;lt;/tt&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;
new 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 ran.  If a single case matches, its code is ran, and the switch is then immediately terminated.&lt;br /&gt;
&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 properties:&lt;br /&gt;
*The '''begin''' statement, which is ran before the first loop occurs.&lt;br /&gt;
*The '''condition''' statement, which checks whether the next loop should run.&lt;br /&gt;
*The '''iterator''' statement, which is ran after each loop runs.&lt;br /&gt;
*The code block itself, which is what's run every loop.&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;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new 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;new 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.  It only has two properties:&lt;br /&gt;
*The '''condition''', which is checked before each loop.&lt;br /&gt;
*The '''code''', which is what's run each loop.&lt;br /&gt;
&lt;br /&gt;
As long as the condition expression remains true, the loop will continue.  Here is an example of the previous for loop as a while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new 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;
   /* Code */&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;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new 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;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new 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;
&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;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new 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;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new 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;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new 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;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new 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;
&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;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new 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;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&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;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static 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;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static 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;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:TheY4Kman&amp;diff=5633</id>
		<title>User:TheY4Kman</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:TheY4Kman&amp;diff=5633"/>
		<updated>2008-03-02T05:10:33Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Redid SourceMod links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This information is from [http://en.wikipedia.org/wiki/User:TheY4Kman Wikipedia].&lt;br /&gt;
&lt;br /&gt;
Zach &amp;quot;theY4Kman&amp;quot; Kanzler is the owner of [http://y4kstudios.com Y4K Studios]. He is a programmer most notable for his work in [http://cheatsync.net CheatSync] and [[SOURCEMOD|SourceMod]].&lt;br /&gt;
&lt;br /&gt;
==Projects==&lt;br /&gt;
theY4Kman has worked on several major projects, and some smaller ones.&lt;br /&gt;
&lt;br /&gt;
===CheatSync===&lt;br /&gt;
With the advent of [http://cheatdevice.com CheatDevice] by edisoncarter, the cheats created for it were spread across the web. On [http://gtaforums.com the GTA Forums], ADePSP and theY4Kman discussed creating a database for all the new cheats. theY4Kman wrote the website front-end for it, and hosted it on his site. It was a very basic form, consisting of an author field, a name field, a description field, and a cheat field. ADePSP  wrote the desktop application for it, in [[Delphi]]. As the new database was about to be released, theY4Kman thought up the name &amp;quot;[http://cheatsync.net CheatSync].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[http://cheatsync.net CheatSync] was a huge hit. Hundreds of users contributed thousands of cheats. The crummy front-end and buggy program couldn't deal with the load. edisoncarter purchased [http://cheatsync.net cheatsync.net] for ADePSP. ADe programmed an online version of [http://cheatsync.net CheatSync], in the [[PHP]] language. At this point, theY4Kman was no longer necessary.&lt;br /&gt;
&lt;br /&gt;
Zach offered to create a version of CheatSync which used AJAX, but the project quickly ended, due to lack of time.&lt;br /&gt;
&lt;br /&gt;
===EventScripts===&lt;br /&gt;
Zach became addicted to [[Source engine|Source]] games (e.g., [[Counter-Strike: Source|CS:S]] and [[Half-Life 2|HL2]]). With his programming background, plug-ins like [[EventScripts ]] and [[SOURCEMOD|SourceMod]]. At first, he experimented with [[EventScripts]]. However, he did not appreciate the lack of performance it held and its heavily scripted language. This led to his delving into [[SOURCEMOD|SourceMod]].&lt;br /&gt;
&lt;br /&gt;
===SourceMod===&lt;br /&gt;
Upon learning '''SourcePawn''' (The language of [[SOURCEMOD|SourceMod]], based off [[Pawn (programming language)|Pawn]]), theY4Kman wrote the plug-in &amp;quot;[http://forums.alliedmods.net/showthread.php?t=56376 Maplister].&amp;quot; It was a very simple program, that printed out all the maps available on a [[Source engine|Source]] game server. After his first plug-in, he developed a few more plug-ins, such as [http://forums.alliedmods.net/showthread.php?t=56264 Weapon Rewards Advanced], [http://forums.alliedmods.net/showthread.php?t=60146 CommandReact], [http://forums.alliedmods.net/showthread.php?t=56778 UserRestrict], and [http://forums.alliedmods.net/showthread.php?t=56960 EventInfo]. His latest plug-in is [http://forums.alliedmods.net/showthread.php?t=67098 Triggers], which provides [http://www.mani-admin-plugin.com/mani_admin_plugin/documentation/mani_install_config_commandlist.htm commandlist.txt] functionality to [[SOURCEMOD|SourceMod]] users.&lt;br /&gt;
&lt;br /&gt;
====Viper====&lt;br /&gt;
One of his latest projects is an extension of [[SOURCEMOD|SourceMod]]. Viper is a program written in C++, which allows [[SOURCEMOD|SourceMod]] developers to code plug-ins with Python, instead of [[SOURCEMOD|SM]]'s native language, SourcePawn.&lt;br /&gt;
&lt;br /&gt;
The project took off the in IRC channel [irc://irc.gamesurge.net/sourcemod #sourcemod]. One of the members bet theY4Kman that he couldn't do it. However, Viper is being actively developed now.&lt;br /&gt;
&lt;br /&gt;
Originally, Viper was named &amp;quot;SMPython,&amp;quot; for &amp;quot;SourceMod Python.&amp;quot; To Zach, though, it seemed very generic. A week or so after the title &amp;quot;SMPython&amp;quot; was given, the project was renamed to &amp;quot;Viper.&amp;quot; The new name came from the [[Viperidae|snake family]] and the user &amp;quot;Viper,&amp;quot; who is an active member of [irc://irc.gamesurge.net/sourcemod #sourcemod].&lt;br /&gt;
&lt;br /&gt;
==Pronunciation==&lt;br /&gt;
'''theY4Kman''' means &amp;quot;the year 4000 man.&amp;quot; The simplification of &amp;quot;Year 4000&amp;quot; to '''Y4K''' was derived from &amp;quot;Y2K&amp;quot;, meaning &amp;quot;Year 2000&amp;quot;. Thus, '''Y4K''' is actually pronounced &amp;quot;Why Four Kay,&amp;quot; not &amp;quot;Yak.&amp;quot; This common mistake originates from the notion that frequent internet users speak [[Leet|Leetspeak]]. However, using &amp;quot;Yak&amp;quot; is accepted.&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:TheY4Kman&amp;diff=5632</id>
		<title>User:TheY4Kman</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:TheY4Kman&amp;diff=5632"/>
		<updated>2008-03-02T05:08:55Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Added it all!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This information is from [http://en.wikipedia.org/wiki/User:TheY4Kman Wikipedia].&lt;br /&gt;
&lt;br /&gt;
Zach &amp;quot;theY4Kman&amp;quot; Kanzler is the owner of [http://y4kstudios.com Y4K Studios]. He is a programmer most notable for his work in [http://cheatsync.net CheatSync] and [[Sourcemod|SourceMod]].&lt;br /&gt;
&lt;br /&gt;
==Projects==&lt;br /&gt;
theY4Kman has worked on several major projects, and some smaller ones.&lt;br /&gt;
&lt;br /&gt;
===CheatSync===&lt;br /&gt;
With the advent of [http://cheatdevice.com CheatDevice] by edisoncarter, the cheats created for it were spread across the web. On [http://gtaforums.com the GTA Forums], ADePSP and theY4Kman discussed creating a database for all the new cheats. theY4Kman wrote the website front-end for it, and hosted it on his site. It was a very basic form, consisting of an author field, a name field, a description field, and a cheat field. ADePSP  wrote the desktop application for it, in [[Delphi]]. As the new database was about to be released, theY4Kman thought up the name &amp;quot;[http://cheatsync.net CheatSync].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[http://cheatsync.net CheatSync] was a huge hit. Hundreds of users contributed thousands of cheats. The crummy front-end and buggy program couldn't deal with the load. edisoncarter purchased [http://cheatsync.net cheatsync.net] for ADePSP. ADe programmed an online version of [http://cheatsync.net CheatSync], in the [[PHP]] language. At this point, theY4Kman was no longer necessary.&lt;br /&gt;
&lt;br /&gt;
Zach offered to create a version of CheatSync which used AJAX, but the project quickly ended, due to lack of time.&lt;br /&gt;
&lt;br /&gt;
===EventScripts===&lt;br /&gt;
Zach became addicted to [[Source engine|Source]] games (e.g., [[Counter-Strike: Source|CS:S]] and [[Half-Life 2|HL2]]). With his programming background, plug-ins like [[EventScripts ]] and [[Sourcemod|SourceMod]]. At first, he experimented with [[EventScripts]]. However, he did not appreciate the lack of performance it held and its heavily scripted language. This led to his delving into [[Sourcemod|SourceMod]].&lt;br /&gt;
&lt;br /&gt;
===SourceMod===&lt;br /&gt;
Upon learning '''SourcePawn''' (The language of [[Sourcemod|SourceMod]], based off [[Pawn (programming language)|Pawn]]), theY4Kman wrote the plug-in &amp;quot;[http://forums.alliedmods.net/showthread.php?t=56376 Maplister].&amp;quot; It was a very simple program, that printed out all the maps available on a [[Source engine|Source]] game server. After his first plug-in, he developed a few more plug-ins, such as [http://forums.alliedmods.net/showthread.php?t=56264 Weapon Rewards Advanced], [http://forums.alliedmods.net/showthread.php?t=60146 CommandReact], [http://forums.alliedmods.net/showthread.php?t=56778 UserRestrict], and [http://forums.alliedmods.net/showthread.php?t=56960 EventInfo]. His latest plug-in is [http://forums.alliedmods.net/showthread.php?t=67098 Triggers], which provides [http://www.mani-admin-plugin.com/mani_admin_plugin/documentation/mani_install_config_commandlist.htm commandlist.txt] functionality to [[Sourcemod|SourceMod]] users.&lt;br /&gt;
&lt;br /&gt;
====Viper====&lt;br /&gt;
One of his latest projects is an extension of [[Sourcemod|SourceMod]]. Viper is a program written in C++, which allows [[Sourcemod|SourceMod]] developers to code plug-ins with Python, instead of [[Sourcemod|SM]]'s native language, SourcePawn.&lt;br /&gt;
&lt;br /&gt;
The project took off the in IRC channel [irc://irc.gamesurge.net/sourcemod #sourcemod]. One of the members bet theY4Kman that he couldn't do it. However, Viper is being actively developed now.&lt;br /&gt;
&lt;br /&gt;
Originally, Viper was named &amp;quot;SMPython,&amp;quot; for &amp;quot;SourceMod Python.&amp;quot; To Zach, though, it seemed very generic. A week or so after the title &amp;quot;SMPython&amp;quot; was given, the project was renamed to &amp;quot;Viper.&amp;quot; The new name came from the [[Viperidae|snake family]] and the user &amp;quot;Viper,&amp;quot; who is an active member of [irc://irc.gamesurge.net/sourcemod #sourcemod].&lt;br /&gt;
&lt;br /&gt;
==Pronunciation==&lt;br /&gt;
'''theY4Kman''' means &amp;quot;the year 4000 man.&amp;quot; The simplification of &amp;quot;Year 4000&amp;quot; to '''Y4K''' was derived from &amp;quot;Y2K&amp;quot;, meaning &amp;quot;Year 2000&amp;quot;. Thus, '''Y4K''' is actually pronounced &amp;quot;Why Four Kay,&amp;quot; not &amp;quot;Yak.&amp;quot; This common mistake originates from the notion that frequent internet users speak [[Leet|Leetspeak]]. However, using &amp;quot;Yak&amp;quot; is accepted.&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(SourceMod_Scripting)&amp;diff=5631</id>
		<title>Optimizing Plugins (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(SourceMod_Scripting)&amp;diff=5631"/>
		<updated>2008-03-02T04:47:06Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* Stock */ Clarified &amp;quot;include&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
SourceMod is pretty fast, but there are some common assumptions about scripts:&lt;br /&gt;
*You can't possibly make it any faster.&lt;br /&gt;
*It's pre-compiled, so it's already quite fast.&lt;br /&gt;
*Details don't matter, as it's only &amp;quot;scripting&amp;quot; anyway.&lt;br /&gt;
&lt;br /&gt;
None of these are true.  The compiler, in fact, is very poor at optimizing, and the JIT is left to do most of the work.  You can '''greatly''' increase the speed and efficiency of your plugins by keeping a few rules in mind.  Remember - it's more important to minimize instructions than it is to minimize lines of code.&lt;br /&gt;
&lt;br /&gt;
Note that many of these optimizations should be taken in context.  An admin command probably doesn't need fine-tuned optimizations.  But a timer that executes every 0.1 seconds, or a GameFrame hook, should definitely be as fast as possible.&lt;br /&gt;
&lt;br /&gt;
=Always Save Results=&lt;br /&gt;
Observe the example code snippet below:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (GetClientTeam(player) == 3)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (GetClientTeam(player) == 2)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (GetClientTeam(player) == 1)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This is a mild example of &amp;quot;cache your results&amp;quot;.  When the compiler generates assembly for this code, it will (in pseudo code) generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Notice the problem?  We have called &amp;lt;tt&amp;gt;GetClientTeam&amp;lt;/tt&amp;gt; an extra two times than necessary.  The result doesn't change, so we can save it.  Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = GetClientTeam(player)&lt;br /&gt;
if (team == 3)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (team == 2)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (team == 1)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now, the compiler will only generate this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If &amp;lt;tt&amp;gt;GetClientTeam&amp;lt;/tt&amp;gt; were a more expensive operation (it's relatively cheap), we would have recalculated the entire result each branch of the &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case, wasting CPU cycles.&lt;br /&gt;
&lt;br /&gt;
Similarly, this type of code is usually not a good idea:&lt;br /&gt;
&amp;lt;pre&amp;gt;for (new i = 0; i &amp;lt; strlen(string); i++) ....&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Better code is:&lt;br /&gt;
&amp;lt;pre&amp;gt;new len = strlen(string);&lt;br /&gt;
for (new i = 0; i &amp;lt; len; i++)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, you may not want to put &amp;lt;tt&amp;gt;GetMaxClients()&amp;lt;/tt&amp;gt; in a loop about players.  While it is a very cheap function call, it incurs the cost of a native call, which might be significant in highly performance-sensitive code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Switch instead of If=&lt;br /&gt;
If you can, you should use &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; cases instead of &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;.  This is because for an &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; statement, the compiler must branch to each consecutive &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case.  Using the example from above, observe the switch version:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = GetClientTeam(player)&lt;br /&gt;
switch (team)&lt;br /&gt;
{&lt;br /&gt;
  case 3:&lt;br /&gt;
     //code...&lt;br /&gt;
  case 2:&lt;br /&gt;
     //code...&lt;br /&gt;
  case 1:&lt;br /&gt;
     //code...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will generate what's called a &amp;quot;case table&amp;quot;.  Rather than worm through displaced &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; tests, the compiler generates a table of possible values.  The JIT is smart enough to optimize this even further, and the best case is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  JUMP Table[CALL GetUserTeam]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your switch cases are listed in perfectly sequential order (that is, skipping no numbers, either ascending or descending), the JIT can make the best optimizations.  For example, &amp;quot;7,8,9&amp;quot; and &amp;quot;2,1,0&amp;quot; are examples of perfect switch cases.  &amp;quot;1,3,4&amp;quot; is not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Don't Re-index Arrays=&lt;br /&gt;
A common practice in Pawn is to &amp;quot;save space&amp;quot; by re-indexing arrays.  There are a few myths behind this, such as saving memory, assuming the compiler does it for you, or readability.  Fact: none of these are true.  Observe the code below.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;SomeFunction(const clients[], num_clients)&lt;br /&gt;
{&lt;br /&gt;
   for (new i = 0; i &amp;lt; num_clients; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (!IsClientInGame(clients[i]))&lt;br /&gt;
      {&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      SetSomething(clients[i], GetSomething(clients[i]) + 1);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For this, the compiler generates code similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   CALL IsClientInGame&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   CALL GetSomething&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL SetSomething&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See what happened?  The compiler does not cache array indexing.  Because we've used &amp;lt;tt&amp;gt;clients[i]&amp;lt;/tt&amp;gt; each time, every instance generates 4-6 (or more) instructions which load &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt;, the address of &amp;lt;tt&amp;gt;clients&amp;lt;/tt&amp;gt;, computes the final location, and then grabs the data out of memory.  It is much faster to do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;SomeFunction(const clients[], num_clients)&lt;br /&gt;
{&lt;br /&gt;
   new client;&lt;br /&gt;
   for (new i = 0; i &amp;lt; num_clients; i++)&lt;br /&gt;
   {&lt;br /&gt;
      client = clients[i];&lt;br /&gt;
      if (!IsClientInGame(client))&lt;br /&gt;
      {&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      SetSomething(client, GetSomething(client) + 1);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Not only is this more readable, but look at how much cruft we've shaved off the compiler's generated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   STORE client&lt;br /&gt;
   CALL IsClientInGame&lt;br /&gt;
   LOAD client&lt;br /&gt;
   CALL GetSomething&lt;br /&gt;
   LOAD client&lt;br /&gt;
   CALL SetSomething&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In a large loop you can drastically reduce codesize in this manner.&lt;br /&gt;
&lt;br /&gt;
=Decl on Local Arrays=&lt;br /&gt;
There is a small caveat to the 'new' statement in Pawn; it automatically writes a zero for every byte in the data structure.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:elephant[512];&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If placed inside local scope, all 512 bytes of the variable will be cleared every time the variable is created.  In a performance-sensitive callback, this could be disastrous.  Even something as innocuous as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new temp_players[MAX_PLAYERS];&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Could be a significant slow-down if called too often.  To solve this, SourceMod has a special replacement for &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; called &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; does not bother setting the entire array or structure to zero.  Thus, the data will be filled with random garbage.&lt;br /&gt;
&lt;br /&gt;
While this is much faster, you must be careful to initialize the data before you use it.  Observe the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:my_string[256];&lt;br /&gt;
&lt;br /&gt;
if (Something())&lt;br /&gt;
{&lt;br /&gt;
   Format(my_string, sizeof(my_string), &amp;quot;clam&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
PrintToChat(client, &amp;quot;%s&amp;quot;, my_string);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the bug?  If &amp;lt;tt&amp;gt;Something()&amp;lt;/tt&amp;gt; returned false, &amp;lt;tt&amp;gt;my_string&amp;lt;/tt&amp;gt; would still have garbage in it.  Thus, you must always take care and make sure that you might not accidentally be reading from uninitialized data.  Once that happens, you will get undefined behavior and possibly even crashes.&lt;br /&gt;
&lt;br /&gt;
A common practice is to short-initialize strings.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:my_string[256];&lt;br /&gt;
my_string[0] = '\0';&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This sets the first byte of the string to zero, which makes sure the string will be read as a valid, but empty, string.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; will work on any local variable type (array, string, float, integer, et cetera).  The one thing it cannot be used for is initialization.  This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl var = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid initializaton, such a line would have no meaning, and thus it is invalid syntax.  You must use &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; in order to do initialize:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new var = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Avoid Large KeyValues=&lt;br /&gt;
KeyValues is an n-ary structure using linked lists.  This type of structure is extremely expensive to allocate and traverse.  While it might be suitable for tiny pieces of information (that is, under 10KB of data or so), its complexity growth is very poor.&lt;br /&gt;
&lt;br /&gt;
If you load KeyValues data, you should make an effort to, at the very least, cache its Handle so you don't need to reparse the file every time.  Caching its contents on a needed basis would be a bonus as well.&lt;br /&gt;
&lt;br /&gt;
If you're trying to use a KeyValues file with thousands of entries and updating/loading it on events such as player connections or disconnections, you will find that the structure will grow to an unmanageably slow size.  If that's the case, you should consider moving to something like SQLite or MySQL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Use Stock/Public Correctly=&lt;br /&gt;
Using &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; correctly won't necessarily optimize your plugin, but they will help your code be more maintainable and will eliminate extra exports/data being written to your plugin file.&lt;br /&gt;
&lt;br /&gt;
==Stock==&lt;br /&gt;
A &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; function is compiled, but only written to the plugin's binary if it's used.  Generally, you should use the &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; keyword if:&lt;br /&gt;
*You may use the function in the future, and don't want the compiler telling you it's never used;&lt;br /&gt;
*You are writing an include file and don't want the function put in the binary if it's never used.&lt;br /&gt;
&lt;br /&gt;
==Public==&lt;br /&gt;
A &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; function is exported externally.  Every plugin binary has a list of all its &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; functions, and Core uses this table whenever it needs to find a matching &amp;lt;tt&amp;gt;forward&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Generally, there are only two reasons you should ever use &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;:&lt;br /&gt;
*You are implementing a &amp;lt;tt&amp;gt;forward&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*You are implementing a callback to another function, and it requires you to use &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It seems common for users to randomly add &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; to completely private functions -- not only is that unnecessary, but it only adds to the amount of work Core has to do to find functions in your plugin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
Although optimization is important, you should always keep context in mind.  Don't replace every single &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; in your plugin with &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; just because it might be faster.  Identify the areas of your plugin where optimization is significant, and tweak from there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(SourceMod_Scripting)&amp;diff=5630</id>
		<title>Optimizing Plugins (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(SourceMod_Scripting)&amp;diff=5630"/>
		<updated>2008-03-02T04:39:55Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* Decl on Local Arrays */ Uh, fuck. Forgot to close the &amp;lt;tt&amp;gt; tag&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
SourceMod is pretty fast, but there are some common assumptions about scripts:&lt;br /&gt;
*You can't possibly make it any faster.&lt;br /&gt;
*It's pre-compiled, so it's already quite fast.&lt;br /&gt;
*Details don't matter, as it's only &amp;quot;scripting&amp;quot; anyway.&lt;br /&gt;
&lt;br /&gt;
None of these are true.  The compiler, in fact, is very poor at optimizing, and the JIT is left to do most of the work.  You can '''greatly''' increase the speed and efficiency of your plugins by keeping a few rules in mind.  Remember - it's more important to minimize instructions than it is to minimize lines of code.&lt;br /&gt;
&lt;br /&gt;
Note that many of these optimizations should be taken in context.  An admin command probably doesn't need fine-tuned optimizations.  But a timer that executes every 0.1 seconds, or a GameFrame hook, should definitely be as fast as possible.&lt;br /&gt;
&lt;br /&gt;
=Always Save Results=&lt;br /&gt;
Observe the example code snippet below:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (GetClientTeam(player) == 3)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (GetClientTeam(player) == 2)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (GetClientTeam(player) == 1)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This is a mild example of &amp;quot;cache your results&amp;quot;.  When the compiler generates assembly for this code, it will (in pseudo code) generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Notice the problem?  We have called &amp;lt;tt&amp;gt;GetClientTeam&amp;lt;/tt&amp;gt; an extra two times than necessary.  The result doesn't change, so we can save it.  Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = GetClientTeam(player)&lt;br /&gt;
if (team == 3)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (team == 2)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (team == 1)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now, the compiler will only generate this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If &amp;lt;tt&amp;gt;GetClientTeam&amp;lt;/tt&amp;gt; were a more expensive operation (it's relatively cheap), we would have recalculated the entire result each branch of the &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case, wasting CPU cycles.&lt;br /&gt;
&lt;br /&gt;
Similarly, this type of code is usually not a good idea:&lt;br /&gt;
&amp;lt;pre&amp;gt;for (new i = 0; i &amp;lt; strlen(string); i++) ....&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Better code is:&lt;br /&gt;
&amp;lt;pre&amp;gt;new len = strlen(string);&lt;br /&gt;
for (new i = 0; i &amp;lt; len; i++)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, you may not want to put &amp;lt;tt&amp;gt;GetMaxClients()&amp;lt;/tt&amp;gt; in a loop about players.  While it is a very cheap function call, it incurs the cost of a native call, which might be significant in highly performance-sensitive code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Switch instead of If=&lt;br /&gt;
If you can, you should use &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; cases instead of &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;.  This is because for an &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; statement, the compiler must branch to each consecutive &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case.  Using the example from above, observe the switch version:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = GetClientTeam(player)&lt;br /&gt;
switch (team)&lt;br /&gt;
{&lt;br /&gt;
  case 3:&lt;br /&gt;
     //code...&lt;br /&gt;
  case 2:&lt;br /&gt;
     //code...&lt;br /&gt;
  case 1:&lt;br /&gt;
     //code...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will generate what's called a &amp;quot;case table&amp;quot;.  Rather than worm through displaced &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; tests, the compiler generates a table of possible values.  The JIT is smart enough to optimize this even further, and the best case is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  JUMP Table[CALL GetUserTeam]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your switch cases are listed in perfectly sequential order (that is, skipping no numbers, either ascending or descending), the JIT can make the best optimizations.  For example, &amp;quot;7,8,9&amp;quot; and &amp;quot;2,1,0&amp;quot; are examples of perfect switch cases.  &amp;quot;1,3,4&amp;quot; is not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Don't Re-index Arrays=&lt;br /&gt;
A common practice in Pawn is to &amp;quot;save space&amp;quot; by re-indexing arrays.  There are a few myths behind this, such as saving memory, assuming the compiler does it for you, or readability.  Fact: none of these are true.  Observe the code below.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;SomeFunction(const clients[], num_clients)&lt;br /&gt;
{&lt;br /&gt;
   for (new i = 0; i &amp;lt; num_clients; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (!IsClientInGame(clients[i]))&lt;br /&gt;
      {&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      SetSomething(clients[i], GetSomething(clients[i]) + 1);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For this, the compiler generates code similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   CALL IsClientInGame&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   CALL GetSomething&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL SetSomething&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See what happened?  The compiler does not cache array indexing.  Because we've used &amp;lt;tt&amp;gt;clients[i]&amp;lt;/tt&amp;gt; each time, every instance generates 4-6 (or more) instructions which load &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt;, the address of &amp;lt;tt&amp;gt;clients&amp;lt;/tt&amp;gt;, computes the final location, and then grabs the data out of memory.  It is much faster to do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;SomeFunction(const clients[], num_clients)&lt;br /&gt;
{&lt;br /&gt;
   new client;&lt;br /&gt;
   for (new i = 0; i &amp;lt; num_clients; i++)&lt;br /&gt;
   {&lt;br /&gt;
      client = clients[i];&lt;br /&gt;
      if (!IsClientInGame(client))&lt;br /&gt;
      {&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      SetSomething(client, GetSomething(client) + 1);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Not only is this more readable, but look at how much cruft we've shaved off the compiler's generated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   STORE client&lt;br /&gt;
   CALL IsClientInGame&lt;br /&gt;
   LOAD client&lt;br /&gt;
   CALL GetSomething&lt;br /&gt;
   LOAD client&lt;br /&gt;
   CALL SetSomething&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In a large loop you can drastically reduce codesize in this manner.&lt;br /&gt;
&lt;br /&gt;
=Decl on Local Arrays=&lt;br /&gt;
There is a small caveat to the 'new' statement in Pawn; it automatically writes a zero for every byte in the data structure.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:elephant[512];&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If placed inside local scope, all 512 bytes of the variable will be cleared every time the variable is created.  In a performance-sensitive callback, this could be disastrous.  Even something as innocuous as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new temp_players[MAX_PLAYERS];&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Could be a significant slow-down if called too often.  To solve this, SourceMod has a special replacement for &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; called &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; does not bother setting the entire array or structure to zero.  Thus, the data will be filled with random garbage.&lt;br /&gt;
&lt;br /&gt;
While this is much faster, you must be careful to initialize the data before you use it.  Observe the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:my_string[256];&lt;br /&gt;
&lt;br /&gt;
if (Something())&lt;br /&gt;
{&lt;br /&gt;
   Format(my_string, sizeof(my_string), &amp;quot;clam&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
PrintToChat(client, &amp;quot;%s&amp;quot;, my_string);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the bug?  If &amp;lt;tt&amp;gt;Something()&amp;lt;/tt&amp;gt; returned false, &amp;lt;tt&amp;gt;my_string&amp;lt;/tt&amp;gt; would still have garbage in it.  Thus, you must always take care and make sure that you might not accidentally be reading from uninitialized data.  Once that happens, you will get undefined behavior and possibly even crashes.&lt;br /&gt;
&lt;br /&gt;
A common practice is to short-initialize strings.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:my_string[256];&lt;br /&gt;
my_string[0] = '\0';&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This sets the first byte of the string to zero, which makes sure the string will be read as a valid, but empty, string.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; will work on any local variable type (array, string, float, integer, et cetera).  The one thing it cannot be used for is initialization.  This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl var = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid initializaton, such a line would have no meaning, and thus it is invalid syntax.  You must use &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; in order to do initialize:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new var = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Avoid Large KeyValues=&lt;br /&gt;
KeyValues is an n-ary structure using linked lists.  This type of structure is extremely expensive to allocate and traverse.  While it might be suitable for tiny pieces of information (that is, under 10KB of data or so), its complexity growth is very poor.&lt;br /&gt;
&lt;br /&gt;
If you load KeyValues data, you should make an effort to, at the very least, cache its Handle so you don't need to reparse the file every time.  Caching its contents on a needed basis would be a bonus as well.&lt;br /&gt;
&lt;br /&gt;
If you're trying to use a KeyValues file with thousands of entries and updating/loading it on events such as player connections or disconnections, you will find that the structure will grow to an unmanageably slow size.  If that's the case, you should consider moving to something like SQLite or MySQL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Use Stock/Public Correctly=&lt;br /&gt;
Using &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; correctly won't necessarily optimize your plugin, but they will help your code be more maintainable and will eliminate extra exports/data being written to your plugin file.&lt;br /&gt;
&lt;br /&gt;
==Stock==&lt;br /&gt;
A &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; function is compiled, but only written to the plugin's binary if it's used.  Generally, you should use the &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; keyword if:&lt;br /&gt;
*You may use the function in the future, and don't want the compiler telling you it's never used;&lt;br /&gt;
*You are writing an include file and don't want the function compiled if it's never used.&lt;br /&gt;
&lt;br /&gt;
==Public==&lt;br /&gt;
A &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; function is exported externally.  Every plugin binary has a list of all its &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; functions, and Core uses this table whenever it needs to find a matching &amp;lt;tt&amp;gt;forward&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Generally, there are only two reasons you should ever use &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;:&lt;br /&gt;
*You are implementing a &amp;lt;tt&amp;gt;forward&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*You are implementing a callback to another function, and it requires you to use &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It seems common for users to randomly add &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; to completely private functions -- not only is that unnecessary, but it only adds to the amount of work Core has to do to find functions in your plugin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
Although optimization is important, you should always keep context in mind.  Don't replace every single &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; in your plugin with &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; just because it might be faster.  Identify the areas of your plugin where optimization is significant, and tweak from there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(SourceMod_Scripting)&amp;diff=5629</id>
		<title>Optimizing Plugins (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(SourceMod_Scripting)&amp;diff=5629"/>
		<updated>2008-03-02T04:39:01Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* Decl on Local Arrays */ Edited for consistency of semicolons and clarification on intialization.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
SourceMod is pretty fast, but there are some common assumptions about scripts:&lt;br /&gt;
*You can't possibly make it any faster.&lt;br /&gt;
*It's pre-compiled, so it's already quite fast.&lt;br /&gt;
*Details don't matter, as it's only &amp;quot;scripting&amp;quot; anyway.&lt;br /&gt;
&lt;br /&gt;
None of these are true.  The compiler, in fact, is very poor at optimizing, and the JIT is left to do most of the work.  You can '''greatly''' increase the speed and efficiency of your plugins by keeping a few rules in mind.  Remember - it's more important to minimize instructions than it is to minimize lines of code.&lt;br /&gt;
&lt;br /&gt;
Note that many of these optimizations should be taken in context.  An admin command probably doesn't need fine-tuned optimizations.  But a timer that executes every 0.1 seconds, or a GameFrame hook, should definitely be as fast as possible.&lt;br /&gt;
&lt;br /&gt;
=Always Save Results=&lt;br /&gt;
Observe the example code snippet below:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (GetClientTeam(player) == 3)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (GetClientTeam(player) == 2)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (GetClientTeam(player) == 1)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This is a mild example of &amp;quot;cache your results&amp;quot;.  When the compiler generates assembly for this code, it will (in pseudo code) generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  CALL GetClientTeam&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Notice the problem?  We have called &amp;lt;tt&amp;gt;GetClientTeam&amp;lt;/tt&amp;gt; an extra two times than necessary.  The result doesn't change, so we can save it.  Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = GetClientTeam(player)&lt;br /&gt;
if (team == 3)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (team == 2)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&lt;br /&gt;
else if (team == 1)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now, the compiler will only generate this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
  COMPARE+JUMP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If &amp;lt;tt&amp;gt;GetClientTeam&amp;lt;/tt&amp;gt; were a more expensive operation (it's relatively cheap), we would have recalculated the entire result each branch of the &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case, wasting CPU cycles.&lt;br /&gt;
&lt;br /&gt;
Similarly, this type of code is usually not a good idea:&lt;br /&gt;
&amp;lt;pre&amp;gt;for (new i = 0; i &amp;lt; strlen(string); i++) ....&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Better code is:&lt;br /&gt;
&amp;lt;pre&amp;gt;new len = strlen(string);&lt;br /&gt;
for (new i = 0; i &amp;lt; len; i++)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, you may not want to put &amp;lt;tt&amp;gt;GetMaxClients()&amp;lt;/tt&amp;gt; in a loop about players.  While it is a very cheap function call, it incurs the cost of a native call, which might be significant in highly performance-sensitive code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Switch instead of If=&lt;br /&gt;
If you can, you should use &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; cases instead of &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;.  This is because for an &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; statement, the compiler must branch to each consecutive &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case.  Using the example from above, observe the switch version:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = GetClientTeam(player)&lt;br /&gt;
switch (team)&lt;br /&gt;
{&lt;br /&gt;
  case 3:&lt;br /&gt;
     //code...&lt;br /&gt;
  case 2:&lt;br /&gt;
     //code...&lt;br /&gt;
  case 1:&lt;br /&gt;
     //code...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will generate what's called a &amp;quot;case table&amp;quot;.  Rather than worm through displaced &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; tests, the compiler generates a table of possible values.  The JIT is smart enough to optimize this even further, and the best case is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  JUMP Table[CALL GetUserTeam]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your switch cases are listed in perfectly sequential order (that is, skipping no numbers, either ascending or descending), the JIT can make the best optimizations.  For example, &amp;quot;7,8,9&amp;quot; and &amp;quot;2,1,0&amp;quot; are examples of perfect switch cases.  &amp;quot;1,3,4&amp;quot; is not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Don't Re-index Arrays=&lt;br /&gt;
A common practice in Pawn is to &amp;quot;save space&amp;quot; by re-indexing arrays.  There are a few myths behind this, such as saving memory, assuming the compiler does it for you, or readability.  Fact: none of these are true.  Observe the code below.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;SomeFunction(const clients[], num_clients)&lt;br /&gt;
{&lt;br /&gt;
   for (new i = 0; i &amp;lt; num_clients; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (!IsClientInGame(clients[i]))&lt;br /&gt;
      {&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      SetSomething(clients[i], GetSomething(clients[i]) + 1);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For this, the compiler generates code similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   CALL IsClientInGame&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   CALL GetSomething&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL SetSomething&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See what happened?  The compiler does not cache array indexing.  Because we've used &amp;lt;tt&amp;gt;clients[i]&amp;lt;/tt&amp;gt; each time, every instance generates 4-6 (or more) instructions which load &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt;, the address of &amp;lt;tt&amp;gt;clients&amp;lt;/tt&amp;gt;, computes the final location, and then grabs the data out of memory.  It is much faster to do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;SomeFunction(const clients[], num_clients)&lt;br /&gt;
{&lt;br /&gt;
   new client;&lt;br /&gt;
   for (new i = 0; i &amp;lt; num_clients; i++)&lt;br /&gt;
   {&lt;br /&gt;
      client = clients[i];&lt;br /&gt;
      if (!IsClientInGame(client))&lt;br /&gt;
      {&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      SetSomething(client, GetSomething(client) + 1);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Not only is this more readable, but look at how much cruft we've shaved off the compiler's generated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD clients&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD clients[i]&lt;br /&gt;
   STORE client&lt;br /&gt;
   CALL IsClientInGame&lt;br /&gt;
   LOAD client&lt;br /&gt;
   CALL GetSomething&lt;br /&gt;
   LOAD client&lt;br /&gt;
   CALL SetSomething&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In a large loop you can drastically reduce codesize in this manner.&lt;br /&gt;
&lt;br /&gt;
=Decl on Local Arrays=&lt;br /&gt;
There is a small caveat to the 'new' statement in Pawn; it automatically writes a zero for every byte in the data structure.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:elephant[512];&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If placed inside local scope, all 512 bytes of the variable will be cleared every time the variable is created.  In a performance-sensitive callback, this could be disastrous.  Even something as innocuous as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new temp_players[MAX_PLAYERS];&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Could be a significant slow-down if called too often.  To solve this, SourceMod has a special replacement for &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; called &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;.  Unlike &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; does not bother setting the entire array or structure to zero.  Thus, the data will be filled with random garbage.&lt;br /&gt;
&lt;br /&gt;
While this is much faster, you must be careful to initialize the data before you use it.  Observe the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:my_string[256];&lt;br /&gt;
&lt;br /&gt;
if (Something())&lt;br /&gt;
{&lt;br /&gt;
   Format(my_string, sizeof(my_string), &amp;quot;clam&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
PrintToChat(client, &amp;quot;%s&amp;quot;, my_string);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice the bug?  If &amp;lt;tt&amp;gt;Something()&amp;lt;/tt&amp;gt; returned false, &amp;lt;tt&amp;gt;my_string&amp;lt;/tt&amp;gt; would still have garbage in it.  Thus, you must always take care and make sure that you might not accidentally be reading from uninitialized data.  Once that happens, you will get undefined behavior and possibly even crashes.&lt;br /&gt;
&lt;br /&gt;
A common practice is to short-initialize strings.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:my_string[256];&lt;br /&gt;
my_string[0] = '\0';&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This sets the first byte of the string to zero, which makes sure the string will be read as a valid, but empty, string.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; will work on any local variable type (array, string, float, integer, et cetera).  The one thing it cannot be used for is initialization.  This is invalid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl var = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid initializaton, such a line would have no meaning, and thus it is invalid syntax.  You must use &amp;lt;tt&amp;gt;new&amp;lt;tt&amp;gt; in order to do initialize:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new var = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Avoid Large KeyValues=&lt;br /&gt;
KeyValues is an n-ary structure using linked lists.  This type of structure is extremely expensive to allocate and traverse.  While it might be suitable for tiny pieces of information (that is, under 10KB of data or so), its complexity growth is very poor.&lt;br /&gt;
&lt;br /&gt;
If you load KeyValues data, you should make an effort to, at the very least, cache its Handle so you don't need to reparse the file every time.  Caching its contents on a needed basis would be a bonus as well.&lt;br /&gt;
&lt;br /&gt;
If you're trying to use a KeyValues file with thousands of entries and updating/loading it on events such as player connections or disconnections, you will find that the structure will grow to an unmanageably slow size.  If that's the case, you should consider moving to something like SQLite or MySQL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Use Stock/Public Correctly=&lt;br /&gt;
Using &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; correctly won't necessarily optimize your plugin, but they will help your code be more maintainable and will eliminate extra exports/data being written to your plugin file.&lt;br /&gt;
&lt;br /&gt;
==Stock==&lt;br /&gt;
A &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; function is compiled, but only written to the plugin's binary if it's used.  Generally, you should use the &amp;lt;tt&amp;gt;stock&amp;lt;/tt&amp;gt; keyword if:&lt;br /&gt;
*You may use the function in the future, and don't want the compiler telling you it's never used;&lt;br /&gt;
*You are writing an include file and don't want the function compiled if it's never used.&lt;br /&gt;
&lt;br /&gt;
==Public==&lt;br /&gt;
A &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; function is exported externally.  Every plugin binary has a list of all its &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; functions, and Core uses this table whenever it needs to find a matching &amp;lt;tt&amp;gt;forward&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Generally, there are only two reasons you should ever use &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;:&lt;br /&gt;
*You are implementing a &amp;lt;tt&amp;gt;forward&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*You are implementing a callback to another function, and it requires you to use &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It seems common for users to randomly add &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt; to completely private functions -- not only is that unnecessary, but it only adds to the amount of work Core has to do to find functions in your plugin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Conclusion=&lt;br /&gt;
Although optimization is important, you should always keep context in mind.  Don't replace every single &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; in your plugin with &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; just because it might be faster.  Identify the areas of your plugin where optimization is significant, and tweak from there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Handle_API_(SourceMod)&amp;diff=5581</id>
		<title>Handle API (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Handle_API_(SourceMod)&amp;diff=5581"/>
		<updated>2008-02-18T08:16:05Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: /* Reading/Checking Handles */ Changed &amp;quot;herr&amp;quot; to &amp;quot;err&amp;quot;. &amp;quot;herr&amp;quot; does not exist!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod [[Handles (SourceMod Scripting)|Handle System]] marshals pointers into typed, unique, 32-bit integers.  This makes coding in SourceMod more cross-platform compatible, type safe, and mistake safe than its predecessor, [[AMX Mod X]].  It also allows for safe object sharing and reference count based object destruction.&lt;br /&gt;
&lt;br /&gt;
The fundamental aspect of Handles is that they encapsulate a single pointer.  This pointer is private data, and can only be read by the Handle's creator.  When the Handle is freed, the pointer is automatically freed (via a special interface), thus ensuring that memory is not leaked.&lt;br /&gt;
&lt;br /&gt;
Handles also provide a simple &amp;quot;security&amp;quot; system for restricting which areas of SourceMod are allowed to directly call certain functions on Handles under a given type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Basic Types=&lt;br /&gt;
==Handle_t==&lt;br /&gt;
The &amp;lt;tt&amp;gt;Handle_t&amp;lt;/tt&amp;gt; type is a 32bit integer.  Currently, it is composed of two 16-bit integers, a serial number and a handle index.  The serial number is private and used for integrity checking.  The index is the internal ID of the Handle, which is tied to the encapsulated pointer and security information.&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;tt&amp;gt;Handle_t&amp;lt;/tt&amp;gt; is a unique Handle, however, there are ''cloned'' Handles which are copies of another Handle.  They have their own unique signatures, but they refer to another Handle internally.  Each Handle is also associated with a ''type'', explained below.&lt;br /&gt;
&lt;br /&gt;
==HandleType_t==&lt;br /&gt;
The &amp;lt;tt&amp;gt;HandleType_t&amp;lt;/tt&amp;gt; describes a type under which Handles can be created.  Types can have up to 15 sub-types; sub-types cannot have their own sub-types, called child types.  When Handles are being read, they are &amp;quot;type checked,&amp;quot; to make sure they are being read under a given type.  When a type is destroyed, all Handles under the type are destroyed.  If the type has child types, each child type is also destroyed. &lt;br /&gt;
&lt;br /&gt;
Handle types also allow overloading of various Handle operations.  Currently, the only overloaded action is for overloading when a Handle is destroyed.  This allows the encapsulated pointer to be safely destroyed by the type interface.  The interface which overloads type operations is called &amp;lt;tt&amp;gt;IHandleTypeDispatch&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Lastly, types provide a &amp;quot;default security&amp;quot; system which lets programmers restrict which functions can be accessed by other areas in SourceMod.  This is explained later.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
'''Note:''' Type defaults can be set via &amp;lt;tt&amp;gt;IHandleSys::InitAccessDefaults()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Type Security==&lt;br /&gt;
Often, extensions may want to share HandleType_t values with each other, so they can create Handles of external types.  However, the owner of the handle type may not want other extensions to perform certain actions.  Thus, types can be ''secured'' by an &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; when created.  Unless the same &amp;lt;tt&amp;gt;IdentityToken&amp;lt;/tt&amp;gt; is provided, a function may fail if restricted.&lt;br /&gt;
&lt;br /&gt;
Type permissions are declared in a &amp;lt;tt&amp;gt;TypeAccess&amp;lt;/tt&amp;gt; struct, which has the following user-set members:&lt;br /&gt;
*&amp;lt;tt&amp;gt;ident&amp;lt;/tt&amp;gt;: The &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; owner of this type.&lt;br /&gt;
*&amp;lt;tt&amp;gt;access&amp;lt;/tt&amp;gt;: An array where each index is a &amp;lt;tt&amp;gt;HTypeAccessRight&amp;lt;/tt&amp;gt; enumeration member.  If an index is set to false, functions requiring that right will fail unless the correct &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; is passed in.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;HTypeAccessRight&amp;lt;/tt&amp;gt; enumeration has the following values:&lt;br /&gt;
*&amp;lt;tt&amp;gt;HTypeAccess_Create&amp;lt;/tt&amp;gt;: Handle creation using this type; default is false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;HTypeAccess_Inherit&amp;lt;/tt&amp;gt;: Inheriting this type for child types; default is false.&lt;br /&gt;
&lt;br /&gt;
Below is a list of each Handle System function that requires type permissions, and which permissions may be required:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CreateType&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HTypeAccess_Inherit&amp;lt;/tt&amp;gt; if a parent is specified&amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;RemoveType&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;(none, always secured)&amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;CreateHandle&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HTypeAccess_Create&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handle Security==&lt;br /&gt;
Handle security permissions inherit from their parent type unless given an alternate set of permissions.  Handles are &amp;quot;secured&amp;quot; by two properties, unlike Handles, which just have one.  When verifying your identity with a secured Handle function, you must use the &amp;lt;tt&amp;gt;HandleSecurity&amp;lt;/tt&amp;gt; struct, which has two properties:&lt;br /&gt;
*&amp;lt;tt&amp;gt;pOwner&amp;lt;/tt&amp;gt;: The owner of the Handle, which is usually a plugin &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;pIdentity&amp;lt;/tt&amp;gt;: The owner of the Handle's type, or the &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; securing its type.&lt;br /&gt;
&lt;br /&gt;
Handle permissions are specified via the &amp;lt;tt&amp;gt;HandleAccess&amp;lt;/tt&amp;gt; struct.  It is passed either through &amp;lt;tt&amp;gt;CreateType&amp;lt;/tt&amp;gt; for default settings in a given type, or through &amp;lt;tt&amp;gt;CreateHandleEx&amp;lt;/tt&amp;gt; for explicit per-Handle permissions.  This struct has the following members:&lt;br /&gt;
*&amp;lt;tt&amp;gt;access&amp;lt;/tt&amp;gt;: An array where each index is a &amp;lt;tt&amp;gt;HandleAccessRight&amp;lt;/tt&amp;gt; enumeration member.  If set to 0, an access right is allowed without a &amp;lt;tt&amp;gt;HandleSecurity&amp;lt;/tt&amp;gt; instance.  Otherwise, the following bitwise flags are checked:&lt;br /&gt;
**&amp;lt;tt&amp;gt;HANDLE_RESTRICT_IDENTITY&amp;lt;/tt&amp;gt;: If flagged, this access right is only granted if the &amp;lt;tt&amp;gt;pIdentity&amp;lt;/tt&amp;gt; member of the &amp;lt;tt&amp;gt;HandleSecurity&amp;lt;/tt&amp;gt; struct matches the Handle's '''type's''' owner.&lt;br /&gt;
**&amp;lt;tt&amp;gt;HANDLE_RESTRICT_OWNER&amp;lt;/tt&amp;gt;: If flagged, this access right is onyl granted if the &amp;lt;tt&amp;gt;pOwner&amp;lt;/tt&amp;gt; member of the &amp;lt;tt&amp;gt;Handlesecurity&amp;lt;/tt&amp;gt; struct matches the Handle's owner.&lt;br /&gt;
&lt;br /&gt;
The following access rights exist for Handles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;HandleAccess_Read&amp;lt;/tt&amp;gt;: This Handle's encapsulated pointer can be retrieved.  Defaults to &amp;lt;tt&amp;gt;HANDLE_RESTRICT_IDENTITY&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;HandleAccess_Delete&amp;lt;/tt&amp;gt;: This Handle can be removed or freed.  Defaults to &amp;lt;tt&amp;gt;HANDLE_RESTRICT_OWNER&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;HandleAccess_Clone&amp;lt;/tt&amp;gt;: This Handle can be cloned.  Defaults to 0.&lt;br /&gt;
&lt;br /&gt;
Below is a list of each Handle system function that requires permissions, and which permissions may be required:&lt;br /&gt;
*&amp;lt;tt&amp;gt;FreeHandle&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HandleAccess_Delete&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloneHandle/CloneHandleEx&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HandleAccess_Clone&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;ReadHandle&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HandleAccess_Read&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SourceMod's generic native wrappers assume follow these rules, however, they assume certain access rights, and will return &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; or 0 if these rights are denied.  Thus, you should make sure your permissions are compatible, unless you explicitly want to deny usage of these functions.&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloneHandle()&amp;lt;/tt&amp;gt;: Passes &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;HandleSecurity&amp;lt;/tt&amp;gt;, meaning &amp;lt;tt&amp;gt;HandleAccess_Clone&amp;lt;/tt&amp;gt; must be 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt;: Passes &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;HandleSecurity::pIdentity&amp;lt;/tt&amp;gt;, and the plugin's &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;HandleSecurity::pOwner&amp;lt;/tt/&amp;gt;.  This means that at most, the only restriction can be &amp;lt;tt&amp;gt;HANDLE_RESTRICT_OWNER&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;HandleAccess_Delete&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Usage Examples=&lt;br /&gt;
Here are some examples of Handle usages.&lt;br /&gt;
&lt;br /&gt;
==Basic Handles==&lt;br /&gt;
The most basic use of Handles is to encapsulate a data structure and allow &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt; to universally destroy it.  Let's say we want to implement two natives - &amp;lt;tt&amp;gt;CreateFile&amp;lt;/tt&amp;gt; for creating an empty file, and &amp;lt;tt&amp;gt;WriteLine&amp;lt;/tt&amp;gt; for writing a line to this file.  How could we implement this using the Handle system?&lt;br /&gt;
&lt;br /&gt;
After reading this, it is tempting to think, &amp;quot;Why can't we just return the &amp;lt;tt&amp;gt;FILE&amp;lt;/tt&amp;gt; pointer as a &amp;lt;tt&amp;gt;cell_t&amp;lt;/tt&amp;gt;?&amp;quot;  The reason is that a &amp;lt;tt&amp;gt;cell_t&amp;lt;/tt&amp;gt; is guaranteed to be a 32bit integer.  There is no guarantee that a pointer will always be this size, however, and thus casting on future platforms could break.  This problem happened in [[AMX Mod X]] and greatly restricted flexibility.  &lt;br /&gt;
&lt;br /&gt;
===Creating the type===&lt;br /&gt;
First, we have to create the type and its Dispatch interface.&lt;br /&gt;
&amp;lt;cpp&amp;gt;HandleType_t g_FileType = 0;	/* Holds the HandleType ID */&lt;br /&gt;
&lt;br /&gt;
class FileTypeHandler : public IHandleTypeDispatch&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	void OnHandleDestroy(HandleType_t type, void *object)&lt;br /&gt;
	{&lt;br /&gt;
		/* :TODO: implement this */&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* Create an instance of the handler */&lt;br /&gt;
FileTypeHandler g_FileTypeHandler;&lt;br /&gt;
&lt;br /&gt;
Initialize()&lt;br /&gt;
{&lt;br /&gt;
	/* Register the type with default security permissions */&lt;br /&gt;
	g_FileType = g_pHandleSys-&amp;gt;CreateType(&amp;quot;File&amp;quot;, &lt;br /&gt;
		&amp;amp;g_FileTypeHandler, &lt;br /&gt;
		0, &lt;br /&gt;
		NULL, &lt;br /&gt;
		NULL, &lt;br /&gt;
		myself-&amp;gt;GetIdentity(), &lt;br /&gt;
		NULL);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Shutdown()&lt;br /&gt;
{&lt;br /&gt;
	/* Remove the type on shutdown */&lt;br /&gt;
	g_pHandleSys-&amp;gt;RemoveType(g_FileType, myself-&amp;gt;GetIdentity());&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating Handles===&lt;br /&gt;
Creating the Handles is fairly easy once we have a valid pointer to stuff in it.&lt;br /&gt;
&amp;lt;cpp&amp;gt;/* native CreateFile(const String:file[]) */&lt;br /&gt;
static cell_t sm_CreateFile(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	char path[PLATFORM_MAX_PATH];&lt;br /&gt;
	char *filename;&lt;br /&gt;
&lt;br /&gt;
	/* Get the filename */&lt;br /&gt;
	pContext-&amp;gt;LocalToString(params[1], &amp;amp;filename);&lt;br /&gt;
	/* Build a full path */&lt;br /&gt;
	g_pSM-&amp;gt;BuildPath(Path_SM, path, sizeof(path), &amp;quot;%s&amp;quot;, filename);&lt;br /&gt;
	&lt;br /&gt;
	/* Open for writing */&lt;br /&gt;
	FILE *fp = fopen(path, &amp;quot;wt&amp;quot;);&lt;br /&gt;
	if (!fp)&lt;br /&gt;
	{&lt;br /&gt;
		return BAD_HANDLE;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Create the Handle with our type, the FILE pointer, the plugin's identity, and our identity */&lt;br /&gt;
	return g_pHandleSys-&amp;gt;CreateHandle(g_FileType, &lt;br /&gt;
		fp, &lt;br /&gt;
		pContext-&amp;gt;GetIdentity(), &lt;br /&gt;
		myself-&amp;gt;GetIdentity(), &lt;br /&gt;
		NULL);&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Reading/Checking Handles===&lt;br /&gt;
Handles aren't very useful unless you have natives to use them.  Let's say we want to write lines of text to our File type.&lt;br /&gt;
&amp;lt;cpp&amp;gt;/* native WriteLine(Handle:hndl, const String:line[]); */&lt;br /&gt;
static cell_t sm_WriteLine(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	Handle_t hndl = static_cast&amp;lt;Handle_t&amp;gt;(params[1]);&lt;br /&gt;
	HandleError err;&lt;br /&gt;
	HandleSecurity sec;&lt;br /&gt;
&lt;br /&gt;
	/* Build our security descriptor */&lt;br /&gt;
	sec.pOwner = NULL;	/* Not needed, owner access is not checked */&lt;br /&gt;
	sec.pIdentity = myself-&amp;gt;GetIdentity();	/* But only this extension can read */&lt;br /&gt;
&lt;br /&gt;
	/* Attempt to read the given handle as our type, using our security info.&lt;br /&gt;
	 * Note that we read the pointer directly in with a little cast.&lt;br /&gt;
	 * This type of cast is safe since sizeof(void **) == sizeof(void *) == sizeof(T *) in almost all cases.&lt;br /&gt;
	 */&lt;br /&gt;
	FILE *fp;&lt;br /&gt;
	if ((err = g_pHandleSys-&amp;gt;ReadHandle(hndl, g_FileType, &amp;amp;sec, (void **)&amp;amp;fp))&lt;br /&gt;
	     != HandleError_None)&lt;br /&gt;
	{&lt;br /&gt;
		return pContext-&amp;gt;ThrowNativeError(&amp;quot;Invalid file handle %x (error %d)&amp;quot;, hndl, err);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Get the text */&lt;br /&gt;
	char *text;&lt;br /&gt;
	pContext-&amp;gt;LocalToString(params[2], &amp;amp;text);&lt;br /&gt;
&lt;br /&gt;
	/* Write it */&lt;br /&gt;
	fputs(text, fp);&lt;br /&gt;
&lt;br /&gt;
	return 1;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CloseHandle Support===&lt;br /&gt;
Lastly, we need to make it so &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;FreeHandle()&amp;lt;/tt&amp;gt; will close our file pointer when removing the Handle, which we skipped before.&lt;br /&gt;
&amp;lt;cpp&amp;gt;class FileTypeHandler : public IHandleTypeDispatch&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	void OnHandleDestroy(HandleType_t type, void *object)&lt;br /&gt;
	{&lt;br /&gt;
		fclose( (FILE *)object );&lt;br /&gt;
	}&lt;br /&gt;
};&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Restricting CloseHandle==&lt;br /&gt;
Let's say that, for various reasons, you don't want users to be able to call CloseHandle().  An example of this might be a data type that is non-temporary, or is being called from a forward, and thus should not be touched.  Or, you might have a special deconstructor that takes extra parameters, and thus you need a separate destroy function.&lt;br /&gt;
&lt;br /&gt;
For example, let's create a separate function called &amp;lt;tt&amp;gt;CloseFile&amp;lt;/tt&amp;gt;.  It doesn't do anything particularly special, but we are going to force its usage over CloseHandle().&lt;br /&gt;
&lt;br /&gt;
===New Security Rules===&lt;br /&gt;
&amp;lt;cpp&amp;gt;Initialize()&lt;br /&gt;
{&lt;br /&gt;
	/* Create default access rights */&lt;br /&gt;
	HandleAccess rules;&lt;br /&gt;
	g_pHandleSys-&amp;gt;InitAccessDefaults(NULL, &amp;amp;rules);&lt;br /&gt;
&lt;br /&gt;
	/* Restrict delete to only our identity */&lt;br /&gt;
	rules.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY;&lt;br /&gt;
&lt;br /&gt;
	/* Register the type with our security permissions */&lt;br /&gt;
	g_FileType = g_pHandleSys-&amp;gt;CreateType(&amp;quot;File&amp;quot;, &lt;br /&gt;
			&amp;amp;g_FileTypeHandler, &lt;br /&gt;
			0, &lt;br /&gt;
			NULL, &lt;br /&gt;
			&amp;amp;rules, &lt;br /&gt;
			myself-&amp;gt;GetIdentity(), &lt;br /&gt;
			NULL);&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Implementing the Native===&lt;br /&gt;
&amp;lt;cpp&amp;gt;/* native Closefile(Handle:hndl); */&lt;br /&gt;
static cell_t sm_CloseFile(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	Handle_t hndl = static_cast&amp;lt;Handle_t&amp;gt;(params[1]);&lt;br /&gt;
	HandleError err;&lt;br /&gt;
	HandleSecurity sec;&lt;br /&gt;
&lt;br /&gt;
	/* Build our security descriptor */&lt;br /&gt;
	sec.pOwner = pContext-&amp;gt;GetIdentity();	/* Needed, HANDLE_RESTRICT_OWNER is default */&lt;br /&gt;
	sec.pIdentity = myself-&amp;gt;GetIdentity();	/* But only this extension can read */&lt;br /&gt;
&lt;br /&gt;
	/* Attempt to read the given handle as our type, using our security info.&lt;br /&gt;
	 * Note that we read the pointer directly in with a little cast.&lt;br /&gt;
	 * This type of cast is safe since sizeof(void **) == sizeof(void *) == sizeof(T *) in almost all cases.&lt;br /&gt;
	 */&lt;br /&gt;
	FILE *fp;&lt;br /&gt;
	if ((herr = g_pHandleSys-&amp;gt;FreeHandle(hndl, &amp;amp;src))&lt;br /&gt;
	     != HandleError_None)&lt;br /&gt;
	{&lt;br /&gt;
		return pContext-&amp;gt;ThrowNativeError(&amp;quot;Invalid file handle %x (error %d)&amp;quot;, hndl, err);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 1;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Restricting CloseHandle Per-Handle==&lt;br /&gt;
Taking our above example, it is possible that we might want some Handles to be closed via CloseHandle(), but others not.  Again, this is useful if you wish to pass a Handle as read-only to a plugin, commonly done when using non-temporary structures or Handles used in Forwards.&lt;br /&gt;
&lt;br /&gt;
In this example, we'll create a global instance of our file type, and this instance will be denied access to CloseHandle(), whereas files returned by OpenFile() will not.&lt;br /&gt;
&lt;br /&gt;
===Implementation===&lt;br /&gt;
&amp;lt;cpp&amp;gt;Handle_t g_GlobalFile;&lt;br /&gt;
&lt;br /&gt;
Initialize()&lt;br /&gt;
{&lt;br /&gt;
	/* Register the type with default security permissions */&lt;br /&gt;
	g_FileType = g_pHandleSys-&amp;gt;CreateType(&amp;quot;File&amp;quot;, &lt;br /&gt;
			&amp;amp;g_FileTypeHandler, &lt;br /&gt;
			0, &lt;br /&gt;
			NULL, &lt;br /&gt;
			NULL, &lt;br /&gt;
			myself-&amp;gt;GetIdentity(), &lt;br /&gt;
			NULL);&lt;br /&gt;
&lt;br /&gt;
	/* Create our 'global' file */&lt;br /&gt;
	FILE *fp = tmpfile();&lt;br /&gt;
&lt;br /&gt;
	/* Set up the security descriptor */&lt;br /&gt;
	HandleSecurity sec;&lt;br /&gt;
	sec.pOwner = NULL;		/* No owner for this Handle */&lt;br /&gt;
	sec.pIdentity = myself-&amp;gt;GetIdentity();	/* Only this identity will be allowed */&lt;br /&gt;
&lt;br /&gt;
	/* Set up the access permissions */&lt;br /&gt;
	HandleAccess rules;&lt;br /&gt;
	g_pHandleSys-&amp;gt;InitAccessDefaults(NULL, &amp;amp;rules);&lt;br /&gt;
	rules.access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTITY;&lt;br /&gt;
&lt;br /&gt;
	/* Finally, create the Handle with our rules */&lt;br /&gt;
	g_GlobalFile = g_pHandleSys-&amp;gt;CreateHandleEx(g_FileType, fp, &amp;amp;sec, &amp;amp;rules, NULL);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Shutdown()&lt;br /&gt;
{&lt;br /&gt;
	/* Remove our global Handle (not needed, but we do it for clarity */&lt;br /&gt;
	HandleSecurity sec;&lt;br /&gt;
	sec.pOwner = NULL;&lt;br /&gt;
	sec.pIdentity = myself-&amp;gt;GetIdentity();&lt;br /&gt;
&lt;br /&gt;
	g_pHandleSys-&amp;gt;FreeHandle(g_GlobalFile, &amp;amp;sec);&lt;br /&gt;
&lt;br /&gt;
	/* Remove the type on shutdown */&lt;br /&gt;
	g_pHandleSys-&amp;gt;RemoveType(g_FileType, myself-&amp;gt;GetIdentity());&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Commands_(SourceMod_Scripting)&amp;diff=5495</id>
		<title>Commands (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Commands_(SourceMod_Scripting)&amp;diff=5495"/>
		<updated>2007-12-16T19:17:54Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[SourceMod]] allows you to create console commands similar to [[AMX Mod X]].  There are two main types of console commands:&lt;br /&gt;
*'''Server Commands''', which are fired from one of the following input methods:&lt;br /&gt;
**the server console itself;&lt;br /&gt;
**the remote console (RCON);&lt;br /&gt;
**the ServerCommand() function, either from SourceMod or the [[Half-Life 2]] engine.&lt;br /&gt;
*'''Console Commands''', which are fired from one of the following input methods:&lt;br /&gt;
**a client's console&lt;br /&gt;
**any of the server command input methods &lt;br /&gt;
&lt;br /&gt;
For server commands, there is no client index.  For console/client commands, there is a client index, but it may be 0 to indicate that the command is from the server.&lt;br /&gt;
&lt;br /&gt;
Note that button &amp;quot;commands,&amp;quot; such as +attack and +duck, are not actually console commands.  They are a separate command stream sent over the network, as they need to be tied to a specific frame.  &lt;br /&gt;
&lt;br /&gt;
=Server Commands=&lt;br /&gt;
As noted above, server commands are fired through the server console, whether remote, local, or through the Source engine.  There is no client index associated with a server command.  &lt;br /&gt;
&lt;br /&gt;
Server commands are registered through the &amp;lt;tt&amp;gt;RegServerCmd()&amp;lt;/tt&amp;gt; function, listed in &amp;lt;tt&amp;gt;console.inc&amp;lt;/tt&amp;gt;.  When registering a server command, you may be hooking an already existing command, and thus whether you return &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt; is important.  &lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;: The original server command will be processed, if there was one.  If the server command was created by a plugin, this has no effect.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;: The original server command will not be processed, if there was one.  If the server command was created by a plugin, this has no effect.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt;: This original server command will not be processed, if there was one.  Additionally, no further hooks will be called for this command until it is fired again.&lt;br /&gt;
&lt;br /&gt;
==Adding Server Commands==&lt;br /&gt;
Let's say we want to add a test command to show how Half-Life 2 breaks down command arguments.  A possible implementation might be:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegServerCmd(&amp;quot;test_command&amp;quot;, Command_Test)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Test(args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg[128]&lt;br /&gt;
	new String:full[256]&lt;br /&gt;
&lt;br /&gt;
	GetCmdArgString(full, sizeof(full))&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Argument string: %s&amp;quot;, full)&lt;br /&gt;
	PrintToServer(&amp;quot;Argument count: %d&amp;quot;, args)&lt;br /&gt;
	for (new i=1; i&amp;lt;=args; i++)&lt;br /&gt;
	{&lt;br /&gt;
		GetCmdArg(i, arg, sizeof(arg))&lt;br /&gt;
		PrintToServer(&amp;quot;Argument %d: %s&amp;quot;, i, arg)&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Blocking Server Commands==&lt;br /&gt;
Let's say we wanted to disable the &amp;quot;kickid&amp;quot; command on the server.  There's no real good reason to do this, but for example's sake:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegServerCmd(&amp;quot;kickid&amp;quot;, Command_KickId)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Kickid(args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Console Commands=&lt;br /&gt;
Unlike server commands, console commands can be triggered by either the server or the client, so the callback function receives a client index as well as the argument count.  If the server fired the command, the client index will be 0.  &lt;br /&gt;
&lt;br /&gt;
When returning the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; from the callback, the following effects will happen:&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;: The original functionality of the command (if any) will still be processed.  If there was no original functionality, the client will receive &amp;quot;Unknown command&amp;quot; in their console.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;: The original functionality of the command (if any) will be blocked.  If there was no functionality originally, this prevents clients from seeing &amp;quot;Unknown command&amp;quot; in their console.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt;: Same as &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;, except that this will be the last hook called.&lt;br /&gt;
&lt;br /&gt;
Note that, unlike AMX Mod X, SourceMod does not allow you to register command filters.  I.e., there is no equivalent to this notation:&lt;br /&gt;
&amp;lt;pawn&amp;gt;register_clcmd(&amp;quot;say /ff&amp;quot;, &amp;quot;Command_SayFF&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This notation was removed to make our internal code simpler and faster.  Writing the same functionality is easy, and demonstrated below.&lt;br /&gt;
&lt;br /&gt;
==Adding Commands==&lt;br /&gt;
Adding client commands is very simple.  Let's port our earlier testing command to display information about the client as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;test_command&amp;quot;, Command_Test)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Test(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg[128]&lt;br /&gt;
	new String:full[256]&lt;br /&gt;
&lt;br /&gt;
	GetCmdArgString(full, sizeof(full))&lt;br /&gt;
&lt;br /&gt;
	if (client)&lt;br /&gt;
	{&lt;br /&gt;
		new String:name[32]&lt;br /&gt;
		GetClientName(client, name, sizeof(name))&lt;br /&gt;
		PrintToServer(&amp;quot;Command from client: %s&amp;quot;, name);&lt;br /&gt;
	} else {&lt;br /&gt;
		PrintToServer(&amp;quot;Command from server.&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Argument string: %s&amp;quot;, full)&lt;br /&gt;
	PrintToServer(&amp;quot;Argument count: %d&amp;quot;, args)&lt;br /&gt;
	for (new i=1; i&amp;lt;=args; i++)&lt;br /&gt;
	{&lt;br /&gt;
		GetCmdArg(i, arg, sizeof(arg))&lt;br /&gt;
		PrintToServer(&amp;quot;Argument %d: %s&amp;quot;, i, arg)&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Hooking Commands==&lt;br /&gt;
A common example is hooking the say command.  Let's say we want to tell players whether FF is enabled when they say '/ff' in game.  &lt;br /&gt;
&lt;br /&gt;
Before we implement this, a common point of confusion with the 'say' command is that Half-Life 2 (and Half-Life 1), by default, send it with the text in one big quoted string.  This means if you say &amp;quot;I like hot dogs,&amp;quot; your command will be broken down as such:&lt;br /&gt;
*Argument string: &amp;quot;I like hot dogs&amp;quot;&lt;br /&gt;
*Argument count: 1&lt;br /&gt;
*Argument #1: I like hot dogs&lt;br /&gt;
&lt;br /&gt;
However, if a player types this in their console: &amp;lt;tt&amp;gt;say I like yams&amp;lt;/tt&amp;gt;, it will be broken up as:&lt;br /&gt;
*Argument string: I like yams&lt;br /&gt;
*Argument count: 3&lt;br /&gt;
*Argument #1: I&lt;br /&gt;
*Argument #2: like&lt;br /&gt;
*Argument #3: yams&lt;br /&gt;
&lt;br /&gt;
Thus, to take into account both of these situations, we are going to use &amp;lt;tt&amp;gt;GetCmdArgString&amp;lt;/tt&amp;gt; and manually parse the input.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;say&amp;quot;, Command_Say)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Say(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:text[192]&lt;br /&gt;
	GetCmdArgString(text, sizeof(text))&lt;br /&gt;
&lt;br /&gt;
	new startidx = 0&lt;br /&gt;
	if (text[0] == '&amp;quot;')&lt;br /&gt;
	{&lt;br /&gt;
		startidx = 1&lt;br /&gt;
		/* Strip the ending quote, if there is one */&lt;br /&gt;
		new len = strlen(text);&lt;br /&gt;
		if (text[len-1] == '&amp;quot;')&lt;br /&gt;
		{&lt;br /&gt;
			text[len-1] = '\0'&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (StrEqual(text[startidx], &amp;quot;/ff&amp;quot;))&lt;br /&gt;
	{&lt;br /&gt;
		new Handle:ff = FindConVar(&amp;quot;mp_friendlyfire&amp;quot;)&lt;br /&gt;
		if (GetConVarInt(ff))&lt;br /&gt;
		{&lt;br /&gt;
			PrintToConsole(client, &amp;quot;Friendly fire is enabled.&amp;quot;)&lt;br /&gt;
		} else {&lt;br /&gt;
			PrintToConsole(client, &amp;quot;Friendly fire is disabled.&amp;quot;)&lt;br /&gt;
		}&lt;br /&gt;
		/* Block the client's messsage from broadcasting */&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Let say continue normally */&lt;br /&gt;
	return Plugin_Continue&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating Admin Commands==&lt;br /&gt;
Let's create a simple admin command which kicks another player by their full name.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;admin_kick&amp;quot;,&lt;br /&gt;
		Command_Kick,&lt;br /&gt;
		ADMFLAG_KICK,&lt;br /&gt;
		&amp;quot;Kicks a player by name&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Kick(client, args)&lt;br /&gt;
{&lt;br /&gt;
	if (args &amp;lt; 1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Usage: admin_kick &amp;lt;name&amp;gt;&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	new String:name[32], maxplayers, target = -1&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	maxplayers = GetMaxClients()&lt;br /&gt;
	for (new i=1; i&amp;lt;=maxplayers; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (!IsClientConnected(i))&lt;br /&gt;
		{&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		decl String:other[32]&lt;br /&gt;
		GetClientName(i, other, sizeof(other))&lt;br /&gt;
		if (StrEqual(name, other))&lt;br /&gt;
		{&lt;br /&gt;
			target = i&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Could not find any player with the name: \&amp;quot;%s\&amp;quot;&amp;quot;, name)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ServerCommand(&amp;quot;kickid %d&amp;quot;, GetClientUserId(target));&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Immunity==&lt;br /&gt;
In our previous example, we did not take immunity into account.  Immunity is a much more complex system in SourceMod than it was in AMX Mod X, and there is no simple flag to denote its permissions.  Instead, two functions are provided:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CanAdminTarget&amp;lt;/tt&amp;gt;: Tests raw AdminId values for immunity.&lt;br /&gt;
*&amp;lt;tt&amp;gt;CanUserTarget&amp;lt;/tt&amp;gt;: Tests in-game clients for immunity.&lt;br /&gt;
&lt;br /&gt;
While immunity is generally tested ''player versus player'', it is possible you might want to check for immunity and not have a targetting client.  While there is no convenience function for this yet, a good idea might be to check for either ''default'' or ''global'' immunity on the player's groups (these can be user-defined for non-player targeted scenarios).&lt;br /&gt;
&lt;br /&gt;
When checking for immunity, the following heuristics are performed in this exact order:&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;If the targeting AdminId is &amp;lt;tt&amp;gt;INVALID_ADMIN_ID&amp;lt;/tt&amp;gt;, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted AdminId is &amp;lt;tt&amp;gt;INVALID_ADMIN_ID&amp;lt;/tt&amp;gt;, targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targeting admin has &amp;lt;tt&amp;gt;Admin_Root&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;ADMFLAG_ROOT&amp;lt;/tt&amp;gt;), targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has global immunity, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has default immunity, and the targeting admin belongs to no groups, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has specific immunity from the targeting admin via group immunities, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If no conclusion is reached via the previous steps, targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, how can we adapt our function about to use immunity?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_Kick(client, args)&lt;br /&gt;
{&lt;br /&gt;
	if (args &amp;lt; 1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Usage: admin_kick &amp;lt;name&amp;gt;&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	new String:name[32], maxplayers, target = -1&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	maxplayers = GetMaxClients()&lt;br /&gt;
	for (new i=1; i&amp;lt;=maxplayers; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (!IsClientConnected(i))&lt;br /&gt;
		{&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		decl String:other[32]&lt;br /&gt;
		GetClientName(i, other, sizeof(other))&lt;br /&gt;
		if (StrEqual(name, other))&lt;br /&gt;
		{&lt;br /&gt;
			target = i&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Could not find any player with the name: \&amp;quot;%s\&amp;quot;&amp;quot;, name)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (!CanUserTarget(client, target))&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;You cannot target this client.&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ServerCommand(&amp;quot;kickid %d&amp;quot;, GetClientUserId(target))&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Client-Only Commands=&lt;br /&gt;
SourceMod exposes a forward that is called whenever a client executes any command string in their console, called &amp;lt;tt&amp;gt;OnClientCommand&amp;lt;/tt&amp;gt;.  An example of this looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:OnClientCommand(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:cmd[16]&lt;br /&gt;
	GetCmdArg(0, cmd, sizeof(cmd));	/* Get command name */&lt;br /&gt;
&lt;br /&gt;
	if (StrEqual(cmd, &amp;quot;test_command&amp;quot;))&lt;br /&gt;
	{&lt;br /&gt;
		/* Got the client command! Block it... */&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that not everything a client sends will be available through this command.  Command registered via external sources in C++ may not be available, especially if they are created via &amp;lt;tt&amp;gt;CON_COMMAND&amp;lt;/tt&amp;gt; in the game mod itself.  For example, &amp;quot;say&amp;quot; is usually implemented this way, because it can be used by both clients and the server, and thus it does not channel through this forward.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Chat Triggers=&lt;br /&gt;
SourceMod will automatically create chat triggers for every command you make (as of revision 900).  For example, if you create a console command called &amp;quot;sm_megaslap,&amp;quot; administrators will be able to type any of the following commands in &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;say_team&amp;lt;/tt&amp;gt; message modes:&lt;br /&gt;
&amp;lt;pre&amp;gt;!sm_megaslap&lt;br /&gt;
!megaslap&lt;br /&gt;
/sm_megaslap&lt;br /&gt;
/megaslap&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SourceMod then executes this command and its arguments as if it came from the client console.&lt;br /&gt;
*&amp;quot;&amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt;&amp;quot; is the default ''public'' trigger (&amp;lt;tt&amp;gt;PublicChatTrigger&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;configs/core.cfg&amp;lt;/tt&amp;gt;) and your entry will be displayed to all clients as normal.&lt;br /&gt;
*&amp;quot;&amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;&amp;quot; is the default ''silent'' trigger (&amp;lt;tt&amp;gt;SilentChatTrigger&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;configs/core.cfg&amp;lt;/tt&amp;gt;) and your entry will be blocked from being displayed.&lt;br /&gt;
&lt;br /&gt;
SourceMod will only execute commands registered with &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;RegAdminCmd&amp;lt;/tt&amp;gt;, and only if those commands are not already provided by Half-Life 2 or the game mod.  If the command is prefixed with &amp;quot;sm_&amp;quot; then the &amp;quot;sm_&amp;quot; can be omitted from the chat trigger.&lt;br /&gt;
&lt;br /&gt;
Console commands which wish to support usage as a chat trigger should not use &amp;lt;tt&amp;gt;PrintTo*&amp;lt;/tt&amp;gt; natives.  Instead, they should use &amp;lt;tt&amp;gt;ReplyToCommand()&amp;lt;/tt&amp;gt;, which will automatically print your message either as a chat message or to the client's console, depending on the source of the command.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Menu_API_(SourceMod)&amp;diff=4778</id>
		<title>Menu API (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Menu_API_(SourceMod)&amp;diff=4778"/>
		<updated>2007-06-12T18:04:54Z</updated>

		<summary type="html">&lt;p&gt;TheY4Kman: Fixed a few typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod has an extensive API for building and displaying menus to clients.  Unlike AMX Mod X, this API is highly state driven.  Menus are based on callbacks which are guaranteed to be fired.&lt;br /&gt;
&lt;br /&gt;
For C++, the Menu API can be found in &amp;lt;tt&amp;gt;public/IMenuManager.h&amp;lt;/tt&amp;gt;.  For SourcePawn, it is in &amp;lt;tt&amp;gt;plugins/include/menus.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Objects=&lt;br /&gt;
The SourceMod Menu System is based on an object oriented hierarchy.  Understanding this hierarchy, even for scripting, is critical to using menus effectively.&lt;br /&gt;
&lt;br /&gt;
==Styles==&lt;br /&gt;
The top level object is a ''MenuStyle'' (&amp;lt;tt&amp;gt;IMenuStyle&amp;lt;/tt&amp;gt; in C++).  Styles describe a unique menu system.  There are two such styles built into SourceMod:&lt;br /&gt;
*Valve Style, also called &amp;quot;ESC&amp;quot; menus; 8 items per page, no raw/disabled text can be rendered&lt;br /&gt;
*Radio Style, also called &amp;quot;AMX&amp;quot; menus; 10 items per page, raw/disabled text can be rendered&lt;br /&gt;
&lt;br /&gt;
Each MenuStyle has its own rules and properties.  You can think of them as existing on separate &amp;quot;channels.&amp;quot;  For example, two different menus can exist on a player's screen as both a Valve menu and a Radio menu at the same time, and SourceMod will be able to manage both without any problems.  This is because each style keeps track of its own menus separately.&lt;br /&gt;
&lt;br /&gt;
==Panels==&lt;br /&gt;
Menu displays are drawn with a lower level interface called ''Panels'' (&amp;lt;tt&amp;gt;IMenuPanel&amp;lt;/tt&amp;gt; in C++).  Panels describe exactly one chunk of display text.  Both selectable items and raw text can be added to a panel as long as its parent style supports the contents you're trying to draw.  For example, the Valve style does not support drawing raw text or disabled items.  But with a Radio-style Panel, you can display a large amount of on-screen data in your own format.&lt;br /&gt;
&lt;br /&gt;
Panels are considered temporary objects.  They are created, rendered, displayed, and destroyed.  Although they can be saved indefinitely, it is not necessary to do so.&lt;br /&gt;
&lt;br /&gt;
Valve Style drawing rules/limitations:&lt;br /&gt;
*Max items per page is 8.&lt;br /&gt;
*Disabled items cannot be drawn.&lt;br /&gt;
*Raw text cannot be drawn.&lt;br /&gt;
*Spacers do not add a space/newline, giving a &amp;quot;cramped&amp;quot; feel.&lt;br /&gt;
*Users must press &amp;quot;ESC&amp;quot; or be at their console to view the menu.&lt;br /&gt;
&lt;br /&gt;
Radio Style drawing rules/limitations:&lt;br /&gt;
*Max items per page is 10.&lt;br /&gt;
*Titles appear white; items appear yellow, unless disabled, in which case they are white.&lt;br /&gt;
*The 0th item is always white.  For consistency, this means navigational controls explained in the next section are always white, and simply not drawn if disabled.&lt;br /&gt;
&lt;br /&gt;
==Menus==&lt;br /&gt;
Lastly, there are plain ''Menus'' (&amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; in C++).  These are helper objects designed for storing a menu based on selectable items.  Unlike low-level panels, menus are containers for '''items''', and can only contain items which are selectable (i.e., do not contain raw text).  They fall into two categories:&lt;br /&gt;
*Non-paginated: The menu can only have a certain number of items on it, and no control/navigation options will be added, except for an &amp;quot;Exit&amp;quot; button which will always be in the last position supported by the style.&lt;br /&gt;
**Valve Style maximum items: 8&lt;br /&gt;
**Radio Style maximum items: 10&lt;br /&gt;
*Paginated: The menu can have any number of items.  When displayed, only a certain number of items will be drawn at a time.  Automatic navigation controls are added so players can easily move back and forth to different &amp;quot;pages&amp;quot; of items in the menu.&lt;br /&gt;
**&amp;quot;Previous&amp;quot; is always drawn as the first navigation item, third from the last supported position.  This will not be drawn if the menu only contains one page.  If there are no previous pages, the text will not be drawn on either style; if possible, the menu will be padded so spacing is consistent.&lt;br /&gt;
***Valve Style position: 6&lt;br /&gt;
***Radio Style position: 8&lt;br /&gt;
**&amp;quot;Next&amp;quot; is always drawn as the second navigation item, second from the last supported position.  This will not be drawn if the menu only contains one page.  If there are no further pages, the text will not be drawn on either style; if possible, the menu will be padded so spacing is consistent.&lt;br /&gt;
***Valve Style position: 7&lt;br /&gt;
***Radio Style position: 9&lt;br /&gt;
**&amp;quot;Exit&amp;quot; is drawn if the menu has the exit button property set.  It is always the last supported item position.&lt;br /&gt;
***Valve Style position: 8&lt;br /&gt;
***Radio Style position: 10&lt;br /&gt;
&lt;br /&gt;
The purpose of Menus is to simplify the procedure of storing, drawing, and calculating the selection of items.  Thus, menus do not allow for adding raw text, as that would considerably complicate the drawing algorithm.  ''Note: The C++ API supports hooking &amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; drawing procedures and adding raw text; this will be added to the scripting API soon.''&lt;br /&gt;
&lt;br /&gt;
Internally, Menus are drawn via a ''RenderMenu'' algorithm.  This algorithm creates a temporary panel and fills it with items from menus.  This panel is then displayed to a client.  The algorithm attempts to create a consistent feel across all menus, and across all styles.  Thus any menu displayed via the &amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; class, or &amp;lt;tt&amp;gt;Menu&amp;lt;/tt&amp;gt; Handles, will look and act the same, and the Menu API is based off the Panel API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Callbacks=&lt;br /&gt;
==Overview==&lt;br /&gt;
Menus are a callback based system.  Each callback represents an action that occurs during a ''menu display cycle''.  A cycle consists of a number of notifications:&lt;br /&gt;
*Start notification.&lt;br /&gt;
**Display notification if the menu can be displayed to the client.&lt;br /&gt;
**Either an item select or menu cancel notification.&lt;br /&gt;
*End notification.&lt;br /&gt;
&lt;br /&gt;
Since ''End'' signifies the end of a full display cycle, it is usually used to destroy temporary menus.&lt;br /&gt;
&lt;br /&gt;
==Specification==&lt;br /&gt;
A detailed explanation of these events is below.  For C++, an &amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; pointer is always available.  For SourcePawn, a &amp;lt;tt&amp;gt;Menu&amp;lt;/tt&amp;gt; Handle and a &amp;lt;tt&amp;gt;MenuAction&amp;lt;/tt&amp;gt; are always set in the &amp;lt;tt&amp;gt;MenuHandler&amp;lt;/tt&amp;gt; callback.  Unlike C++, the SourcePawn API allows certain actions to only be called if they are requested at menu creation time.  This is an optimization.  However, certain actions cannot be prevented from being called.&lt;br /&gt;
&lt;br /&gt;
*'''Start'''.  The menu has been acknowledged.  This does not mean it will be displayed; however, it guarantees that &amp;quot;OnMenuEnd&amp;quot; will be called.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuStart()&amp;lt;/tt&amp;gt; in C++.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Start&amp;lt;/tt&amp;gt; in SourcePawn.  This action is not triggered unless requested.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: Ignored (always 0).&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: Ignored (always 0).&lt;br /&gt;
*'''Display'''.  The menu is being displayed to a client.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuDisplay()&amp;lt;/tt&amp;gt; in C++.  An &amp;lt;tt&amp;gt;IMenuPanel&amp;lt;/tt&amp;gt; pointer and client index are available.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Display&amp;lt;/tt&amp;gt; in SourcePawn.  This action is not triggered unless requested.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: A Handle to a menu panel.&lt;br /&gt;
*'''Select'''.  An item on the menu has been selected.  The item position given will be the position in the menu, rather than the key pressed (unless the menu is a raw panel).  &lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuSelect()&amp;lt;/tt&amp;gt; in C++.  A client index and item position are passed.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Select&amp;lt;/tt&amp;gt; in SourcePawn.  This action is always triggerable, whether requested or not.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: An item position.&lt;br /&gt;
*'''Cancel'''.  The menu's display to one client has been cancelled.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuCancel()&amp;lt;/tt&amp;gt; in C++.  A reason for cancellation is provided.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Cancel&amp;lt;/tt&amp;gt; in SourcePawn.  This action is always triggerable, whether requested or not.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: A menu cancellation reason code.&lt;br /&gt;
*'''End'''.  The menu's display cycle has finished; this means that the &amp;quot;Start&amp;quot; action has occurred, and either &amp;quot;Select&amp;quot; or &amp;quot;Cancel&amp;quot; has occurred thereafter.  This is typically where menu resources are removed/deleted.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuEnd()&amp;lt;/tt&amp;gt; in C++.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt; in SourcePawn.  This action is always triggered, whether requested or not.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: Ignored (always 0).&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: Ignored (always 0).&lt;br /&gt;
&lt;br /&gt;
==Panels==&lt;br /&gt;
For panels, the callback rules change.  Panels only receive two of the above callbacks, and it is guaranteed that only one of them will be called for a given display cycle.  For C++, the &amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; pointer will always be &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;.  For SourcePawn, the menu Handle will always be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
*'''Select'''.  A key has been pressed.  This can be any number and should not be considered as reliably in bounds.  For example, even if you only had 2 items in your panel, a client could trigger a key press of &amp;quot;43.&amp;quot;&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuSelect()&amp;lt;/tt&amp;gt; in C++.  A client index and key number pressed are passed.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Select&amp;lt;/tt&amp;gt; in SourcePawn.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: Number of the key pressed.&lt;br /&gt;
*'''Cancel'''.  The menu's display to one client has been cancelled.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuCancel()&amp;lt;/tt&amp;gt; in C++.  A reason for cancellation is provided.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Cancel&amp;lt;/tt&amp;gt; in SourcePawn.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: A menu cancellation reason code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Examples=&lt;br /&gt;
First, let's start off with a very basic menu.  We want the menu to look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Do you like apples?&lt;br /&gt;
1. Yes&lt;br /&gt;
2. No&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We'll draw this menu with both a basic Menu and a Panel to show the API differences.&lt;br /&gt;
&lt;br /&gt;
==Basic Menu==&lt;br /&gt;
First, let's write our example using the Menu building API.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public MenuHandler1(Handle:menu, MenuAction:action, param1, param2)&lt;br /&gt;
{&lt;br /&gt;
	/* Either Select or Cancel will ALWAYS be sent! */&lt;br /&gt;
	if (action == MenuAction_Select)&lt;br /&gt;
	{&lt;br /&gt;
		new String:info[32]&lt;br /&gt;
		new bool:found = GetMenuItem(menu, param2, info, sizeof(info))&lt;br /&gt;
		PrintToConsole(param1, &amp;quot;You selected item: %d (found? %d info: %s)&amp;quot;, param2, found, info)&lt;br /&gt;
	} else if (action == MenuAction_Cancel) {&lt;br /&gt;
		PrintToServer(&amp;quot;Client %d's menu was cancelled.  Reason: %d&amp;quot;, param1, param2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* If the menu has ended, destroy it */&lt;br /&gt;
	if (action == MenuAction_End)&lt;br /&gt;
	{&lt;br /&gt;
		CloseHandle(menu)&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Menu_Test1(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new Handle:menu = CreateMenu(MenuHandler1)&lt;br /&gt;
	SetMenuTitle(menu, &amp;quot;Do you like apples?&amp;quot;)&lt;br /&gt;
	AddMenuItem(menu, &amp;quot;yes&amp;quot;, &amp;quot;Yes&amp;quot;)&lt;br /&gt;
	AddMenuItem(menu, &amp;quot;no&amp;quot;, &amp;quot;No&amp;quot;)&lt;br /&gt;
	SetMenuExitButton(menu, false)&lt;br /&gt;
	DisplayMenu(menu, 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;
Note a few very important points from this example:&lt;br /&gt;
*One of either &amp;lt;tt&amp;gt;Select&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;Cancel&amp;lt;/tt&amp;gt; will always be sent to the action handler.&lt;br /&gt;
*&amp;lt;tt&amp;gt;End&amp;lt;/tt&amp;gt; will always be sent to the action handler.&lt;br /&gt;
*We destroy our Menu in the &amp;lt;tt&amp;gt;End&amp;lt;/tt&amp;gt; action, because our Handle is no longer needed.  If we had destroyed the Menu after &amp;lt;tt&amp;gt;DisplayMenu&amp;lt;/tt&amp;gt;, it would have canceled the menu's display to the client.&lt;br /&gt;
*Menus, by default, have an exit button.  We disabled this in our example.&lt;br /&gt;
*Our menu is set to display for 20 seconds.  That means that if the client does not select an item within 20 seconds, the menu will be canceled.  This is usually desired for menus that are for voting.  Note that unlike AMX Mod X, you do not need to set a timer to make sure the menu will be ended.&lt;br /&gt;
*Although we created and destroyed a new Menu Handle, we didn't need to.  It is perfectly acceptable to create the Handle once for the lifetime of the plugin.&lt;br /&gt;
&lt;br /&gt;
Our finished menu and attached console output looks like this (I selected &amp;quot;Yes&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
[[Image:Basic_menu_1.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Basic Panel==&lt;br /&gt;
Now, let's rewrite our example to use Panels instead.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;panel_test1&amp;quot;, Panel_Test1)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public PanelHandler1(Handle:menu, MenuAction:action, param1, param2)&lt;br /&gt;
{&lt;br /&gt;
	if (action == MenuAction_Select)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(param1, &amp;quot;You selected item: %d&amp;quot;, param2)&lt;br /&gt;
	} else if (action == MenuAction_Cancel) {&lt;br /&gt;
		PrintToServer(&amp;quot;Client %d's menu was cancelled.  Reason: %d&amp;quot;, param1, param2)&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Panel_Test1(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new Handle:panel = CreatePanel();&lt;br /&gt;
	SetPanelTitle(panel, &amp;quot;Do you like apples?&amp;quot;)&lt;br /&gt;
	DrawPanelItem(panel, &amp;quot;Yes&amp;quot;)&lt;br /&gt;
	DrawPanelItem(panel, &amp;quot;No&amp;quot;)&lt;br /&gt;
		&lt;br /&gt;
	SendPanelToClient(panel, client, PanelHandler1, 20)&lt;br /&gt;
&lt;br /&gt;
	CloseHandle(panel)&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, Panels are significantly different.&lt;br /&gt;
*We can destroy the Panel as soon as we're done displaying it.  We can create the Panel once and keep re-using it, but we can destroy it at any time without interrupting client menus.&lt;br /&gt;
*The Handler function gets much less data.  Since panels are designed as a raw display, no &amp;quot;item&amp;quot; information is saved internally.  Thus, the handler function only knows whether the display was canceled or whether (and what) numerical key was pressed.&lt;br /&gt;
*There is no automation.  You cannot add more than a certain amount of selectable items to a Panel and get pagination.  Automated control functionality requires using the heftier Menu object API.&lt;br /&gt;
&lt;br /&gt;
Our finished display and console output looks like this (I selected &amp;quot;Yes&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
[[Image:Basic_panel_1.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Basic Paginated Menu==&lt;br /&gt;
Now, let's take a more advanced example -- pagination. Let's say we want to build a menu for changing the map.  An easy way to do this is to read the &amp;lt;tt&amp;gt;maplist.txt&amp;lt;/tt&amp;gt; file at the start of a plugin and build a menu out of it.&lt;br /&gt;
&lt;br /&gt;
Since reading and parsing a file is an expensive operation, we only want to do this once per map.  Thus we'll build the menu in &amp;lt;tt&amp;gt;OnMapStart&amp;lt;/tt&amp;gt;, and we won't call &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt; until &amp;lt;tt&amp;gt;OnMapEnd&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Source code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:g_MapMenu = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_changemap&amp;quot;, Command_ChangeMap)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnMapStart()&lt;br /&gt;
{&lt;br /&gt;
	g_MapMenu = BuildMapMenu()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnMapEnd()&lt;br /&gt;
{&lt;br /&gt;
	if (g_MapMenu != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		CloseHandle(g_MapMenu)&lt;br /&gt;
		g_MapMenu = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Handle:BuildMapMenu()&lt;br /&gt;
{&lt;br /&gt;
	/* Open the file */&lt;br /&gt;
	new Handle:file = OpenFile(&amp;quot;maplist.txt&amp;quot;, &amp;quot;rt&amp;quot;)&lt;br /&gt;
	if (file == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		return INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/* Create the menu Handle */&lt;br /&gt;
	new Handle:menu = CreateMenu(Menu_ChangeMap);&lt;br /&gt;
	new String:mapname[255]&lt;br /&gt;
	while (!IsEndOfFile(file) &amp;amp;&amp;amp; ReadFileLine(file, mapname, sizeof(mapname)))&lt;br /&gt;
	{&lt;br /&gt;
		if (mapname[0] == ';' || !IsCharAlpha(mapname[0]))&lt;br /&gt;
		{&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		/* Cut off the name at any whitespace */&lt;br /&gt;
		new len = strlen(mapname)&lt;br /&gt;
		for (new i=0; i&amp;lt;len; i++)&lt;br /&gt;
		{&lt;br /&gt;
			if (IsCharSpace(mapname[i]))&lt;br /&gt;
			{&lt;br /&gt;
				mapname[i] = '\0'&lt;br /&gt;
				break&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		/* Check if the map is valid */&lt;br /&gt;
		if (!IsMapValid(mapname))&lt;br /&gt;
		{&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		/* Add it to the menu */&lt;br /&gt;
		AddMenuItem(menu, mapname, mapname)&lt;br /&gt;
	}&lt;br /&gt;
	/* Make sure we close the file! */&lt;br /&gt;
	CloseHandle(file)&lt;br /&gt;
	&lt;br /&gt;
	/* Finally, set the title */&lt;br /&gt;
	SetMenuTitle(menu, &amp;quot;Please select a map:&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	return menu&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Menu_ChangeMap(Handle:menu, MenuAction:action, param1, param2)&lt;br /&gt;
{&lt;br /&gt;
	if (action == MenuAction_Select)&lt;br /&gt;
	{&lt;br /&gt;
		new String:info[32]&lt;br /&gt;
&lt;br /&gt;
		/* Get item info */&lt;br /&gt;
		new bool:found = GetMenuItem(menu, param2, info, sizeof(info))&lt;br /&gt;
&lt;br /&gt;
		/* Tell the client */&lt;br /&gt;
		PrintToConsole(param1, &amp;quot;You selected item: %d (found? %d info: %s)&amp;quot;, param2, found, info)&lt;br /&gt;
&lt;br /&gt;
		/* Change the map */&lt;br /&gt;
		ServerCommand(&amp;quot;changelevel %s&amp;quot;, info)&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_ChangeMap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	if (g_MapMenu == INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;The maplist.txt file was not found!&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}	&lt;br /&gt;
	&lt;br /&gt;
	DisplayMenu(g_MapMenu, client, MENU_TIME_FOREVER)&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This menu results in many selections (my &amp;lt;tt&amp;gt;maplist.txt&amp;lt;/tt&amp;gt; file had around 18 maps).  So, our final menu has 3 pages, which side by side, look like:&lt;br /&gt;
&lt;br /&gt;
[[Image:Basic_menu_2_page1.PNG]]&lt;br /&gt;
[[Image:Basic_menu_2_page2.PNG]]&lt;br /&gt;
[[Image:Basic_menu_2_page3.PNG]]&lt;br /&gt;
&lt;br /&gt;
Finally, the console output printed this before the map changed to my selection, &amp;lt;tt&amp;gt;cs_office&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;You selected item: 8 (found? 1 info: cs_office)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Displaying and designing this Menu with a raw &amp;lt;tt&amp;gt;ShowMenu&amp;lt;/tt&amp;gt; message or &amp;lt;tt&amp;gt;Panel&amp;lt;/tt&amp;gt; API would be very time consuming and difficult.  We would have to keep track of all the items in an array of hardcoded size, pages which the user is viewing, and write a function which calculated item selection based on current page and key press.  The Menu system, thankfully, handles all of this for you.&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
*Control options which are not available are not drawn.  For example, in the first page, you cannot go &amp;quot;back,&amp;quot; and in the last page, you cannot go &amp;quot;next.&amp;quot;  Despite this, the menu API tries to keep each the interface as consistent as possible.  Thus, visually, each navigational control is always in the same position.  &lt;br /&gt;
*Although we specified no time out for our menu, if we had placed a timeout, flipping through pages does not affect the overall time.  For example, if we had a timeout of 20, each successive page flip would continue to detract from the overall display time, rather than restart the allowed hold time back to 20.&lt;br /&gt;
*If we had disabled the Exit button, options 8 and 9 would still be &amp;quot;Back&amp;quot; and &amp;quot;Next,&amp;quot; respectively.&lt;br /&gt;
*Again, we did not free the Menu Handle in &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt;.  This is because our menu is global/static, and we don't want to rebuild it every time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Voting=&lt;br /&gt;
SourceMod also has API for displaying menus as votable choices to more than one client.  SourceMod automatically handles selecting an item and randomly picking a tie-breaker.  The voting API adds two new &amp;lt;tt&amp;gt;MenuAction&amp;lt;/tt&amp;gt; values, which for vote displays, are '''always''' passed:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;MenuAction_VoteStart&amp;lt;/tt&amp;gt;: Fired after &amp;lt;tt&amp;gt;MenuAction_Start&amp;lt;/tt&amp;gt; when the voting has officially started.&lt;br /&gt;
*&amp;lt;tt&amp;gt;MenuAction_VoteEnd&amp;lt;/tt&amp;gt;: Fired when all clients have either voted or cancelled their vote menu.  The chosen item is passed through &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;.  This is fired '''before''' &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt;.  It is important to note that it does not supercede &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt;, nor is it the same thing.  Menus should never be destroyed in &amp;lt;tt&amp;gt;MenuAction_VoteEnd&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;MenuACtion_VoteCancel&amp;lt;/tt&amp;gt;: Fired if the menu is cancelled while the vote is in progress.  If this is called, &amp;lt;tt&amp;gt;MenuAction_VoteEnd&amp;lt;/tt&amp;gt; will not be called, but &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt; will be afterwards.&lt;br /&gt;
&lt;br /&gt;
The example below shows has to create a function called &amp;lt;tt&amp;gt;DoVoteMenu()&amp;lt;/tt&amp;gt; which will ask all clients whether or not they would like to change to the given map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Handle_VoteMenu(Handle:menu, MenuAction:action, param1, param2)&lt;br /&gt;
{&lt;br /&gt;
	if (action == MenuAction_End)&lt;br /&gt;
	{&lt;br /&gt;
		/* This is called after VoteEnd */&lt;br /&gt;
		CloseHandle(menu);&lt;br /&gt;
	} else if (action == MenuAction_VoteEnd) {&lt;br /&gt;
		/* 0=yes, 1=no */&lt;br /&gt;
		if (param1 == 0)&lt;br /&gt;
		{&lt;br /&gt;
			new String:map[64]&lt;br /&gt;
			GetMenuItem(menu, param1, map, sizeof(map))&lt;br /&gt;
			ServerCommand(&amp;quot;changelevel %s&amp;quot;, map);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DoVoteMenu(const String:map[])&lt;br /&gt;
{&lt;br /&gt;
	new Handle:menu = CreateMenu(Handle_VoteMenu)&lt;br /&gt;
	SetMenuTitle(menu, &amp;quot;Change map to: %s?&amp;quot;, map)&lt;br /&gt;
	AddMenuItem(menu, map, &amp;quot;Yes&amp;quot;)&lt;br /&gt;
	AddMenuItem(menu, &amp;quot;no&amp;quot;, &amp;quot;No&amp;quot;)&lt;br /&gt;
	SetMenuExitButton(menu, false)&lt;br /&gt;
	VoteMenuToAll(menu, 20);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>TheY4Kman</name></author>
		
	</entry>
</feed>