<?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=FaTony</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=FaTony"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/FaTony"/>
	<updated>2026-05-01T08:06:42Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8735</id>
		<title>Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8735"/>
		<updated>2012-10-12T23:13:12Z</updated>

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

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

		<summary type="html">&lt;p&gt;FaTony: &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''' - 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''' - 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-bound &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 defined 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 the return value is important.&lt;br /&gt;
*&amp;lt;b&amp;gt;&amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;&amp;lt;/b&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;b&amp;gt;&amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;&amp;lt;/b&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;b&amp;gt;&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt;&amp;lt;/b&amp;gt; - The 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;&lt;br /&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;
}&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;&lt;br /&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;
}&lt;br /&gt;
&amp;lt;/pawn&amp;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;
		PrintToServer(&amp;quot;Command from client: %N&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;new Handle:ff = INVALID_HANDLE;&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	AddCommandListener(Command_Say, &amp;quot;say&amp;quot;);&lt;br /&gt;
	AddCommandListener(Command_Say, &amp;quot;say2&amp;quot;);&lt;br /&gt;
	AddCommandListener(Command_Say, &amp;quot;say_team&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	ff = FindConVar(&amp;quot;mp_friendlyfire&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Say(client, const String:command[], argc)&lt;br /&gt;
{&lt;br /&gt;
	decl String:text[192];&lt;br /&gt;
	new startidx = 0;&lt;br /&gt;
	if (GetCmdArgString(text, sizeof(text)) &amp;lt; 1);&lt;br /&gt;
	{&lt;br /&gt;
		return Plugin_Continue;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if (text[strlen(text)-1] == '&amp;quot;')&lt;br /&gt;
	{&lt;br /&gt;
		text[strlen(text)-1] = '\0';&lt;br /&gt;
		startidx = 1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (strcmp(command, &amp;quot;say2&amp;quot;, false) == 0)&lt;br /&gt;
		startidx += 4;&lt;br /&gt;
&lt;br /&gt;
	if (strcmp(text[startidx], &amp;quot;ff&amp;quot;, false) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		if (ff != INVALID_HANDLE)&lt;br /&gt;
		{&lt;br /&gt;
			if (GetConVarBool(ff))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToChat(client, &amp;quot;Friendly fire is enabled.&amp;quot;);&lt;br /&gt;
			} else {&lt;br /&gt;
				PrintToChat(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;
&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], target = -1;&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	for (new i=1; i&amp;lt;=MaxClients; 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], target = -1;&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	for (new i=1; i&amp;lt;=MaxClients; 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. For example, if you create a console command called &amp;lt;tt&amp;gt;&amp;quot;sm_megaslap&amp;quot;&amp;lt;/tt&amp;gt;, 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;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8732</id>
		<title>Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8732"/>
		<updated>2012-10-12T20:38:50Z</updated>

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

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

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

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

		<summary type="html">&lt;p&gt;FaTony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://forums.alliedmods.net/member.php?u=41205&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Category:SourceMod_Scripting&amp;diff=8719</id>
		<title>Category:SourceMod Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Category:SourceMod_Scripting&amp;diff=8719"/>
		<updated>2012-10-06T09:52:37Z</updated>

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

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

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

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

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

		<summary type="html">&lt;p&gt;FaTony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic introduction to writing a [[SourceMod]] plugin.  If you are not familiar with the SourcePawn language, it is recommended that you at least briefly read the [[Introduction to SourcePawn]] article.&lt;br /&gt;
&lt;br /&gt;
For information on compiling plugins, see [[Compiling SourceMod Plugins]]. You can use [http://www.crimsoneditor.com/ Crimson Editor], [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ Pawn Studio] or any other text editor you're comfortable with to write plugins.&lt;br /&gt;
&lt;br /&gt;
=Plugin Structure=&lt;br /&gt;
Almost all plugins have the same three elements:&lt;br /&gt;
*'''Includes''' - Allows you to access the SourceMod API, and if you desire, APIs from external SourceMod extensions and plugins.&lt;br /&gt;
*'''Info''' - Public information about your plugin.&lt;br /&gt;
*'''Startup''' - A function which performs start-up routines in your plugin.&lt;br /&gt;
&lt;br /&gt;
A skeletal plugin structure looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Perform one-time startup tasks ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The information portion is a special syntax construct.  You cannot change any of the keywords, or the &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt; declaration.  The best idea is to copy and paste this skeletal structure and modify the strings to get started.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
Pawn requires '''include files''', much like C requires header files.  Include files list all of the structures, functions, callbacks, and tags that are available.  There are three types of include files:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; and anything it includes.  These are all provided by SourceMod's Core.&lt;br /&gt;
*'''Extension''' - adds a dependency against a certain extension.&lt;br /&gt;
*'''Plugin''' - adds a dependency against a certain plugin.&lt;br /&gt;
&lt;br /&gt;
Include files are loaded using the &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; compiler directive.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  Any command that you type in the console, even if it's registered by SourceMod, will be sent to the engine to be processed. Because we have not had SourceMod block this functionality yet, the engine replies with &amp;quot;Unknown command&amp;quot; because it is not a valid engine command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything. This is because returning &amp;quot;Plugin_Handled&amp;quot; in a command callback will prevent the engine from processing the command. The engine will never even see that the command was run. This is what you will want to do if you are registering a completely new command through SourceMod.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage;&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1);&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;);&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH];&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count;&lt;br /&gt;
	new bool:tn_is_ml;&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage);&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They almost always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;);&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id);&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id);&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8713</id>
		<title>Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8713"/>
		<updated>2012-10-05T08:05:28Z</updated>

		<summary type="html">&lt;p&gt;FaTony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic introduction to writing a [[SourceMod]] plugin.  If you are not familiar with the SourcePawn language, it is recommended that you at least briefly read the [[Introduction to SourcePawn]] article.&lt;br /&gt;
&lt;br /&gt;
For information on compiling plugins, see [[Compiling SourceMod Plugins]].  The author of this article uses [http://www.crimsoneditor.com/ Crimson Editor] to write plugins.  Other possibilities are [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ Pawn Studio] or any other text editor you're comfortable with.&lt;br /&gt;
&lt;br /&gt;
=Plugin Structure=&lt;br /&gt;
Almost all plugins have the same three elements:&lt;br /&gt;
*'''Includes''' - Allows you to access the SourceMod API, and if you desire, APIs from external SourceMod extensions and plugins.&lt;br /&gt;
*'''Info''' - Public information about your plugin.&lt;br /&gt;
*'''Startup''' - A function which performs start-up routines in your plugin.&lt;br /&gt;
&lt;br /&gt;
A skeletal plugin structure looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Perform one-time startup tasks ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The information portion is a special syntax construct.  You cannot change any of the keywords, or the &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt; declaration.  The best idea is to copy and paste this skeletal structure and modify the strings to get started.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
Pawn requires '''include files''', much like C requires header files.  Include files list all of the structures, functions, callbacks, and tags that are available.  There are three types of include files:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; and anything it includes.  These are all provided by SourceMod's Core.&lt;br /&gt;
*'''Extension''' - adds a dependency against a certain extension.&lt;br /&gt;
*'''Plugin''' - adds a dependency against a certain plugin.&lt;br /&gt;
&lt;br /&gt;
Include files are loaded using the &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; compiler directive.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  Any command that you type in the console, even if it's registered by SourceMod, will be sent to the engine to be processed. Because we have not had SourceMod block this functionality yet, the engine replies with &amp;quot;Unknown command&amp;quot; because it is not a valid engine command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything. This is because returning &amp;quot;Plugin_Handled&amp;quot; in a command callback will prevent the engine from processing the command. The engine will never even see that the command was run. This is what you will want to do if you are registering a completely new command through SourceMod.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage;&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1);&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;);&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH];&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count;&lt;br /&gt;
	new bool:tn_is_ml;&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage);&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They almost always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;);&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id);&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id);&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Talk:Admin_API_(SourceMod)&amp;diff=8704</id>
		<title>Talk:Admin API (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Talk:Admin_API_(SourceMod)&amp;diff=8704"/>
		<updated>2012-09-29T15:40:04Z</updated>

		<summary type="html">&lt;p&gt;FaTony: Created page with &amp;quot;No example code, wtf?&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No example code, wtf?&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:FaTony&amp;diff=8699</id>
		<title>User:FaTony</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:FaTony&amp;diff=8699"/>
		<updated>2012-09-16T20:39:41Z</updated>

		<summary type="html">&lt;p&gt;FaTony: Created page with &amp;quot;.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;.&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8698</id>
		<title>Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Introduction_to_SourceMod_Plugins&amp;diff=8698"/>
		<updated>2012-09-16T20:38:15Z</updated>

		<summary type="html">&lt;p&gt;FaTony: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will give you a basic introduction to writing a [[SourceMod]] plugin.  If you are not familiar with the SourcePawn language, it is recommended that you at least briefly read the [[Introduction to SourcePawn]] article.&lt;br /&gt;
&lt;br /&gt;
For information on compiling plugins, see [[Compiling SourceMod Plugins]].  The author of this article uses [http://www.crimsoneditor.com/ Crimson Editor] to write plugins.  Other possibilities are [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] or any other text editor you're comfortable with.&lt;br /&gt;
&lt;br /&gt;
=Plugin Structure=&lt;br /&gt;
Almost all plugins have the same three elements:&lt;br /&gt;
*'''Includes''' - Allows you to access the SourceMod API, and if you desire, APIs from external SourceMod extensions and plugins.&lt;br /&gt;
*'''Info''' - Public information about your plugin.&lt;br /&gt;
*'''Startup''' - A function which performs start-up routines in your plugin.&lt;br /&gt;
&lt;br /&gt;
A skeletal plugin structure looks like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Perform one-time startup tasks ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The information portion is a special syntax construct.  You cannot change any of the keywords, or the &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt; declaration.  The best idea is to copy and paste this skeletal structure and modify the strings to get started.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
Pawn requires '''include files''', much like C requires header files.  Include files list all of the structures, functions, callbacks, and tags that are available.  There are three types of include files:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; and anything it includes.  These are all provided by SourceMod's Core.&lt;br /&gt;
*'''Extension''' - adds a dependency against a certain extension.&lt;br /&gt;
*'''Plugin''' - adds a dependency against a certain plugin.&lt;br /&gt;
&lt;br /&gt;
Include files are loaded using the &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; compiler directive.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  Any command that you type in the console, even if it's registered by SourceMod, will be sent to the engine to be processed. Because we have not had SourceMod block this functionality yet, the engine replies with &amp;quot;Unknown command&amp;quot; because it is not a valid engine command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything. This is because returning &amp;quot;Plugin_Handled&amp;quot; in a command callback will prevent the engine from processing the command. The engine will never even see that the command was run. This is what you will want to do if you are registering a completely new command through SourceMod.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage;&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1);&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage);&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH];&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name));&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage);&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage);&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;);&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY);&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;);&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32];&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage);&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1));&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH];&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count;&lt;br /&gt;
	new bool:tn_is_ml;&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage);&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They almost always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;);&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id);&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id);&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8697</id>
		<title>Creating Natives (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8697"/>
		<updated>2012-09-16T15:32:10Z</updated>

		<summary type="html">&lt;p&gt;FaTony: /* Throwing Errors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod allows plugins to create their own natives that other plugins can use.  This is very similar to AMX Mod X's {{amxx_func|register_native}} function.  It is a powerful inter-plugin communication resource that can greatly enhance the functionality you provide.&lt;br /&gt;
&lt;br /&gt;
''Prerequisites:'' You should have a good grasp of Pawn or SourcePawn scripting, as well as how [[Tags (Scripting)|Tags]] work.&amp;lt;br&amp;gt;&lt;br /&gt;
''Note:'' Most functions herein can be found in the [[SourceMod SDK]], under &amp;lt;tt&amp;gt;plugins/include/functions.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Before creating natives, you should always document and specify exactly how they will work.  This means writing your &amp;quot;include file&amp;quot; beforehand.  Not only does this guide you in writing your natives, but it has the added benefit of completing a large portion of documentation at the same time.&lt;br /&gt;
&lt;br /&gt;
==Include File==&lt;br /&gt;
For our first example, let's start off with a simple native that adds two numbers, a float and a non-float.  It might look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/** Double-include prevention */&lt;br /&gt;
#if defined _mynatives_included_&lt;br /&gt;
  #endinput&lt;br /&gt;
#endif&lt;br /&gt;
#define _mynatives_included_&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Adds two numbers together.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num1    An integer.&lt;br /&gt;
 * @param num2    A float.&lt;br /&gt;
 * @return        The float value of the integer and float added together.&lt;br /&gt;
 */&lt;br /&gt;
native Float:My_AddNumbers(num1, num2);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The documentation and commenting style above is a SourceMod Development Team convention.  While you are not required to follow it for your own code, it may be a good idea to enhance readability (as readers will expect the style to conform).&lt;br /&gt;
&lt;br /&gt;
==Creating the Native==&lt;br /&gt;
To actually create the native, first let's define the native handler itself.  From &amp;lt;tt&amp;gt;functions.inc&amp;lt;/tt&amp;gt; we can see that this follows the prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;functag NativeCall public(Handle:plugin, numParams);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, we have a function like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we don't use the same function name as we did in our include file.  This is to prevent a possible ''name clash''.  Otherwise, two different symbols (one a native, another a function) could have the same name, and that's not allowed.  We'll see later how we bind the native to its actual name.&lt;br /&gt;
&lt;br /&gt;
Next, we need to implement our native.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   /* Retrieve the first parameter we receive */&lt;br /&gt;
   new num1 = GetNativeCell(1);&lt;br /&gt;
   /* Retrieve the second parameter we receive */&lt;br /&gt;
   new Float:num2 = Float:GetNativeCell(2);&lt;br /&gt;
   /* Add them together */&lt;br /&gt;
   new Float:value = num1 + num2;&lt;br /&gt;
   /* Return the value */&lt;br /&gt;
   return _:value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should note four important details.  The first is that we have to manually grab the parameters -- they're not easily sent via arguments.  This is for technical reasons that go beyond the scope of this document.  That means you have to know exactly ''how'' to grab each parameter.  For our example, we know that both parameters are simply cells, and thus we can use &amp;lt;tt&amp;gt;GetNativeCell&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
However, the second detail is that there is no &amp;lt;tt&amp;gt;GetNativeCellFloat&amp;lt;/tt&amp;gt;.  This is because a &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; is still a cell; the data is just interpreted differently.  Thus, we ''change'' the tag to &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; manual.  '''This is different from calling float(GetNativeCell(2)).'''  In fact, that would not work; the &amp;lt;tt&amp;gt;float()&amp;lt;/tt&amp;gt; call would interpret the cell as an integer, when in fact it's already a float, just with the wrong tag (i.e., no tag at all).&lt;br /&gt;
&lt;br /&gt;
Similarly, the third detail is that we cannot simply put &amp;lt;tt&amp;gt;return value&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;return FloatRound(value)&amp;lt;/tt&amp;gt;.  The reason is that our native is supposed to be returning a float.  If we return &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;, we'll get a tag mismatch.  If we return &amp;lt;tt&amp;gt;FloatRound(value)&amp;lt;/tt&amp;gt;, we'll be returning an integer when a float is expected.  The solution is to change the tag to the default tag, which will retain the value but remove the tag warning.&lt;br /&gt;
&lt;br /&gt;
Lastly, we did not need to verify &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt;.  The compiler will always send the correct amount of parameters - the user can't mess this up in any easy way.  Only if you use variadic arguments, or add parameters and need to support older binaries, do you need to handle &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt; variations.&lt;br /&gt;
&lt;br /&gt;
==Registering the Native==&lt;br /&gt;
Natives must be registered in &amp;lt;tt&amp;gt;AskPluginLoad2&amp;lt;/tt&amp;gt;.  Although they can be registered elsewhere, only this function guarantees that all other plugins will see your native.  The definition for this forward is in &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)&lt;br /&gt;
{&lt;br /&gt;
   CreateNative(&amp;quot;My_AddNumbers&amp;quot;, Native_My_AddNumbers);&lt;br /&gt;
   return APLRes_Success;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, any plugin will be able to use our native as if it were from a Core or a C++ extension.&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
==By-Reference==&lt;br /&gt;
Sometimes, it may be desirable to return data through by-reference parameters.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Closes a Handle, and sets the variable to INVALID_HANDLE by reference.&lt;br /&gt;
 *&lt;br /&gt;
 * @param hndl     Handle to close and clear.&lt;br /&gt;
 * @return         Anything that CloseHandle() returns.&lt;br /&gt;
 */&lt;br /&gt;
native bool:AltCloseHandle(&amp;amp;Handle:hndl);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_AltCloseHandle(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new Handle:hndl = Handle:GetNativeCellRef(1);&lt;br /&gt;
   SetNativeCellRef(1, 0);   /* Zero out the variable by reference */&lt;br /&gt;
   return CloseHandle(hndl);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we have a native that is &amp;quot;safer&amp;quot; than a normal &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;, as it ensures we don't hold onto invalid Handles.&lt;br /&gt;
&lt;br /&gt;
==Strings==&lt;br /&gt;
Strings can be retrieved and altered via dynamic natives.  Observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Converts a string to upper case.&lt;br /&gt;
 *&lt;br /&gt;
 * @param str      String to convert.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native StringToUpper(String:str[]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this is very easy, because of dynamic arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_StringToUpper(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new len;&lt;br /&gt;
   GetNativeStringLength(1, len);&lt;br /&gt;
&lt;br /&gt;
   if (len &amp;lt;= 0)&lt;br /&gt;
   {&lt;br /&gt;
      return;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new String:str[len + 1];&lt;br /&gt;
   GetNativeString(1, str, len + 1);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; len; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* 5th bit specifies case in ASCII -- &lt;br /&gt;
       * this is not UTF-8 compatible.&lt;br /&gt;
       */&lt;br /&gt;
      if ((str[i] &amp;amp; (1 &amp;lt;&amp;lt; 5)) == (1 &amp;lt;&amp;lt; 5))&lt;br /&gt;
      {&lt;br /&gt;
         str[i] &amp;amp;= ~(1 &amp;lt;&amp;lt; 5)&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   SetNativeString(1, str, len+1, false);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Arrays==&lt;br /&gt;
Working with arrays is very similar to strings.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums an array of numbers and returns the sum.&lt;br /&gt;
 *&lt;br /&gt;
 * @param array     Array of numbers to sum.&lt;br /&gt;
 * @param size      Size of array.&lt;br /&gt;
 * @return          Sum of the array elements.&lt;br /&gt;
 */&lt;br /&gt;
native SumArray(const array[], size);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this could look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumArray(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new size = GetNativeCell(2);&lt;br /&gt;
   if (size &amp;lt; 1)&lt;br /&gt;
   {&lt;br /&gt;
      return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new array[size], total;&lt;br /&gt;
   GetNativeArray(1, array, size);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, there is a &amp;lt;tt&amp;gt;SetNativeArray&amp;lt;/tt&amp;gt;, which is used to alter array contents.&lt;br /&gt;
&lt;br /&gt;
==Variable Arguments==&lt;br /&gt;
Variable arguments are usually used when dealing with [[Format Class Functions (SourceMod Scripting)|format class functions]], however it is also possible to use them for general functionality.  The only trick is that unlike normal parameters, every variable argument parameter is passed by-reference.  This adds no change for arrays and strings, but for floats, handles, numbers, or anything else that fits in a cell, &amp;lt;tt&amp;gt;GetNativeCellRef&amp;lt;/tt&amp;gt; must be used instead.&lt;br /&gt;
&lt;br /&gt;
As an example, let's convert our function from above to use variable arguments:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums a list of numbers.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num    First number to use as a base.&lt;br /&gt;
 * @param ...    Any number of additional numbers to add.&lt;br /&gt;
 * @return       Sum of all numbers passed.&lt;br /&gt;
 */&lt;br /&gt;
native SumParams(num, ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumParams(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new base = GetNativeCell(1);&lt;br /&gt;
   for (new i = 2; i &amp;lt;= numParams; i++)&lt;br /&gt;
   {&lt;br /&gt;
      base += GetNativeCellRef(i);&lt;br /&gt;
   }&lt;br /&gt;
   return base;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Format Functions==&lt;br /&gt;
It is also possible to create your own [[Format Class Functions (SourceMod Scripting)|format class functions]].  This topic is much more complicated than the previous ones, as the native string formatter allows for many different configurations.  This is mainly for optimization.  Note that a formatting routine deals with two buffers: the input format string, and the output buffer.  &amp;lt;tt&amp;gt;FormatNativeString&amp;lt;/tt&amp;gt;, by default, uses parameter indexes directly so you don't have to copy or locally store any of these buffers.&lt;br /&gt;
&lt;br /&gt;
The most common usage of this is to accept a user-formatted string and to not&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Prints a message with a [DEBUG] prefix to the server.&lt;br /&gt;
 *&lt;br /&gt;
 * @param fmt         Format string.&lt;br /&gt;
 * @param ...         Format arguments.&lt;br /&gt;
 */&lt;br /&gt;
native DebugPrint(const String:fmt[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be easily implemented as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native DebugPrint(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   decl String:buffer[1024], written&lt;br /&gt;
&lt;br /&gt;
   FormatNativeString(0, /* Use an output buffer */&lt;br /&gt;
      1, /* Format param */&lt;br /&gt;
      2, /* Format argument #1 */&lt;br /&gt;
      sizeof(buffer), /* Size of output buffer */&lt;br /&gt;
      written, /* Store # of written bytes */&lt;br /&gt;
      buffer /* Use our buffer */&lt;br /&gt;
      );&lt;br /&gt;
   &lt;br /&gt;
   PrintToServer(&amp;quot;[DEBUG] %s&amp;quot;, buffer);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Throwing Errors==&lt;br /&gt;
Often, your native will encounter an unrecoverable error, and you wish to trigger a fatal exception.  This is equivalent to &amp;lt;tt&amp;gt;IPluginContext::ThrowNativeError&amp;lt;/tt&amp;gt;, and will halt the current function execution in the plugin.  The debugger will be invoked and a backtrace will be printed out (if the plugin is in debug mode).  Although the current function is cancelled, the plugin will continue to operate normally afterward.&lt;br /&gt;
&lt;br /&gt;
For example, let's say we have a native that operates on clients.  We want to throw an error if we get a client index that is invalid or disconnected.  We could do this like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MyFunction(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new client = GetNativeCell(1);&lt;br /&gt;
   if (client &amp;lt; 1 || client &amp;gt; MaxClients);&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Invalid client index (%d)&amp;quot;, client);&lt;br /&gt;
   }&lt;br /&gt;
   if (!IsClientConnected(client))&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Client %d is not connected&amp;quot;, client);&lt;br /&gt;
   }&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8696</id>
		<title>Creating Natives (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8696"/>
		<updated>2012-09-16T15:31:33Z</updated>

		<summary type="html">&lt;p&gt;FaTony: /* Throwing Errors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod allows plugins to create their own natives that other plugins can use.  This is very similar to AMX Mod X's {{amxx_func|register_native}} function.  It is a powerful inter-plugin communication resource that can greatly enhance the functionality you provide.&lt;br /&gt;
&lt;br /&gt;
''Prerequisites:'' You should have a good grasp of Pawn or SourcePawn scripting, as well as how [[Tags (Scripting)|Tags]] work.&amp;lt;br&amp;gt;&lt;br /&gt;
''Note:'' Most functions herein can be found in the [[SourceMod SDK]], under &amp;lt;tt&amp;gt;plugins/include/functions.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Before creating natives, you should always document and specify exactly how they will work.  This means writing your &amp;quot;include file&amp;quot; beforehand.  Not only does this guide you in writing your natives, but it has the added benefit of completing a large portion of documentation at the same time.&lt;br /&gt;
&lt;br /&gt;
==Include File==&lt;br /&gt;
For our first example, let's start off with a simple native that adds two numbers, a float and a non-float.  It might look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/** Double-include prevention */&lt;br /&gt;
#if defined _mynatives_included_&lt;br /&gt;
  #endinput&lt;br /&gt;
#endif&lt;br /&gt;
#define _mynatives_included_&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Adds two numbers together.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num1    An integer.&lt;br /&gt;
 * @param num2    A float.&lt;br /&gt;
 * @return        The float value of the integer and float added together.&lt;br /&gt;
 */&lt;br /&gt;
native Float:My_AddNumbers(num1, num2);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The documentation and commenting style above is a SourceMod Development Team convention.  While you are not required to follow it for your own code, it may be a good idea to enhance readability (as readers will expect the style to conform).&lt;br /&gt;
&lt;br /&gt;
==Creating the Native==&lt;br /&gt;
To actually create the native, first let's define the native handler itself.  From &amp;lt;tt&amp;gt;functions.inc&amp;lt;/tt&amp;gt; we can see that this follows the prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;functag NativeCall public(Handle:plugin, numParams);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, we have a function like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we don't use the same function name as we did in our include file.  This is to prevent a possible ''name clash''.  Otherwise, two different symbols (one a native, another a function) could have the same name, and that's not allowed.  We'll see later how we bind the native to its actual name.&lt;br /&gt;
&lt;br /&gt;
Next, we need to implement our native.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   /* Retrieve the first parameter we receive */&lt;br /&gt;
   new num1 = GetNativeCell(1);&lt;br /&gt;
   /* Retrieve the second parameter we receive */&lt;br /&gt;
   new Float:num2 = Float:GetNativeCell(2);&lt;br /&gt;
   /* Add them together */&lt;br /&gt;
   new Float:value = num1 + num2;&lt;br /&gt;
   /* Return the value */&lt;br /&gt;
   return _:value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should note four important details.  The first is that we have to manually grab the parameters -- they're not easily sent via arguments.  This is for technical reasons that go beyond the scope of this document.  That means you have to know exactly ''how'' to grab each parameter.  For our example, we know that both parameters are simply cells, and thus we can use &amp;lt;tt&amp;gt;GetNativeCell&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
However, the second detail is that there is no &amp;lt;tt&amp;gt;GetNativeCellFloat&amp;lt;/tt&amp;gt;.  This is because a &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; is still a cell; the data is just interpreted differently.  Thus, we ''change'' the tag to &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; manual.  '''This is different from calling float(GetNativeCell(2)).'''  In fact, that would not work; the &amp;lt;tt&amp;gt;float()&amp;lt;/tt&amp;gt; call would interpret the cell as an integer, when in fact it's already a float, just with the wrong tag (i.e., no tag at all).&lt;br /&gt;
&lt;br /&gt;
Similarly, the third detail is that we cannot simply put &amp;lt;tt&amp;gt;return value&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;return FloatRound(value)&amp;lt;/tt&amp;gt;.  The reason is that our native is supposed to be returning a float.  If we return &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;, we'll get a tag mismatch.  If we return &amp;lt;tt&amp;gt;FloatRound(value)&amp;lt;/tt&amp;gt;, we'll be returning an integer when a float is expected.  The solution is to change the tag to the default tag, which will retain the value but remove the tag warning.&lt;br /&gt;
&lt;br /&gt;
Lastly, we did not need to verify &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt;.  The compiler will always send the correct amount of parameters - the user can't mess this up in any easy way.  Only if you use variadic arguments, or add parameters and need to support older binaries, do you need to handle &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt; variations.&lt;br /&gt;
&lt;br /&gt;
==Registering the Native==&lt;br /&gt;
Natives must be registered in &amp;lt;tt&amp;gt;AskPluginLoad2&amp;lt;/tt&amp;gt;.  Although they can be registered elsewhere, only this function guarantees that all other plugins will see your native.  The definition for this forward is in &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)&lt;br /&gt;
{&lt;br /&gt;
   CreateNative(&amp;quot;My_AddNumbers&amp;quot;, Native_My_AddNumbers);&lt;br /&gt;
   return APLRes_Success;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, any plugin will be able to use our native as if it were from a Core or a C++ extension.&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
==By-Reference==&lt;br /&gt;
Sometimes, it may be desirable to return data through by-reference parameters.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Closes a Handle, and sets the variable to INVALID_HANDLE by reference.&lt;br /&gt;
 *&lt;br /&gt;
 * @param hndl     Handle to close and clear.&lt;br /&gt;
 * @return         Anything that CloseHandle() returns.&lt;br /&gt;
 */&lt;br /&gt;
native bool:AltCloseHandle(&amp;amp;Handle:hndl);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_AltCloseHandle(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new Handle:hndl = Handle:GetNativeCellRef(1);&lt;br /&gt;
   SetNativeCellRef(1, 0);   /* Zero out the variable by reference */&lt;br /&gt;
   return CloseHandle(hndl);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we have a native that is &amp;quot;safer&amp;quot; than a normal &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;, as it ensures we don't hold onto invalid Handles.&lt;br /&gt;
&lt;br /&gt;
==Strings==&lt;br /&gt;
Strings can be retrieved and altered via dynamic natives.  Observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Converts a string to upper case.&lt;br /&gt;
 *&lt;br /&gt;
 * @param str      String to convert.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native StringToUpper(String:str[]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this is very easy, because of dynamic arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_StringToUpper(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new len;&lt;br /&gt;
   GetNativeStringLength(1, len);&lt;br /&gt;
&lt;br /&gt;
   if (len &amp;lt;= 0)&lt;br /&gt;
   {&lt;br /&gt;
      return;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new String:str[len + 1];&lt;br /&gt;
   GetNativeString(1, str, len + 1);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; len; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* 5th bit specifies case in ASCII -- &lt;br /&gt;
       * this is not UTF-8 compatible.&lt;br /&gt;
       */&lt;br /&gt;
      if ((str[i] &amp;amp; (1 &amp;lt;&amp;lt; 5)) == (1 &amp;lt;&amp;lt; 5))&lt;br /&gt;
      {&lt;br /&gt;
         str[i] &amp;amp;= ~(1 &amp;lt;&amp;lt; 5)&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   SetNativeString(1, str, len+1, false);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Arrays==&lt;br /&gt;
Working with arrays is very similar to strings.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums an array of numbers and returns the sum.&lt;br /&gt;
 *&lt;br /&gt;
 * @param array     Array of numbers to sum.&lt;br /&gt;
 * @param size      Size of array.&lt;br /&gt;
 * @return          Sum of the array elements.&lt;br /&gt;
 */&lt;br /&gt;
native SumArray(const array[], size);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this could look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumArray(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new size = GetNativeCell(2);&lt;br /&gt;
   if (size &amp;lt; 1)&lt;br /&gt;
   {&lt;br /&gt;
      return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new array[size], total;&lt;br /&gt;
   GetNativeArray(1, array, size);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, there is a &amp;lt;tt&amp;gt;SetNativeArray&amp;lt;/tt&amp;gt;, which is used to alter array contents.&lt;br /&gt;
&lt;br /&gt;
==Variable Arguments==&lt;br /&gt;
Variable arguments are usually used when dealing with [[Format Class Functions (SourceMod Scripting)|format class functions]], however it is also possible to use them for general functionality.  The only trick is that unlike normal parameters, every variable argument parameter is passed by-reference.  This adds no change for arrays and strings, but for floats, handles, numbers, or anything else that fits in a cell, &amp;lt;tt&amp;gt;GetNativeCellRef&amp;lt;/tt&amp;gt; must be used instead.&lt;br /&gt;
&lt;br /&gt;
As an example, let's convert our function from above to use variable arguments:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums a list of numbers.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num    First number to use as a base.&lt;br /&gt;
 * @param ...    Any number of additional numbers to add.&lt;br /&gt;
 * @return       Sum of all numbers passed.&lt;br /&gt;
 */&lt;br /&gt;
native SumParams(num, ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumParams(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new base = GetNativeCell(1);&lt;br /&gt;
   for (new i = 2; i &amp;lt;= numParams; i++)&lt;br /&gt;
   {&lt;br /&gt;
      base += GetNativeCellRef(i);&lt;br /&gt;
   }&lt;br /&gt;
   return base;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Format Functions==&lt;br /&gt;
It is also possible to create your own [[Format Class Functions (SourceMod Scripting)|format class functions]].  This topic is much more complicated than the previous ones, as the native string formatter allows for many different configurations.  This is mainly for optimization.  Note that a formatting routine deals with two buffers: the input format string, and the output buffer.  &amp;lt;tt&amp;gt;FormatNativeString&amp;lt;/tt&amp;gt;, by default, uses parameter indexes directly so you don't have to copy or locally store any of these buffers.&lt;br /&gt;
&lt;br /&gt;
The most common usage of this is to accept a user-formatted string and to not&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Prints a message with a [DEBUG] prefix to the server.&lt;br /&gt;
 *&lt;br /&gt;
 * @param fmt         Format string.&lt;br /&gt;
 * @param ...         Format arguments.&lt;br /&gt;
 */&lt;br /&gt;
native DebugPrint(const String:fmt[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be easily implemented as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native DebugPrint(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   decl String:buffer[1024], written&lt;br /&gt;
&lt;br /&gt;
   FormatNativeString(0, /* Use an output buffer */&lt;br /&gt;
      1, /* Format param */&lt;br /&gt;
      2, /* Format argument #1 */&lt;br /&gt;
      sizeof(buffer), /* Size of output buffer */&lt;br /&gt;
      written, /* Store # of written bytes */&lt;br /&gt;
      buffer /* Use our buffer */&lt;br /&gt;
      );&lt;br /&gt;
   &lt;br /&gt;
   PrintToServer(&amp;quot;[DEBUG] %s&amp;quot;, buffer);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Throwing Errors==&lt;br /&gt;
Often, your native will encounter an unrecoverable error, and you wish to trigger a fatal exception.  This is equivalent to &amp;lt;tt&amp;gt;IPluginContext::ThrowNativeError&amp;lt;/tt&amp;gt;, and will halt the current function execution in the plugin.  The debugger will be invoked and a backtrace will be printed out (if the plugin is in debug mode).  Although the current function is cancelled, the plugin will continue to operate normally afterward.&lt;br /&gt;
&lt;br /&gt;
For example, let's say we have a native that operates on clients.  We want to throw an error if we get a client index that is invalid or disconnected.  We could do this like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MyFunction(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new client = GetNativeCell(1);&lt;br /&gt;
   if (client &amp;lt; 1 || client &amp;gt; GetMaxClients());&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Invalid client index (%d)&amp;quot;, client);&lt;br /&gt;
   }&lt;br /&gt;
   if (!IsClientConnected(client))&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Client %d is not connected&amp;quot;, client);&lt;br /&gt;
   }&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8695</id>
		<title>Creating Natives (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8695"/>
		<updated>2012-09-16T15:31:04Z</updated>

		<summary type="html">&lt;p&gt;FaTony: /* Format Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod allows plugins to create their own natives that other plugins can use.  This is very similar to AMX Mod X's {{amxx_func|register_native}} function.  It is a powerful inter-plugin communication resource that can greatly enhance the functionality you provide.&lt;br /&gt;
&lt;br /&gt;
''Prerequisites:'' You should have a good grasp of Pawn or SourcePawn scripting, as well as how [[Tags (Scripting)|Tags]] work.&amp;lt;br&amp;gt;&lt;br /&gt;
''Note:'' Most functions herein can be found in the [[SourceMod SDK]], under &amp;lt;tt&amp;gt;plugins/include/functions.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Before creating natives, you should always document and specify exactly how they will work.  This means writing your &amp;quot;include file&amp;quot; beforehand.  Not only does this guide you in writing your natives, but it has the added benefit of completing a large portion of documentation at the same time.&lt;br /&gt;
&lt;br /&gt;
==Include File==&lt;br /&gt;
For our first example, let's start off with a simple native that adds two numbers, a float and a non-float.  It might look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/** Double-include prevention */&lt;br /&gt;
#if defined _mynatives_included_&lt;br /&gt;
  #endinput&lt;br /&gt;
#endif&lt;br /&gt;
#define _mynatives_included_&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Adds two numbers together.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num1    An integer.&lt;br /&gt;
 * @param num2    A float.&lt;br /&gt;
 * @return        The float value of the integer and float added together.&lt;br /&gt;
 */&lt;br /&gt;
native Float:My_AddNumbers(num1, num2);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The documentation and commenting style above is a SourceMod Development Team convention.  While you are not required to follow it for your own code, it may be a good idea to enhance readability (as readers will expect the style to conform).&lt;br /&gt;
&lt;br /&gt;
==Creating the Native==&lt;br /&gt;
To actually create the native, first let's define the native handler itself.  From &amp;lt;tt&amp;gt;functions.inc&amp;lt;/tt&amp;gt; we can see that this follows the prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;functag NativeCall public(Handle:plugin, numParams);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, we have a function like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we don't use the same function name as we did in our include file.  This is to prevent a possible ''name clash''.  Otherwise, two different symbols (one a native, another a function) could have the same name, and that's not allowed.  We'll see later how we bind the native to its actual name.&lt;br /&gt;
&lt;br /&gt;
Next, we need to implement our native.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   /* Retrieve the first parameter we receive */&lt;br /&gt;
   new num1 = GetNativeCell(1);&lt;br /&gt;
   /* Retrieve the second parameter we receive */&lt;br /&gt;
   new Float:num2 = Float:GetNativeCell(2);&lt;br /&gt;
   /* Add them together */&lt;br /&gt;
   new Float:value = num1 + num2;&lt;br /&gt;
   /* Return the value */&lt;br /&gt;
   return _:value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should note four important details.  The first is that we have to manually grab the parameters -- they're not easily sent via arguments.  This is for technical reasons that go beyond the scope of this document.  That means you have to know exactly ''how'' to grab each parameter.  For our example, we know that both parameters are simply cells, and thus we can use &amp;lt;tt&amp;gt;GetNativeCell&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
However, the second detail is that there is no &amp;lt;tt&amp;gt;GetNativeCellFloat&amp;lt;/tt&amp;gt;.  This is because a &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; is still a cell; the data is just interpreted differently.  Thus, we ''change'' the tag to &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; manual.  '''This is different from calling float(GetNativeCell(2)).'''  In fact, that would not work; the &amp;lt;tt&amp;gt;float()&amp;lt;/tt&amp;gt; call would interpret the cell as an integer, when in fact it's already a float, just with the wrong tag (i.e., no tag at all).&lt;br /&gt;
&lt;br /&gt;
Similarly, the third detail is that we cannot simply put &amp;lt;tt&amp;gt;return value&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;return FloatRound(value)&amp;lt;/tt&amp;gt;.  The reason is that our native is supposed to be returning a float.  If we return &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;, we'll get a tag mismatch.  If we return &amp;lt;tt&amp;gt;FloatRound(value)&amp;lt;/tt&amp;gt;, we'll be returning an integer when a float is expected.  The solution is to change the tag to the default tag, which will retain the value but remove the tag warning.&lt;br /&gt;
&lt;br /&gt;
Lastly, we did not need to verify &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt;.  The compiler will always send the correct amount of parameters - the user can't mess this up in any easy way.  Only if you use variadic arguments, or add parameters and need to support older binaries, do you need to handle &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt; variations.&lt;br /&gt;
&lt;br /&gt;
==Registering the Native==&lt;br /&gt;
Natives must be registered in &amp;lt;tt&amp;gt;AskPluginLoad2&amp;lt;/tt&amp;gt;.  Although they can be registered elsewhere, only this function guarantees that all other plugins will see your native.  The definition for this forward is in &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)&lt;br /&gt;
{&lt;br /&gt;
   CreateNative(&amp;quot;My_AddNumbers&amp;quot;, Native_My_AddNumbers);&lt;br /&gt;
   return APLRes_Success;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, any plugin will be able to use our native as if it were from a Core or a C++ extension.&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
==By-Reference==&lt;br /&gt;
Sometimes, it may be desirable to return data through by-reference parameters.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Closes a Handle, and sets the variable to INVALID_HANDLE by reference.&lt;br /&gt;
 *&lt;br /&gt;
 * @param hndl     Handle to close and clear.&lt;br /&gt;
 * @return         Anything that CloseHandle() returns.&lt;br /&gt;
 */&lt;br /&gt;
native bool:AltCloseHandle(&amp;amp;Handle:hndl);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_AltCloseHandle(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new Handle:hndl = Handle:GetNativeCellRef(1);&lt;br /&gt;
   SetNativeCellRef(1, 0);   /* Zero out the variable by reference */&lt;br /&gt;
   return CloseHandle(hndl);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we have a native that is &amp;quot;safer&amp;quot; than a normal &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;, as it ensures we don't hold onto invalid Handles.&lt;br /&gt;
&lt;br /&gt;
==Strings==&lt;br /&gt;
Strings can be retrieved and altered via dynamic natives.  Observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Converts a string to upper case.&lt;br /&gt;
 *&lt;br /&gt;
 * @param str      String to convert.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native StringToUpper(String:str[]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this is very easy, because of dynamic arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_StringToUpper(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new len;&lt;br /&gt;
   GetNativeStringLength(1, len);&lt;br /&gt;
&lt;br /&gt;
   if (len &amp;lt;= 0)&lt;br /&gt;
   {&lt;br /&gt;
      return;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new String:str[len + 1];&lt;br /&gt;
   GetNativeString(1, str, len + 1);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; len; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* 5th bit specifies case in ASCII -- &lt;br /&gt;
       * this is not UTF-8 compatible.&lt;br /&gt;
       */&lt;br /&gt;
      if ((str[i] &amp;amp; (1 &amp;lt;&amp;lt; 5)) == (1 &amp;lt;&amp;lt; 5))&lt;br /&gt;
      {&lt;br /&gt;
         str[i] &amp;amp;= ~(1 &amp;lt;&amp;lt; 5)&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   SetNativeString(1, str, len+1, false);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Arrays==&lt;br /&gt;
Working with arrays is very similar to strings.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums an array of numbers and returns the sum.&lt;br /&gt;
 *&lt;br /&gt;
 * @param array     Array of numbers to sum.&lt;br /&gt;
 * @param size      Size of array.&lt;br /&gt;
 * @return          Sum of the array elements.&lt;br /&gt;
 */&lt;br /&gt;
native SumArray(const array[], size);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this could look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumArray(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new size = GetNativeCell(2);&lt;br /&gt;
   if (size &amp;lt; 1)&lt;br /&gt;
   {&lt;br /&gt;
      return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new array[size], total;&lt;br /&gt;
   GetNativeArray(1, array, size);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, there is a &amp;lt;tt&amp;gt;SetNativeArray&amp;lt;/tt&amp;gt;, which is used to alter array contents.&lt;br /&gt;
&lt;br /&gt;
==Variable Arguments==&lt;br /&gt;
Variable arguments are usually used when dealing with [[Format Class Functions (SourceMod Scripting)|format class functions]], however it is also possible to use them for general functionality.  The only trick is that unlike normal parameters, every variable argument parameter is passed by-reference.  This adds no change for arrays and strings, but for floats, handles, numbers, or anything else that fits in a cell, &amp;lt;tt&amp;gt;GetNativeCellRef&amp;lt;/tt&amp;gt; must be used instead.&lt;br /&gt;
&lt;br /&gt;
As an example, let's convert our function from above to use variable arguments:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums a list of numbers.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num    First number to use as a base.&lt;br /&gt;
 * @param ...    Any number of additional numbers to add.&lt;br /&gt;
 * @return       Sum of all numbers passed.&lt;br /&gt;
 */&lt;br /&gt;
native SumParams(num, ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumParams(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new base = GetNativeCell(1);&lt;br /&gt;
   for (new i = 2; i &amp;lt;= numParams; i++)&lt;br /&gt;
   {&lt;br /&gt;
      base += GetNativeCellRef(i);&lt;br /&gt;
   }&lt;br /&gt;
   return base;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Format Functions==&lt;br /&gt;
It is also possible to create your own [[Format Class Functions (SourceMod Scripting)|format class functions]].  This topic is much more complicated than the previous ones, as the native string formatter allows for many different configurations.  This is mainly for optimization.  Note that a formatting routine deals with two buffers: the input format string, and the output buffer.  &amp;lt;tt&amp;gt;FormatNativeString&amp;lt;/tt&amp;gt;, by default, uses parameter indexes directly so you don't have to copy or locally store any of these buffers.&lt;br /&gt;
&lt;br /&gt;
The most common usage of this is to accept a user-formatted string and to not&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Prints a message with a [DEBUG] prefix to the server.&lt;br /&gt;
 *&lt;br /&gt;
 * @param fmt         Format string.&lt;br /&gt;
 * @param ...         Format arguments.&lt;br /&gt;
 */&lt;br /&gt;
native DebugPrint(const String:fmt[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be easily implemented as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native DebugPrint(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   decl String:buffer[1024], written&lt;br /&gt;
&lt;br /&gt;
   FormatNativeString(0, /* Use an output buffer */&lt;br /&gt;
      1, /* Format param */&lt;br /&gt;
      2, /* Format argument #1 */&lt;br /&gt;
      sizeof(buffer), /* Size of output buffer */&lt;br /&gt;
      written, /* Store # of written bytes */&lt;br /&gt;
      buffer /* Use our buffer */&lt;br /&gt;
      );&lt;br /&gt;
   &lt;br /&gt;
   PrintToServer(&amp;quot;[DEBUG] %s&amp;quot;, buffer);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Throwing Errors==&lt;br /&gt;
Often, your native will encounter an unrecoverable error, and you wish to trigger a fatal exception.  This is equivalent to &amp;lt;tt&amp;gt;IPluginContext::ThrowNativeError&amp;lt;/tt&amp;gt;, and will halt the current function execution in the plugin.  The debugger will be invoked and a backtrace will be printed out (if the plugin is in debug mode).  Although the current function is cancelled, the plugin will continue to operate normally afterward.&lt;br /&gt;
&lt;br /&gt;
For example, let's say we have a native that operates on clients.  We want to throw an error if we get a client index that is invalid or disconnected.  We could do this like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MyFunction(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new client = GetNativeCell(1)&lt;br /&gt;
   if (client &amp;lt; 1 || client &amp;gt; GetMaxClients())&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Invalid client index (%d)&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   if (!IsClientConnected(client))&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Client %d is not connected&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8694</id>
		<title>Creating Natives (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8694"/>
		<updated>2012-09-16T15:30:20Z</updated>

		<summary type="html">&lt;p&gt;FaTony: /* Variable Arguments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod allows plugins to create their own natives that other plugins can use.  This is very similar to AMX Mod X's {{amxx_func|register_native}} function.  It is a powerful inter-plugin communication resource that can greatly enhance the functionality you provide.&lt;br /&gt;
&lt;br /&gt;
''Prerequisites:'' You should have a good grasp of Pawn or SourcePawn scripting, as well as how [[Tags (Scripting)|Tags]] work.&amp;lt;br&amp;gt;&lt;br /&gt;
''Note:'' Most functions herein can be found in the [[SourceMod SDK]], under &amp;lt;tt&amp;gt;plugins/include/functions.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Before creating natives, you should always document and specify exactly how they will work.  This means writing your &amp;quot;include file&amp;quot; beforehand.  Not only does this guide you in writing your natives, but it has the added benefit of completing a large portion of documentation at the same time.&lt;br /&gt;
&lt;br /&gt;
==Include File==&lt;br /&gt;
For our first example, let's start off with a simple native that adds two numbers, a float and a non-float.  It might look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/** Double-include prevention */&lt;br /&gt;
#if defined _mynatives_included_&lt;br /&gt;
  #endinput&lt;br /&gt;
#endif&lt;br /&gt;
#define _mynatives_included_&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Adds two numbers together.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num1    An integer.&lt;br /&gt;
 * @param num2    A float.&lt;br /&gt;
 * @return        The float value of the integer and float added together.&lt;br /&gt;
 */&lt;br /&gt;
native Float:My_AddNumbers(num1, num2);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The documentation and commenting style above is a SourceMod Development Team convention.  While you are not required to follow it for your own code, it may be a good idea to enhance readability (as readers will expect the style to conform).&lt;br /&gt;
&lt;br /&gt;
==Creating the Native==&lt;br /&gt;
To actually create the native, first let's define the native handler itself.  From &amp;lt;tt&amp;gt;functions.inc&amp;lt;/tt&amp;gt; we can see that this follows the prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;functag NativeCall public(Handle:plugin, numParams);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, we have a function like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we don't use the same function name as we did in our include file.  This is to prevent a possible ''name clash''.  Otherwise, two different symbols (one a native, another a function) could have the same name, and that's not allowed.  We'll see later how we bind the native to its actual name.&lt;br /&gt;
&lt;br /&gt;
Next, we need to implement our native.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   /* Retrieve the first parameter we receive */&lt;br /&gt;
   new num1 = GetNativeCell(1);&lt;br /&gt;
   /* Retrieve the second parameter we receive */&lt;br /&gt;
   new Float:num2 = Float:GetNativeCell(2);&lt;br /&gt;
   /* Add them together */&lt;br /&gt;
   new Float:value = num1 + num2;&lt;br /&gt;
   /* Return the value */&lt;br /&gt;
   return _:value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should note four important details.  The first is that we have to manually grab the parameters -- they're not easily sent via arguments.  This is for technical reasons that go beyond the scope of this document.  That means you have to know exactly ''how'' to grab each parameter.  For our example, we know that both parameters are simply cells, and thus we can use &amp;lt;tt&amp;gt;GetNativeCell&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
However, the second detail is that there is no &amp;lt;tt&amp;gt;GetNativeCellFloat&amp;lt;/tt&amp;gt;.  This is because a &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; is still a cell; the data is just interpreted differently.  Thus, we ''change'' the tag to &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; manual.  '''This is different from calling float(GetNativeCell(2)).'''  In fact, that would not work; the &amp;lt;tt&amp;gt;float()&amp;lt;/tt&amp;gt; call would interpret the cell as an integer, when in fact it's already a float, just with the wrong tag (i.e., no tag at all).&lt;br /&gt;
&lt;br /&gt;
Similarly, the third detail is that we cannot simply put &amp;lt;tt&amp;gt;return value&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;return FloatRound(value)&amp;lt;/tt&amp;gt;.  The reason is that our native is supposed to be returning a float.  If we return &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;, we'll get a tag mismatch.  If we return &amp;lt;tt&amp;gt;FloatRound(value)&amp;lt;/tt&amp;gt;, we'll be returning an integer when a float is expected.  The solution is to change the tag to the default tag, which will retain the value but remove the tag warning.&lt;br /&gt;
&lt;br /&gt;
Lastly, we did not need to verify &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt;.  The compiler will always send the correct amount of parameters - the user can't mess this up in any easy way.  Only if you use variadic arguments, or add parameters and need to support older binaries, do you need to handle &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt; variations.&lt;br /&gt;
&lt;br /&gt;
==Registering the Native==&lt;br /&gt;
Natives must be registered in &amp;lt;tt&amp;gt;AskPluginLoad2&amp;lt;/tt&amp;gt;.  Although they can be registered elsewhere, only this function guarantees that all other plugins will see your native.  The definition for this forward is in &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)&lt;br /&gt;
{&lt;br /&gt;
   CreateNative(&amp;quot;My_AddNumbers&amp;quot;, Native_My_AddNumbers);&lt;br /&gt;
   return APLRes_Success;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, any plugin will be able to use our native as if it were from a Core or a C++ extension.&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
==By-Reference==&lt;br /&gt;
Sometimes, it may be desirable to return data through by-reference parameters.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Closes a Handle, and sets the variable to INVALID_HANDLE by reference.&lt;br /&gt;
 *&lt;br /&gt;
 * @param hndl     Handle to close and clear.&lt;br /&gt;
 * @return         Anything that CloseHandle() returns.&lt;br /&gt;
 */&lt;br /&gt;
native bool:AltCloseHandle(&amp;amp;Handle:hndl);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_AltCloseHandle(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new Handle:hndl = Handle:GetNativeCellRef(1);&lt;br /&gt;
   SetNativeCellRef(1, 0);   /* Zero out the variable by reference */&lt;br /&gt;
   return CloseHandle(hndl);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we have a native that is &amp;quot;safer&amp;quot; than a normal &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;, as it ensures we don't hold onto invalid Handles.&lt;br /&gt;
&lt;br /&gt;
==Strings==&lt;br /&gt;
Strings can be retrieved and altered via dynamic natives.  Observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Converts a string to upper case.&lt;br /&gt;
 *&lt;br /&gt;
 * @param str      String to convert.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native StringToUpper(String:str[]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this is very easy, because of dynamic arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_StringToUpper(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new len;&lt;br /&gt;
   GetNativeStringLength(1, len);&lt;br /&gt;
&lt;br /&gt;
   if (len &amp;lt;= 0)&lt;br /&gt;
   {&lt;br /&gt;
      return;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new String:str[len + 1];&lt;br /&gt;
   GetNativeString(1, str, len + 1);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; len; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* 5th bit specifies case in ASCII -- &lt;br /&gt;
       * this is not UTF-8 compatible.&lt;br /&gt;
       */&lt;br /&gt;
      if ((str[i] &amp;amp; (1 &amp;lt;&amp;lt; 5)) == (1 &amp;lt;&amp;lt; 5))&lt;br /&gt;
      {&lt;br /&gt;
         str[i] &amp;amp;= ~(1 &amp;lt;&amp;lt; 5)&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   SetNativeString(1, str, len+1, false);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Arrays==&lt;br /&gt;
Working with arrays is very similar to strings.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums an array of numbers and returns the sum.&lt;br /&gt;
 *&lt;br /&gt;
 * @param array     Array of numbers to sum.&lt;br /&gt;
 * @param size      Size of array.&lt;br /&gt;
 * @return          Sum of the array elements.&lt;br /&gt;
 */&lt;br /&gt;
native SumArray(const array[], size);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this could look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumArray(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new size = GetNativeCell(2);&lt;br /&gt;
   if (size &amp;lt; 1)&lt;br /&gt;
   {&lt;br /&gt;
      return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new array[size], total;&lt;br /&gt;
   GetNativeArray(1, array, size);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, there is a &amp;lt;tt&amp;gt;SetNativeArray&amp;lt;/tt&amp;gt;, which is used to alter array contents.&lt;br /&gt;
&lt;br /&gt;
==Variable Arguments==&lt;br /&gt;
Variable arguments are usually used when dealing with [[Format Class Functions (SourceMod Scripting)|format class functions]], however it is also possible to use them for general functionality.  The only trick is that unlike normal parameters, every variable argument parameter is passed by-reference.  This adds no change for arrays and strings, but for floats, handles, numbers, or anything else that fits in a cell, &amp;lt;tt&amp;gt;GetNativeCellRef&amp;lt;/tt&amp;gt; must be used instead.&lt;br /&gt;
&lt;br /&gt;
As an example, let's convert our function from above to use variable arguments:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums a list of numbers.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num    First number to use as a base.&lt;br /&gt;
 * @param ...    Any number of additional numbers to add.&lt;br /&gt;
 * @return       Sum of all numbers passed.&lt;br /&gt;
 */&lt;br /&gt;
native SumParams(num, ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumParams(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new base = GetNativeCell(1);&lt;br /&gt;
   for (new i = 2; i &amp;lt;= numParams; i++)&lt;br /&gt;
   {&lt;br /&gt;
      base += GetNativeCellRef(i);&lt;br /&gt;
   }&lt;br /&gt;
   return base;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Format Functions==&lt;br /&gt;
It is also possible to create your own [[Format Class Functions (SourceMod Scripting)|format class functions]].  This topic is much more complicated than the previous ones, as the native string formatter allows for many different configurations.  This is mainly for optimization.  Note that a formatting routine deals with two buffers: the input format string, and the output buffer.  &amp;lt;tt&amp;gt;FormatNativeString&amp;lt;/tt&amp;gt;, by default, uses parameter indexes directly so you don't have to copy or locally store any of these buffers.&lt;br /&gt;
&lt;br /&gt;
The most common usage of this is to accept a user-formatted string and to not&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Prints a message with a [DEBUG] prefix to the server.&lt;br /&gt;
 *&lt;br /&gt;
 * @param fmt         Format string.&lt;br /&gt;
 * @param ...         Format arguments.&lt;br /&gt;
 */&lt;br /&gt;
native DebugPrint(const String:fmt[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be easily implemented as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native DebugPrint(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   decl String:buffer[1024], written&lt;br /&gt;
&lt;br /&gt;
   FormatNativeString(0, /* Use an output buffer */&lt;br /&gt;
      1, /* Format param */&lt;br /&gt;
      2, /* Format argument #1 */&lt;br /&gt;
      sizeof(buffer), /* Size of output buffer */&lt;br /&gt;
      written, /* Store # of written bytes */&lt;br /&gt;
      buffer /* Use our buffer */&lt;br /&gt;
      )&lt;br /&gt;
   &lt;br /&gt;
   PrintToServer(&amp;quot;[DEBUG] %s&amp;quot;, buffer)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Throwing Errors==&lt;br /&gt;
Often, your native will encounter an unrecoverable error, and you wish to trigger a fatal exception.  This is equivalent to &amp;lt;tt&amp;gt;IPluginContext::ThrowNativeError&amp;lt;/tt&amp;gt;, and will halt the current function execution in the plugin.  The debugger will be invoked and a backtrace will be printed out (if the plugin is in debug mode).  Although the current function is cancelled, the plugin will continue to operate normally afterward.&lt;br /&gt;
&lt;br /&gt;
For example, let's say we have a native that operates on clients.  We want to throw an error if we get a client index that is invalid or disconnected.  We could do this like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MyFunction(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new client = GetNativeCell(1)&lt;br /&gt;
   if (client &amp;lt; 1 || client &amp;gt; GetMaxClients())&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Invalid client index (%d)&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   if (!IsClientConnected(client))&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Client %d is not connected&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8693</id>
		<title>Creating Natives (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8693"/>
		<updated>2012-09-16T15:29:33Z</updated>

		<summary type="html">&lt;p&gt;FaTony: /* Arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod allows plugins to create their own natives that other plugins can use.  This is very similar to AMX Mod X's {{amxx_func|register_native}} function.  It is a powerful inter-plugin communication resource that can greatly enhance the functionality you provide.&lt;br /&gt;
&lt;br /&gt;
''Prerequisites:'' You should have a good grasp of Pawn or SourcePawn scripting, as well as how [[Tags (Scripting)|Tags]] work.&amp;lt;br&amp;gt;&lt;br /&gt;
''Note:'' Most functions herein can be found in the [[SourceMod SDK]], under &amp;lt;tt&amp;gt;plugins/include/functions.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Before creating natives, you should always document and specify exactly how they will work.  This means writing your &amp;quot;include file&amp;quot; beforehand.  Not only does this guide you in writing your natives, but it has the added benefit of completing a large portion of documentation at the same time.&lt;br /&gt;
&lt;br /&gt;
==Include File==&lt;br /&gt;
For our first example, let's start off with a simple native that adds two numbers, a float and a non-float.  It might look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/** Double-include prevention */&lt;br /&gt;
#if defined _mynatives_included_&lt;br /&gt;
  #endinput&lt;br /&gt;
#endif&lt;br /&gt;
#define _mynatives_included_&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Adds two numbers together.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num1    An integer.&lt;br /&gt;
 * @param num2    A float.&lt;br /&gt;
 * @return        The float value of the integer and float added together.&lt;br /&gt;
 */&lt;br /&gt;
native Float:My_AddNumbers(num1, num2);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The documentation and commenting style above is a SourceMod Development Team convention.  While you are not required to follow it for your own code, it may be a good idea to enhance readability (as readers will expect the style to conform).&lt;br /&gt;
&lt;br /&gt;
==Creating the Native==&lt;br /&gt;
To actually create the native, first let's define the native handler itself.  From &amp;lt;tt&amp;gt;functions.inc&amp;lt;/tt&amp;gt; we can see that this follows the prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;functag NativeCall public(Handle:plugin, numParams);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, we have a function like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we don't use the same function name as we did in our include file.  This is to prevent a possible ''name clash''.  Otherwise, two different symbols (one a native, another a function) could have the same name, and that's not allowed.  We'll see later how we bind the native to its actual name.&lt;br /&gt;
&lt;br /&gt;
Next, we need to implement our native.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   /* Retrieve the first parameter we receive */&lt;br /&gt;
   new num1 = GetNativeCell(1);&lt;br /&gt;
   /* Retrieve the second parameter we receive */&lt;br /&gt;
   new Float:num2 = Float:GetNativeCell(2);&lt;br /&gt;
   /* Add them together */&lt;br /&gt;
   new Float:value = num1 + num2;&lt;br /&gt;
   /* Return the value */&lt;br /&gt;
   return _:value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should note four important details.  The first is that we have to manually grab the parameters -- they're not easily sent via arguments.  This is for technical reasons that go beyond the scope of this document.  That means you have to know exactly ''how'' to grab each parameter.  For our example, we know that both parameters are simply cells, and thus we can use &amp;lt;tt&amp;gt;GetNativeCell&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
However, the second detail is that there is no &amp;lt;tt&amp;gt;GetNativeCellFloat&amp;lt;/tt&amp;gt;.  This is because a &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; is still a cell; the data is just interpreted differently.  Thus, we ''change'' the tag to &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; manual.  '''This is different from calling float(GetNativeCell(2)).'''  In fact, that would not work; the &amp;lt;tt&amp;gt;float()&amp;lt;/tt&amp;gt; call would interpret the cell as an integer, when in fact it's already a float, just with the wrong tag (i.e., no tag at all).&lt;br /&gt;
&lt;br /&gt;
Similarly, the third detail is that we cannot simply put &amp;lt;tt&amp;gt;return value&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;return FloatRound(value)&amp;lt;/tt&amp;gt;.  The reason is that our native is supposed to be returning a float.  If we return &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;, we'll get a tag mismatch.  If we return &amp;lt;tt&amp;gt;FloatRound(value)&amp;lt;/tt&amp;gt;, we'll be returning an integer when a float is expected.  The solution is to change the tag to the default tag, which will retain the value but remove the tag warning.&lt;br /&gt;
&lt;br /&gt;
Lastly, we did not need to verify &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt;.  The compiler will always send the correct amount of parameters - the user can't mess this up in any easy way.  Only if you use variadic arguments, or add parameters and need to support older binaries, do you need to handle &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt; variations.&lt;br /&gt;
&lt;br /&gt;
==Registering the Native==&lt;br /&gt;
Natives must be registered in &amp;lt;tt&amp;gt;AskPluginLoad2&amp;lt;/tt&amp;gt;.  Although they can be registered elsewhere, only this function guarantees that all other plugins will see your native.  The definition for this forward is in &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)&lt;br /&gt;
{&lt;br /&gt;
   CreateNative(&amp;quot;My_AddNumbers&amp;quot;, Native_My_AddNumbers);&lt;br /&gt;
   return APLRes_Success;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, any plugin will be able to use our native as if it were from a Core or a C++ extension.&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
==By-Reference==&lt;br /&gt;
Sometimes, it may be desirable to return data through by-reference parameters.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Closes a Handle, and sets the variable to INVALID_HANDLE by reference.&lt;br /&gt;
 *&lt;br /&gt;
 * @param hndl     Handle to close and clear.&lt;br /&gt;
 * @return         Anything that CloseHandle() returns.&lt;br /&gt;
 */&lt;br /&gt;
native bool:AltCloseHandle(&amp;amp;Handle:hndl);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_AltCloseHandle(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new Handle:hndl = Handle:GetNativeCellRef(1);&lt;br /&gt;
   SetNativeCellRef(1, 0);   /* Zero out the variable by reference */&lt;br /&gt;
   return CloseHandle(hndl);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we have a native that is &amp;quot;safer&amp;quot; than a normal &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;, as it ensures we don't hold onto invalid Handles.&lt;br /&gt;
&lt;br /&gt;
==Strings==&lt;br /&gt;
Strings can be retrieved and altered via dynamic natives.  Observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Converts a string to upper case.&lt;br /&gt;
 *&lt;br /&gt;
 * @param str      String to convert.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native StringToUpper(String:str[]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this is very easy, because of dynamic arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_StringToUpper(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new len;&lt;br /&gt;
   GetNativeStringLength(1, len);&lt;br /&gt;
&lt;br /&gt;
   if (len &amp;lt;= 0)&lt;br /&gt;
   {&lt;br /&gt;
      return;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new String:str[len + 1];&lt;br /&gt;
   GetNativeString(1, str, len + 1);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; len; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* 5th bit specifies case in ASCII -- &lt;br /&gt;
       * this is not UTF-8 compatible.&lt;br /&gt;
       */&lt;br /&gt;
      if ((str[i] &amp;amp; (1 &amp;lt;&amp;lt; 5)) == (1 &amp;lt;&amp;lt; 5))&lt;br /&gt;
      {&lt;br /&gt;
         str[i] &amp;amp;= ~(1 &amp;lt;&amp;lt; 5)&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   SetNativeString(1, str, len+1, false);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Arrays==&lt;br /&gt;
Working with arrays is very similar to strings.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums an array of numbers and returns the sum.&lt;br /&gt;
 *&lt;br /&gt;
 * @param array     Array of numbers to sum.&lt;br /&gt;
 * @param size      Size of array.&lt;br /&gt;
 * @return          Sum of the array elements.&lt;br /&gt;
 */&lt;br /&gt;
native SumArray(const array[], size);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this could look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumArray(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new size = GetNativeCell(2);&lt;br /&gt;
   if (size &amp;lt; 1)&lt;br /&gt;
   {&lt;br /&gt;
      return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new array[size], total;&lt;br /&gt;
   GetNativeArray(1, array, size);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, there is a &amp;lt;tt&amp;gt;SetNativeArray&amp;lt;/tt&amp;gt;, which is used to alter array contents.&lt;br /&gt;
&lt;br /&gt;
==Variable Arguments==&lt;br /&gt;
Variable arguments are usually used when dealing with [[Format Class Functions (SourceMod Scripting)|format class functions]], however it is also possible to use them for general functionality.  The only trick is that unlike normal parameters, every variable argument parameter is passed by-reference.  This adds no change for arrays and strings, but for floats, handles, numbers, or anything else that fits in a cell, &amp;lt;tt&amp;gt;GetNativeCellRef&amp;lt;/tt&amp;gt; must be used instead.&lt;br /&gt;
&lt;br /&gt;
As an example, let's convert our function from above to use variable arguments:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums a list of numbers.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num    First number to use as a base.&lt;br /&gt;
 * @param ...    Any number of additional numbers to add.&lt;br /&gt;
 * @return       Sum of all numbers passed.&lt;br /&gt;
 */&lt;br /&gt;
native SumParams(num, ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumParams(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new base = GetNativeCell(1)&lt;br /&gt;
   for (new i=2; i&amp;lt;=numParams; i++)&lt;br /&gt;
   {&lt;br /&gt;
      base += GetNativeCellRef(i)&lt;br /&gt;
   }&lt;br /&gt;
   return base&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Format Functions==&lt;br /&gt;
It is also possible to create your own [[Format Class Functions (SourceMod Scripting)|format class functions]].  This topic is much more complicated than the previous ones, as the native string formatter allows for many different configurations.  This is mainly for optimization.  Note that a formatting routine deals with two buffers: the input format string, and the output buffer.  &amp;lt;tt&amp;gt;FormatNativeString&amp;lt;/tt&amp;gt;, by default, uses parameter indexes directly so you don't have to copy or locally store any of these buffers.&lt;br /&gt;
&lt;br /&gt;
The most common usage of this is to accept a user-formatted string and to not&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Prints a message with a [DEBUG] prefix to the server.&lt;br /&gt;
 *&lt;br /&gt;
 * @param fmt         Format string.&lt;br /&gt;
 * @param ...         Format arguments.&lt;br /&gt;
 */&lt;br /&gt;
native DebugPrint(const String:fmt[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be easily implemented as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native DebugPrint(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   decl String:buffer[1024], written&lt;br /&gt;
&lt;br /&gt;
   FormatNativeString(0, /* Use an output buffer */&lt;br /&gt;
      1, /* Format param */&lt;br /&gt;
      2, /* Format argument #1 */&lt;br /&gt;
      sizeof(buffer), /* Size of output buffer */&lt;br /&gt;
      written, /* Store # of written bytes */&lt;br /&gt;
      buffer /* Use our buffer */&lt;br /&gt;
      )&lt;br /&gt;
   &lt;br /&gt;
   PrintToServer(&amp;quot;[DEBUG] %s&amp;quot;, buffer)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Throwing Errors==&lt;br /&gt;
Often, your native will encounter an unrecoverable error, and you wish to trigger a fatal exception.  This is equivalent to &amp;lt;tt&amp;gt;IPluginContext::ThrowNativeError&amp;lt;/tt&amp;gt;, and will halt the current function execution in the plugin.  The debugger will be invoked and a backtrace will be printed out (if the plugin is in debug mode).  Although the current function is cancelled, the plugin will continue to operate normally afterward.&lt;br /&gt;
&lt;br /&gt;
For example, let's say we have a native that operates on clients.  We want to throw an error if we get a client index that is invalid or disconnected.  We could do this like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MyFunction(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new client = GetNativeCell(1)&lt;br /&gt;
   if (client &amp;lt; 1 || client &amp;gt; GetMaxClients())&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Invalid client index (%d)&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   if (!IsClientConnected(client))&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Client %d is not connected&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8692</id>
		<title>Creating Natives (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8692"/>
		<updated>2012-09-16T15:28:47Z</updated>

		<summary type="html">&lt;p&gt;FaTony: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod allows plugins to create their own natives that other plugins can use.  This is very similar to AMX Mod X's {{amxx_func|register_native}} function.  It is a powerful inter-plugin communication resource that can greatly enhance the functionality you provide.&lt;br /&gt;
&lt;br /&gt;
''Prerequisites:'' You should have a good grasp of Pawn or SourcePawn scripting, as well as how [[Tags (Scripting)|Tags]] work.&amp;lt;br&amp;gt;&lt;br /&gt;
''Note:'' Most functions herein can be found in the [[SourceMod SDK]], under &amp;lt;tt&amp;gt;plugins/include/functions.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Before creating natives, you should always document and specify exactly how they will work.  This means writing your &amp;quot;include file&amp;quot; beforehand.  Not only does this guide you in writing your natives, but it has the added benefit of completing a large portion of documentation at the same time.&lt;br /&gt;
&lt;br /&gt;
==Include File==&lt;br /&gt;
For our first example, let's start off with a simple native that adds two numbers, a float and a non-float.  It might look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/** Double-include prevention */&lt;br /&gt;
#if defined _mynatives_included_&lt;br /&gt;
  #endinput&lt;br /&gt;
#endif&lt;br /&gt;
#define _mynatives_included_&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Adds two numbers together.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num1    An integer.&lt;br /&gt;
 * @param num2    A float.&lt;br /&gt;
 * @return        The float value of the integer and float added together.&lt;br /&gt;
 */&lt;br /&gt;
native Float:My_AddNumbers(num1, num2);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The documentation and commenting style above is a SourceMod Development Team convention.  While you are not required to follow it for your own code, it may be a good idea to enhance readability (as readers will expect the style to conform).&lt;br /&gt;
&lt;br /&gt;
==Creating the Native==&lt;br /&gt;
To actually create the native, first let's define the native handler itself.  From &amp;lt;tt&amp;gt;functions.inc&amp;lt;/tt&amp;gt; we can see that this follows the prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;functag NativeCall public(Handle:plugin, numParams);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, we have a function like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we don't use the same function name as we did in our include file.  This is to prevent a possible ''name clash''.  Otherwise, two different symbols (one a native, another a function) could have the same name, and that's not allowed.  We'll see later how we bind the native to its actual name.&lt;br /&gt;
&lt;br /&gt;
Next, we need to implement our native.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   /* Retrieve the first parameter we receive */&lt;br /&gt;
   new num1 = GetNativeCell(1);&lt;br /&gt;
   /* Retrieve the second parameter we receive */&lt;br /&gt;
   new Float:num2 = Float:GetNativeCell(2);&lt;br /&gt;
   /* Add them together */&lt;br /&gt;
   new Float:value = num1 + num2;&lt;br /&gt;
   /* Return the value */&lt;br /&gt;
   return _:value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should note four important details.  The first is that we have to manually grab the parameters -- they're not easily sent via arguments.  This is for technical reasons that go beyond the scope of this document.  That means you have to know exactly ''how'' to grab each parameter.  For our example, we know that both parameters are simply cells, and thus we can use &amp;lt;tt&amp;gt;GetNativeCell&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
However, the second detail is that there is no &amp;lt;tt&amp;gt;GetNativeCellFloat&amp;lt;/tt&amp;gt;.  This is because a &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; is still a cell; the data is just interpreted differently.  Thus, we ''change'' the tag to &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; manual.  '''This is different from calling float(GetNativeCell(2)).'''  In fact, that would not work; the &amp;lt;tt&amp;gt;float()&amp;lt;/tt&amp;gt; call would interpret the cell as an integer, when in fact it's already a float, just with the wrong tag (i.e., no tag at all).&lt;br /&gt;
&lt;br /&gt;
Similarly, the third detail is that we cannot simply put &amp;lt;tt&amp;gt;return value&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;return FloatRound(value)&amp;lt;/tt&amp;gt;.  The reason is that our native is supposed to be returning a float.  If we return &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;, we'll get a tag mismatch.  If we return &amp;lt;tt&amp;gt;FloatRound(value)&amp;lt;/tt&amp;gt;, we'll be returning an integer when a float is expected.  The solution is to change the tag to the default tag, which will retain the value but remove the tag warning.&lt;br /&gt;
&lt;br /&gt;
Lastly, we did not need to verify &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt;.  The compiler will always send the correct amount of parameters - the user can't mess this up in any easy way.  Only if you use variadic arguments, or add parameters and need to support older binaries, do you need to handle &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt; variations.&lt;br /&gt;
&lt;br /&gt;
==Registering the Native==&lt;br /&gt;
Natives must be registered in &amp;lt;tt&amp;gt;AskPluginLoad2&amp;lt;/tt&amp;gt;.  Although they can be registered elsewhere, only this function guarantees that all other plugins will see your native.  The definition for this forward is in &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)&lt;br /&gt;
{&lt;br /&gt;
   CreateNative(&amp;quot;My_AddNumbers&amp;quot;, Native_My_AddNumbers);&lt;br /&gt;
   return APLRes_Success;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, any plugin will be able to use our native as if it were from a Core or a C++ extension.&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
==By-Reference==&lt;br /&gt;
Sometimes, it may be desirable to return data through by-reference parameters.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Closes a Handle, and sets the variable to INVALID_HANDLE by reference.&lt;br /&gt;
 *&lt;br /&gt;
 * @param hndl     Handle to close and clear.&lt;br /&gt;
 * @return         Anything that CloseHandle() returns.&lt;br /&gt;
 */&lt;br /&gt;
native bool:AltCloseHandle(&amp;amp;Handle:hndl);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_AltCloseHandle(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new Handle:hndl = Handle:GetNativeCellRef(1);&lt;br /&gt;
   SetNativeCellRef(1, 0);   /* Zero out the variable by reference */&lt;br /&gt;
   return CloseHandle(hndl);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we have a native that is &amp;quot;safer&amp;quot; than a normal &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;, as it ensures we don't hold onto invalid Handles.&lt;br /&gt;
&lt;br /&gt;
==Strings==&lt;br /&gt;
Strings can be retrieved and altered via dynamic natives.  Observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Converts a string to upper case.&lt;br /&gt;
 *&lt;br /&gt;
 * @param str      String to convert.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native StringToUpper(String:str[]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this is very easy, because of dynamic arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_StringToUpper(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new len;&lt;br /&gt;
   GetNativeStringLength(1, len);&lt;br /&gt;
&lt;br /&gt;
   if (len &amp;lt;= 0)&lt;br /&gt;
   {&lt;br /&gt;
      return;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new String:str[len + 1];&lt;br /&gt;
   GetNativeString(1, str, len + 1);&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; len; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* 5th bit specifies case in ASCII -- &lt;br /&gt;
       * this is not UTF-8 compatible.&lt;br /&gt;
       */&lt;br /&gt;
      if ((str[i] &amp;amp; (1 &amp;lt;&amp;lt; 5)) == (1 &amp;lt;&amp;lt; 5))&lt;br /&gt;
      {&lt;br /&gt;
         str[i] &amp;amp;= ~(1 &amp;lt;&amp;lt; 5)&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   SetNativeString(1, str, len+1, false);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Arrays==&lt;br /&gt;
Working with arrays is very similar to strings.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums an array of numbers and returns the sum.&lt;br /&gt;
 *&lt;br /&gt;
 * @param array     Array of numbers to sum.&lt;br /&gt;
 * @param size      Size of array.&lt;br /&gt;
 * @return          Sum of the array elements.&lt;br /&gt;
 */&lt;br /&gt;
native SumArray(const array[], size);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this could look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumArray(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new size = GetNativeCell(2)&lt;br /&gt;
   if (size &amp;lt; 1)&lt;br /&gt;
   {&lt;br /&gt;
      return 0&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new array[size], total&lt;br /&gt;
   GetNativeArray(1, array, size)&lt;br /&gt;
&lt;br /&gt;
   for (new i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i]&lt;br /&gt;
   }&lt;br /&gt;
   return total&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, there is a &amp;lt;tt&amp;gt;SetNativeArray&amp;lt;/tt&amp;gt;, which is used to alter array contents.&lt;br /&gt;
&lt;br /&gt;
==Variable Arguments==&lt;br /&gt;
Variable arguments are usually used when dealing with [[Format Class Functions (SourceMod Scripting)|format class functions]], however it is also possible to use them for general functionality.  The only trick is that unlike normal parameters, every variable argument parameter is passed by-reference.  This adds no change for arrays and strings, but for floats, handles, numbers, or anything else that fits in a cell, &amp;lt;tt&amp;gt;GetNativeCellRef&amp;lt;/tt&amp;gt; must be used instead.&lt;br /&gt;
&lt;br /&gt;
As an example, let's convert our function from above to use variable arguments:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums a list of numbers.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num    First number to use as a base.&lt;br /&gt;
 * @param ...    Any number of additional numbers to add.&lt;br /&gt;
 * @return       Sum of all numbers passed.&lt;br /&gt;
 */&lt;br /&gt;
native SumParams(num, ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumParams(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new base = GetNativeCell(1)&lt;br /&gt;
   for (new i=2; i&amp;lt;=numParams; i++)&lt;br /&gt;
   {&lt;br /&gt;
      base += GetNativeCellRef(i)&lt;br /&gt;
   }&lt;br /&gt;
   return base&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Format Functions==&lt;br /&gt;
It is also possible to create your own [[Format Class Functions (SourceMod Scripting)|format class functions]].  This topic is much more complicated than the previous ones, as the native string formatter allows for many different configurations.  This is mainly for optimization.  Note that a formatting routine deals with two buffers: the input format string, and the output buffer.  &amp;lt;tt&amp;gt;FormatNativeString&amp;lt;/tt&amp;gt;, by default, uses parameter indexes directly so you don't have to copy or locally store any of these buffers.&lt;br /&gt;
&lt;br /&gt;
The most common usage of this is to accept a user-formatted string and to not&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Prints a message with a [DEBUG] prefix to the server.&lt;br /&gt;
 *&lt;br /&gt;
 * @param fmt         Format string.&lt;br /&gt;
 * @param ...         Format arguments.&lt;br /&gt;
 */&lt;br /&gt;
native DebugPrint(const String:fmt[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be easily implemented as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native DebugPrint(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   decl String:buffer[1024], written&lt;br /&gt;
&lt;br /&gt;
   FormatNativeString(0, /* Use an output buffer */&lt;br /&gt;
      1, /* Format param */&lt;br /&gt;
      2, /* Format argument #1 */&lt;br /&gt;
      sizeof(buffer), /* Size of output buffer */&lt;br /&gt;
      written, /* Store # of written bytes */&lt;br /&gt;
      buffer /* Use our buffer */&lt;br /&gt;
      )&lt;br /&gt;
   &lt;br /&gt;
   PrintToServer(&amp;quot;[DEBUG] %s&amp;quot;, buffer)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Throwing Errors==&lt;br /&gt;
Often, your native will encounter an unrecoverable error, and you wish to trigger a fatal exception.  This is equivalent to &amp;lt;tt&amp;gt;IPluginContext::ThrowNativeError&amp;lt;/tt&amp;gt;, and will halt the current function execution in the plugin.  The debugger will be invoked and a backtrace will be printed out (if the plugin is in debug mode).  Although the current function is cancelled, the plugin will continue to operate normally afterward.&lt;br /&gt;
&lt;br /&gt;
For example, let's say we have a native that operates on clients.  We want to throw an error if we get a client index that is invalid or disconnected.  We could do this like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MyFunction(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new client = GetNativeCell(1)&lt;br /&gt;
   if (client &amp;lt; 1 || client &amp;gt; GetMaxClients())&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Invalid client index (%d)&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   if (!IsClientConnected(client))&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Client %d is not connected&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8691</id>
		<title>Creating Natives (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Creating_Natives_(SourceMod_Scripting)&amp;diff=8691"/>
		<updated>2012-09-16T15:27:29Z</updated>

		<summary type="html">&lt;p&gt;FaTony: /* Creating the Native */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod allows plugins to create their own natives that other plugins can use.  This is very similar to AMX Mod X's {{amxx_func|register_native}} function.  It is a powerful inter-plugin communication resource that can greatly enhance the functionality you provide.&lt;br /&gt;
&lt;br /&gt;
''Prerequisites:'' You should have a good grasp of Pawn or SourcePawn scripting, as well as how [[Tags (Scripting)|Tags]] work.&amp;lt;br&amp;gt;&lt;br /&gt;
''Note:'' Most functions herein can be found in the [[SourceMod SDK]], under &amp;lt;tt&amp;gt;plugins/include/functions.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Before creating natives, you should always document and specify exactly how they will work.  This means writing your &amp;quot;include file&amp;quot; beforehand.  Not only does this guide you in writing your natives, but it has the added benefit of completing a large portion of documentation at the same time.&lt;br /&gt;
&lt;br /&gt;
==Include File==&lt;br /&gt;
For our first example, let's start off with a simple native that adds two numbers, a float and a non-float.  It might look like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/** Double-include prevention */&lt;br /&gt;
#if defined _mynatives_included_&lt;br /&gt;
  #endinput&lt;br /&gt;
#endif&lt;br /&gt;
#define _mynatives_included_&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Adds two numbers together.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num1    An integer.&lt;br /&gt;
 * @param num2    A float.&lt;br /&gt;
 * @return        The float value of the integer and float added together.&lt;br /&gt;
 */&lt;br /&gt;
native Float:My_AddNumbers(num1, num2);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The documentation and commenting style above is a SourceMod Development Team convention.  While you are not required to follow it for your own code, it may be a good idea to enhance readability (as readers will expect the style to conform).&lt;br /&gt;
&lt;br /&gt;
==Creating the Native==&lt;br /&gt;
To actually create the native, first let's define the native handler itself.  From &amp;lt;tt&amp;gt;functions.inc&amp;lt;/tt&amp;gt; we can see that this follows the prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;functag NativeCall public(Handle:plugin, numParams);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, we have a function like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we don't use the same function name as we did in our include file.  This is to prevent a possible ''name clash''.  Otherwise, two different symbols (one a native, another a function) could have the same name, and that's not allowed.  We'll see later how we bind the native to its actual name.&lt;br /&gt;
&lt;br /&gt;
Next, we need to implement our native.  &lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_My_AddNumbers(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   /* Retrieve the first parameter we receive */&lt;br /&gt;
   new num1 = GetNativeCell(1);&lt;br /&gt;
   /* Retrieve the second parameter we receive */&lt;br /&gt;
   new Float:num2 = Float:GetNativeCell(2);&lt;br /&gt;
   /* Add them together */&lt;br /&gt;
   new Float:value = num1 + num2;&lt;br /&gt;
   /* Return the value */&lt;br /&gt;
   return _:value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should note four important details.  The first is that we have to manually grab the parameters -- they're not easily sent via arguments.  This is for technical reasons that go beyond the scope of this document.  That means you have to know exactly ''how'' to grab each parameter.  For our example, we know that both parameters are simply cells, and thus we can use &amp;lt;tt&amp;gt;GetNativeCell&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
However, the second detail is that there is no &amp;lt;tt&amp;gt;GetNativeCellFloat&amp;lt;/tt&amp;gt;.  This is because a &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; is still a cell; the data is just interpreted differently.  Thus, we ''change'' the tag to &amp;lt;tt&amp;gt;Float&amp;lt;/tt&amp;gt; manual.  '''This is different from calling float(GetNativeCell(2)).'''  In fact, that would not work; the &amp;lt;tt&amp;gt;float()&amp;lt;/tt&amp;gt; call would interpret the cell as an integer, when in fact it's already a float, just with the wrong tag (i.e., no tag at all).&lt;br /&gt;
&lt;br /&gt;
Similarly, the third detail is that we cannot simply put &amp;lt;tt&amp;gt;return value&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;return FloatRound(value)&amp;lt;/tt&amp;gt;.  The reason is that our native is supposed to be returning a float.  If we return &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;, we'll get a tag mismatch.  If we return &amp;lt;tt&amp;gt;FloatRound(value)&amp;lt;/tt&amp;gt;, we'll be returning an integer when a float is expected.  The solution is to change the tag to the default tag, which will retain the value but remove the tag warning.&lt;br /&gt;
&lt;br /&gt;
Lastly, we did not need to verify &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt;.  The compiler will always send the correct amount of parameters - the user can't mess this up in any easy way.  Only if you use variadic arguments, or add parameters and need to support older binaries, do you need to handle &amp;lt;tt&amp;gt;numParams&amp;lt;/tt&amp;gt; variations.&lt;br /&gt;
&lt;br /&gt;
==Registering the Native==&lt;br /&gt;
Natives must be registered in &amp;lt;tt&amp;gt;AskPluginLoad2&amp;lt;/tt&amp;gt;.  Although they can be registered elsewhere, only this function guarantees that all other plugins will see your native.  The definition for this forward is in &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)&lt;br /&gt;
{&lt;br /&gt;
   CreateNative(&amp;quot;My_AddNumbers&amp;quot;, Native_My_AddNumbers);&lt;br /&gt;
   return APLRes_Success;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, any plugin will be able to use our native as if it were from a Core or a C++ extension.&lt;br /&gt;
&lt;br /&gt;
=Usage=&lt;br /&gt;
==By-Reference==&lt;br /&gt;
Sometimes, it may be desirable to return data through by-reference parameters.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Closes a Handle, and sets the variable to INVALID_HANDLE by reference.&lt;br /&gt;
 *&lt;br /&gt;
 * @param hndl     Handle to close and clear.&lt;br /&gt;
 * @return         Anything that CloseHandle() returns.&lt;br /&gt;
 */&lt;br /&gt;
native bool:AltCloseHandle(&amp;amp;Handle:hndl);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_AltCloseHandle(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new Handle:hndl = Handle:GetNativeCellRef(1);&lt;br /&gt;
   SetNativeCellRef(1, 0);   /* Zero out the variable by reference */&lt;br /&gt;
   return CloseHandle(hndl);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we have a native that is &amp;quot;safer&amp;quot; than a normal &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt;, as it ensures we don't hold onto invalid Handles.&lt;br /&gt;
&lt;br /&gt;
==Strings==&lt;br /&gt;
Strings can be retrieved and altered via dynamic natives.  Observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Converts a string to upper case.&lt;br /&gt;
 *&lt;br /&gt;
 * @param str      String to convert.&lt;br /&gt;
 * @noreturn&lt;br /&gt;
 */&lt;br /&gt;
native StringToUpper(String:str[]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this is very easy, because of dynamic arrays:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_StringToUpper(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new len&lt;br /&gt;
   GetNativeStringLength(1, len)&lt;br /&gt;
&lt;br /&gt;
   if (len &amp;lt;= 0)&lt;br /&gt;
   {&lt;br /&gt;
      return&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new String:str[len+1]&lt;br /&gt;
   GetNativeString(1, str, len+1)&lt;br /&gt;
&lt;br /&gt;
   for (new i=0; i&amp;lt;len; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* 5th bit specifies case in ASCII -- &lt;br /&gt;
       * this is not UTF-8 compatible.&lt;br /&gt;
       */&lt;br /&gt;
      if ((str[i] &amp;amp; (1&amp;lt;&amp;lt;5)) == (1&amp;lt;&amp;lt;5))&lt;br /&gt;
      {&lt;br /&gt;
         str[i] &amp;amp;= ~(1&amp;lt;&amp;lt;5)&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   SetNativeString(1, str, len+1, false)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Arrays==&lt;br /&gt;
Working with arrays is very similar to strings.  For example, observe the following native prototype:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums an array of numbers and returns the sum.&lt;br /&gt;
 *&lt;br /&gt;
 * @param array     Array of numbers to sum.&lt;br /&gt;
 * @param size      Size of array.&lt;br /&gt;
 * @return          Sum of the array elements.&lt;br /&gt;
 */&lt;br /&gt;
native SumArray(const array[], size);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this could look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumArray(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new size = GetNativeCell(2)&lt;br /&gt;
   if (size &amp;lt; 1)&lt;br /&gt;
   {&lt;br /&gt;
      return 0&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   new array[size], total&lt;br /&gt;
   GetNativeArray(1, array, size)&lt;br /&gt;
&lt;br /&gt;
   for (new i=0; i&amp;lt;size; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i]&lt;br /&gt;
   }&lt;br /&gt;
   return total&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, there is a &amp;lt;tt&amp;gt;SetNativeArray&amp;lt;/tt&amp;gt;, which is used to alter array contents.&lt;br /&gt;
&lt;br /&gt;
==Variable Arguments==&lt;br /&gt;
Variable arguments are usually used when dealing with [[Format Class Functions (SourceMod Scripting)|format class functions]], however it is also possible to use them for general functionality.  The only trick is that unlike normal parameters, every variable argument parameter is passed by-reference.  This adds no change for arrays and strings, but for floats, handles, numbers, or anything else that fits in a cell, &amp;lt;tt&amp;gt;GetNativeCellRef&amp;lt;/tt&amp;gt; must be used instead.&lt;br /&gt;
&lt;br /&gt;
As an example, let's convert our function from above to use variable arguments:&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Sums a list of numbers.&lt;br /&gt;
 *&lt;br /&gt;
 * @param num    First number to use as a base.&lt;br /&gt;
 * @param ...    Any number of additional numbers to add.&lt;br /&gt;
 * @return       Sum of all numbers passed.&lt;br /&gt;
 */&lt;br /&gt;
native SumParams(num, ...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An implementation of this would look like:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Native_SumParams(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new base = GetNativeCell(1)&lt;br /&gt;
   for (new i=2; i&amp;lt;=numParams; i++)&lt;br /&gt;
   {&lt;br /&gt;
      base += GetNativeCellRef(i)&lt;br /&gt;
   }&lt;br /&gt;
   return base&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Format Functions==&lt;br /&gt;
It is also possible to create your own [[Format Class Functions (SourceMod Scripting)|format class functions]].  This topic is much more complicated than the previous ones, as the native string formatter allows for many different configurations.  This is mainly for optimization.  Note that a formatting routine deals with two buffers: the input format string, and the output buffer.  &amp;lt;tt&amp;gt;FormatNativeString&amp;lt;/tt&amp;gt;, by default, uses parameter indexes directly so you don't have to copy or locally store any of these buffers.&lt;br /&gt;
&lt;br /&gt;
The most common usage of this is to accept a user-formatted string and to not&lt;br /&gt;
&amp;lt;pawn&amp;gt;/**&lt;br /&gt;
 * Prints a message with a [DEBUG] prefix to the server.&lt;br /&gt;
 *&lt;br /&gt;
 * @param fmt         Format string.&lt;br /&gt;
 * @param ...         Format arguments.&lt;br /&gt;
 */&lt;br /&gt;
native DebugPrint(const String:fmt[], any:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be easily implemented as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native DebugPrint(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   decl String:buffer[1024], written&lt;br /&gt;
&lt;br /&gt;
   FormatNativeString(0, /* Use an output buffer */&lt;br /&gt;
      1, /* Format param */&lt;br /&gt;
      2, /* Format argument #1 */&lt;br /&gt;
      sizeof(buffer), /* Size of output buffer */&lt;br /&gt;
      written, /* Store # of written bytes */&lt;br /&gt;
      buffer /* Use our buffer */&lt;br /&gt;
      )&lt;br /&gt;
   &lt;br /&gt;
   PrintToServer(&amp;quot;[DEBUG] %s&amp;quot;, buffer)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Throwing Errors==&lt;br /&gt;
Often, your native will encounter an unrecoverable error, and you wish to trigger a fatal exception.  This is equivalent to &amp;lt;tt&amp;gt;IPluginContext::ThrowNativeError&amp;lt;/tt&amp;gt;, and will halt the current function execution in the plugin.  The debugger will be invoked and a backtrace will be printed out (if the plugin is in debug mode).  Although the current function is cancelled, the plugin will continue to operate normally afterward.&lt;br /&gt;
&lt;br /&gt;
For example, let's say we have a native that operates on clients.  We want to throw an error if we get a client index that is invalid or disconnected.  We could do this like so:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public MyFunction(Handle:plugin, numParams)&lt;br /&gt;
{&lt;br /&gt;
   new client = GetNativeCell(1)&lt;br /&gt;
   if (client &amp;lt; 1 || client &amp;gt; GetMaxClients())&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Invalid client index (%d)&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   if (!IsClientConnected(client))&lt;br /&gt;
   {&lt;br /&gt;
      return ThrowNativeError(SP_ERROR_NATIVE, &amp;quot;Client %d is not connected&amp;quot;, client)&lt;br /&gt;
   }&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>FaTony</name></author>
		
	</entry>
</feed>