# MIRC Scripting/Basics/Basics

Chapter 2: Getting Started
Starting From Scratch: Become Familiar with mIRC | Getting Started Learning the Ropes: Branching and Loops | Timers | User Levels | Text Matching | File Handling | Hash Tables | Dialogs Advanced Subjects: Custom Windows | Agents | Sockets Planned: DLLs | COM Objects | Error Checking and Handling
You've got the foundation to use mIRC and the Scripts Editor. Now we can start with learning how to script. Read this chapter section by section and follow along with the examples. You will need to understand the skills in this chapter to move on and make any sort of script whatsoever. This is a very long chapter, especially for beginners, so take your time reading this.

## Types of Scripts

There are three types of scripts in mIRC.; aliases, popups, and remotes. Each one is comprised of different parts and has its own tab in the scripts editor.

### Aliases

Aliases are user-defined commands that stand for a set of one or more commands. Aliases are usually used to simplify everyday IRC tasks, such as identifying your nickname. The syntax of an alias is:
* aliasname command
An example of an alias placed in the aliases tab of your script editor would look something like this:
* hello say Hi, I'm $me and I am an mIRC user.
The first part of the alias is hello. This is the alias' name. You would type the command /hello in the command line. The say Hi, I'm $me and I am an mIRC user. part is the command that is executed when you type /hello. Typing /hello and pressing Enter would result in the line showing up in the current window saying "Hi, I'm mynickname and I am an mIRC user."
One important thing to take note of is that I didn't use a / before the alias name or the command. This is unnecessary in the scripts editor. mIRC prefixes every command in a script with a //, which runs every command and evaluates any variables or identifiers in the command automatically. So, mIRC would treat both of these the exact same way:
* /hello /say Hi, I'm $me and I am an mIRC user.
* hello say Hi, I'm $me and I am an mIRC user.

#### Multi-line Aliases

mIRC requires anything spanning multiple lines to be enclosed in brackets ({ and }). For example, the alias hello that we had above could use /say twice. This could be accomplished using this code:
* hello {
* say Hi, I'm $me and I am an mIRC user.
* say Do you use mIRC too?
WARNING: Another method of doing multi-command blocks of code in mIRC Scripting is called piping, where a pipe character (|) is stuck in between the two commands, such as /echo hi! | /echo goodbye! This makes hard to read code, takes mIRC longer to process, and in general is bad coding practice. Use it sparingly.

#### Function Key Aliases

Function keys can also be given functions using aliases. Enter the following script in your script editor under Aliases.
* F1 {
* var %n = $?="What's your nickname and password?"
* tokenize 32 %n
* nick $1
* msg nickserv identify $2
Now push F1 on your keyboard. You should see a little dialog box pop up asking for your nickname and password. Enter a nickname, and a password for NickServ if you have one, and hit enter. The script should try and change your nick and identify you to NickServ. Note that depending on your network, you may not have a Nickname Service.
If 12 Fkeys aren't enough for you, well, you can assign up to 36 commands to Fkeys. Use c or s behind an fkey to make the alias work for the key combinations "shift + FX" or "Ctrl + FX."
* sF1 {
* var %n = $?="What's your nickname and password?"
* tokenize 32 %n
* nick $1
* msg nickserv identify $2
See the s before the F1? It's the only thing that changed since the last example. However, instead of pressing F1 to activate it, hold shift and press F1. The same thing should happen as last time.
One more notable thing about function key aliases: you can can use them on the command line by typing the name of the alias, like any old alias name. For the alias we made, you would simply type /sF1.

#### Aliases in Remote Scripts

Aliases also serve a much more important purpose than simply doing a set of commands. Aliases in remote scripts can be used to shorten code and reuse a certain set of commands over and over, which makes writing code a lot easier. Aliases change their syntax a bit when in remote scripts.
* alias aliasname command(s)
To do an alias in a remote section, it must have the alias prefix. For example, the command I just made above would now look like
* alias hello {
* say Hi, I'm $me and I am an mIRC user.
* say Do you use mIRC too?
The alias prefix is the only thing that changes. Running the alias still works the same; type /hello to see the lines of text on the screen.
The real advantage of putting an alias inside a remote script is being able to use it repeatedly. For example, maybe you have an alias that increases a number three times. Technically, you can use the /inc command to do this, but for the sake of the example, we'll make our own alias.
* alias incnum3 {
* // $1 is the first paramter passed to /incnum3.
* // So if you use /incnum3 7, $1 =7
* var %x = $1
* incnum %x
* incnum %x
* incnum %x
* echo %x
* alias incnum {
* inc %x
See how I used the incnum alias three times? If this was a longer script, I could have saved myself a lot of time and typing by using aliases multiple times. People familiar to other programming/scripting languages will notice that aliases, in this respect, are similar to functions or subroutines that can be recycled.

#### Local Aliases

If you only want a command to be able to run in one script, or it would overwrite a command built-in to mIRC or another script, you can do alias -l in front of the alias name. The -l is a switch that tells the alias ONLY to work when called from a script inside that remote file. Let's take our previous example and add a local alias.
* alias incnum3 {
* // $1 is the first parameter passed to /incnum3.
* // So if you use /incnum3 7, $1 =7
* var %x = $1
* incnum %x
* incnum %x
* incnum %x
* echo %x
* alias -l incnum {
* inc %x
Now you cannot use /incnum from the command line or from other scripts, but the alias /incnum3 CAN call it.

#### Recursive Aliases

mIRC cannot call an alias from inside itself. For example, this code would not work:
* alias echomyname {
* echo -a Hi I'm $me $+ !
* echomyname
You cannot use /echomyname recursively inside itself. You CAN call it from another alias, however.
* alias echomyname {
* echo -a Hi I'm $me $+ !
* echomyname2
* alias echomyname2 {
* echo -a Hi I'm $me $+ ! This is a recursive alias.
* echomyname
That would work, although it would loop forever, and most likely crash mIRC. Crashing programs is generally a bad idea. And it's quite embarrassing for you when your own program locks up in an infinite loop. So don't do it.
Now, there is one caveat to this recursive alias business. Say you wanted to write over an alias with a custom one of your own. When you call an alias from inside itself, and it has a built-in mIRC version, the alias will call mIRC's version. Take a look at this example:
* alias k {
* inc %k
* kick $1- Total kicks %k
Let's say you wanted to overwrite the kick alias to say how many kicks you've done. You could do /k from now on. Or, using the knowledge that mIRC can't recurse aliases, you could do this:
* alias kick {
* inc %k
* kick $1- Total kicks %k
This will increase your kick count and kick the user you want from the channel, WITH the Total Kicks message. This comes in very useful in more advanced scripting, especially when making themes for full scripts.

### Popups

Popups are user-defined context menus that show up at certain places in mIRC when you right-click. There are five popups you can customize; one on the Menu Bar, one in the status window, one on the nicklist, one in channels, and one in private messages.

#### Making Menus

Open your scripts editor to the Popup tab. I'll be using the Channel tab for the purposes of this book. To define a simple menu item, the syntax is:
* Menuitem: command(s)
So, to make a simple menu item that would change your nickname to "mIRCUser" you could do this:
* Change Nick: nick mIRCUser

#### Submenus

Now right click in any channel. You should see an option saying "Change Nick →" appear. Click it. Your nick, provided it isn't in use, should change to mIRCUser. But what if you have more than one nickname you like to use. Maybe you have the nicknames mIRCUser, Cakeman, and Blackknight. You can add a submenu to this existing menu.
* Change Nick To
* .mIRCUser: nick mIRCUser
* .Cakeman: nick Cakeman
* .Blackknight: nick Blackknight
Now, right-click in the channel again. You should see a menu looking something like "Change Nick To →". If you hover over the menu, you get three choices; mIRCUser, Cakeman, and Blacknight, all three of your nicks. You can even make submenus inside your menus.
* Change Nick To
* .Nickname
* ..mIRCUser: nick mIRCUser
* ..Cakeman: nick Cakeman
* ..Blackknight: nick Blackknight

#### Multi-Line Menus

But what if your server has a Nickname Service and you identify with your nicks, like in the fkey alias example? Well, popup menu definitions can have multi-line sections just like other parts of scripts using { and }.
* Change Nick To
* .Nickname
* ..mIRCUser:{
* nick mIRCUser
* ns identify password
* ..Cakeman:{
* nick Cakeman
* ns identify password
* ..Blackknight:{
* nick Blackknight
* ns identify password

#### Nicklist Menus

Making menus in a nicklist is relatively similar to making regular menus, except you need to specify which nicklist nick is being affected. This is specified by the identifier $1. Take note that these menus go under the Nicklist view in the Popups tab.
* Kick $$1: kick $$chan $$1 You got kicked by $me $+ !
* Ban $$1: mode $$chan +b $address($$1,2)
* Kickban $$1: ban -k $$chan $$1 2 You got kickbanned by $me $+ !
The identifier $$1 in this case means the same thing as $1. It is the nickname selected on the nicklist (if there is one and you are in a channel). When you click on an option (kick, ban, or kickban), it will do that option to whatever nickname is in $$1. For example, the kick option kicks $$1 from $$chan with the message, "You got kicked by mynick!"
Now, allow me to use this example to explain the double $$ prefix. When used with an identifier, this will stop a command from executing if the identifier returns $null. For instance, if you did not select a nick on the nicklist, $$1 returns nothing and halts the command. As an added aesthetic bonus, if a double-prefixed identifier returns nothing in a menu item, the menu item will not show up. In this example, the entire menu would be hidden from view if you did not select a nick on the nicklist.
Nicklist menus also support everything regular menus support. You can use multi-line commands, submenus, etc. They work exactly the same. The only real caveat to using pop up menus that target a user in the nicklist is to remember to use $1 or $$1.

#### Menu Bar Menus

Menu Bar menus work like the rest of the popup menus, except they appear in the menu bar at the top of the mIRC Windows under the "Commands" menu. You can also change the name of the Commands menu, if you'd like. On the first line of a popup file under the menu bar section, put the word Pie. Save the file and look at your menu bar. The menu should now be labeled "Pie."

#### Identifiers and Variables In Menu Items

Variables and identifiers in menu items are evaluated each time a menu is opened. As seen in the previous example, a nicklist menu like this:
* Kick $$1: kick $$chan $$1 You got kicked by $me $+ !
* Ban $$1: mode $$chan +b $address($$1,2)
* Kickban $$1: ban -k $$chan $$1 2 You got kickbanned by $me $+ !
Would have $$1 evaluated each time you open then menu.
* %mytext:%mycmd
If you have variables set called %mytext and %mycmd then the menu item will appear clickable. If you only have %mytext set, the item will appear, but grayed out and disabled. If you only have %mycmd% set, The menu item will evaluate to $null and not appear at all in the menu.
The advantage of using identifiers and variables in popup menus is to make them more dynamic, as seen in the kick/ban menu example above.

#### Popups in Remote Files

Much like aliases, popups can be defined in remote files, in almost the same way. You simply use the menu [menuname] prefix, and then enclose the menu commands in brackets. Menuname is the location of the popup; either channel, status, query, menubar, or nicklist. Unlike the Popups tab, a menu under the Remote tab does not know where to open it the menu, so you must say it after the menu prefix.
* menu channel {
* Get Channel Info: channel
This is roughly the same as the default menu in mIRC under the Popups/Channel tab, however, it is in a remote file now, with the menu prefix attached.
* menu channel,query {
* Slap Someone!: me slaps a random user with a large trout.
Menus in remote files can also have multiple menu names of where the menu should pop up. This one will pop up in a channel window OR a query window.

#### Popup Menu Styles

Menu Styles are used to change the look of your menu items. You can make a menu item appear checked off or disabled using menu styles. There are three menu styles you can use, using the $style identifier.
Menu Styles :
| Style | Result |
| $style(1) Checked Item | √ Checked Item |
| $style(2) Disabled Item | Disabled Item |
| $style(3) Checked and Disabled Item | √ Checked and Disabled Item |
This is an example of a menu that uses styles to disable items if you are not connected to a server.
* menu status {
* $iif(!$server,$style(2),$style(1)) Join #mIRC: join #mIRC
* $iif(!$server,$style(2),$style(1)) Get a list of channels: list
If mIRC is not connected to a server, both commands will be disabled. If you ARE connected, both of them will be enabled and have check marks (√) next to them.

#### $submenu

$submenu is a fairly advanced identifier that makes a dynamic submenu for a popup menu. It calls a custom identifier with the parameter $1, where 1 is a number that increases each time it runs through the identifier, until it stops. Sound confusing? Perhaps this code example will help.
* ; The Identifier $submenu calls; generates a list of channels.
* alias _infochan {
* if ($1 == begin) return -
* if ($chan($1) ischan) return $ifmatch : .msg chanserv info $ifmatch
* if ($1 == end) return -
* ; Check to see if ChanServ exists on the network you are on.
* alias _cschk {
* .notify ChanServ $network
* if ($notify(ChanServ) > 0) { var %csison = 1 }
* elseif ($notify(ChanServ) < 1) { var %csison = 0 }
* .timer 1 1 .notify -r ChanServ
* return %csison
* menu status {
* ; If there is no Chanserv, hide the menu.
* $iif($_cschk < 1,$style(2)) Get Channel Info
* ; Else, list the channels.
* .$submenu($_infochan($1))
The main thing to pay attention to here is how $submenu is used. $submenu Inserts the value 1 into $1, then increases that each time it goes through until it ends. So for $chan($1) in the custom identifier $_infochan will return the first channel you are on, then the second one, and so on, until you run out of channels.
Let's assume you are on #mIRC, #Windows, and #Scripting, and ChanServ is on your network. If you right-click in your status window, you will see a menu saying "Get Channel Info →" and three menu items in that menu's submen; #mIRC, #Windows, and #Scripting. Clicking on one of those will do a /msg chanserv info on the channel. This command returns information about a registered channel, if it is registered. The output would look something like this:
* -ChanServ- Information for channel #scripting:<br />
* -<br />
* -ChanServ- Founder: Master_Scripter<br />
* -<br />
* -ChanServ- Description: Help Channel for mIRC Scripting<br />
* -<br />
* -ChanServ- Registered: Nov 14 20:24:34 2005 CST<br />
* -<br />
* -ChanServ- Last used: Mar 24 11:02:55 2008 CDT<br />
* -<br />
* -ChanServ- Last topic: ^[ Scripting Help Channel ]^<br />
* -<br />
* -ChanServ- Topic set by: Master_Scripter<br />
* -<br />
* -ChanServ- URL: http://www.someurl.com<br />
* -<br />
* -ChanServ- E-mail address: someemail@email.com<br />
* -<br />

#### Menu Separators

To separate menu items, you can use a single '-' (hyphen) in between items.

### Remote Scripts

Remote scripts make up the majority of what you will script in mIRC. They are a combination of aliases, popup menus, and event-driven blocks of commands. Unlike aliases and popups, you can have multiple remotes loaded at the same time. Each remote file usually contains one script. An individual script is a remote file (a file ending in .mrc or .ini) with related events, aliases, and popup definitions. An example of a script could be a script that makes you join a channel when you connect to a server, or manage a list of quotes people have said on IRC. The basic syntax of a remote event looks like this:

#### Remote Events

* On *:Event:parameters:{
* commands
The * is what user level the event will trigger on. User levels are defined later in this section. Typically, events will usually have a user level of * or 1. * means the event will trigger on any level, and the 1 means it will trigger by anyone with a user level of 1 or higher (1 is the default level in mIRC, unless you change it, so this will also usually mean anyone). The event is the name of the event you are defining. Examples of events are Text, Action, Ban, Join, and Part. You should only have one type of each event in a script for them to work right. The parameters part of the event can be anything. It's usually match text, where the event takes place, both, or neither of them. Inside this event block are all the commands you want the script to do.
* On *:Text:*:#:{
* if (hello isin $1-) {
* msg $chan Why hello there $nick $+ !
This is an example of one of the more popular remote events, and one of the easiest to understand. It triggers whenever someone says text that matches the matchtext. The matchtext in this case is *, the wild card symbol. This means it will match anything. The if-then-else statement in the event's body determines what text it matches. This is a better idea in practice when using events. Instead of using multiple events that match different things, using one event that uses if-then-else statements will ensure that everything is processed in the right order. In this case, the script checks to see if the word "hello" is in the text said, but only in channels. The # after the * is what determines where the event triggers. You can also specify a ? for private messages only, and * to make it trigger in both channels and PMs.
* On *:Load:{
* echo -a Thank you for loading my script!
This is another example of a remote event. This one has no parameters. The event simply triggers when you load the script it is in. When you load this script, it will display the line on your screen, "Thank you for loading my script!".
One important thing to know about remote event scripts is that most of them do not work when you trigger them yourself. Some events do, like On Kick or On Ban, while others like On Text will not work when you say something in a channel with the script loaded. mIRC will generally say in the help file when you can or can't trigger it yourself. Otherwise, it's trial and error.

#### CTCP Events

CTCP Events are events that trigger when you get a CTCP (client-to-client protocol) from another client. A CTCP event can be used to override a default mIRC action for a CTCP event (with the exception of VERSION), but can also be used to make your own CTCP replies.
* CTCP *:secretword:*:{
* if ($2 == moo) { msg $nick You got the secret word! }
* else { msg $nick Sorry, you're wrong. }
* CTCP *:ctcpname:*|#|?:{
* commands
A CTCP event looks very similar to a regular remote event. However, instead of the On prefix, CTCP events start with CTCP. The * is still the same; the access level required to trigger the event. Ctcpname is the name of the ctcp the event should trigger on. This could be anything from a built-in CTCP event such as TIME or VERSION or a made-up event such as BLAH or HELLO. The location parameter, again, is the same as a regular event. # is a channel, ? is a PM, and * is both.
* CTCP *:secretword:*:{
* if ($2 == moo) { msg $nick You got the secret word! }
* else { msg $nick Sorry, you're wrong. }
This event will respond any time someone CTCPs you with the text "secretword." It will check and see if the word they gave matches the secret word. If it matches, the script will PM them saying so.
* CTCP *:%secretword:*:{
* msg $nick You got the secret word!
Using a variable (%secretword) as the matchtext for the CTCP event, you can change the secret word any time and shorten the code. Now, the script will only respond when they CTCP you with the correct word.
* CTCP *:Version:*:{
* ctcpreply $nick VERSION MyScript version 1.0
While you can't hide the original mIRC version reply itself, you can add your own reply to the standard one. This one will send a CTCP reply back using /ctcpreply to the person who CTCP'd you with your custom version reply, after the mIRC one.
* CTCP *:*help*:*:{
* msg $nick What can I help you with, $nick $+ ?
By enclosing the matchtext in wildcards, this script will trigger any time anyone says the word help anywhere in the CTCP query, and msg them back.

#### Raw Events

Raw events are advanced events that trigger when you receive a raw numeric from a server. This happens when you send a query to a server using a command such as /whois and you get a reply back.
* Raw numeric:matchtext:{
* commands
Unlike remotes and CTCPs, Raw events ONLY trigger in your client, when you receive raw numerics from the IRC server. This happens when you get a reply after sending a query to a server; for example, using /whois or /away.
* Raw 431:*:{
* .haltdef
* echo -s ERROR: Raw 431 - No nickname given.
This event replaces mIRC's default reply for Raw 431, the message you get when you fail to specify a target for a command like /whois or /nick. It silences the default reply using /haltdef.
You may know how to use remote events now, but they are only a small fraction of making remote scripts. Making the events themselves is simple, but there is a huge amount commands to put inside the events. This is the real challenge of mIRC scripting, and what the remaining bulk of this book will cover.

## Variables

Variables are dynamic values that evaluate each time the script is run to a certain value. Variables are assigned a certain value and always return their current value when called upon. In mIRC Scripting, variables are untyped. This means that a variable can store any type of data; text, numbers, or any combination of the two. A variable starts with a % prefix. There are two kinds of variables; local and global.

### Local Variables

Local variables are created during scripts, and do not overwrite other local variables or global variables of the same name. Local variables are destroyed after the calling script executes.
* alias saysomething {
* var %text = $$?="What should I say?"
* echo -a %text
If you type /saysomething and hit enter, a box will come up asking, "What should I say?". Enter some text and hit okay. That text will get put into %text, and then whatever is in %text will be echoed to the screen. %text will not exist after the script ends. Try typing //echo -a %text into the command line. You should get a * /echo: insufficient parameters error. This is because variables evaluate to $null if they do not exist.

### Global Variables

Global variables stay around once they are set, until they are unset, unlike local variables.
* On *:Connect:{
* if (!%connnick) {
* set %connnick $?="What do you want your nickname to be?"
* nick %connnick
When you connect to a server, the server will ask you what you want your nickname to be if the variable %connnick doesn't exist. Either way, it will change your nickname to whatever is in %connnick. Now, open your script editor and open the Variables tab. You should see a variable called %connnick with a value of whatever nickname you chose. You may also see other variables, if you have run other scripts. These variables are all global, and will stick around under the Variables tab and return a value, until you use the /unset command.
* On *:Connect:{
* if (!%connnick) {
* set -u0 %connnick $?="What do you want your nickname to be?"
* nick %connnick
Notice the difference in this script? The variable %connnick, in a sense, will act like a global variable in this script because of the -u0 flag in the /set command. -uN make the global variable unset after N seconds. However, if you specify 0 for N, the variable will unset when the script finishes executing. It is not completely like a local variable; other global variables can overwrite it, and vice-versa. However, it is still a way to make sure the script cleans up all its global variables when it finishes.

### Mathematical Equations With Variables

There are two ways to perform mathematical operations on variables; the commands /inc and /dec, and the = (assignment operator).
* alias incnum2 {
* var %num = $$1
* inc %num
* inc %num
* echo -a Your number was increased by two! You got %num $+ !
This alias will take any number you give it, assign it to a variable, and increases it twice using /inc. For example, if you did /incnum2 7 you would get the message "Your number was increased by two! You got 9!"
* alias decnum2 {
* var %num = $$1
* dec %num
* dec %num
* echo -a Your number was decreased by two! You got %num $+ !
Now the /inc commands have changed to /dec commands. This will decrease your number by two. The same /incnum2 7 changed to /decnum2 7 would give you the number 5.
* alias math {
* if (($1 isnum) && ($2 isin +-*/) && ($3 isnum)) {
* var %num1 = $1, %num2 = $3
* var %num3 = %num1 $2 %num2
* echo -a %num3
This code snippet uses the assignment operator to perform math on the variable. The first thing this code does is check to see if you gave it three parameters. It makes sure $1 is a number, $2 is a mathematical operator (+, -, *, or /), and $3 is a number. If they are all correct, the script then puts the two numbers into variables %num1 and %num2. %num1 and %num2 have an operation done to them (whatever you put into $2) and reports the result. Doing the command /math 3 * 2 would output 6.
* alias square {
* var %1 = $$1
* var %2 = %1 * %1
* echo -a %2
A simpler alias than the last one, this command simply takes the first number you give it and multiplies it by itself. /square 3 will give you 9.

## Identifiers

Identifiers are similar to variables. They are dynamic values in scripts that evaluate when they are parsed in the script. However, unlike variables, they do not always return a static value that is the same every time. Like variables, they can evaluate to $null.
For example, one identifier we have used a lot so far is $1. $1 evaluates to the first parameter, if any, passed to a command when it is run. However, this is not always in the same. In the example above, we could use the command /square 3. $1 in this case is 3. Let's change that 3 to a 4. Now $1 is 4. Pass nothing to it, and $1 will evaluate to $null.
Another popular identifier used is $chan. $chan returns whatever channel a script or command triggers in. Make sure you have two channels open. Go to one of them, and type //echo $chan $chan.The effect of this action is to print in the current channel(the first occurrence of "$chan")right the name of current channel(evalutate by the second "$chan"). Now go to a different channel and do the same command. Notice you still get the channel name. This is because $chan re-evaluates every time is occurs in a script.

### Built-In Identifiers

Built-In identifiers are identifiers coded into mIRC. There are dozens of built-in identifiers, but some of the most used are $nick, $chan, $me, $1, and $+. Identifiers built-in to mIRC have priority over custom ones and cannot be changed or re-coded, unlike built-in commands.

### Custom Identifiers

A custom identifier is an alias that can return a value. Custom identifiers take the form of a regular alias, but are used differently. They are called with the same $ prefix as regular identifiers instead of the / prefix used when calling an alias as a command.
* alias addnum {
* if ($$1 isnum) && ($$2 isnum) {
* return $calc($1 + $2)
The script first starts off by again, checking to make sure the two parameters are valid numbers. Then, it returns the value of the two numbers added together. The proper way to use this is //echo -a $addnum(n1,n2). If you type this as a command, nothing will happen. /addnum 1 2 will return a value of 3, but nothing will show up because it returns a value, instead of echoing it. You can change this, however, using the identifier $isid.
* alias addnum {
* if ($$1 isnum) && ($$2 isnum) {
* $iif($isid,return,echo) $calc($1 + $2)
$isid returns $true if the alias was called as $addnum and $false if it was called as the alias /addnum. Combined with another identifier, $iif, we can determine if $isid returns $true or $false and take an action based on what the result is. If $isid is true, that means addnum was called as an identifier, and will return a value. If $isid is false, then addnum was called as an alias, and will echo a value to the screen. Try the command both ways now with 1 and 2. Both times, you should get 3

#### Custom Properties

You may notice that some identifiers have properties. For example, if you type //echo -a $chan(1).topic, the topic of the first channel you are on will display on your screen. .topic is the property of the identifier. You can add properties to your identifiers, too.
* alias addnum {
* if ($$1 isnum) && ($$2 isnum) {
* $iif($isid,return,echo) $iif($prop == neg,$calc(-1 * ($1 + $2)),$calc($1 + $2))
Again, using $iif, we can check the property of the identifier. If you use the command //echo -a $addnum(1,2).neg, instead of returning 3 you will get -3. This because the property .neg was used with $addnum.
Note: Built in identifiers to mIRC will take precedence over custom ones with the same name. You cannot re-script $chan to return 42. mIRC will still return the name of the channel you are on.

## Comments

Comments are a very important part of coding when your scripts start to get very large and complex. You will hopefully remember tomorrow what your code did last night, but can you say you will remember what a line of code should do six months from now? Comments are lines of code that are ignored by mIRC's interpreter and can be used to remind you what a certain part of a script does. This is what the last example could look like if we commented it.

### Single Line Comments

* alias addnum {
* ; Are $1 and $2 numbers?
* if ($$1 isnum) && ($$2 isnum) {
* ; Was addnum called as a command or an identifier?
* ; Should the number be negative?
* $iif($isid,return,echo) $iif($prop == neg,$calc(-1 * ($1 + $2)),$calc($1 + $2))
* ; End of code
All the comments in this code were one line comments. One line comments start with either ; or // and a blank space, then the comment. We could just as easily have used // for comments in that script instead of ;. All one line comments end at the end of the line they start on.

### Multi Line Comments

Multi line comments span multiple lines. They start wherever a /* is placed in the code and ends wherever there is a */ in the code.
* alias addnum {
* Are $1 and $2 numbers?
* Was addnum called as a command or an identifier?
* Should the number be negative?
* if ($$1 isnum) && ($$2 isnum) {
* $iif($isid,return,echo) $iif($prop == neg,$calc(-1 * ($1 + $2)),$calc($1 + $2))
Using multi-line comments, we achieved the same effect as the one line comments, but in one multi line comment.

## Command Prefixes

There are three types of prefixes that are placed in front of commands, and one prefix placed before identifiers, variables, and operators.
Command Prefixes :
| Prefix | What it does | Example |
| // | Forces mIRC to evaluate identifiers and variables on the command line. | //echo -a $chan |
| . | Silences the output from commands like /timer. | /.timer 1 1 echo -a hi |
| ! | Forces mIRC to use the original command, instead of any alias. | /!msg $chan hi |
Control Codes :
| Prefix | What it does | Example |
| ! | Is the same thing as saying if (%var/$id == $null). Can also be used to mean NOT; e.g. if (b !isnum). | if (!%var) |

## Control Codes

Control codes are special characters that are placed in text to modify the look of text.
Identifier/Variable/Operator Prefixes :
| Code | Effect on Text | Example |
| Ctrl+K | Changes the color of text. | �9This is green text.� This is not. produces: This is green text. This is not. |
| Ctrl+B | Makes font bold. | �This is bold text.� This is not. produces: This is bold text. This is not. |
| Ctrl+U | Makes font underlined. | �This is underlined text.� This is not. produces: This is underlined text. This is not. |
| Ctrl+O | Makes text after the code but before the next control code plain text. | �This is plain text.� This is not. produces: This is plain text. This is not. |
If you've made it this far, congratulations for making it through this long chapter! You can now make some basic mIRC scripts, and you should understand a few of the concepts required to script. If you're ready, you can go on to the next chapter.