Introduction

Welcome to Mudlet, a modern MUD client for GNU/Linux, Windows and Mac OSX that offers all the tools to get the most out of your gaming experience. Throughout this document we hope to familiarize you with the basic aspects of Mudlet, from the interface to its very powerful and feature rich scripting backend The main focus in the development of Mudlet has been efficiency and performance, but we also try to make it as easily accessible as possible. However, keep in mind that this is a complex piece of software with a large set of tools that does require some deeper understanding of the underlying principles. To use Mudlet in any meaningful way, you have to take a closer look at the technical section in this manual. If you are not familiar with using modern MUD clients in general you should also take a look at the general introduction to MUD clients section at the beginning of this manual. You are welcome to ask questions on the forum of our website. If you find a bug, please let us know.

Note Everything is centered around the central Lua scripting unit. Everything shares the same variables & functions and everything is accessible from anywhere.

Quick Start

To connect to the MUD of your choice, click on ConnectionsConnection Profiles.

1. General Introduction to Modern MUD Clients

1.1 Mudlet’s automation features

Mudlet offers a vast array of standard features to automate or otherwise improve your gaming experience. These include, but are not limited to:

Scripting allows the user to create automation utilities (triggers, aliases) with the Lua scripting language. The possibilities of what can be achieved by using this technique are, practically speaking, endless - ranging from teaching the client how to heal your character in combat for you to creating a fully automated robot (known as `bot`s) that will completely take over the control for your character (especially useful for completing repetitive, rudimentary tasks).

1.2 Automation and MUD rules

Effectively speaking, it is possible to create an AI (Artificial Intelligence) that does everything you can do in a MUD. Even more so, the program will be able outperform you in almost every routine operation. The difficulty of creating such a program depends on the task it has to perform: gathering loot being very easy, walking through a dungeon and leveling you character being moderately easy and socially interacting with other real people being outrageously difficult (see A.L.I.C.E.). In the end of the day, you’re teaching your client to process information and act the way you consider best suited. Because scripting is so powerful, it can give you a competitive advantage that some people consider it unfair or even cheating. As of the moment of this writing (2 November 2008), this sort of automation can be best observed in commercial massively-multiplayer online role-playing games (MMORPG), known as gold-farming or power-leveling. The basic idea is creating a system that will raise your character to the maximum level and gather in-game currency in the process, both of which can be effectively exchanged for real-world currency. The spread of the above aspects can have much more far reaching consequences than just being unfair, such as inflation, loss of balance in terms of game-mechanics or, ultimately, a complete crash of in-game economy. For more information see the paper "Simple Economics of Real-Money Trading in Online Games" by Jun-Sok Huhh of the Seoul National University. For these, and various other, reasons the administrators and owners of the corresponding virtual worlds can forbid the usage of automation tools. A failure to comply can result in suspension or deletion of the user’s character or account for future denial of service. By including scripting support in Mudlet, we effectively give you the ability to create and utilise AI tool-kits, however, we do not endorse or promote the usage of these systems if it’s prohibited in your MUD. Keep in mind that by cheating you can lessen the quality of gameplay for both, your fellow players and yourself.

1.3 Basic scripting

The following part of the guide is written for new beginners in scripting. If you’re coming over from zMud or cMud, you may move on to section two.

1.4 Variables - basics

Variables are containers for data. In Lua, they can store numbers or words. You can use variables to store important information like how much gold do you have, or have them remember things for you.

The syntax for making a variable remember a number is the following:

variable = number

Or to make it remember some text:

variable = "some text"

For example, here we’ll set the myhealth variable to number 1345, and the myname variable to Anna:

myhealth = 1345
myname = "Anna"

You can also do basic maths easily, for example:

a = 2 + 2 --sets variable a to the value of 4
b = a - 1 --sets variable b to the value of 3

To concatenate strings together, you can use the .. expression:

first_name = "Joe"
last_name = "Plumber"
full_name = firstname .. " " .. last_name --sets the full_name variable to "Joe Plumber", with a space inbetween.

1.5 How to send text to the mud

To send a command to the MUD, you can use the send() function. Data inside the quotes is sent to the MUD.

For example, the following code sends the command to eat bread:

send("eat bread")

If you’d like to include variables in the send command, you need to prefix and suffix them with two dots outside the quotes, like this:

send("My name is " .. full_name .. ". What's yours?")

1.6 How to echo text to yourself

To echo (show text to yourself) you can use the echo() or the insertText() function. For example, the following code will display Time to eat dinner! on your screen:

echo("Time to eat dinner")

If you’d like to include variables in your echo, you concatenate the value of your variable to the text:

my_old = 5;
echo("I have " .. my_gold .. " pieces of gold!");

1.7 Aliases

The aliases are the most basic way of automating the gameplay - you can use aliases to shorten the amount of typing you do. For example:

Example - Brew’o'Matic 6000

You’re walking around the epic dungeon of the Unholy Firedragon of Westersand, gathering roots in order to brew a potion and thus restore the growth of hair on Farmer Benedict’s bald head. Once you see a root, you need to:

open the bag of tools
get the sickle of damnation from the bag of tools
cut the root of hair-growth
clean the sickle of damnation of deadly root acid
put the sickle of damnation in the bag of tools
close the bag of tools
open the magical bag of storing
take the root
put the root into the magical bag of storing
close the magical of storing

and once you’re done, do the exact same thing nine more times… trice a day.

Alternatively, you just create an alias that would do this all with a single command - for example, quest.

1.8 Making a simple alias

To get started, go click on the Aliases button in Mudlet, and then on the Add one. This will make a blank alias for you, which we’ll now fill in.

The Alias name field is optional - it’s mainly used for the alias listing that you see on the left as an easy way to distintuish all of the aliases. You can just name our alias test for now. The Regex field is where you’d put in the alias command, i. e. the command that is being sent to the MUD instead of the alias. In other words, the alias is a front for a real command. We call this substitution process alias expansion. Mudlet uses Perl regular expression aliases. Regexes are a special way of matching patterns of words. For the beginners it is enough to think of them as a general way to specify the words itself and their placement within the line. For basic alias it is enough to know that the character ^ symbolizes the beginning of the line and the charachter $ symbolizes the end of the line. If you want to make an alias "tw" that sends the command "take weapon", you don’t have to care about placement or pattern matching in general. All you need to do is fill "tw" in the field called "Regex" and type "take weapon" in the field called "substitution". Then you need to save the new alias by clicking on the "Save" icon in the top middle. The symbol for unsaved items disappears and makes way for a little blue checkbox. If this box is checked the alias is active. If the blue box is empty, the alias is deactived and will not work unless you press the "activate" toggle padlock icon. Now you are ready to go. Type "tw" in the command line and press the enter key. Mudlet will send "take weapon" to the MUD. Alias as basically, a feature to save you a bit of typing - much like buttons which will be described in detail in section two of the manual. To learn more about more complex aliases have a look at section 2 of the manual.

1.9 Simple Triggers

Triggers are an automation feature offered in all MUD clients. They help you respond quicker a parcticular situation and generally make things more convenient for you since you need to do less manual work as your triggers will do the hard work for you often times. This helps you concentrate more on the important aspects of the game and lessen stress. The way a trigger works is simple: You define some text that you want to trigger some action. This is called the trigger pattern. When the trigger "sees" this text in the MUD output, it’ll run the commands you’ve told it to. Example: Whenever you see a bunny, you want to attack it. You type "bunny" in the data field titled "add to list" and then either press the enter key or click on the little + icon next to the input line to add this word to the list of texts this trigger fires on. Now you type "kill bunny" in the field called "send plain text". Then click on the save icon to save the trigger and activate your new trigger (= blue checkbox icon in front of the trigger name in the trigger tree on the right side is checked). When the trigger is active each time the word "bunny" will appear in the MUD output, your trigger will issue the command "kill bunny" automatically as long as it is active. When you want to stop hunting bunnies, you can simply select the bunny trigger and then click on the padlock icon to deactivate the trigger. The trigger will stop firing until you re-enable it again via the padlock icon. If you lock a group of triggers or an entire trigger branch, all triggers in this branch will be locked until you remove the lock again. The locking starts from the root of the tree down to the end. As soon as a lock is met the trigger engine will skip the locked branch. Locking and unlocking branches is one of the most common actions you have to take care of when playing. You turn on your defensive triggers when engaging into a battle and you turn them off afterwards, or you turn on your harvesting triggers only when you are going to harvest.

Tip Beginners should use Mudlet’s automated colorizer triggers in the beginning to get the hang of the different trigger and pattern types quicker. Click on the "colorizer trigger" option and pick a foreground and a background color that you like to highlight your trigger with. When the trigger matches it automatically colorizes its pattern. This is the most used form of triggers in mudding as it is a quick way of highlighting words that are important to you at the moment. You don’t have to know anything about scripting, regular expressions etc. to use colorizer triggers. Just type in the word you like to be highlighted, select appropriate colors, save the new trigger and activate it.
1.10 Matching one unknown

You can also set up a trigger to gather the scimitars, gold or whatever the skeletons could carry around with them. Since we do not know what the loot is, we will need to set up a trigger to match the line and take whatever was dropped. Examples:

The skeleton drops ring.
The skeleton drops gold.
The skeleton drops scimitar.

The skeleton drops_ is the generic segment of the line, the loot itself varies. Thus, we need to tell the client to take_ whatever the skeleton dropped. We do this by setting up a so-called regular expression:

Perl Style Regular Expression: The skeleton drops (.*?)\.
Script: send("take " .. matches[2]);

The expression (.*?) matches any characters that the client receives between The skeleton drops_ (NB: notice the blank at the end) and the full-stop. matches[2] simply transfers the first matched text fitting the search criterea into the output (matches[1] contains the entire matched text, matches[2] contains the first capture group. More on this in section two of the manual).

1.11 Matching multiple unknowns

Now, let’s try making a trigger that would gather the loot from anybody:

Perl Style Regular Expression: (.*?) drops (.*?).
Script:
send("take " .. matches[3])

In this case, any time somebody, or something, drops something else, or someone else, the client will pick it up. Note that we used matches[3] instead of matches[2] this time, in order to pick up the second match. If we used matches[2], we’d end up picking up the skeleton’s corpse.

1.12 Matching known variants

If you’re playing a MUD in English, you’ll notice that these triggers probably won’t work due to English syntax. Compare:

The skeleton drops apple.
The skeleton drops an apple.

Chances are that you’ll see the later a little more often. If we used our old RegEx, the output would look something like this.

INPUT: The skeleton drops an apple.
OUTPUT: take an apple

Most MUDs can’t handle determiners, such as articles (i.e. a, an, the) or quantifiers (e.g. five, some, each), in user-input. To match this line we could either create multiple triggers matching every possible article or a regular expression filtering out these words:

Perl Style Regular Expression: (.*?) drops (a|an|the|some|a couple of|a few|) (.*?).
Script:
send("take " .. matches[4])

Once again, note that we’re using the third match (matches[4]) this time. NOTE: Certain other languages, with a morphology richer than that of English, might require a somewhat different approach. If you’re stuck, and your MUD-adminitrators don’t prohibit the use of triggers, try asking on the corresponding world’s forums.

For more information, see the chapter Regular Expressions.

1.13 explain basic regex characters (^, $, (\w+), (\d+) and .*) and how to use them properly.

Retrieving wildcards from triggers

Wildcards from triggers are stored in the matches[] table. The first wildcard goes into matches[1], second into matches[2], and so on, for however many wildcards do you have in your trigger.

For example, you’d like to say outloud how much gold did you pick up from a slain monster. The message that you get when you pick up the gold is the following:

You pick up 16 gold.

A trigger that matches this pattern could be the following:

Perl Style Regular Expression: You pick up (\d+) gold

And in your code, the variables matches[2] will contain the amount of gold you picked up (in this case, 16). So now to say outloud how much gold did you loot, you can do the following:

Script: echo("I got " .. matches[2] .. " gold!")
More advanced example

Here’s an example by Heiko, which makes you talk like Yoda:

Perl Style Regular Expression: say (\w+).*(\w*).*(.*)
Script:  command = "say "..matches[4].." "..matches[2].." "..matches[3]

What it does here is save the first word, the second word and then the rest of the text into wildcards. It then says rest of the text first, then the first word and then the second word.

1.14 How to highlight words

To highlight something in Mudlet, you first use the selectString() function to select what you’d like to highlight, and then either the fg function to color the letters or bg to highlight the background of the letters. For example, the following code would highlight the word pond in a bluebackground and red letters: The first parameter to selectString() is the text you want to select and the second parameter tells the function which occurence of the word in the current line you want to select i.e. the first, the second, the third etc.

selectString( "pond", 1 )
fg( "red " )
bg( "blue" )

1.15 Keybindings

Keybindings, or hotkeys, are in many respects very similar to aliases, however, instead of typing in what you want to be done, you simply hit a key (or combination of keys) and let the Mudlet do the work.

Example - You don’t drink tea, you sip it!

You’re participating in an in-game tea sipping contest. The winner is the first person to sip an Earl Grey, should the quiz-master make a vague reference to a series of tubes, or a Ceylon Mint, if he begins talking about the specific theory of relativity. In order to give us a competitive advantage, we will define two keybindings:

HOTKEY: F1
EXPAND TO: sip earl grey

HOTKEY: F2
EXPAND TO: sip ceylon mint

Now you just have to listen, or rather read, carefully and hit either F1 or F2 to claim that prize.

Another practical use for keybindings would be creating a so-called "targeting system", which is especially useful for grinding down armies of pumpkin-men in MUDs without auto-attack. See the Variables chapter for further details.

1.16 Timers

Timers, as the name suggests, can be used to execute a specific command at a certain time, after a certain time or once every so often.

Example - Don’t miss the training!

Your character can train in his attributes once every three hours. You could either try tracking this manually or add a trigger starting timer after each training. Once the three hours have passed, your character will conveniently say to himself that it is time to do a couple of push-ups.

Main Manual

Multi Session Gameing

Mudlet lets you play several simultaneous MUD sessions. However, currently we have the restriction that you cannot use the same profile twice. Consequently, if you want to play three characters on the same MUD at the same time, you need to make 3 profiles with 3 different names e.g. ernie@avalon.de, bert@avalon.de etc.

Split Screen

Mudlet has a split screen. If you scroll up in the old text, the screen will split in two parts. The lower part will follow the MUD output while the upper part will stay focused on your scrolling. This way you can read easier through old passages without missing what is going on at the moment.

Split screen can be activated via the page up / page down keys or with the mouse wheel. Scrolling back to the end will close the split screen automatically. A click on the middle mouse button will close the split screen immediately as well as pressing control+return on the keyboard. The size of the 2 parts of the split screen can be modidfied when dragging the seperator bar with the mouse. Split screen usage is necessary when selecting text in order to copy it to trigger editor e.g. when making triggers. If you don’t use split screen when selecting text, new arriving text will upset your selection.

Command Line Auto-Completion, Tab-Completion and History

Mudlet’s command line is especially designed for MUD and MUSH playing. It aims at reducing the amount of typing by using autocompletion and tab completion schemes that take typical MUD playing situations into account. Normally, autocompletion works on the basis of alphabetic indexing, which isn’t suitable for MUD playing as it wouldn’t distinguish between the temporal proximity of words, which, in turn is closely related to the probability that the word is The command line offers Tab Completion (TAB key) and Autocompletion (cursor up key).

  1. Tab completion searches the MUD output buffer for words matching the word that you are currently typing. This is useful if you have to type complicated long names. You only have to type the first letters and then press the tab key until the proposal is what you want.

  2. Autocompletion tries to match your current typing with your command history. Example: If you typed the same command a while ago, you only have to start typing the first couple of letters and then press the cursor up key until the proposal matches the command that you want to use.

  3. Command History: If you haven’t started to type anything yet, you can browse through your command history with the cursor up and cursor down keys. However, if you have started typing pressing cursor up will result in a shot at autocompletion.

  4. ESC:To get out of autocompletion you can press the ESC key any time. After pressing ESC the entire text gets selected and you can overwrite it or get back into command history mode.

Logging Output to HTML Log Files

Press on the little button with the blue folder with the green arrow icon on the lower right side of the screen next to the command line.

Clicking it a second time stops logging. A red system message will tell you where you can find the log file. Just copy the the filename and open the log file in your web browser. The log files are html files that can be put on web pages without any further editing etc.. Log files can be found at the mudlet home directory in your profile directory. The path is <path to mudlet home>/.config/mudlet/profiles/<name>/logs On Linux this would be: /home/username/.config/mudlet/profiles/profilename/logs

On Windows the path prefix depends on your windows version and your language settings: On my system it’s c:\Dokumente und Einstellungen\heiko\.config\mudlet\profiles\<name>\logs. Log files have a file name similar to the autosaved profiles: date#time.html

Exporting and Importing Profiles or Packages

Mudlet supports XML packages that can be imported and exported while playing. You can find a package section on the forum of http://mudlet.sourceforge.net where you can download ready made packages for your MUD or upload your own packages for other players to use. A package can contain anything ranging from a single trigger to hundrets of button groups, trigger groups alias - in other words, entire "systems". To import a package you simply have to open the trigger editor and click the import icon, select the xml package file and import it. Often package files will be compressed to save space. If the file is compressed, you’ll need to uncompress it before importing it.

Importing Packages

The imported package will be stored permanently in your profile when you safe the profile. If you don’t like the imported package, delete its components manually or simply don’t save the profile. Then the new content will be lost on restart. Automatic package removal is not yet supported in Mudlet.

Packages are nothing else, but profiles - or parts of profiles that can be exchanged, imported and exported between your own profiles and between different players. From a technical perspective a package and a profile xml file are the same thing. === Exporting Packages Exporting is also easy. Select your item in the script editor and then click on the "Export" button. You’ll be prompted for a file name and that’s it. You can send your cool trigger, buttons, timers etc. to your friends via email or use them in another profile of yours. Exporting your good stuff is strongly recommended as it makes MUDding more enjoyable for everybody. Share your knowledge and help others! Mudlet stores your saved profiles as XML files in your home directory under .config/mudlet/profiles/your_profile_name/current (note the leading dot).unless you have specified a different file name or location by using the "save profile as" profile button meant for creating generic packages to be shared with other profiles or other users. The file name of normally saved profiles ("save profile" button) consists of the date and time, the profile was written to disc. You can export packages of a trigger branch, alias branch, function key, scripts etc. by clicking on a folder in the tree of the particular item in question and then click on the export icon. You’ll be asked to give a filename for your package. You can export arbitrarily complex structures by moving them into a folder that e.g. is named after the package you’d like to make. You cannot mix items at the moment. Importing packages is straight forward and fully automatic. You can also import entire profiles as they are basically packages. === Sharing your System with others - Making complex Packages If you have written a nice set of triggers, buttons, scripts etc. or maybe even a fully fledged "system" of some sort and you want to share it with others, you can make a nice packages that other people can import with a single mouse click. Of course, you can open your xml profile in a text editor and delete what is not needed for the package, but this is too much work. The simplest way is to arrange your modules in such a way that they all go into one main folder e.g. all triggers that belong to the package are put into a main trigger folder and named according to the intended package name. Then you export this trigger package by using the button "profiles save as" in the trigger editor. You are asked for a filename. Call it MySystemTriggerPackage.xml etc. Then you proceed with the Alias, the scripts, the buttons, the keys etc. and make packages for each and export them individually. Finally, you create a new empty profile in Mudlet and import all your sub packages. When everything is imported, export the whole thing via "profile save as" and give it the desired package name. Others can now import the entire system in a single package file. It’s a good idea in the spirit of open source software to share your systems with others. Please use the forum on http://mudlet.sourceforge.net to share your finished packages with other users so that other users can learn from your work or improve it.

Using Variables in Mudlet

Using Variables in Mudlet

One of the major design goals in Mudlet was to integrate scripts and variables as seemlessly as possible. The usage of variables in Mudlet is distinctly different from the other major clients, as native Lua scripting has been integrated into Mudlet from the ground up. As scripts are so closely intertwined with the core of Mudlet, variables do not need any special treatment as in other clients. If you define a variable in any given script in Mudlet, be it a trigger, a button, an alias key, an event handler, a free function, etc. It can be used from within any context without any special getVariable() type of function or any special variable symbols, such as @myVar etc.. In Mudlet all variables are native Lua variables. Each session (connection) runs in its own dedicated Lua interpreter. Consequently, all scripts are compiled into the same Lua interpreter and thus their code runs in the same variable space.

Note Everything shares the same variables & functions.

To give you an example: Let’s make a little trigger that counts how many monsters you have killed. Each time you have made a new kill, the trigger matches on the kill message and runs a little script that increases the amount of kills by one each time the trigger fires - in other words, each time you kill a monster and the kill message is sent from the MUD. For the kill counter we declare a variable and call it myKills. This variable is going to hold the number of kills we’ve made so far. The script will look like this:

myKills = myKills + 1

Then we add a little alias, a button or a keybindings that executes another little script that prints your current kill statistics on the screen. The attached script would look like this:

echo( "I have killed " .. myKills .. " monsters today." )
Lua Primer: Variables, Strings & numbers

Lua variables can be either a string or a number. They are whatever there were initially initialized with or what data type they can be converted to.

a = "Jim"
b = "Tom"
c = 350
d = 1

Then you can write:

e = c + d and e will equal 351
e = a .. b and e will equal "JimTom" note that you cant use a+b to concatenate string values. For this you must use ..
e = a .. c and e will equal "Jim350"

There is another form of variables in Lua called tables which can be used for lists, arrays or dictionaries. This is explained later. For an indepth coverage of variables in Lua take a look at a Lua tutorial e. g. this one on numbers http://lua-users.org/wiki/NumbersTutorial and this one on strings http://lua-users.org/wiki/StringsTutorial or this one on Lua tables http://lua-users.org/wiki/TablesTutorial

Let’s get back to our example. The trigger script expects myKills to be a number so you have to initialze the variable myKills to 0 before running the script for the first time. The best place to initialze variables is in script script outside of a function definiton as this code is executed when the session is loaded or if you compile the script again after you have edited it. To do this click on the "Scripts" icon and select the standard script "My Global Variable Definitions". If you are using an older version of Mudlet or a profile that doesn’t have this script item, simply click on the "Add" icon and make your own script. You can call it whatever you want to. Add following code to initialze your new variable myKills to a number and set its value to 0:

myKills = 0

Whenever you edit this script, it will be recompiled and the code will be run as it is not part of a function definiton. This is the major difference between trigger-scripts, alias-scripts etc. and script-scripts. Script-scripts can contain an unlimited amount of function definitions and also free code i. e. code outside of a function definition - code that is not enclosed by function xyz() …. end. On saving the script the script gets compiled and the free code is run instantly. All other item scripts, i. e. trigger-scripts etc., secretly define a function name for the script and thus the script is not free code, but function code. When a trigger fires Mudlet calls this invisible function name to run the script e.g. trigger738(), button82(), alias8(). This means that if you define variables inside a trigger script the variable will not be defined before the trigger runs for the first time. However, if you define this variable as free code in a script-script the definition becomes available immediately on script save. Now, whenever you add new variables to your variable definiton script, the script gets run and your old variables will be reeinitialzed and reset to 0. This will be no big problem in most cases as you won’t work on your systems while really playing in most cases. To solve this problem you have two options:

First option: Add a script group (a folder) and add a new script item for each variable you define. This way, editing a variable definition will only reset the edited variable and none of the others that are defined in different scripts. This has the added advantage that you have a nice graphical overview of your defined variables.

Note Organize your variables

Second option (more advanced): Change the variable initialization to only initialize the variable if it hasn’t been initialized before, thus keeping the values of previously defined variables. This would look like this:

if myKills == nil then    -- this code initialzes the variable myKills to the number 0 if it hasn't been initialzed before
    myKills = 0
end

In Lua all undefined variables are initialzed to the value nil. The value nil is not the same thing as the number 0 or the empty string "". What it means is that a variable that has the value nil has not been declared yet and does not exist. If a variable does not exist, it cannot be used as its value is undefined at this point. Consequently, increasing the value of nil by one is impossible as the variable doesnt exist yet and will lead to a Lua error. The above script simply checks if the variable myKills has been defined yet and if it hasn’t, it will declare the variable and set its value to 0. === Lists Having variables that hold a single value is the most important usage of variables, but very often you’ll like to define variables that hold a list of values e. g. a list of your ennemies, a list the items you are currently carrying etc.. To define a variable to be a list you need to declare it to be a Lua table. Let’s declare the variable myEnnemies as a list containing the names of your ennemies:

myEnnemies = {}

You can now add new ennemies to this list by calling the lua function listAdd( listName, item ) e.g.

listAdd( myEnnemies, "Tom" )
listAdd( myEnnemies, "Jim" )

To print the content of your ennemy list on the screen you can run this script

listPrint( myEnnemies )

Now let’s make a little alias that adds a new name to your ennemy list when you type "add ennemy " followed by the name of the ennemy e. g. "add ennemy Peter" Open the alias editor by clicking on the alias icon. Click on the "Add" icon to add a new alias. Choose any name you like for your alias e.g. "add new ennemy" and then define following pattern for the alias: ^add ennemy (.*) Then add this little script in the script editor below:

listAdd( myEnnemies, matches[2] )
echo( "Added a new ennemy:" .. matches[2] .. "\n" )

Save the alias and try. Alias are explained in detail below. Another way to declare a list is to define its values directly.

myEnnemies = { "Peter", "Jim", "Carl", "John" }

To remove an item from the list you can use the function listRemove( listName, item ). === Saving Variable Values to Disc Having statistics scripts that last as long as the session lasts is a nice thing, but it makes more sense to write the variables to disc and reload them when you play the next time. To do this you have to save your variables. Mudlet has 2 ways to implement variable persistency. First, you can tell Mudlet to save all of your variables on exit automatically and ask Mudlet to automatically restore them when the session gets reloaded the next time you play on this profile. Second, you can take care of saving your variables yourself and reloading them yourself. This gives you more control and will be the preferred solution in bigger systems.

To be continued …

Input Triggers - Mudlet’s Alias Engine

Alias are triggers that operate on user input. Mudlet uses hierarchically ordered powerful Perl regex expression alias. We have explicitly chosen not to offer multi condition alias, alias chains or the same trigger types the trigger engine offers because this would be way over the top and is simply not needed for alias expansion - although it should be noted that the processes are closely related, except that aliases, i.e. input triggers, operate on a different data stream, namely the user input stream, whereas triggers operate on the MUD output data stream. The only real difference between output triggers and input triggers is that input triggers can change the input stream they work on, whereas output triggers cannot change the stream itself - output triggers can change what is printed on the screen as a result of the stream, but they cannot change the stream itself. This is a fundamental difference and a deeper understanding is key to getting to grips with Mudlet’s alias engine. When you enter a command on the keyboard and press enter or return, the text that you have typed in the command line will be forwarded to the alias unit, i. e. the input trigger unit, in form of the Lua variable command. This variable will be matched against all active alias in the hierarchy unless access to an alias branch is locked by the user or by a script. If an input trigger matches, it will intercept the user command and the original command will be ignored. Upon a match the clear text command is being send as a command to the MUD in replacement of the original command, if a clear text command has been specified by the user and the attached alias script is being executed. However, the initial command that the user has typed in the command line will not be sent unless you do this as part of your script. Consequently, if you want your input trigger to send a command to the MUD, you’ll either have to specify a clear text command for simple cases or send commands via the attached alias script e.g. send("kill monster"). You may argue that you feel that it is unnecessary work to be forced to send a command replacement yourself, but this very fact makes our alias system way more powerful because it gives you complete control about what is happening. Why is this so? The initial user command is being helt in the Lua variable command. When this value changes within the alias unit processing chain, the initial user input that the input triggers work on can be rewritten and changed in the process. Consequently, you can substitute the user input step by step - or alias by alias - without that anything happens as far as sending commands is being concerned unless you explicitly decide to do so.

Note .

The example in the diagram above shows 2 matching aliases, but only one of them sends commands to the MUD - and only if the player is healthy enough to attack the opponent. The other alias that matched the user input (ennemy) choses a fitting opponent and sets the variable ennemy accordingly, otherwise it issues a warning that attacking one of the available ennemies would be too dangerous.

For an input trigger to match the command text the same rules as explained above in the trigger section apply. However, to simplify matters there is only one alias type. As alias are not performance critical we could reduce the amount of trigger types to just Perl regex as this type can do it all and performance is no issue with alias as the amount of data is much less. Even if you type like a madman you’ll never get close to sending the same amount of text to the MUD than the amount of text the MUD sends back to you.

What does it mean that a regex is true or "matched"? A trigger or an alias fires - or executes its commands/script - when the text matches the pattern of the trigger or alias. In most cases this means that the text contains the trigger/alias pattern. If the regex pattern is reen then a text "The green house" will match because "reen" is contained in the text. More complex regex patterns can also hold information on where in the text a certain pattern must occur in order to match. ^tj only matches when the letters "tj" occur at the beginning of the text. Consequently, a text like "go tj" would not match. Regex patterns can also capture data like numbers, sequences of letters, words etc. at certain positions in the text. This is very useful for MUD related scripting and this is why it is explained below.

Let’s get back to alias. We start with a simple example.

We want Mudlet to send "put weapon in bag" whenever we type "pwb". Consequently, the pattern is pwb and as the task is so simple it’s enough to enter "put weapon in bag" in the send field. Then we click on save to save the changes and activate the alias by clicking on the padlock icon. Then we leave the trigger editor and test our new alias. After typing "pwb" and pressing return Mudlet will send the command "put weapon in bag" to the MUD.

Let’s move on to a more complicated example that is needed very often.

We want our script to automatically put the weapon in the correct bag as we have many bags and many weapons. The pattern stays the same. ^pwb The ^ at the beginning of the line means that the command starts with pwd and no other letter in front of this. If we define our pattern more clearly, the pattern will match less often. Without the ^ the alias will match and the alias script will always be run whenever there is the sequence of letters "pwd" in your commands. This may not always be what you want. This is why it’s usually a good idea to make the pattern definition as exact as needed by being less general. The more general the pattern, the more often it will match.

Back to our task: The pattern is ^pwb. Let’s assume that we have defined 2 variables in some other script. The variable "weapon" is the weapon we use and the variale "bag" is the name of the bag. NOTE: In Mudlet global variables can be accessed anywhere from within Mudlet scripts - no matter if they have been defined in a trigger script, in an alias script or in a key or button script. As soon as it’s been defined it somewhere it is usable. To make sure that a variable is local only, i. e. cannot be referenced from other scripts, you have to use the keyword local in front of your variable definition. Back to our alias: Pattern is:^pwb Script is:

send( "put " .. weapon .. " in " .. bag )

Depending on the values of our variables Weapon and bag the command "pwd" will be substitued with an appropriate command. To set your weapon and bag variables we use 2 more aliases: Alias to set the weapon: uw (\w)+ Script:

weapon = matches[2];
send( "wield " .. weapon )

To set our bag variable: Pattern:^set bag (.*)

bag = matches[2]

Now let’s go back to our initial problem. We want an alias to put our current weapon into our current bag. But what happens if we are in the middle of a fight and absolutely need to sip a healing potions because we are close to death and cannot take the risk that the bag may be too full to take the weapon? We want to upgrade out little alias to take into account that the bag may be full and chose an empty bag instead. To do this we set up a trigger that detects messages that indicate that the attempt to put the weapon in the bag failed. In this trigger we execute this little bag-is-full-detection-trigger Trigger Pattern: (type substring) "Your bag is full." script:

bagIsFull = true;

This detection trigger will set the variable bagIsFull to true as soon as it sees the message "Your bag is full.". Then you know that you have to use your spare bag to take the weapon.

Now we have the tools to write an improved version of our little alias script:

if bagIsFull then
    send( "put " .. weapon .. " in " .. spareBag )
else
    send( "put " .. weapon .. " in " .. bag )
end

The next example is one of the most common aliases a tell alias: Pattern:^tj (.*) Script:

send( "tell Jane " .. matches[2]

Sadly, Jane is your fiance and the one thing she is a vegetarian and absolutely hates all words that relate to meat. Luckily, you know enough about aliases by now to make her believe that you’d never ever even think about meat. So you head to your globa function script (any script item will do as long as you define your variables outside of your function definitions. See the scripts chapter below for more information. In your script "my global functions" you add a Lua table containing a list of all of all words that a vegetarian might hate. For example:

happyJaneTable = { "meat", "burger", "steak", "hamburger", "chickenburger" }

Now you can upgrade your tell-jane script to automatically search our tell for all words that Jane might not like. In case such a word is found we substitute the entire tell with "How is the weather?".

for key, value in ipairs( happyJaneTable ) do     -- looking at each element of the list
    badWord = happyJaneTable[key]                 -- check out the Lua table chapter below for more info
    begin, end = string.find( command, badWord )  -- begin holds the start position of the word, end* the end-position
    if begin ~= nil then                          -- we have found a bad word
        send( "tell Jane How is the weather?" )
        return
    end
end

Mudlet’s Trigger Engine

Simple Trigger Matching

Type your trigger in the input line below the trigger conditions list box and then press add to add it to the list. You can edit an expression in the list by clicking on it and then edit it on the input line below. After your edit you have to press the return key to accept the changes. After editing is finished your changes will only become permanent if you press on the save icon on the upper middle. This is the same throughout the entire program. If you forget to save your current changes or new additions, they will not be usable until you save them or edit some other item, as chosing another item will trigger an automatic save. So adding multiple new triggers without saving them will autosave the previous item, but the current item will not be saved until you do it manually. After having chosen a trigger pattern, you have to tell Mudlet what type of pattern it is. Select the pattern type from the listbox below the expression line edit. Normal substring matching will do for most people and it is one of the fastest matching type available.

Example: You want to trigger on the word "pond" in a line such as: "The frog swims in the pond. Plop." All you need to do is enter "pond" in the trigger expression input line and add it to the expression list. Then enter the command you like to send to the MUD if the trigger matches e.g. "drink water" and then you are done. The more advanced trigger types are explained below.

Simple Highlighter Triggers

Tip Beginners should use Mudlet’s automated colorizer triggers in the beginning to get the hang of the different trigger and pattern types quicker. Click on the "colorizer trigger" option and pick a foreground and a background color. When the trigger matches it automatically colorizes its pattern. This is the most used form of triggers in mudding as it is a quick way of highlighting words that are important to you at the moment. This helps you spot things at a single glance instead of reading the entire text. You don’t have to know anything about scripting, regular expressions etc. to use colorizer triggers. Just type in the word you like to be highlighted, select appropriate colors, save the new trigger and activate it.

More advanced users will often want to do custom highlighting from within scripts. This is how it works: If you want to highlight the word "pond" in the above example you have to add the following little Lua script to the script editor on the lower right side of the Script Editor window:

selectString( "pond", 1 )
fg( "red " )
bg( "blue" )

"AND" and "OR" Condition Triggers

AND -Triggers execute their respective command or script only if all conditions in their respective conditions expression list are fullfilled. OR-Triggers execute when any one of their conditions is true. To make OR-Triggers you simply have to add a few conditions to the conditions list e.g. in our example: "pond", "frog", "Plop". The trigger will now also execute on lines like this: "A frog is green" or "You hear a loud Plop!" However, it will not execute on "With a loud plop the frog dived into the water." because "plop" in the line is in lower case letters and your condition specified a "P" in upper case. The simplest form of AND-Triggers in Mudlet are Trigger Chains or Filter Chains, whatever you’d like to call it.

Trigger Chains - Filter Chains

Imagine the following scenario: You want to collect some berries. You know that the room contains some berries if the room description contains the words "You are inside a forrest." You make a new substring trigger for this line, but instead of chosing a regular trigger, you chose to add a new trigger group. Now you add "You are inside a forrest" to the expression list of the trigger group. When adding condions to a trigger group, the trigger group turns from an organizational unit into a filter unit. From now on this folder is a filter and will only let data pass through that matches it’s condition. In our case this is exactly what we want, because we don’t want to collect all sorts of berries, but we only want 2 particular kinds, namely, strawberries and blackberries, and we know that these berries can only be trusted if they are picked inside a forrest as other areas may contain contaminated berries. Now you add two regular triggers to our berry-in-the-forrest filter - one containing the condition: "strawberries" and the other one "blackberries". Then we add the commands to pick the particular kind of berry to both triggers (send field). Now what happens is that as soon as a room description reads "You are inside a forrest." the filter will let the line containing the room description pass through to our two berry triggers and they will issue commands to pick berries, if there are such berries. However, in any other situation the words "strawberries" and "blackberries" will NOT trigger a pick - only in the above scenario when the filter parent’s condition is met. This is a very nice way to solve complicated problems with a few easy filter chains. This example is trivial, but using filter chains will rapidly show you how formerly complicated things that could only be solved with very complicated regular expressions can be solved easily now with a couple of filter chains. It should be noted that filter chains only work on single lines. This means that if the filter chain head "You are inside a forrest" is in a different line than the other child chain element triggers (stawberr- and black berry triggers) the triggers will not fire as the line that is being let through the filter does not contain the words strawberries or blackberries. Most MUDs, however, offer a feature that lets your client do the word wrapping. This is a very powerful tool for scripting and should be enabled by you in your MUD as then the entire room description or the entire tell will be sent out to Mudlet in one line and Mudlet will do the word wrapping for you. Now you can use filter chains much more effectively as the line content comprises many lines. Triggering will become much easier. Ask your MUD operators how to enable this feature. Most big MUDs can do this these days. Let’s look at a practical example for a trigger chain:

Practical example: Prompt Detection Trigger Chain that raises a prompt event and checks balance

My newbie prompt on Achaea looks like this 500h, 500m ex- when I have balance and 500h, 500m ex- when I have lost balance. We are going to develop a prompt detection trigger that raises the event gotPrompt and sets the variables myBalance=true or myBalance=false; To begin with, we add a new trigger group and add the Perl regex pattern to detect the prompt:

^(\d+)h, (\d+)m

The pattern reads in plain English: At the beginning of a prompt line there are is a number directly followed by the letter h, a comma, a space and another number followed by the letter h. Whenever this pattern matches the trigger will fire and we’ll know that we have a prompt line. We use the 2 numbers that we captured in our pattern to update our health and mana stats.

Detecting balance is more difficult as balance is indicated by the letters ex- on the same line after the prompt and imbalance is indicated by the letters e-. As we have set a pattern in a trigger group (folder), the folder is turned into a filter or a trigger chain head. It will now only let data through to its children when its own pattern is matched. In other words, the child triggers of the trigger chain will only recieve data on prompt lines. We are going to take advantage of this by adding two simple substring triggers to detect balance and imbalance. The balance trigger pattern is ex- and the imbalance detector pattern is e-. On the screen this looks like this:

Note .

In the two balance detection triggers we now write myBalance=false and myBalance=true respectively plus a little echo on the screen that shows our current balance status. The outcome looks like this:

Note .

We could now add a call deleteLine() to the prompt detection trigger to erase the prompt from the screen if we don’t want to see it as we have computed all relevant information.

Multi-Line Triggers and Multi-Condition Triggers

Multi Condition Triggers are the most advanced feature of Mudlet’s trigger engine. Like trigger chains or filter chains they are a form of AND-Triggers. All conditions in the list must have matched within the specified margin of lines (delta), in order to trigger the script. Normal triggers fire and run the script as soon as one of the conditions in the regex list is met i.e. if one of the regex/string matches match - or the Lua function condition returns true, the trigger script is run. In multiline triggers, however, each single regex/string/Lua function condition in the list has to have matched within the specified margin of lines at least once to trigger the script. The sequence of the conditions is binding. This means that if the 10th regex on the regex list would be matched on the eleventh line after the match of the first line happened, the trigger will NOT run unless the margin of lines is set to 11. If condition #3 is true but currently #2 is waiting to be true, condition #3 is ignored and must be true again after condidtion #2 has been true. Conditions can also be Lua Functions or plain Lua code that returns a boolean truth value. You can mix all types of condtions to build complex multi-condition triggers that only fire if all conditions are met. This is a very powerful feature as it reduces the amount of scripting to a minimum or even takes away with the need to script formerly complex processes completely. Multicondition triggers are multi-line triggers, i. e. the conditions can all be met in a single line or many lines after the first condition has been fulfilled. This effectively reduces the amount of complexity as you have all the important conditions placed into a single trigger and all the tedious bookeeping, variable and condition state accounting is being done by Mudlet’s trigger engine. The result of this is that the amount of manual condition checking via many different trigger scripts and legions of if condition1 == true then check conditon2 can be forgotten about. All you have to do is to define the conditions and the final action that is taken if the trigger fires.

Note This diagram shows what steps are involved in the process of problem solving with Mudlet’s trigger engine. The main question is: How do we arrive at a solution to our problem, and how can we simplify the problem as much as possible?

Example: Let’s go back to our pond & frog example. We have explained the difference between AND-triggers and OR-triggers. If you have a room description consisting of 3 lines:

1. You see a pond
2. You see a frog.
3. The frog sits on a stone.

Every single one of these 3 lines will be fed into the trigger engine one after another. If we define an OR-trigger with a condition list consisting of 3 condition patterns:

condition #1 pattern = pond condition #2 pattern = frog condition #3 pattern = stone

Wheather or not a condition is found to be true also depends on another property, namely the type of the condition. The condition type can be among others:

  1. substring matching → the condition is true if the condition pattern is a substring of the output line from the MUD. In other words: If the pattern "pond" is contained in any line of output, the condition is true.

  2. begin of line matching → the condition is only true if the conditon pattern can be found at the beginning of a line from the MUD.

  3. Perl regular expression → the condition is true if the Perl regex pattern is matched. You’ll find more information on Perl regex below.

  4. Lua code that returns a truth value e.g. a call to a function check() that return either true or false depending on the condition

In our example we chose condition type "substring" for all three condtions. Consequently, the trigger will fire the command or script 3 times i. e. the trigger will execute on each line it is matched against because in every line at least one condition evaluates to true because the pattern is a substring of the line.

in line #1 we get: pond = true.
in line #2 we get frog = true and
in line #3 two conditions are true i.e. frog=true and stone = true

Because an OR-trigger fires on the first condition that is true and ignores the rest the trigger will only execute 3 times on these 3 lines although 4 conditions are true.

CAUTION: The multiline condition switch must be turned off to get an OR-trigger! If the multiline condition switch is turned on the trigger becomes and AND trigger which means that the trigger only fires if all conditions are true and fullfilled in the correct sequence. With OR-triggers the sequence is irrelevant.

To complicate matters, however, you don’t want your trigger to fire 3 commands, because you want to use this room description as a whole to fire your trigger e. g. this pond is the only kind of ponds in the entire world that doesn’t have poisoned water. So you want to make sure that you only drink water from a pond of this kind and from no other pond. Your solution is to use Multi Conditon Triggers (MCT). If you check the MCT checkbox this trigger will fire only once from now on - and only if all conditions are met i e. when you can guarantee that you only drink water from a good pond because your drinking trigger is matching on the entire room description despite that this room description my be spread over a number of lines. (NOTE: If you have word wrap turned off in your MUD chances are that the entire room description will be contained in a single line, but we are trying to keep the examples as easy as possible.)

Sadly, there are many unfriendly people in this world and somebody goes around and poisons your good ponds. Consequently, you would want to examine the frog and find out if it is poisoned before drinking water from the pond. This is difficult because the villain is a mean magician who used illusion spells to make everything look like the good pond. To solve the problem you can now resort to Lua function conditions in the trigger condition list that perform certain check ups to put the current room description into a wider context e. g. check if you have been here before etc. This adds yet another level of complexity to your problem but this is a very powerful means to use the full potential of Mudlet’s MCTs.

You can combine all forms of conditions with trigger chains, filters and Lua functions. Mudlet gives you relatively easy to use tools that require no programming background. However, these tools can evolve into complex powerful problem solving mechanisms if they are combined with each other thus enabling non-programmer users to solve problems that would need a profound programming background in other MUD clients. However, unlocking the full potential of Mudlet requires you do learn some Lua basics. In this manual we’ll try to be as easy on you as we can in this respect, but it’s highly recommended that you dig deeper into Lua after a while. It’s one of the easiest fully fledged scripting languages available, easy to learn and the fastest of them all, and this is why it has been chosen by us. You don’t need to become a programmer to be able to use Mudlet effectively. All you have to know is how to work with variables and how to do if conditions and maybe a few loops. But knowing more won’t harm you and it will make your systems more effective.

Lua Code Conditions & Variable Triggers - Expression Triggers

In a Lua Code/Function Condition (LFC) you can run Lua code inside the trigger engine directly. The easiest example would be a simple variable trigger: Add a new trigger and chose pattern type Lua Function Conditon. Then define this pattern: if health ⇐ 100 then escape() end Another formulation of the same would be: checkHealth() For the last formulation to work you have defined a lua function checkHealth(). Open the script editor, add a new script "health care" and add this code to the new script-script.

function checkHealth()
    if health <= 100 then
        echo( "WARNING: Low health! I have to run away!\n" )
        startEscape();
        return true
    else
        return false
    end
end
Lua Sytax Primer: Expressions
if A == B then (...)   ----> if A equals B
if A ~= B then (...)   ----> if A *NOT* equals B
if A <= B then (...)   ----> if A is smaller or equal to B
if A >= B then (...)   ----> if A is greater or equalt to B
if A < B then (...)    ----> if A is smaller than B
if A > B then (...)    ----> if A is greater than B

The operators and and or behave differently in Lua than in most other programming languages as they are not guaranteed to return a boolean value. For more information look here:

Lua function conditions effectively means that you run the Lua code they represent on every single line that is received from the MUD, unless the LFCs are part of a multi-condition trigger, in which case the LFCs would only be run when they would be the current test-condition of their respective trigger state. LFCs are implemented in such a way that the trigger engine only calls the compiled byte code, but running as few scripts as possible is always the best idea. LFCs are nice and handy, and for most people the performance aspect will not be relevant at all.

Scripting: Generating Triggers - Special Trigger Types for Scripting Needs

Temporary Triggers (scripting only)

Temporary triggers are lightweight triggers that are tailored for typical scripting needs. These are only available via Lua scripting. They are not stored in profiles, but stay in memory as long as the program runs or until they are deleted (killTimer()). There are several forms of temp-triggers that address different scripting needs. Check the Lua API table for reference.

Line Triggers (scripting only)

Line triggers trigger on a specified line in the future - or a sequence of lines - irrespective of the content of the line. This type of triggers can be very handy in scripting if you know what is coming e.g. you want to parse a table from the MUD, maps etc.

Enabling and Disabling Triggers in Scripts

enableTrigger() disableTrigger()

The Timer Engine

Mudlet supports 4 different sort of timers:

  1. Regular GUI Timers that fire repeatedly in a certain interval specified by the user.

  2. Offset Timers are child timers of a parent timer and fire a single shot after a specified timeout after their parent firied its respective timeout. This interval is an offset to the interval of its parent timer. Example: parent timer fires every 30 seconds and by doing so kicks off 3 offset timers with an offset of 5 seconds each. Consequently, the 3 children fire 5 seconds after each time the parent timer fired. Offset timers differ visually from regular timers and are represented with a + icon for offset. Offset timers can be turned on and off by the user just like any other timer.

  3. Temporary Timers are very useful for scripting. They behave like regular timers, but they are one shot only timers.

  4. Batch Job Timers are a form of timers that issue a sequence of commands/scripts according to a certain timeout instead of a single command/script. This is a very important tool if the sequence of commands is important. Timers depend largely on the operating system you are using and it cannot be guaranteed under certain conditions that if you have set up 5 timers to fire after 1.3 seconds that the sequence in which they fire is the same sequence in which they were created. If the sequence of commands is important, you should always use batch job timers as this form of timers guarantees that the sequence of commands is observed. For example: If you want to make an autominer bot that digs its way into a gold mine digging left, down, down, right, left, down until a trigger catches a message that indicates that the mine is going to collapse and bury your poor soul unless you run for your life and head out of the mine. In this scenario the sequence of commands is vital as you’d lose your way and die. This is a classical case for a batch job timer.

The most common usage of temporary timers is the function tempTimer(). It let’s you specify a timeout after which a script is being run e. g.

tempTimer( 0.3, [[send("kill rat")]] )

This will issue the command "kill rat" after 0.3 seconds. Other clients call this kind of function wait() or doAfter() etc. It is one of the most used functions in MUD scripting. tempTimer() is a single shot timer. It will only fire once and is then marked for deletion. TempTriggers(), by contrast, live through the entire session and are never deleted unless you explicitly delete them or disable them.

Anothe often used function in the context of timers is enableTimer( timerName ), or disableTimer( timerName ). Those are the counterparts of enableTrigger( triggerName ) and disableTrigger( triggerName ), enableKey( keyName ) etc..

NOTE: Temporary timers cannot be accessed from the GUI and are not saved in profiles.

To be continued ….

Buttons and Custom User Toolbars

Note .

Scripting with Mudlet

Lua tables can basically be considered multidimensional arrays and dictionaries at the same time. If we have the table matches, matches[1] is the first element, matches[n] the n-th element.

a = "Tom"
matches[1] = "Betty"
b = matches[1]
c = a .. b and e will equal "TomBetty"

To output a table you can use a conveniance function printTable( name ). This function is defined in LuaGlobal.lua and can be found in your home directory under ./mudlet (note the leading dot ) Profiles and mudlet_documentation.html are stored in this directory as well.

Lua interface functions to Mudlet - or how do I access triggers, timers etc. from Lua scripts

How to get data from regex capture groups? Regular expression capture groups (e.g. „(\d+)“ ) are passed on to Lua scripts as a Lua table matches. To make use of this information inside Lua scripts, you need to specify the number of the capture group within the regex.

Example: You have (\d+) weapons and they are (?:(\b\w+\W+)+)

This regex contains 3 capture groups, but only the 2 green colored ones contain data as the red capture group is a non-capturing group. Consequently, your Lua script gets passed only 2 instead of 3 capture groups and matches[3] is undefined.

In your Lua script you may write following program in order to print the number and status of your weapons on the screen:

You have (\d+) weapons and they are (?:(\b\w+\W+)+)

number_of_weapons = matches[1]
status_of_weapons = matches[2]
notice = number_of_weapons .. status_of_weapons
echo( notice )
send( „put weapons in backpack“ )

-- the following 2 lines color the first capture
-- group red and the second group blue
-- see below for details

selectCaptureGroup( 1 )
setFgColor( 255,0,0 )

selectCaptureGroup( 2 )
setFgColor( 0,0,255 )

The best way is to use selectCaptureGroup( number ) to select the proper capture group and then perform your actions on it e.g. replace(), colorize etc. Note: Both selectCaptureGroup() and matches[n] start with group 1.

How to select all occurrences of "Tom" and colorize them?

You add a functon like this to a script conataining you main function definitions. Note that script items differ from all other "scripts" in triggers, timers, actions etc. because they require you to put your code in proper functions that can be called by your other trigger-scripts, timer-scripts etc. via normal function calls. Trigger-scripts, timer-scripts etc. cannot contain any function definitions because they are automatically generated functions themself because this makes usage a lot easier.

To come back to our question how to select all occurrences of "Tom" and colorize them:

function setBgColorAll( word, r, g, b )
    i = 0
    word_count = 1
    while i > -1 do
        i = selectString(word, word_count)
        if i == -1 then
             return
        end
        word_count = word_count +1
        setBgColor( r, g, b )
    end
end

Then you simply define a substring matching trigger on the word "Tom" and in the trigger script you call above function:

setBgColorAll("Tom", 255,50,50)

Sending commands to the MUD or printing information messages on the screen

To print information messages on the session screen you can use the echo( message ) function, or insertText( text). Currently, it only takes one string as argument.

To send a command to the MUD, you can use the send( command ) function. Note: everything you send via send() will be processed by the alias processing unit. In Alias scripts the command that is being sent to the MUD is contained in the variable command that you can change in the context of Alias scripts. Alias take regular expressions, as well. As a result, you can use following regex and script to talk like Yoda: Perl regex:

say (\w+).*(\w*).*(.*)

script:

send( "say " .. matches[3] .." " .. matches[1] .." ".. matches[2] )

Note: The variable "command" contains what was entered in the command line or issued via the expandAlias( ) function. If you use expandAlias( command ) inside an alias script the command would be doubled. You have to use send( ) inside an alias script to prevent recursion. This will send the data directly and bypass the alias expansion.

Changing text from the MUD or reformatting text (colorize, make bold etc.)

When sending commands to the MUD - from now on referred to as output stream - alias scripts find the command that whas issued by the user stored in the variable "command".

By manipulating the value, the command can easily be changed before it is being sent to the MUD.

However, things get much more complicated with the data received from the MUD – from now on referred to as input stream. Before triggers can be run on the MUD data Mudlet has to strip all format codes from the text and store it in data structures associated with the text. Consequently, the text that is being passed on to the trigger processing unit is a small subset of the data received from the MUD. If you want to edit, replace, delete or reformat text from within your trigger scripts you have to keep this in mind if you don’t want to lose all text format information as colors etc.

As the text is linked with data structures containing the format of the text, the cursor position inside the line is important if data is being changed. You select a word or a sequence of characters from the line and then issue commands to do actions on the selected data.

Replacing the word "Tom" with "Betty" in the line: Jim, Tom and Lucy are learning a new spell. Could be done with following script:

selectString("Tom",1)
replace("Betty")

Things get more complicated if there are two or more occurrences of "Tom" in the line e. g. Jim and Tom like magic. Jim, Tom and Lucy are learning a new spell.

The above example code would select the first occurrence of "Tom" in this line and ignore the second. If you want to work on the the second occurrence of "Tom" you have to specify the occurrence number in the call to select().

selectString( "Tom", 2 )
replace( "Betty" )

This code would change the second "Tom" and leave the first "Tom" alone. The function call

replaceAll( "Betty" )

will replace all occurrences of "Tom" with "Betty" in the line if "Tom" has been selected before. ReplaceAll() is a conveniance function defined in LuaGlobal.lua.

Colorization example: You want to change to color of the words ugly monster to red on a white background.

You add a new trigger and define the regex: ugly monster In the script you write:

selectString("ugly monster", 1 )
setFgColor(255,0,0)
setBgColor(255,255,255)

Another means to select text is to select a range of characters by specifying cursor positions. If we have following line: Jim and Tom like magic. Jim, Tom and Lucy are learning a new spell.

selectSection( 28, 3 )

This example would select the second Tom. The first argument to selectSection is the cursor position within the line and the second argument is the length of the selection.

selectCaptureGroup( number )

Deleting Text - Gagging

This function selects the captureGroup number if you use Perl regular expressions containing capture groups. The first capture group starts with index 1.

deleteLine()

This function deletes the current line - or any line where the cursor is currently placed. You can use repeated calls to this function to effectively erase the entire text buffer. If you want to delete or gag certain words only, you can select the text that you want to delete and then replace it with an empty string e.g:

If you get this line form the MUD: "Mary and Tom walk to the diner."

selectString( "Tom", 1 )
replace( "" );

Then the output will be changed to: "Mary and walk to the diner."

Cursor Movement and Cursor Placement

moveCursor( windowName, x, y ) This will move the user cursor of window windowName to the absolute (x/y) coordinates in the text.

moveCursor( "main", 20, 3950 ) will move the cursor on the 20th character from the left on line number 3950. To determine the current cursor position you can use getLineNumber() and getColumnNumber() as well as getLastLineNumber() to get the number of the last line in the text buffer. moveCursorEnd("main") will move the cursor of the main display to end of the buffer. This is always a new line of size 1 containing the character \n.

number_of_last_line_in_text = getLineCount()

returns the number of the last line of the text in the console buffer. This number will change as soon as a new \n is printed either by the user or

when a new line arrives from the MUD. All lines from the MUD are terminated with \n which is called line feed or the new line character. This control character ends the current line and move the cursor to the beginning of the next line, thus creating a new, empty line below the line that contains the \n.

line_number_of_the_current_cursor_position = getLineNumber()

column_number_of_the_current_cursor_position = getColumnNumber()

luaTable_containing_textlines = getLines( absolute_line_number_from, absolute_line_number_to )

this will return a Lua table containing all lines between the absolute positions from and to. NOTE: This function uses absolute line numbers, not relative ones like in moveCursor(). This little demo script shows you how to use cursor functions:

moveCursor() return true or false depending on wheather the move was possible.

User defined dockable windows

You may want to use dock windows to display information you gathered in your scripts, or you may want to use them as chat windows etc. Adding a user defined window:

openUserWindow( string window_name )

echoUserWindow( string window_name, string text )

setWindowSize( int x, int y )

clearWindow( string window_name )

Dynamic Timers

tempTimer( double timout, string lua_code_to_execute, string/float/int timer_name ) disableTimer( name ) enableTimer( name )

Dynamic Triggers

triggerID = tempTrigger( regex, code ) creates a fast substring matching trigger triggerID = tempRegexTrigger( regex, code ) creates a regular expression matching trigger

Registering Event Handlers and Raising Events

raiseEvent( string name, args )

Handling Tables in Lua

Nick Gammon has written a very nice overview on how to deal with Lua tables. You can find it here: http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=6036.

How to use multilinematches[n][m]

(The following example can be tested on the MUD batmud.bat.org)

In the case of a multiline trigger with these 2 Perl regex as conditions:

^You have (\w+) (\w+) (\w+) (\w+)
^You are (\w+).*(\w+).*

The command "score" generates the following output on batMUD:

You have an almost non-existent ability for avoiding hits.
You are irreproachably kind.
You have not completed any quests.
You are refreshed, hungry, very young and brave.
Conquer leads the human race.
Hp:295/295 Sp:132/132 Ep:182/181 Exp:269 >

If you add this script to the trigger:

showMultimatches();

The script, i.e. the call to the function showMultimatches() generates this output:

 -------------------------------------------------------
 The table multimatches[n][m] contains:
 -------------------------------------------------------
 regex 1 captured: (multimatches[1][1-n])
           key=1 value=You have not completed any quests
           key=2 value=not
           key=3 value=completed
           key=4 value=any
           key=5 value=quests
 regex 2 captured: (multimatches[2][1-n])
           key=1 value=You are refreshed, hungry, very young and brave
           key=2 value=refreshed
           key=3 value=young
           key=4 value=and
           key=5 value=brave
 -------------------------------------------------------

The function showMultimatches() prints out the content of the table multimatches[n][m]. You can now see what the table multimatches[][] contains in this case. The first trigger condition (=regex 1) got as the first full match "You have not completed any quests". This is stored in multimatches[1][1] as the value of key=1 in the sub-table matches[1] which, in turn, is the value of key=1 of the table multimatches[n][m].

The structure of the table multimatches:

multimatches {
                1 = {
                       matches[1] of regex 1
                       matches[2] of regex 1
                       matches[3] of regex 1
                              ...
                       matches[n] of regex 1 },
                2 = {
                       matches[1] of regex 2
                       matches[2] of regex 2
                             ...
                       matches[n] of regex 2 },
                 ...         ...
                n = {
                       matches[1] of regex n
                       matches[2] of regex n
                             ...
                       matches[n] of regex n }
}

The sub-table matches[n] is the same table matches[n] you get when you have a standard non-multiline trigger. The value of the first key, i. e. matches[1], holds the first complete match of the regex. Subsequent keys hold the respective capture groups. For example: Let regex = "You have (\d+) gold and (\d+) silver" and the text from the MUD = "You have 5 gold and 7 silver coins in your bag." Then matches[1] contains "You have 5 gold and 7 silver", matches[2] = "5" and matches[3] = "7". In your script you could do:

myGold = myGold + tonumber( matches[2] )
mySilver = mySilver + tonumber( matches[3] )

However, if you’d like to use this script in the context of a multiline trigger, matches[] would not be defined as there are more than one regex. You need to use multimatches[n][m] in multiline triggers. Above script would look like this if above regex would be the first regex in the multiline trigger:

myGold = myGold + tonumber( multimatches[1][2] );
mySilver = mySilver + tonumber( multimatches[1][3] );

What makes multiline triggers really shine is the ability to react to MUD output that is spread over multiple lines and only fire the action (=run the script) if all conditions have been fulfilled in the specified amount of lines.

Lua API

Mudlet defines several global Lua variables that are accessible from anywhere.

Lua Variables
Variable Name Description

command

This variable holds the current user command. This is typically used in alias scripts.

line

This variable holds the content of the current line as being processed by the trigger engine. The engine runs all triggers on each line as it arrives from the MUD.

matches[n]

This Lua table is being used by Mudlet in the context of triggers that use Perl regular expressions. matches[1] holds the entire match, matches[2] holds the first capture group, matches[n] holds the n-th capture group.

If the trigger uses the Perl style /g switch to evaluate all possible matches of the given regex within the current line, matches[n+1] will hold the second entire match, matches[n+2] the first capture group of the second match and matches[n+m] the m-th capture group of the second match.

multimatches[n][m]

This table is being used by Mudlet in the context of multiline triggers that use Perl regular expression. It holds the table matches[n] as described above for each Perl regular expression based condition of the multiline trigger. multimatches[5][4] may hold the 3rd capture group of the 5th regex in the multiline trigger. This way you can examine and process all relevant data within a single script. Have a look at this example.

Main Functions
Function Description

send( command )

This sends data directly to the socket layer, bypassing the alias expansion unit. If you want your command to be expanded by the alias unit, call expandAlias() instead.

echo( text )

prints text to the main window

listPrint( listName )

prints the content of list listName on the screen e.g. listPrint( myEnnemies )

listAdd( listName, what )

adds a new element what to the list listName e.g. listAdd( myEnnemies, "Tom" )

listRemove( listName, what )

removes item what from the list listName e.g. listRemove( myEnnemies, "Bert" )

int pos_begin_of_match_in_line = selectString( text, number_of_match ) or -1 on error

Selects a substring from the line where the user cursor is currently positioned. You can move the user cursor with moveCursor(). When a new line arrives from the MUD, the user cursor is positioned at the beginning of the line. However, if one of your trigger scripts moves the cursor around you need to take care of the cursor position yourself and make sure that the cursor is in the correct line if you want to call one of the select functions. NOTE: to prevent selection of random data use the error return if not found like this: "if selectString( "big monster", 1 ) > -1 then setFgColor( 255,0,0) end"

deleteLine()

deletes the current Line under the user cursor.

timer_id = tempTimer( seconds, lua_code )

Creates a temporary single shot timer. You can use 2.3 seconds or 0.45 etc. After it has fired, the timer will be deactivated and killed.

enableTrigger( name )

enables a Trigger. see enableTimer() for more details.

disableTrigger( name )

Use trigger name or the id returned by tempTrigger() to identify the timer that you want to disable.

insertText( string )

Insertion takes place at the current position of the user cursor or replaces the current selection. Use deselect() to unselect unwanted selections to prevent overwriting.

suffix( what )

prints "what" at the end of the line when used in a trigger script

prefix( what )

prints "what" at the beginning of a line when used in a trigger script

boolean = selectSection( from, length_of_string )

Absolute column number for start of selection and length of selection

selectCaptureGroup( groupNumber ) with first group = 0

Selects the content of the capture group number in your perl regular expression e.g. "you have (\d+) Euro". If you want to color the amount of money you have green you do: selectCaptureGroup(1); setFgColor(0,255,0)

replace( with )

replaces the selected text with "with". To delete text use replace("")

replaceAll( what, with )

replaces all occurrences of what in the current line with with

fg( color_name )

Sets the current selection foreground color to color_name. You can find the pre-defined color names here

bg( color_name )

same as fg( color_name ) just for the background color.

resetFormat()

Resets the character format to default. This should be used after you have colorized some text, but don’t want to keep using these colors for further prints.

setBgColor( r,g,b )

Values are RGB: red, green, blue ranging from 0-255 e.g. for red: setFgColor(255,0,0)

setFgColor( r, g, b )

Values are RGB: red, green, blue ranging from 0-255 e.g. for blue: setBgColor(0,0,255)

openUserWindow( name )

Opens a user dockable console window for user output e.g. statistics, chat etc. If a window of such a name already exists, nothing happens. You can move these windows, dock them, make them into notebook tabs or float them.

Trigger, Timer, Alias and Key Functions
Function Description

disableTimer( name )

Use timer name or the id returned by tempTimer() to identify the timer that you want to disable.

disableTrigger( name )

Use trigger name or the id returned by tempTrigger() to identify the timer that you want to disable.

disableKey( name )

Uses trigger name as id or the id returned by tempTrigger()

echoUserWindow( window_name, text )

prints text to user dock window name

enableTimer( name )

enables or activates a timer that was previously disabled. The parameter "name" expects the timer ID that was returned by tempTimer() on creation of the timer or the name of the timer in case of a GUI timer

enableTrigger( name )

enables a Trigger. see enableTimer() for more details.

enableKey( name )

enable key or key group "name"

expandAlias( command )

like send(), but without bypassing alias expansion. This function may lead to infinite recursion if you are not careful. This function can be used to make recursive alias expansion.

raiseEvent( event_name, arg-1, … arg-n )

Raises the event event_name. The event system will call the main function (the one that is called exactly like the script name) of all such scripts that have registered event handlers. If an event is raised, but no event handler scripts have been registered with the event system, the event is ignored and nothing happens. This is convenient as you can raise events in your triggers, timers, scripts etc. without having to care if the actual event handling has been implemented yet - or more specifically how it is implemented. Your triggers raise an event to tell the system that they have detected a certain condition to be true or that a certain event has happened. How - and if - the system is going to respond to this event is up to the system and your trigger scripts don’t have to care about such details. For small systems it will be more convienient to use regular function calls instead of events, however, the more complicated your system will get, the more important events will become because they help reduce complexity very much.

The corresponding event handlers that listen to the events raised with raiseEvent() need to use the script name as function name and take the correct number of arguments. NOTE: If you raise an event with 5 arguments but your event handlers functions only take 2,10 or 0 arguments, the functions will not be called. For exmaple: raiseEvent("fight") a correct event handler function would be: myScript( event_name ). In this example raiseEvent uses minimal arguments, name the event name. There can only be one event handler function per script, but a script can still handle multiple events as the first argument is always the event name. So you can call your own special handlers for individual events. The reason behind this is that you should rather use many individual scripts instead of one huge script that has all your function code etc. Scripts can be organized very well in trees and thus help reduce complexity on large systems.

timer_id = tempTimer( seconds, lua_code )

Creates a temporary single shot timer. You can use 2.3 seconds or 0.45 etc. After it has fired, the timer will be deactivated and killed.

trigger_id = tempTrigger( string, lua_code )

creates a temporary trigger using substring matching. Contrary to tempTimers, tempTriggers live throughout the entire session unless they are explicitely disabled or killed. Disabled tempTimers can be reenabled with enableTrigger(). This is much faster than killing the trigger and creating a new one.

trigger_id = tempLineTrigger( from, howMany, LuaCode )

Temporary trigger that will fire on n consecutive lines following the current line. This is useful to parse output that is known to arrive in a certain line margin or to delete unwanted output from the MUD. Example: tempLineTrigger( 1, 3, ) will fire 3 times starting with the line from the MUD. tempLineTrigger( 20, 2, ) will fire 20 lines after the current line and fire twice on 2 consecutive lines.

trigger_id = tempRegexTrigger( regex, lua_code )

temorary trigger using perl regex pattern matching

killTimer( name )

Deletes a tempTimer. Use the Timer ID returned by tempTimer() as name parameter.

killTrigger( name )

See killTimer()

Buffer, Screen and Mini Windows Functions
Function Description

openUserWindow( name )

Opens a user dockable console window for user output e.g. statistics, chat etc. If a window of such a name already exists, nothing happens. You can move these windows, dock them, make them into notebook tabs or float them.

clearUserWindow( window_name )

Clears the user window with the name given as argument.

userWindowLineWrap( window, boolean )

turns line wrap mode on or off in user dock windows userWindowLineWrap( "chat", true ) turns on line wrap for window "chat" (not implemented)

copy()

Copies the current selection to the clipboard. This function operates on rich text, i. e. the selected text including all its format codes like colors, fonts etc.

cut()

Cuts the current selection and stores it in the clipboard. This text remains available in the clipboard until it gets overwritten by another cut or copy operation. This function works on rich text ( see copy() )

deselect()

deselects the last selected text (not implemented yet)

lineNumber = getLineNumber()

to get the absolute line number of the current user cursor

number = getColumnNumber()

To get the absolute column number of the current user cursor

number = getLineCount()

To get the absolute amount of lines in the current console buffer

lua_table[relative_linenumber, content] = getLines( from_line_number, to_line_number )

Returns a section of the content of the screen text buffer. Absolute line numbers are used

number_of_last_line = getLineCount()

number of the last line in the buffer

boolean = moveCursor( windowName, x, y )

Moves the user cursor of the window windowName to the absolute point (x,y). This function returns false if such a move is impossible e.g. the coordinates don’t exist. To determine tha correct coordinates use getLineNumber(), getColumnNumber() and getLastLineNumber(). The trigger engine will always place the user cursor at the beginning of the current line before the script is run. Use "main" for the main window and the name you called your user window otherwise.

moveCursorEnd( windowName )

Moves the cursor to the end of the buffer. "main" is the name of the main window, otherwise use the name of your user window.

paste()

pastes the previously copied or cut text including all format codes like color, font etc. at the current user cursor position. The copy(), cut() and paste() functions can be used to copy formated text from the main window to a user window without losing colors e. g. for chat windows, map windows etc.

pasteWindow( name )

pastes the previously copied or cut rich text (including text formats like color etc.) into user window (dock window) name. selectString( line, 1 ) cut() pasteWindow( "chat" )

printTable( table_name )

Lua debug function that prints the content of a Lua table on the screen, split up in keys and values. Useful if you want to see what the capture groups contain i. e. the lua table "matches". This function is defined in luaglobal.lua.

showCaptureGroups()

Lua debug function that highlights all capture groups in your trigger regex on the screen. This is very handy if you make complex regex and want to see what really matches in the text. example: make a trigger with the regex (\w) and call this function in the trigger script. All words in the text will be highlighted in random colors. This function is defined in luaglobal.lua

showMultimatches()

Lua helper function to show you what the table multimatches[n][m] contains. This is very useful when debugging multiline triggers

table.load( file, table )

restores a Lua table from a data file that has been saved with table.save()

table.save( file, table )

saves the given table into the given file

showCaptureGroups()

a debug function for building triggers: this function highlights all capture groups in random colors in the MUD output text online on the screen. You get more precise debug information on what captured what and when if you look at the debug console (→trigger editor→bug symbol)

printTable( table )

another debug function that prints the content of a Lua table on the screen split in key and value.

sendAll( what )

sends a list of commands to the MUD

debug( arg1 … argn )

prints out debug information to the user debug console

function replaceWildcard(what, replacement)

Replaces the given wildcard (as a number) with the given text. Example: replaceWildcard(1, "hello") on a trigger of ^You wave (goodbye)\.$

resetFormat()

resets the user character format to the default.

Miscellaneous Functions
Function Description

createBuffer( name )

creates a named buffer for formatated text, much like a user terminal window, but the buffer cannot be shown on the screen; intended for temporary buffer work

appendBuffer( name )

like paste() but pastes at the end of the buffer/window and wraps new text automatically

showWindow( name )

shows user window name

hideWindow( name )

hides user window name

resizeWindow( name, x1, y1, x2, y2 )

resizes window name to x1/y1 and x2/y2 vectors

closeUserWindow( name )

closes a named window and delete it.

latency = getNetworkLatency()

returns the last measured response time between the sent command and the server reply e.g. 0.058 (=58 milliseconds lag) or 0.309 (=309 milliseconds)

watchID = createStopWatch()

return the ID of a high resolution clock with milliseconds to measure time more accurately than what is possible with std. Lua routines

startStopWatch( watchID )

start the stop watch

time = stopStopWatch( watchID )

stops the stop watch and returns elapsed time in milliseconds in form of 0.001

resetStopWatch( watchID )

resets the time to 0:0:0:0

time = getStopWatchTime( watchID )

returns the time (milliseconds) in form of 0.058 (= clock ran for 58 milliseconds before it was stopped)

debug( text )

print text to debug console

appendBuffer( name, text )

append text at the end of temp buffer name (fast function)

setWindowWrap( windowName, wrapAt )

sets at what position in the line the console or miniconsole will start word wrap

createMiniConsole( name, posX, posY, width, height )

opens a console window inside the main window of Mudlet at position posX/posY with size according to width/height (values depend on your own screen resolution usually between 0-1600 for x and 0-1024 for y). This console is the ideal fast colored text display for everything that requires a bit more text e.g. status screens, log windows, chat windows etc.. You can use clearWindow/moveCursor etc. functions for this window for custom printing as well as copy/cut/paste functions for colored text copies from the main window or normal echoUserWindow( name, text) for normal printing.

createLabel( name, posX, posY, width, height, fillBackground)

labels are intended for very small variable or prompt displays or images. labels are clickable and if you specify a callback function with setLabelClickCallback( labelName, myLabelOnClickFunction ) your function will get called if the user clicks on the label with the mouse. If fillBackground = 0, the background will be hidden, if fillBackground = 1 the background will be shown i.e. you can see the background color. labels can be transparent. You can place labels anywhere within then main display, also als overlays over the main displays e.g. for on screen buttons, micro display, etc. DON’T use labels for larger text displays because they are a lot slower than the highspeed mini consoles

hideWindow( name )

hides a user window, button or label

showWindow( name )

shows a window, button or label

resizeWindow( name, width, height )

resizes a user window, button or label

setMiniConsoleFontSize( name, fontSize )

Sets the font size of the mini console.

getCurrentLine()

returns the content of the current line under the user cursor in the buffer. The Lua variable line holds the content of getCurrentLine() before any triggers have been run on this line. When triggers change the content of the buffer, the variable line will not be adjusted and thus hold an outdated string. line = getCurrentLine() will update line to the real content of the current buffer. This is important if you want to copy the current line after it has been changed by some triggers. selectString( line,1 ) will return false and won’t select anything because line no longer equals getCurrentLine(). Consequently, selectString( getCurrentLine(), 1 ) is what you need.

selectCurrentLine()

selects the content of the current buffer line

setBackgroundImage( labelName, imageFileName )

loads an image file (png) as a background image for a label. This can be used to display clickable images etc.

setBackgroundColor( red, green, blue, alpha )

sets rgb color values + an alpha channel for the level of transperancy of the background color 0=completely transparent, 255=no transparency values in between specify the level of transparency.

setLabelClickCallback( labelName, luaFunctionName )

specify a lua function to be called if the user clicks on the label/image e.g. setLabelClickCallback( "compassNorthImage", "onClickGoNorth" )

createButton( … )

echoUserWindow( windowName )

This function will print text to both mini console windows, dock windows and labels. Note that labels accept rich text formats (= html = very slow → don’t use this if the text is updated often! In this case use a mini console instead)

width, height = getMainWindowSize()

return window width and window height ( function with 2 return values ) to calculate the window dimensions and placement of custom gui toolkit items like labels, buttons, mini consoles etc.

setTextFormat( windowName, r1, g1, b1, r2, g2, b2, bold, underline, italics )

sets current text format of window windowName: foreground color(r1,g1,b1), background color(r2,g2,b2), bold(1/0), underline(1/0), italics(1/0) example: ---- createMiniConsole( "con1", 0,0,300,100); setTextFormat("con1",0,0,255,255,255,0,1,1,1); echoUserWindow("con1","This is a test") ---- This script would create a mini text console and write with yellow foreground color and blue background color "This is a test".

table.size( tableName )

Gets the actual size of a non-numerical table

io.exists(file)

Checks to see if a file exists

string:split(delimiter)

Splits a string

table.contains(t, value)

Determines if a table contains a value as a key or as a value (recursive)

state = getButtonState() with state = 1 button is checked and state = 0, button is not checked

this function can be used in checkbox button scripts (2-state buttons) to determine the current state of the checkbox. Example: checked = getButtonStated(); if checked == 1 then hideExits() else showExits() end;

showToolBar( name )

shows tool bar name on the screen

hideToolBar( name )

hides tool bar name and makes it disappear. If all tool bars of a tool bar area (top, left, right) are hidden, the entire tool bar area disappears automatically.

Color Table (for use in the fg("colorname") and bg("colorname") functions)
snow ghost_white white_smoke gainsboro floral_white

old_lace

linen

antique_white

papaya_whip

blanched_almond

bisque

peach_puff

navajo_white

moccasin

cornsilk

ivory

lemon_chiffon

seashell

honeydew

mint_cream

azure

alice_blue

lavender

lavender_blush

misty_rose

white

black

dark_slate_gray

dark_slate_grey

dim_gray

dim_grey

slate_gray

slate_grey

light_slate_gray

light_slate_grey

gray

grey

light_grey

light_gray

midnight_blue

navy

navy_blue

cornflower_blue

dark_slate_blue

slate_blue

medium_slate_blue

light_slate_blue

medium_blue

royal_blue

blue

dodger_blue

deep_sky_blue

sky_blue

light_sky_blue

steel_blue

light_steel_blue

light_blue

powder_blue

pale_turquoise

dark_turquoise

medium_turquoise

turquoise

cyan

light_cyan

cadet_blue

medium_aquamarine

aquamarine

dark_green

dark_olive_green

dark_sea_green

sea_green

medium_sea_green

light_sea_green

pale_green

spring_green

lawn_green

green

chartreuse

medium_spring_green

green_yellow

lime_green

yellow_green

forest_green

olive_drab

dark_khaki

khaki

pale_goldenrod

light_goldenrod_yellow

light_yellow

yellow

gold

light_goldenrod

goldenrod

dark_goldenrod

rosy_brown

indian_red

saddle_brown

sienna

peru

burlywood

beige

wheat

sandy_brown

tan

chocolate

firebrick

brown

dark_salmon

salmon

light_salmon

orange

dark_orange

coral

light_coral

tomato

orange_red

red

hot_pink

deep_pink

pink

light_pink

pale_violet_red

maroon

medium_violet_red

violet_red

magenta

violet

plum

orchid

medium_orchid

dark_orchid

blue_violet

purple

medium_purple

thistle