Difference between revisions of "Manual:Introduction"
(Started on Buttons) |
|||
(105 intermediate revisions by 14 users not shown) | |||
Line 1: | Line 1: | ||
+ | <languages/> | ||
{{TOC right}} | {{TOC right}} | ||
− | + | {{#description2:Basic introduction to Mudlet, including aliases, variables, scripts, triggers, keybindings, timers, events, etc.}} | |
+ | <translate> | ||
+ | = Automation and game rules = <!--T:1--> | ||
− | + | <!--T:2--> | |
+ | It is possible to create an Artificial Intelligence (AI) that does everything you can do in a game. Even more so, an AI can outperform you in every routine operation, depending on the complexity of the task. Because scripting is so powerful, it can give you a competitive advantage that some people consider unfair or even cheating. In some cases it can have much more far reaching consequences on a game, such as inflation, loss of balance in terms of game-mechanics or, ultimately, a complete crash of in-game economy. For these and various other reasons the administrators and owners of some games forbid or limit the use of automation tools. | ||
+ | <!--T:197--> | ||
+ | By including scripting support in Mudlet, we effectively give you the ability to create and utilize AI toolkits. However, '''we do not endorse or promote the usage of automation if it is prohibited in your game!''' Keep in mind that by cheating you can lessen the quality of gameplay for both your fellow players and yourself. | ||
− | + | = Mudlet's Automation Features = <!--T:3--> | |
+ | <!--T:4--> | ||
Mudlet offers a vast array of standard features to automate or otherwise improve your gaming experience. These include, but are not limited to: | Mudlet offers a vast array of standard features to automate or otherwise improve your gaming experience. These include, but are not limited to: | ||
− | ; [[Aliases]] | + | <!--T:5--> |
− | : User-defined text input, which is converted into a different, usually longer input before being sent to the | + | ; [[#Aliases|Aliases]] |
− | : e.g. | + | : User-defined text input, which is converted into a different, usually longer input before being sent to the game. |
+ | : e.g. typing '''gg''' to have '''get gold from ground;put gold in bag''' be sent to the game'''. | ||
− | ; [[Keybindings]] | + | <!--T:9--> |
+ | ; [[#Variables|Variables]] | ||
+ | : allow the user to store text or numbers for easier use inside scripts. | ||
+ | |||
+ | <!--T:7--> | ||
+ | ; [[#Triggers|Triggers]] | ||
+ | : execute user-defined commands upon receiving specific out from the game, | ||
+ | : e.g. gamesends: "You see Elyssa standing here." and Mudlet automatically sends "poke Elyssa" to the game. | ||
+ | |||
+ | <!--T:6--> | ||
+ | ; [[#Keybindings|Keybindings]] | ||
: also known as hotkeys, allow executing certain user-defined commands by simultaneously pressing a specific combination of keys | : also known as hotkeys, allow executing certain user-defined commands by simultaneously pressing a specific combination of keys | ||
− | :e.g. | + | :e.g. pressing '''CTRL+H''' to send "say Hello Miyuki!" to the game or play '''La Marseillaise''' |
− | + | <!--T:8--> | |
− | : | + | ; [[#Timers|Timers]] |
− | |||
− | |||
− | ; [[Timers]] | ||
: delay the execution of a command or execute it after a specified period of time. | : delay the execution of a command or execute it after a specified period of time. | ||
: e.g. throw gauntlet to Eric-wait 3 seconds-exclaim Let us end this here! | : e.g. throw gauntlet to Eric-wait 3 seconds-exclaim Let us end this here! | ||
− | ; [[ | + | <!--T:10--> |
− | : allow the user to | + | ; [[Manual:Event_Engine|Events]] |
+ | : allow the user to make triggers for specific events like when Mudlet has connected to the game, or even user-defined events to use in complex system making. | ||
+ | |||
+ | <!--T:11--> | ||
+ | To get started on programming in Mudlet, '''[http://www.mudlet.org/media/ watch these screencasts]''' that explain the basics that'll help you get started. | ||
+ | |||
+ | <!--T:12--> | ||
+ | Keep on reading for an introduction to Mudlet's features: | ||
+ | |||
+ | |||
+ | |||
+ | </translate> | ||
+ | <span id="aliases"></span> | ||
+ | <translate> | ||
+ | |||
+ | = Aliases = <!--T:13--> | ||
+ | |||
+ | <!--T:14--> | ||
+ | Aliases are the most basic way of automating the gameplay - you can use aliases to shorten the amount of typing you do. See more detailed info here: [[Manual:Alias Engine|Manual:Alias Engine]] | ||
+ | |||
+ | |||
+ | |||
+ | == Example - Brew’o'Matic 6000 == <!--T:15--> | ||
+ | |||
+ | <!--T:16--> | ||
+ | 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: | ||
+ | |||
+ | <!--T:17--> | ||
+ | <pre> | ||
+ | open the bag of tools | ||
+ | get the sickle of damnation from the bag of tools | ||
+ | cut the root of hair-growth | ||
+ | <wait 5 seconds> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | <!--T:18--> | ||
+ | And once you’re done, do the exact same thing nine more times… thrice a day! | ||
+ | |||
+ | <!--T:19--> | ||
+ | Alternatively, you just create an alias that would do this all with a single command - for example, "quest". To make that happen, read on! Here's a sneak peek on what you should have in the end: | ||
+ | |||
+ | <!--T:20--> | ||
+ | [[File:Quest alias.png|center]] | ||
+ | |||
+ | |||
+ | |||
+ | == Making an Alias == <!--T:21--> | ||
+ | |||
+ | <!--T:22--> | ||
+ | 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. | ||
+ | |||
+ | <!--T:23--> | ||
+ | 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 distinguish all of the aliases. You can just name our alias "test" for now. The ''Pattern'' field is where you put your regex pattern to describe the command you'll enter to make your new alias spring into action. Let’s say we want our new alias to send the command "say hello" whenever we type "sh". The regex pattern would be '''^sh$'''. Then we put '''say hello''' into the ''Command'' field. After you have saved and activated your new alias "test", whenever you type "sh" Mudlet will not send "sh", but "say hello" instead. We call this replacement process alias expansion. | ||
+ | |||
+ | <!--T:24--> | ||
+ | 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 aliases it is enough to know that the character ^ symbolizes the beginning of the line and the character $ 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 "command". 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 deactivated 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 game. Aliases are basically a feature to save you a bit of typing (much like buttons which will be described in detail in a later section of the manual). More advance alias usage will be described later in the manual. | ||
+ | |||
+ | == Making a Targetting Alias == <!--T:25--> | ||
+ | |||
+ | <!--T:26--> | ||
+ | To make an alias that'll remember your target - making it easier to use your skills and saving you the hassle of typing the target in all the time, do the following: | ||
+ | |||
+ | <!--T:27--> | ||
+ | In the '''Pattern''' field, place the following: | ||
+ | |||
+ | <!--T:28--> | ||
+ | ^t (.+)$ | ||
+ | |||
+ | <!--T:29--> | ||
+ | That will match all commands that you type in the format of '''t <any words>''' - it'll match ''t rat'', ''t tsol'aa'', ''t human'' and etcetera. | ||
+ | |||
+ | <!--T:30--> | ||
+ | Next, make the big box do this: | ||
+ | |||
+ | <!--T:31--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | target = matches[2] | ||
+ | cecho("<light_slate_blue>My target is now: <red>"..target.."\n") | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <!--T:32--> | ||
+ | [[File:Basic_targetting.png|center]] | ||
+ | |||
+ | <!--T:33--> | ||
+ | You can also make an alias with an optional target: | ||
+ | |||
+ | <!--T:34--> | ||
+ | ^dd(?: (.+))?$ | ||
+ | |||
+ | <!--T:35--> | ||
+ | Now the target, if it is supplied, is going to be ''matches[2]''. You can test if the target was given with this code: | ||
+ | |||
+ | <!--T:36--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | send("cast spell at "..(matches[2] or target)) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | <!--T:37--> | ||
+ | That's it - whenever you use this alias, your target will be remembered in the ''target'' variable. | ||
+ | |||
+ | <!--T:38--> | ||
+ | Next, you'd like to make use of this variable - so make another alias that will do the actual attacking for you! Here's an example one: | ||
+ | |||
+ | <!--T:39--> | ||
+ | Pattern: | ||
+ | |||
+ | <!--T:40--> | ||
+ | ^atk$ | ||
+ | |||
+ | <!--T:41--> | ||
+ | Code: | ||
+ | |||
+ | <!--T:42--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | send("kick "..target) | ||
+ | </syntaxhighlight> | ||
− | + | <!--T:43--> | |
− | + | This alias will kick the target when you type in ''atk''. Feel free to adjust the "trigger" word and the command as you need them. | |
+ | <!--T:44--> | ||
+ | [[File:Basic attack alias.png|center]] | ||
− | === Variables == | + | </translate> |
+ | <span id="variables"></span> | ||
+ | <translate> | ||
+ | == Variables == <!--T:45--> | ||
+ | <!--T:46--> | ||
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. | 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: | + | <!--T:47--> |
− | <lua>variable = 1234</ | + | The syntax for making a variable remember a number is the following - create them in the Script editor in a new script: |
+ | <syntaxhighlight lang="lua">variable = 1234</syntaxhighlight> | ||
+ | <!--T:48--> | ||
Or to make it remember some text: | Or to make it remember some text: | ||
− | <lua>my_name = "Bob"</ | + | <syntaxhighlight lang="lua">my_name = "Bob"</syntaxhighlight> |
+ | |||
+ | <!--T:49--> | ||
+ | It'll then appear in the Variables view, like so: | ||
+ | |||
+ | <!--T:50--> | ||
+ | [[File:Variables_view.png|border|center|800px|]] | ||
+ | |||
+ | </translate> | ||
+ | {{note|The variables view doesn't autoupdate, but it can be refreshed by clicking the Variables button.}} | ||
+ | <translate> | ||
+ | <!--T:51--> | ||
You can also do basic maths easily, for example: | You can also do basic maths easily, for example: | ||
+ | <!--T:52--> | ||
To concatenate strings together, you can use the .. expression: | To concatenate strings together, you can use the .. expression: | ||
− | <lua>my_full_name = "Bob" .. " the Builder"</ | + | <syntaxhighlight lang="lua">my_full_name = "Bob" .. " the Builder"</syntaxhighlight> |
− | Don't forget to use a space when you're | + | <!--T:53--> |
− | <lua> | + | Don't forget to use a space when you're concatenating two variables together: |
+ | <syntaxhighlight lang="lua"> | ||
firstname = "Apple" | firstname = "Apple" | ||
lastname = "Red" | lastname = "Red" | ||
+ | <!--T:54--> | ||
-- bad: will produce "AppleRed" | -- bad: will produce "AppleRed" | ||
full_name = firstname .. lastname | full_name = firstname .. lastname | ||
+ | <!--T:55--> | ||
-- good: will produce "Apple Red" | -- good: will produce "Apple Red" | ||
full_name = firstname .. " " .. lastname | full_name = firstname .. " " .. lastname | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | <!--T:56--> | ||
+ | You can also edit and delete variables from the variables view. Be careful when changing or deleting existing variables made by third-party scripts - you might break them. If that happens, re-opening the profiles will restore the variables back to working order. | ||
+ | |||
+ | <!--T:57--> | ||
+ | While you can create variables in the Variables view, remember that they won't be saved when Mudlet shuts down - if you'd like them to be more permanent, create scripts with the variables instead. | ||
+ | |||
+ | = Command-line Shortcuts = | ||
− | + | The command line has some built in keyboard shortcuts. | |
− | + | {| class="wikitable" | |
+ | |- | ||
+ | | Tab || Tab completion, see [[Manual:Technical Manual#Command_Line_Auto-Completion.2C_Tab-Completion_and_Command_History|this technical manual section]]. | ||
+ | |- | ||
+ | | Up or Down || Command line history, see [[Manual:Technical Manual#Command_Line_Auto-Completion.2C_Tab-Completion_and_Command_History|this technical manual section]]. | ||
+ | |- | ||
+ | | Home || Move cursor to beginning of line. | ||
+ | |- | ||
+ | | End || Move cursor to end of line. | ||
+ | |- | ||
+ | | CTRL+A || Select all. | ||
+ | |- | ||
+ | | CTRL+F || Move cursor to search bar. | ||
+ | |- | ||
+ | | SHIFT+Enter || Create an additional input line. | ||
+ | |- | ||
+ | | SHIFT+Left || Highlight one character left of the cursor (or unhighlight if already highlighted). | ||
+ | |- | ||
+ | | SHIFT+Right || Highlight one character right of the cursor (or unhighlight if already highlighted). | ||
+ | |- | ||
+ | | CTRL+Left || Move cursor one word to the left. | ||
+ | |- | ||
+ | | CTRL+Right || Move cursor one word to the right. | ||
+ | |- | ||
+ | | Backspace || Deletes the character to the left of the cursor. | ||
+ | |- | ||
+ | | CTRL+Backspace || Remove one word left of the cursor. | ||
+ | |- | ||
+ | | Delete || Deletes the character to the right of the cursor. | ||
+ | |- | ||
+ | | CTRL+Delete || Remove one word right of the cursor. | ||
+ | |- | ||
+ | | SHIFT+CTRL+Left || Highlight one word left of cursor. | ||
+ | |- | ||
+ | | SHIFT+CTRL+Right || Highlight one word right of cursor. | ||
+ | |- | ||
+ | | CTRL+C || Copies the selected text to the clipboard. | ||
+ | |- | ||
+ | | CTRL+Insert || Copies the selected text to the clipboard. | ||
+ | |- | ||
+ | | CTRL+K || Deletes to the end of the line. | ||
+ | |- | ||
+ | | CTRL+V || Pastes the clipboard text into line edit. | ||
+ | |- | ||
+ | | SHIFT+Insert || Pastes the clipboard text into line edit. | ||
+ | |- | ||
+ | | CTRL+X || Deletes the selected text and copies it to the clipboard. | ||
+ | |- | ||
+ | | SHIFT+Delete || Deletes the selected text and copies it to the clipboard. | ||
+ | |- | ||
+ | | Ctrl+Z || Undoes the last operation. | ||
+ | |- | ||
+ | | Ctrl+Y || Redoes the last undone operation. | ||
+ | |- | ||
+ | | PgUp || Scroll up one page in the main window buffer | ||
+ | |- | ||
+ | | PgDn || Scroll down one page in the main window buffer | ||
+ | |- | ||
+ | | Ctrl+Enter || Return to the bottom of the main window buffer | ||
+ | |- | ||
+ | |} | ||
+ | See also: [https://doc.qt.io/qt-6/qlineedit.html#details QT manual] | ||
+ | |||
+ | = Sending commands to the game = <!--T:58--> | ||
+ | |||
+ | <!--T:59--> | ||
+ | To send a command to the game, you can use the send() function. Data inside the quotes is sent to the game. | ||
+ | |||
+ | <!--T:60--> | ||
For example, the following code sends the command to eat bread: | For example, the following code sends the command to eat bread: | ||
− | <lua>send("eat bread")</ | + | <syntaxhighlight lang="lua">send("eat bread")</syntaxhighlight> |
+ | <!--T:61--> | ||
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: | 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: | ||
− | <lua>send("My name is " .. full_name .. ". What's yours?")</ | + | <syntaxhighlight lang="lua">send("My name is " .. full_name .. ". What's yours?")</syntaxhighlight> |
− | = | + | <!--T:62--> |
+ | If your commands ends with a variable, you don't need the two dots after: | ||
+ | <syntaxhighlight lang="lua">send("Hi, my name is " .. character)</syntaxhighlight> | ||
+ | <!--T:63--> | ||
+ | Should you want to include double quotes, use a double set of square brackets like this: | ||
+ | <syntaxhighlight lang="lua">send([[say "Hi, I'm new here!"]])</syntaxhighlight> | ||
+ | |||
+ | <!--T:64--> | ||
+ | When inserting a variable, you'd use the ]] and [[ appropriately: | ||
+ | <syntaxhighlight lang="lua">send([[poke ]]..victim)</syntaxhighlight> | ||
+ | |||
+ | <!--T:207--> | ||
+ | To send many directions, use [[Manual:Mapper_Functions#speedwalk|speedwalk()]]: | ||
+ | <syntaxhighlight lang="lua">speedwalk("n;e;s;w;")</syntaxhighlight> | ||
+ | |||
+ | <!--T:208--> | ||
+ | To send many actions, use [[Manual:Networking_Functions#sendAll|sendAll()]]: | ||
+ | <syntaxhighlight lang="lua">sendAll("attack", "cast magic missile")</syntaxhighlight> | ||
+ | |||
+ | = Showing text on screen = <!--T:65--> | ||
+ | |||
+ | <!--T:66--> | ||
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: | 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: | ||
− | |||
− | If you’d like to include variables in your echo, you concatenate the value of your variable to the text: | + | <!--T:67--> |
− | <lua> | + | <syntaxhighlight lang="lua">echo("Time to eat dinner!")</syntaxhighlight> |
+ | |||
+ | <!--T:68--> | ||
+ | If you’d like to include variables in your echo, you concatenate (put together) the value of your variable to the text: | ||
+ | <syntaxhighlight lang="lua"> | ||
my_gold = 5 | my_gold = 5 | ||
− | echo("I have " .. my_gold .. " pieces of gold!") | + | echo("I have " .. my_gold .. " pieces of gold!\n") |
− | </ | + | </syntaxhighlight> |
+ | <!--T:69--> | ||
If you'd like to include a new line in your text, insert ''\n'' for it: | If you'd like to include a new line in your text, insert ''\n'' for it: | ||
− | <lua> | + | <!--T:70--> |
+ | <syntaxhighlight lang="lua"> | ||
echo("this echo\nis on\nthree lines!") | echo("this echo\nis on\nthree lines!") | ||
+ | <!--T:71--> | ||
-- comes out at: | -- comes out at: | ||
this echo | this echo | ||
is on | is on | ||
three lines! | three lines! | ||
− | </ | + | </syntaxhighlight> |
− | |||
− | |||
− | ==== | + | = Seeing errors in your code = <!--T:72--> |
− | + | ||
+ | <!--T:73--> | ||
+ | Undoubtedly you'll be making mistakes when you're coding! To err is human, after all. There are two types of mistakes you can make in general: when the words you've typed in make no sense to Lua at all, or they do make sense, but they don't do what you actually thought and intended them to do - or other circumstances are preventing it from working at that point in time. | ||
+ | |||
+ | |||
+ | |||
+ | == Syntax errors aka Ladybugs == <!--T:74--> | ||
+ | |||
+ | <!--T:75--> | ||
+ | When you type something in that doesn't make sense to Lua, it's called a syntax mistake (or [http://en.wikipedia.org/wiki/Syntax_error error]). Mudlet will realize this and show you a little ladybug, and '''also tell you on which line the mistake is'''. Here's an example: | ||
+ | |||
+ | <!--T:76--> | ||
+ | [[File:Syntax error.png|1000px|center]] | ||
+ | |||
+ | <!--T:77--> | ||
+ | The ''echo()'' function on line 3 is missing a closing bracket - every bracket in Lua that's not green needs to be closed. Mudlet showed you a ladybug symbol on the alias, to indicate that the alias has a problem. It also showed you that the ( bracket should be closed on line 3. To fix this, you'd add the ''')''', save, and it will be all happy. | ||
+ | |||
+ | |||
+ | |||
+ | == Runtime errors aka Errors View == <!--T:78--> | ||
+ | |||
+ | <!--T:79--> | ||
+ | Another type of mistake is when what you typed in makes sense to Lua when you typed it in, but when it's time for code to be actually run, something wrong happens. For example, you asked Lua to '''eecho("hey!")''' - this is valid, you typed it in right, but there is one problem - eecho doesn't exist. So when you run the alias, nothing actually happens. Why? | ||
+ | |||
+ | <!--T:80--> | ||
+ | Mudlet puts all problems that happen when things are run into the Errors view. It is hidden by default, open it by '''pressing the errors button that you see on bottom-left'''. This is where the error is logged at - not your main window, so you aren't spammed when you make a mistake in a piece of code that happens very often. | ||
+ | |||
+ | <!--T:81--> | ||
+ | Opening it up will show this: | ||
+ | |||
+ | <!--T:82--> | ||
+ | [[File:Runtime error.png|1000px|center]] | ||
+ | |||
+ | <!--T:83--> | ||
+ | Let's analyse the message that's shown to us. ''object:<Some random alias>'' means that the Mudlet name you gave to the thing that had a problem is ''Some random alias'' - which is, indeed, our alias. ''function'' will tell you ''Alias'', ''Trigger'', ''Script'' or something else - this helps you locate the problematic item in question. | ||
+ | |||
+ | <!--T:84--> | ||
+ | Next red line is the actual error: it's saying that on line 2 (it's off by one - so actually line 1), ''eecho'' is a '''nil value'''. In Lua, nil means doesn't exist. Hence what it's telling you is that eecho does not actually exist! Change it to ''echo'', run it again, and there will be happiness. | ||
+ | |||
+ | <!--T:85--> | ||
+ | That's it for now - this page in time will be improved with common techniques you can use to diagnose errors quickly, etc... if you know anything about this, feel free to add it here! | ||
+ | |||
+ | |||
+ | |||
+ | </translate> | ||
+ | <span id="triggers"></span> | ||
+ | <translate> | ||
+ | |||
+ | = Triggers = <!--T:86--> | ||
+ | |||
+ | <!--T:87--> | ||
+ | Triggers are an automation feature offered in all game clients. They help you respond quicker a particular 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. | ||
+ | |||
+ | <!--T:88--> | ||
+ | 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 game output, it’ll run the commands you’ve told it to. | ||
+ | |||
+ | <!--T:89--> | ||
+ | Simple example: Whenever you see a bunny, you want to attack it (meanie!). | ||
− | < | + | <!--T:90--> |
− | + | # You type "bunny" in the data field titled "1" to add this word to the list of texts this trigger fires on. Make sure the dropdown next to it says "substring". | |
+ | # Now you type "kill bunny" in the field called "Command". This will be the command that the trigger will send to your game whenever the trigger fires. | ||
+ | # Finally click "Save Item" to save your new trigger and also click "Activate". By doing this, the blue checkbox icon in front of the trigger name (in the trigger tree on the left side) gets checked. The trigger is now activated. | ||
− | + | <!--T:209--> | |
+ | [[File:Trigger intro.png|1000px|center]] | ||
− | + | <!--T:91--> | |
+ | As the trigger is active, each time the word "bunny" will appear in the game output, your trigger will issue the command "kill bunny" automatically. It will repeat this as long as the trigger stays 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 check mark will vanish and the trigger will stop firing until you re-enable it again via the padlock icon. | ||
− | + | <!--T:92--> | |
+ | You can also put triggers in a group, then lock a group of triggers or an entire trigger branch. If you do that, all triggers in this group or 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. For example, you can 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. | ||
− | + | <!--T:93--> | |
+ | Beginners should use Mudlet's automated highlight triggers in the beginning to highlight the text that has been triggered on to get the hang of the different trigger and pattern types. Click on the "highlight trigger" option and pick a foreground and a background color that you like to highlight your trigger with. When the trigger matches it automatically highlights its pattern. This is the most used form of triggers in Mudlet 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 highlight triggers. Just type in the word you like to be highlighted, select appropriate colors, save the new trigger and activate it. | ||
− | |||
− | |||
− | + | == Matching one unknown word == <!--T:94--> | |
− | + | <!--T:95--> | |
+ | You can also set up a trigger to gather the weapons, gold or whatever skeletons could carry around with them. Since we do not know what the loot is exactly just yet, we will need to set up a trigger to match the line, identify the loot and take whatever it is that was dropped. | ||
− | + | <!--T:96--> | |
− | < | + | Examples for messages received could be: |
− | + | <!--T:97--> | |
+ | The skeleton drops ring. | ||
+ | The skeleton drops gold. | ||
+ | The skeleton drops scimitar. | ||
+ | The skeleton drops wooden key. | ||
− | + | <!--T:98--> | |
+ | "The skeleton drops " (including the last space character) is the generic segment of the line, but 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: | ||
− | = | + | <!--T:99--> |
− | + | # In the data field titled "1" write the following '''perl regex''' type pattern: <syntaxhighlight lang="lua">^The skeleton drops (.+)\.$</syntaxhighlight> | |
+ | # Make sure to change the dropdown menu for this line to "perl regex" as well | ||
+ | # In the big script box below write the following lua code: <syntaxhighlight lang="lua">send("take " .. matches[2])</syntaxhighlight> | ||
− | + | <!--T:210--> | |
+ | [[File:Trigger intro 2.png|1000px|center]] | ||
− | + | <!--T:100--> | |
+ | The regular expression (.+) matches any characters that the client receives between "The skeleton drops " (NB: notice the blank/space character at the end) and the full-stop symbol that ends the sentence. Know that the variable matches[2] simply transfers the first matched text fitting the search criteria into the output. For this example, it will be the dropped loot we now will take automatically. This text may actually contain more than one word, like in the fourth example shown above. | ||
− | + | <!--T:101--> | |
+ | In case you may wonder, matches[1] contains the entire line in whitch the matched text was found, whereas matches[2] contains only the first capture group. More on this in section two of the manual. The symbols ^ and $ indicate the start and end of a whole line. | ||
− | + | == Matching multiple unknowns == <!--T:102--> | |
− | + | <!--T:103--> | |
+ | Now, we don't want to take only loot from skeletons but from many different sources. | ||
− | + | <!--T:104--> | |
− | + | Examples could be: | |
+ | <!--T:105--> | ||
The skeleton drops ring. | The skeleton drops ring. | ||
− | The | + | The giant drops gold. |
− | The | + | The king drops scimitar. |
+ | The box drops wooden key. | ||
− | + | <!--T:106--> | |
+ | So let’s make a trigger that would gather the loot from anybody: | ||
− | + | <!--T:107--> | |
− | <lua>^ | + | # In data field "1" write: <syntaxhighlight lang="lua">^(.+) drops (.+)\.$</syntaxhighlight> |
+ | # Select '''perl regex''' type pattern again | ||
+ | # Below write the lua code: <syntaxhighlight lang="lua">send("take " .. matches[3])</syntaxhighlight> | ||
− | + | <!--T:211--> | |
− | + | [[File:Trigger intro 3.png|1000px|center]] | |
− | + | <!--T:108--> | |
+ | In this case, any time somebody, or something, "drops" something 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. | ||
− | + | == Matching known variants == <!--T:109--> | |
− | |||
− | + | <!--T:110--> | |
+ | If you’re playing a game in English, you’ll notice that these triggers probably won’t work due to English syntax. Compare: | ||
− | + | <!--T:111--> | |
− | + | The skeleton drops ring. | |
+ | The skeleton drops a ring. | ||
− | + | <!--T:112--> | |
+ | Chances are that you’ll see the later case a little more often. If we used our old regex, the trigger would produce something like this. | ||
− | + | <!--T:113--> | |
− | + | TRIGGERED LINE: The skeleton drops a ring. | |
+ | OUR REACTION: take a ring | ||
− | < | + | <!--T:114--> |
− | + | However most games can’t handle determiners in user-input, such as articles (i.e. a, an, the) or quantifiers (e.g. five, some, each). In effect, our triggered reaction won't suffice. Instead we would need to react with just "take ring" again. | |
− | |||
− | |||
− | + | <!--T:115--> | |
+ | To correctly handle lines like this, we could either create multiple triggers matching every possible article, which could become very cumbersome. Instead we make one regular expression filtering out all these words and phrases: | ||
− | < | + | <!--T:116--> |
− | + | # Write a new '''perl regex''' type pattern: <syntaxhighlight lang="lua">(.+) drops (a|an|the|some|a couple of|a few|) (.+)\.$</syntaxhighlight> | |
− | + | # With this script: <syntaxhighlight lang="lua">send("take " .. matches[4])</syntaxhighlight> | |
− | </ | ||
− | + | <!--T:212--> | |
+ | [[File:Trigger intro 4.png|1000px|center]] | ||
− | + | <!--T:117--> | |
+ | Once again, note that this time we are using the third matched group through matches[4] now. | ||
− | + | </translate> | |
− | < | + | == Basic Regex Characters == <!--T:120--> |
− | + | <!--T:121--> | |
+ | You already know <code>(.+)</code> which will match to any and all characters that follow until the end of line or another specific text that you may put in your regex. How about if you only want to match to certain type of characters? | ||
− | |||
− | |||
− | |||
− | Retrieving | + | === Retrieving numbers from triggers === <!--T:122--> |
+ | |||
+ | |||
+ | <!--T:123--> | ||
Wildcards from triggers are stored in the matches[] table. The first wildcard goes into matches[2], second into matches[3], and so on, for however many wildcards do you have in your trigger. | Wildcards from triggers are stored in the matches[] table. The first wildcard goes into matches[2], second into matches[3], and so on, for however many wildcards do you have in your trigger. | ||
+ | <!--T:124--> | ||
For example, you’d like to say out loud 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: | For example, you’d like to say out loud 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: | ||
− | |||
− | A trigger that matches this pattern could be | + | <!--T:125--> |
+ | You pick up 16 gold. | ||
+ | |||
+ | |||
+ | <!--T:126--> | ||
+ | A trigger that matches this pattern could be: | ||
+ | |||
+ | |||
+ | <!--T:127--> | ||
+ | # Perl Regex: <syntaxhighlight lang="lua">^You pick up (\d+) gold\.$</syntaxhighlight> | ||
+ | # Script: <syntaxhighlight lang="lua">echo("I got " .. tonumber(matches[2]) .. " gold!")</syntaxhighlight> | ||
− | |||
− | + | <!--T:128--> | |
+ | In your code, the variable matches[2] will contain the amount of gold you picked up - in this case, 16. Now you say out loud how much gold you did loot. Notice also that (\d+) will only recognize numbers but not letters or a space character. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | === | + | === Retrieving alphanumeric characters === <!--T:129--> |
− | |||
− | + | <!--T:130--> | |
+ | Here’s a more advanced example by Heiko, which makes you talk like Yoda: | ||
− | |||
− | + | <!--T:131--> | |
+ | # Perl Regex: <syntaxhighlight lang="lua">^say (\w+) *(\w*) .*?(.*)</syntaxhighlight> | ||
+ | # Script: <syntaxhighlight lang="lua">send( "say "..matches[4].." "..matches[2].." "..matches[3] )</syntaxhighlight> | ||
+ | |||
+ | <!--T:132--> | ||
+ | The trigger will recognize that you say something, and save in seperate groups the first word, the second word and then the rest of you text. Here the \w wildcards will match any numbers or letters but no non-alphanumeric characters. It then shows you say the rest of the text first, then the first word and finally the second word. Notice this will only affect the text displayed for yourself, but if you want to also adjust the text you are sending to other players, please see the [[#Aliases|chapter about aliases]]. | ||
+ | |||
+ | |||
+ | {{Note}}want to learn more regex? Try [https://regexlearn.com/ https://regexlearn.com] which is a great, easy to follow resource for this. | ||
+ | |||
+ | ==<span class="mw-headline" id="Highlighting_Words">Highlighting Words</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span>[[/index.php?title=Manual:Introduction&veaction=edit§ion=4|edit]]<span class="mw-editsection-divider"> | </span>[[/index.php?title=Manual:Introduction&action=edit§ion=4|edit source]]<span class="mw-editsection-bracket">]</span></span>== | ||
+ | <span></span> | ||
+ | To highlight something in the game output, make a trigger and use the "highlight trigger" option to highlight the matched trigger pattern. | ||
+ | |||
+ | Optionally, you can also make use of the [[/w/Special:MyLanguage/Manual:Lua Functions#bg|bg()]] and [[/w/Special:MyLanguage/Manual:Lua Functions#fg|fg()]] functions in scripting to highlight. | ||
+ | |||
+ | |||
+ | |||
+ | <span id="keybindings"></span> | ||
+ | <translate> | ||
+ | |||
+ | = Keybindings = <!--T:136--> | ||
+ | |||
+ | <!--T:137--> | ||
+ | Keybindings (also known as hotkeys or macros), are in many respects very similar to aliases. However, instead of typing in what you want to be done (maybe including additional parameters) and pressing Enter, you simply hit a single key (or combination of keys) to let Mudlet do the work. | ||
+ | |||
+ | <!--T:138--> | ||
Example - You don’t drink tea, you sip it! | 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: | 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: | ||
+ | <!--T:139--> | ||
HOTKEY: F1 | HOTKEY: F1 | ||
command on button down: sip earl gray | command on button down: sip earl gray | ||
+ | <!--T:140--> | ||
HOTKEY: F2 | HOTKEY: F2 | ||
command on button down: sip ceylon mint | command on button down: sip ceylon mint | ||
Now you just have to listen, or rather read, carefully and hit either F1 or F2 to claim that prize. | 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 | + | <!--T:141--> |
+ | 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 games without auto-attack. See the Variables chapter for further details. | ||
− | + | <!--T:142--> | |
+ | Example instructions on how to make a keybinding (for a set of settings for binding the keypad): | ||
− | + | <!--T:198--> | |
+ | # Click the '''Keys''' button: [[File:Keys button.jpg]] | ||
+ | # If you wish to group them together, click the '''Add Group''' button | ||
+ | # Then name your group, ''Keypad'' for instance | ||
+ | # With the group selected now click the '''Add Item''' button | ||
+ | # Name it, let's say ''North'', in the '''Name:''' widget | ||
+ | # If you only need a single command, like ''north'' for our example, place it into the '''Command:''' widget, otherwise skip to step 9 | ||
+ | # Click the '''Grab New Key''' button | ||
+ | # Click the '''button sequence''' you want to use for your keybinding, ''keypad 8'' for north | ||
+ | # Now if you need additional code to execute when you click your keybinding, or want more complicated code, place it into the giant code box. | ||
+ | # Click the '''Save Item''' button if done or '''New Item''' button if not. | ||
+ | # Click the '''Activate''' button when finished to make sure they work. | ||
− | + | <!--T:199--> | |
+ | Here is a link to the resulting keybinding XML file on the forums: [http://forums.mudlet.org/viewtopic.php?f=6&t=2163] | ||
− | |||
− | |||
− | |||
− | + | </translate> | |
+ | <span id="timers"></span> | ||
+ | <translate> | ||
− | == | + | = Timers = <!--T:143--> |
− | + | <!--T:144--> | |
+ | 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. They can be used by clicking in the "timer" editor, or direcly in your script. | ||
+ | <!--T:200--> | ||
+ | To use a simple timer that does something after a period, write like this: | ||
− | === | + | <!--T:145--> |
+ | <syntaxhighlight lang="lua"> | ||
+ | tempTimer(seconds, [[code]]) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <!--T:201--> | ||
+ | Seconds needs to be a number, the time until the timer starts. Code can be any commands which you want executed then. | ||
+ | |||
+ | <!--T:202--> | ||
+ | {{note}} Seconds can be a decimal, so 0.5 for half a second, or 1 for a full second will both work as expected. | ||
+ | |||
+ | <!--T:146--> | ||
+ | Here's a finished example which you can copy and put in your code directly: | ||
+ | |||
+ | <!--T:147--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- this timer will greet you exactly 2 seconds after it was made | ||
+ | tempTimer(2, [[ echo("hello!\n") ]]) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <!--T:203--> | ||
+ | You can combine both normal and timed commands, for example as code in an alias or keybinding: | ||
+ | |||
+ | <!--T:204--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- this code will let you go north immediately, then go east after 2 seconds | ||
+ | send("n") | ||
+ | tempTimer(2, [[ send("e") ]]) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <!--T:148--> | ||
+ | {{note}} All timers which are made at the same time, will start counting from this common point in time, not relative to each other - so if you want to make one timer go off 1 second after another, '''don't do this''': | ||
+ | |||
+ | <!--T:149--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- incorrect: | ||
+ | tempTimer(1, [[ echo("hello!\n") ]]) | ||
+ | tempTimer(1, [[ echo("how are you?\n") ]]) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <!--T:150--> | ||
+ | Both of these timers will go off at once, because both started together, right away! Instead, '''do this''': | ||
+ | |||
+ | <!--T:151--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- correct: | ||
+ | tempTimer(1, [[ echo("hello!\n") ]]) | ||
+ | tempTimer(2, [[ echo("how are you?\n") ]]) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <!--T:205--> | ||
+ | {{note}} If you do not want to put all your timed code in <nowiki>[[ brackets ]]</nowiki> there is another way of writing the same example. (This is available since Mudlet 3.5) | ||
+ | |||
+ | <!--T:206--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- this timer will greet you exactly 2 seconds after it was made | ||
+ | tempTimer(2, function() echo("hello!\n") end) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <!--T:152--> | ||
+ | That's it for the basics of scriptable timers in Mudlet. Want to know more? Here is a '''[[Special:MyLanguage/Manual:Technical Manual#Timer Engine|full description of timers in Mudlet]]'''. | ||
+ | |||
+ | = Buttons = <!--T:153--> | ||
+ | |||
+ | <!--T:154--> | ||
You can use Mudlet to create simple buttons on your screen without much coding at all - you can attach button bars to the top, left or right side of the screen. Each of these locations can contain an infinite number of button bars that are shown when active or hidden when inactive. You can also create drop-down menus or or two-state buttons - ones that you can click on and they stay pressed down. | You can use Mudlet to create simple buttons on your screen without much coding at all - you can attach button bars to the top, left or right side of the screen. Each of these locations can contain an infinite number of button bars that are shown when active or hidden when inactive. You can also create drop-down menus or or two-state buttons - ones that you can click on and they stay pressed down. | ||
+ | <!--T:155--> | ||
To get started with buttons, '''make a group''' (buttons have to be in a group to show) and add buttons inside them. Active buttons or groups to make them be visible. Here's an example - by making a new group and a button inside it, and activating both, we got a button to spawn: | To get started with buttons, '''make a group''' (buttons have to be in a group to show) and add buttons inside them. Active buttons or groups to make them be visible. Here's an example - by making a new group and a button inside it, and activating both, we got a button to spawn: | ||
− | [[File:Buttons Start.png]] | + | <!--T:156--> |
+ | [[File:Buttons Start.png|1000px|center|]] | ||
+ | |||
+ | <!--T:157--> | ||
+ | Buttons show '''in the order they appear in''' - so if you'd like one button to be above another, just drag it visually in the editor! | ||
+ | |||
+ | |||
+ | |||
+ | == Menus == <!--T:158--> | ||
− | + | <!--T:159--> | |
An important use case for buttons is to have various menus which contain a number of checkbox buttons or sub menus in order to quickly set various scripting configuration or other options in your scripts. To start a menu of buttons, create another group inside your toolbar group and add individual buttons inside it, like so: | An important use case for buttons is to have various menus which contain a number of checkbox buttons or sub menus in order to quickly set various scripting configuration or other options in your scripts. To start a menu of buttons, create another group inside your toolbar group and add individual buttons inside it, like so: | ||
− | [[File:Buttons Menu.png]] | + | <!--T:160--> |
+ | [[File:Buttons Menu.png|center|]] | ||
+ | |||
+ | <!--T:161--> | ||
+ | To change the side of Mudlet that the buttons use, change the '''Dock area <side>''' option and save. You can also make buttons align themselves top to bottom or left to right with the '''Orientation <horizontal or vertical>''' option. | ||
+ | |||
+ | <!--T:162--> | ||
+ | [[File:Changing button group position.png|center|]] | ||
+ | |||
+ | |||
+ | |||
+ | == Making buttons do stuff == <!--T:163--> | ||
+ | |||
+ | <!--T:164--> | ||
+ | Buttons are half as useful only being there. You can also make them do commands for you for when you press them! To make a button do your command, or alias, or anything - type it into the ''Command on Button Down'' field. Pressing the button will do that command then: | ||
+ | |||
+ | <!--T:165--> | ||
+ | [[File:Button command.png|center|]] | ||
+ | |||
+ | <!--T:166--> | ||
+ | You can also make a button do two things, toggling between each. To do that, '''enable the ''Push Down Button''''' option, and type the command you'd like your button to do when it's released in the ''Command on Button Up'' field. | ||
+ | |||
+ | <!--T:167--> | ||
+ | [[File:Alternating button.png|center|]] | ||
+ | |||
+ | </translate> | ||
+ | {{note}} | ||
+ | <translate> <!--T:168--> | ||
+ | If you'd like to include & in the button name, put double && - a single & will act as a mnemonic to underline the shortcut letter. | ||
+ | |||
+ | |||
+ | |||
+ | == Coloring & customizing buttons == <!--T:169--> | ||
+ | |||
+ | <!--T:170--> | ||
+ | To change how your buttons look, you put descriptions into the ''CSS Style Sheet'' field, in the format of '''<a word describing something>: <how it should look>;'''. For example, if you'd like to make the button be red, put ''background-color: red;'' into the CSS box: | ||
+ | |||
+ | <!--T:171--> | ||
+ | [[File:Red button.png|center|]] | ||
+ | |||
+ | <!--T:172--> | ||
+ | A full list of names you can use to customize your buttons view is [https://doc.qt.io/qt-5/stylesheet-reference.html available here]. Take note of how that page has the descriptions inside {} brackets - you don't need them, only paste what's inside them in Mudlet. | ||
+ | |||
+ | <!--T:173--> | ||
+ | Applying some skills, we can make our buttons look much more aesthetic: | ||
+ | |||
+ | <!--T:174--> | ||
+ | [[File:Sexy Buttons.png|center|]] | ||
+ | |||
+ | <!--T:175--> | ||
+ | This was the code used, feel free to start your buttons off with it: | ||
+ | |||
+ | <!--T:176--> | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | color: white; background-color: orange; font-size: 12px; | ||
+ | padding: 6px; | ||
+ | border-radius: 5px; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Users with OS Windows 10 may find that for Mudlet versions 4.11+, the ''background-color: <colour>;'' is not changing the background as expected. This can be fixed by changing the border of the button. For example ''border: none;''. Although that may destroy the size of button and it has to be set manualy. To achieve somehow similar size to default buttons you can use something like this: | ||
+ | |||
+ | <syntaxhighlight lang="lua"> | ||
+ | background-color: <your_colour>; | ||
+ | border: 1px solid gray; | ||
+ | width: 90px; height: 25px; | ||
+ | margin: 1px; | ||
+ | font-size: 14px; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | == Managed layouts == <!--T:177--> | ||
+ | |||
+ | <!--T:178--> | ||
+ | To get your buttons to align into rows or columns (that depends on their orientation), add a number to the ''Number of columns or rows'' field. Here's an example with two columns on the left: | ||
+ | |||
+ | <!--T:179--> | ||
+ | [[File:Two row alignment.png|center|]] | ||
+ | |||
+ | <!--T:180--> | ||
+ | Here's another example with three columns on the left: | ||
+ | |||
+ | <!--T:181--> | ||
+ | [[File:Three column alignment.png|center|]] | ||
+ | |||
+ | </translate> | ||
+ | {{note}} | ||
+ | <translate> <!--T:182--> | ||
+ | You can change how your buttons are aligned within rows by clicking on the button group - it will cycle through different possible configurations for you. | ||
+ | |||
+ | <!-- Zooka 20230712 WIP : working on https://github.com/Mudlet/Mudlet/issues/5067 --> | ||
+ | == Making Buttons with Labels == | ||
+ | |||
+ | Labels can also be used to make buttons. They are far more flexible and you can design [https://www.mudlet.org/media/ almost any UI] you can dream up considering they are simply [[Manual:Geyser#Clickable_images|clickable images]]. | ||
+ | |||
+ | We'll start by making twelve buttons along the top of our screen. | ||
+ | |||
+ | <nowiki> | ||
+ | -- set a 10% margin from the top border to provide space | ||
+ | local width, height = getMainWindowSize() | ||
+ | setBorderTop(height/10) | ||
+ | |||
+ | -- create some variable space so we don't pollute global variables | ||
+ | MyButtons = {} | ||
+ | |||
+ | -- create a label for the entire margin, for now | ||
+ | MyButtons.Top = Geyser.Label:new({ | ||
+ | name = "MyButtons.Top", | ||
+ | x = 0, y = 0, | ||
+ | width = "100%", | ||
+ | height = "10%", | ||
+ | }) | ||
+ | |||
+ | -- create a horizontal box to organise the buttons equally | ||
+ | MyButtons.TopHBox = Geyser.HBox:new({ | ||
+ | name = "MyButtons.TopHBox", | ||
+ | x = 0, y = 0, | ||
+ | width = "100%", | ||
+ | height = "100%", | ||
+ | },MyButtons.Top) | ||
+ | |||
+ | -- add some buttons to the HBox using a Geyser label | ||
+ | for i=1,12 do | ||
+ | MyButtons["MyButton"..i] = Geyser.Label:new({ | ||
+ | name = "MyButtons.Button"..i, | ||
+ | },MyButtons.TopHBox) | ||
+ | MyButtons["MyButton"..i]:echo("<center>My Button "..i) | ||
+ | end | ||
+ | </nowiki> | ||
+ | |||
+ | [[File:Label-button-tutorial-1.png|thumb|center|Basic top button layout, made with labels.]] | ||
+ | |||
+ | The main function creating the button labels is Geyser.Label. You should now see the results as above. A bit plain, you could add some CSS to spark things up a bit. | ||
+ | |||
+ | <nowiki> | ||
+ | -- add some buttons to the HBox using a Geyser label | ||
+ | for i=1, 12 do | ||
+ | MyButtons["MyButton"..i] = Geyser.Label:new({ | ||
+ | name = "MyButtons.Button"..i, | ||
+ | },MyButtons.TopHBox) | ||
+ | MyButtons["MyButton"..i]:echo("<center>My Button "..i) | ||
+ | |||
+ | -- colour my buttons with CSS | ||
+ | MyButtons["MyButton"..i]:setStyleSheet([[ | ||
+ | background-color: rgba(135,206,250,100); | ||
+ | border-style: solid; | ||
+ | border-width: 1px; | ||
+ | border-color: white; | ||
+ | border-radius: 5px; | ||
+ | margin: 5px; | ||
+ | qproperty-wordWrap: true; | ||
+ | ]]) | ||
+ | end | ||
+ | </nowiki> | ||
+ | |||
+ | Much better. But currently they are just twelve pretty labels that don't perform any function. Let's make them clickable with [https://www.mudlet.org/geyser/files/geyser/GeyserLabel.html#Geyser.Label:setClickCallback setClickCallback] | ||
+ | |||
+ | [https://www.mudlet.org/geyser/files/geyser/GeyserLabel.html#Geyser.Label:setClickCallback setClickCallback] assigns a function to a Geyser label that will be called when the mouse is clicked on the label. This function has similar methods for double clicking, hovering, etc.. all of which can be found in the [https://www.mudlet.org/geyser/files/geyser/GeyserLabel.html Geyser manual]. Let's keep it straightforward for now with a single click. Consider the following addition; | ||
+ | |||
+ | <nowiki> | ||
+ | -- add some buttons to the HBox using a Geyser label | ||
+ | for i=1,12 do | ||
+ | MyButtons["MyButton"..i] = Geyser.Label:new({ | ||
+ | name = "MyButtons.Button"..i, | ||
+ | },MyButtons.TopHBox) | ||
+ | MyButtons["MyButton"..i]:echo("<center>My Button "..i) | ||
+ | |||
+ | -- colour my buttons with CSS | ||
+ | MyButtons["MyButton"..i]:setStyleSheet([[ | ||
+ | background-color: rgba(135,206,250,100); | ||
+ | border-style: solid; | ||
+ | border-width: 1px; | ||
+ | border-color: white; | ||
+ | border-radius: 5px; | ||
+ | margin: 5px; | ||
+ | qproperty-wordWrap: true; | ||
+ | ]]) | ||
+ | |||
+ | -- make our buttons clickable | ||
+ | MyButtons["MyButton"..i]:setClickCallback(function() echo("My Button " ..i.." clicked!\n") end) | ||
+ | end | ||
+ | </nowiki> | ||
+ | [[File:Label-button-tutorial-2.png|thumb|center|CSS labels acting as clickable buttons.]] | ||
+ | |||
+ | You should now be able to click the button and see the echo to the main screen. | ||
+ | |||
+ | === Adjustable Containers for Labels === | ||
+ | |||
+ | [[Manual:Geyser#Adjustable.Container|Adjustable Containers]] are a Geyser element that provides a flexible, user configurable, dockable window. Let's move our buttons to one of these containers and see what else we can do. | ||
+ | |||
+ | <nowiki> | ||
+ | -- create some variable space so we don't pollute global variables | ||
+ | MyButtons = {} | ||
+ | |||
+ | -- create an adjustable container for more flexibility | ||
+ | MyButtons.Top = Adjustable.Container:new({ | ||
+ | name = "MyButtons.Top", | ||
+ | x = 0, y = 0, | ||
+ | width = "100%", | ||
+ | height = "10%", | ||
+ | }) | ||
+ | |||
+ | -- create a horizontal box to organise the buttons equally | ||
+ | MyButtons.TopHBox = Geyser.HBox:new({ | ||
+ | name = "MyButtons.TopHBox", | ||
+ | x = 0, y = 0, | ||
+ | width = "100%", | ||
+ | height = "100%", | ||
+ | },MyButtons.Top) | ||
+ | |||
+ | -- add some buttons to the HBox using a Geyser label | ||
+ | for i=1, 12 do | ||
+ | MyButtons["MyButton"..i] = Geyser.Label:new({ | ||
+ | name = "MyButtons.Button"..i, | ||
+ | },MyButtons.TopHBox) | ||
+ | MyButtons["MyButton"..i]:echo("<center>My Button "..i) | ||
+ | |||
+ | -- colour my buttons with CSS | ||
+ | MyButtons["MyButton"..i]:setStyleSheet([[ | ||
+ | background-color: rgba(135,206,250,100); | ||
+ | border-style: solid; | ||
+ | border-width: 1px; | ||
+ | border-color: white; | ||
+ | border-radius: 5px; | ||
+ | margin: 5px; | ||
+ | qproperty-wordWrap: true; | ||
+ | ]]) | ||
+ | |||
+ | -- make our buttons clickable | ||
+ | MyButtons["MyButton"..i]:setClickCallback(function() echo("My Button " ..i.." clicked!\n") end) | ||
+ | end | ||
+ | </nowiki> | ||
+ | |||
+ | [[File:Label-button-tutorial-3.png|thumb|center|Labels in an adjustable container, docked to the top border.]] | ||
+ | |||
+ | We removed the setBorderTop code because the adjustable container can be docked to a border by right clicking on the title bar and a margin is automatically created. It is docked to the top border in this example. | ||
+ | |||
+ | The container can be resized and moved around or perhaps changed to a VBox for slick left and right border docking. | ||
+ | |||
+ | [[File:Label-button-tutorial-4.png|thumb|center|Resized and undocked adjustable container with clickable labels acting as buttons.]] | ||
+ | |||
+ | This example can be further expanded to add images to the labels, highlighting when hovering over labels or even multi-state buttons with variables to track the state. Your imagination is the only limit. | ||
+ | |||
+ | = Built-in aliases = <!--T:183--> | ||
+ | |||
+ | <!--T:184--> | ||
+ | The following aliases are available by default in new Mudlet profiles. | ||
+ | |||
+ | <!--T:185--> | ||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Alias !! Description !! Examples | ||
+ | |- | ||
+ | | lua || Run Lua code from the input line. || lua print("hello")<br>lua 2+2<br>lua clearWindow() | ||
+ | |- | ||
+ | | `echo || Simulate text from the game to test your triggers.<br>You can use $ for a new line. || `echo You see a rabbit cross the road.<br>`echo line1$line2 | ||
+ | |} | ||
+ | |||
+ | <!--T:186--> | ||
+ | If an alias on the list isn't working for you - try copying it from a new profile, since existing profiles will not get new aliases as they're introduced to Mudlet. | ||
+ | |||
+ | = Misc examples = <!--T:191--> | ||
+ | |||
+ | <!--T:192--> | ||
+ | Here are some more miscellaneous examples. | ||
+ | <!--T:193--> | ||
+ | '''Game syntax''': ''get coins from corpse'' and also ''get coins from corpse 3''. | ||
+ | '''Alias Pattern''': '''^gcc(?:\s(\d+))?$''' (can accept simply ''gcc'' and also ''gcc 3'' for example). | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | send("get coins from corpse " .. (matches[2] or "") ) | ||
+ | </syntaxhighlight> | ||
− | + | <!--T:194--> | |
+ | '''Game syntax''': ''unlock northwest with steel key'' | ||
+ | '''Alias Pattern''': '''^un (\w+) (.*)$''' | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | send("unlock " .. matches[2] .. " with " .. matches[3] ) | ||
+ | </syntaxhighlight> | ||
− | See also: [[Manual:Technical Manual|Mudlet Technical Manual]] | + | <!--T:195--> |
+ | See also: [[Special:MyLanguage/Manual:Technical Manual|Mudlet Technical Manual]] | ||
+ | <!--T:196--> | ||
[[Category:Mudlet Manual]] | [[Category:Mudlet Manual]] | ||
+ | </translate> |
Revision as of 22:33, 11 January 2024
Automation and game rules
It is possible to create an Artificial Intelligence (AI) that does everything you can do in a game. Even more so, an AI can outperform you in every routine operation, depending on the complexity of the task. Because scripting is so powerful, it can give you a competitive advantage that some people consider unfair or even cheating. In some cases it can have much more far reaching consequences on a game, such as inflation, loss of balance in terms of game-mechanics or, ultimately, a complete crash of in-game economy. For these and various other reasons the administrators and owners of some games forbid or limit the use of automation tools.
By including scripting support in Mudlet, we effectively give you the ability to create and utilize AI toolkits. However, we do not endorse or promote the usage of automation if it is prohibited in your game! Keep in mind that by cheating you can lessen the quality of gameplay for both your fellow players and yourself.
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:
- Aliases
- User-defined text input, which is converted into a different, usually longer input before being sent to the game.
- e.g. typing gg to have get gold from ground;put gold in bag be sent to the game.
- Variables
- allow the user to store text or numbers for easier use inside scripts.
- Triggers
- execute user-defined commands upon receiving specific out from the game,
- e.g. gamesends: "You see Elyssa standing here." and Mudlet automatically sends "poke Elyssa" to the game.
- Keybindings
- also known as hotkeys, allow executing certain user-defined commands by simultaneously pressing a specific combination of keys
- e.g. pressing CTRL+H to send "say Hello Miyuki!" to the game or play La Marseillaise
- Timers
- delay the execution of a command or execute it after a specified period of time.
- e.g. throw gauntlet to Eric-wait 3 seconds-exclaim Let us end this here!
- Events
- allow the user to make triggers for specific events like when Mudlet has connected to the game, or even user-defined events to use in complex system making.
To get started on programming in Mudlet, watch these screencasts that explain the basics that'll help you get started.
Keep on reading for an introduction to Mudlet's features:
Aliases
Aliases are the most basic way of automating the gameplay - you can use aliases to shorten the amount of typing you do. See more detailed info here: Manual:Alias Engine
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 <wait 5 seconds> 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… thrice a day!
Alternatively, you just create an alias that would do this all with a single command - for example, "quest". To make that happen, read on! Here's a sneak peek on what you should have in the end:
Making an 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 distinguish all of the aliases. You can just name our alias "test" for now. The Pattern field is where you put your regex pattern to describe the command you'll enter to make your new alias spring into action. Let’s say we want our new alias to send the command "say hello" whenever we type "sh". The regex pattern would be ^sh$. Then we put say hello into the Command field. After you have saved and activated your new alias "test", whenever you type "sh" Mudlet will not send "sh", but "say hello" instead. We call this replacement 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 aliases it is enough to know that the character ^ symbolizes the beginning of the line and the character $ 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 "command". 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 deactivated 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 game. Aliases are basically a feature to save you a bit of typing (much like buttons which will be described in detail in a later section of the manual). More advance alias usage will be described later in the manual.
Making a Targetting Alias
To make an alias that'll remember your target - making it easier to use your skills and saving you the hassle of typing the target in all the time, do the following:
In the Pattern field, place the following:
^t (.+)$
That will match all commands that you type in the format of t <any words> - it'll match t rat, t tsol'aa, t human and etcetera.
Next, make the big box do this:
target = matches[2]
cecho("<light_slate_blue>My target is now: <red>"..target.."\n")
You can also make an alias with an optional target:
^dd(?: (.+))?$
Now the target, if it is supplied, is going to be matches[2]. You can test if the target was given with this code:
send("cast spell at "..(matches[2] or target))
That's it - whenever you use this alias, your target will be remembered in the target variable.
Next, you'd like to make use of this variable - so make another alias that will do the actual attacking for you! Here's an example one:
Pattern:
^atk$
Code:
send("kick "..target)
This alias will kick the target when you type in atk. Feel free to adjust the "trigger" word and the command as you need them.
Variables
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 - create them in the Script editor in a new script:
variable = 1234
Or to make it remember some text:
my_name = "Bob"
It'll then appear in the Variables view, like so:
You can also do basic maths easily, for example:
To concatenate strings together, you can use the .. expression:
my_full_name = "Bob" .. " the Builder"
Don't forget to use a space when you're concatenating two variables together:
firstname = "Apple"
lastname = "Red"
-- bad: will produce "AppleRed"
full_name = firstname .. lastname
-- good: will produce "Apple Red"
full_name = firstname .. " " .. lastname
You can also edit and delete variables from the variables view. Be careful when changing or deleting existing variables made by third-party scripts - you might break them. If that happens, re-opening the profiles will restore the variables back to working order.
While you can create variables in the Variables view, remember that they won't be saved when Mudlet shuts down - if you'd like them to be more permanent, create scripts with the variables instead.
Command-line Shortcuts
The command line has some built in keyboard shortcuts.
Tab | Tab completion, see this technical manual section. |
Up or Down | Command line history, see this technical manual section. |
Home | Move cursor to beginning of line. |
End | Move cursor to end of line. |
CTRL+A | Select all. |
CTRL+F | Move cursor to search bar. |
SHIFT+Enter | Create an additional input line. |
SHIFT+Left | Highlight one character left of the cursor (or unhighlight if already highlighted). |
SHIFT+Right | Highlight one character right of the cursor (or unhighlight if already highlighted). |
CTRL+Left | Move cursor one word to the left. |
CTRL+Right | Move cursor one word to the right. |
Backspace | Deletes the character to the left of the cursor. |
CTRL+Backspace | Remove one word left of the cursor. |
Delete | Deletes the character to the right of the cursor. |
CTRL+Delete | Remove one word right of the cursor. |
SHIFT+CTRL+Left | Highlight one word left of cursor. |
SHIFT+CTRL+Right | Highlight one word right of cursor. |
CTRL+C | Copies the selected text to the clipboard. |
CTRL+Insert | Copies the selected text to the clipboard. |
CTRL+K | Deletes to the end of the line. |
CTRL+V | Pastes the clipboard text into line edit. |
SHIFT+Insert | Pastes the clipboard text into line edit. |
CTRL+X | Deletes the selected text and copies it to the clipboard. |
SHIFT+Delete | Deletes the selected text and copies it to the clipboard. |
Ctrl+Z | Undoes the last operation. |
Ctrl+Y | Redoes the last undone operation. |
PgUp | Scroll up one page in the main window buffer |
PgDn | Scroll down one page in the main window buffer |
Ctrl+Enter | Return to the bottom of the main window buffer |
See also: QT manual
Sending commands to the game
To send a command to the game, you can use the send() function. Data inside the quotes is sent to the game.
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?")
If your commands ends with a variable, you don't need the two dots after:
send("Hi, my name is " .. character)
Should you want to include double quotes, use a double set of square brackets like this:
send([[say "Hi, I'm new here!"]])
When inserting a variable, you'd use the ]] and [[ appropriately:
send([[poke ]]..victim)
To send many directions, use speedwalk():
speedwalk("n;e;s;w;")
To send many actions, use sendAll():
sendAll("attack", "cast magic missile")
Showing text on screen
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 (put together) the value of your variable to the text:
my_gold = 5
echo("I have " .. my_gold .. " pieces of gold!\n")
If you'd like to include a new line in your text, insert \n for it:
echo("this echo\nis on\nthree lines!")
-- comes out at:
this echo
is on
three lines!
Seeing errors in your code
Undoubtedly you'll be making mistakes when you're coding! To err is human, after all. There are two types of mistakes you can make in general: when the words you've typed in make no sense to Lua at all, or they do make sense, but they don't do what you actually thought and intended them to do - or other circumstances are preventing it from working at that point in time.
Syntax errors aka Ladybugs
When you type something in that doesn't make sense to Lua, it's called a syntax mistake (or error). Mudlet will realize this and show you a little ladybug, and also tell you on which line the mistake is. Here's an example:
The echo() function on line 3 is missing a closing bracket - every bracket in Lua that's not green needs to be closed. Mudlet showed you a ladybug symbol on the alias, to indicate that the alias has a problem. It also showed you that the ( bracket should be closed on line 3. To fix this, you'd add the ), save, and it will be all happy.
Runtime errors aka Errors View
Another type of mistake is when what you typed in makes sense to Lua when you typed it in, but when it's time for code to be actually run, something wrong happens. For example, you asked Lua to eecho("hey!") - this is valid, you typed it in right, but there is one problem - eecho doesn't exist. So when you run the alias, nothing actually happens. Why?
Mudlet puts all problems that happen when things are run into the Errors view. It is hidden by default, open it by pressing the errors button that you see on bottom-left. This is where the error is logged at - not your main window, so you aren't spammed when you make a mistake in a piece of code that happens very often.
Opening it up will show this:
Let's analyse the message that's shown to us. object:<Some random alias> means that the Mudlet name you gave to the thing that had a problem is Some random alias - which is, indeed, our alias. function will tell you Alias, Trigger, Script or something else - this helps you locate the problematic item in question.
Next red line is the actual error: it's saying that on line 2 (it's off by one - so actually line 1), eecho is a nil value. In Lua, nil means doesn't exist. Hence what it's telling you is that eecho does not actually exist! Change it to echo, run it again, and there will be happiness.
That's it for now - this page in time will be improved with common techniques you can use to diagnose errors quickly, etc... if you know anything about this, feel free to add it here!
Triggers
Triggers are an automation feature offered in all game clients. They help you respond quicker a particular 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 game output, it’ll run the commands you’ve told it to.
Simple example: Whenever you see a bunny, you want to attack it (meanie!).
- You type "bunny" in the data field titled "1" to add this word to the list of texts this trigger fires on. Make sure the dropdown next to it says "substring".
- Now you type "kill bunny" in the field called "Command". This will be the command that the trigger will send to your game whenever the trigger fires.
- Finally click "Save Item" to save your new trigger and also click "Activate". By doing this, the blue checkbox icon in front of the trigger name (in the trigger tree on the left side) gets checked. The trigger is now activated.
As the trigger is active, each time the word "bunny" will appear in the game output, your trigger will issue the command "kill bunny" automatically. It will repeat this as long as the trigger stays 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 check mark will vanish and the trigger will stop firing until you re-enable it again via the padlock icon.
You can also put triggers in a group, then lock a group of triggers or an entire trigger branch. If you do that, all triggers in this group or 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. For example, you can 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.
Beginners should use Mudlet's automated highlight triggers in the beginning to highlight the text that has been triggered on to get the hang of the different trigger and pattern types. Click on the "highlight trigger" option and pick a foreground and a background color that you like to highlight your trigger with. When the trigger matches it automatically highlights its pattern. This is the most used form of triggers in Mudlet 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 highlight triggers. Just type in the word you like to be highlighted, select appropriate colors, save the new trigger and activate it.
Matching one unknown word
You can also set up a trigger to gather the weapons, gold or whatever skeletons could carry around with them. Since we do not know what the loot is exactly just yet, we will need to set up a trigger to match the line, identify the loot and take whatever it is that was dropped.
Examples for messages received could be:
The skeleton drops ring. The skeleton drops gold. The skeleton drops scimitar. The skeleton drops wooden key.
"The skeleton drops " (including the last space character) is the generic segment of the line, but 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:
- In the data field titled "1" write the following perl regex type pattern:
^The skeleton drops (.+)\.$
- Make sure to change the dropdown menu for this line to "perl regex" as well
- In the big script box below write the following lua code:
send("take " .. matches[2])
The regular expression (.+) matches any characters that the client receives between "The skeleton drops " (NB: notice the blank/space character at the end) and the full-stop symbol that ends the sentence. Know that the variable matches[2] simply transfers the first matched text fitting the search criteria into the output. For this example, it will be the dropped loot we now will take automatically. This text may actually contain more than one word, like in the fourth example shown above.
In case you may wonder, matches[1] contains the entire line in whitch the matched text was found, whereas matches[2] contains only the first capture group. More on this in section two of the manual. The symbols ^ and $ indicate the start and end of a whole line.
Matching multiple unknowns
Now, we don't want to take only loot from skeletons but from many different sources.
Examples could be:
The skeleton drops ring. The giant drops gold. The king drops scimitar. The box drops wooden key.
So let’s make a trigger that would gather the loot from anybody:
- In data field "1" write:
^(.+) drops (.+)\.$
- Select perl regex type pattern again
- Below write the lua code:
send("take " .. matches[3])
In this case, any time somebody, or something, "drops" something 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.
Matching known variants
If you’re playing a game in English, you’ll notice that these triggers probably won’t work due to English syntax. Compare:
The skeleton drops ring. The skeleton drops a ring.
Chances are that you’ll see the later case a little more often. If we used our old regex, the trigger would produce something like this.
TRIGGERED LINE: The skeleton drops a ring. OUR REACTION: take a ring
However most games can’t handle determiners in user-input, such as articles (i.e. a, an, the) or quantifiers (e.g. five, some, each). In effect, our triggered reaction won't suffice. Instead we would need to react with just "take ring" again.
To correctly handle lines like this, we could either create multiple triggers matching every possible article, which could become very cumbersome. Instead we make one regular expression filtering out all these words and phrases:
- Write a new perl regex type pattern:
(.+) drops (a|an|the|some|a couple of|a few|) (.+)\.$
- With this script:
send("take " .. matches[4])
Once again, note that this time we are using the third matched group through matches[4] now.
Basic Regex Characters
You already know (.+)
which will match to any and all characters that follow until the end of line or another specific text that you may put in your regex. How about if you only want to match to certain type of characters?
Retrieving numbers from triggers
Wildcards from triggers are stored in the matches[] table. The first wildcard goes into matches[2], second into matches[3], and so on, for however many wildcards do you have in your trigger.
For example, you’d like to say out loud 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:
- Perl Regex:
^You pick up (\d+) gold\.$
- Script:
echo("I got " .. tonumber(matches[2]) .. " gold!")
In your code, the variable matches[2] will contain the amount of gold you picked up - in this case, 16. Now you say out loud how much gold you did loot. Notice also that (\d+) will only recognize numbers but not letters or a space character.
Retrieving alphanumeric characters
Here’s a more advanced example by Heiko, which makes you talk like Yoda:
- Perl Regex:
^say (\w+) *(\w*) .*?(.*)
- Script:
send( "say "..matches[4].." "..matches[2].." "..matches[3] )
The trigger will recognize that you say something, and save in seperate groups the first word, the second word and then the rest of you text. Here the \w wildcards will match any numbers or letters but no non-alphanumeric characters. It then shows you say the rest of the text first, then the first word and finally the second word. Notice this will only affect the text displayed for yourself, but if you want to also adjust the text you are sending to other players, please see the chapter about aliases.
Note: want to learn more regex? Try https://regexlearn.com which is a great, easy to follow resource for this.
Highlighting Words[edit | edit source]
To highlight something in the game output, make a trigger and use the "highlight trigger" option to highlight the matched trigger pattern.
Optionally, you can also make use of the bg() and fg() functions in scripting to highlight.
Keybindings
Keybindings (also known as hotkeys or macros), are in many respects very similar to aliases. However, instead of typing in what you want to be done (maybe including additional parameters) and pressing Enter, you simply hit a single key (or combination of keys) to let 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 command on button down: sip earl gray
HOTKEY: F2 command on button down: 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 games without auto-attack. See the Variables chapter for further details.
Example instructions on how to make a keybinding (for a set of settings for binding the keypad):
- Click the Keys button: File:Keys button.jpg
- If you wish to group them together, click the Add Group button
- Then name your group, Keypad for instance
- With the group selected now click the Add Item button
- Name it, let's say North, in the Name: widget
- If you only need a single command, like north for our example, place it into the Command: widget, otherwise skip to step 9
- Click the Grab New Key button
- Click the button sequence you want to use for your keybinding, keypad 8 for north
- Now if you need additional code to execute when you click your keybinding, or want more complicated code, place it into the giant code box.
- Click the Save Item button if done or New Item button if not.
- Click the Activate button when finished to make sure they work.
Here is a link to the resulting keybinding XML file on the forums: [1]
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. They can be used by clicking in the "timer" editor, or direcly in your script.
To use a simple timer that does something after a period, write like this:
tempTimer(seconds, [[code]])
Seconds needs to be a number, the time until the timer starts. Code can be any commands which you want executed then.
Note: Seconds can be a decimal, so 0.5 for half a second, or 1 for a full second will both work as expected.
Here's a finished example which you can copy and put in your code directly:
-- this timer will greet you exactly 2 seconds after it was made
tempTimer(2, [[ echo("hello!\n") ]])
You can combine both normal and timed commands, for example as code in an alias or keybinding:
-- this code will let you go north immediately, then go east after 2 seconds
send("n")
tempTimer(2, [[ send("e") ]])
Note: All timers which are made at the same time, will start counting from this common point in time, not relative to each other - so if you want to make one timer go off 1 second after another, don't do this:
-- incorrect:
tempTimer(1, [[ echo("hello!\n") ]])
tempTimer(1, [[ echo("how are you?\n") ]])
Both of these timers will go off at once, because both started together, right away! Instead, do this:
-- correct:
tempTimer(1, [[ echo("hello!\n") ]])
tempTimer(2, [[ echo("how are you?\n") ]])
Note: If you do not want to put all your timed code in [[ brackets ]] there is another way of writing the same example. (This is available since Mudlet 3.5)
-- this timer will greet you exactly 2 seconds after it was made
tempTimer(2, function() echo("hello!\n") end)
That's it for the basics of scriptable timers in Mudlet. Want to know more? Here is a full description of timers in Mudlet.
Buttons
You can use Mudlet to create simple buttons on your screen without much coding at all - you can attach button bars to the top, left or right side of the screen. Each of these locations can contain an infinite number of button bars that are shown when active or hidden when inactive. You can also create drop-down menus or or two-state buttons - ones that you can click on and they stay pressed down.
To get started with buttons, make a group (buttons have to be in a group to show) and add buttons inside them. Active buttons or groups to make them be visible. Here's an example - by making a new group and a button inside it, and activating both, we got a button to spawn:
Buttons show in the order they appear in - so if you'd like one button to be above another, just drag it visually in the editor!
Menus
An important use case for buttons is to have various menus which contain a number of checkbox buttons or sub menus in order to quickly set various scripting configuration or other options in your scripts. To start a menu of buttons, create another group inside your toolbar group and add individual buttons inside it, like so:
To change the side of Mudlet that the buttons use, change the Dock area <side> option and save. You can also make buttons align themselves top to bottom or left to right with the Orientation <horizontal or vertical> option.
Making buttons do stuff
Buttons are half as useful only being there. You can also make them do commands for you for when you press them! To make a button do your command, or alias, or anything - type it into the Command on Button Down field. Pressing the button will do that command then:
You can also make a button do two things, toggling between each. To do that, enable the Push Down Button option, and type the command you'd like your button to do when it's released in the Command on Button Up field.
Note:
If you'd like to include & in the button name, put double && - a single & will act as a mnemonic to underline the shortcut letter.
Coloring & customizing buttons
To change how your buttons look, you put descriptions into the CSS Style Sheet field, in the format of <a word describing something>: <how it should look>;. For example, if you'd like to make the button be red, put background-color: red; into the CSS box:
A full list of names you can use to customize your buttons view is available here. Take note of how that page has the descriptions inside {} brackets - you don't need them, only paste what's inside them in Mudlet.
Applying some skills, we can make our buttons look much more aesthetic:
This was the code used, feel free to start your buttons off with it:
color: white; background-color: orange; font-size: 12px;
padding: 6px;
border-radius: 5px;
Users with OS Windows 10 may find that for Mudlet versions 4.11+, the background-color: <colour>; is not changing the background as expected. This can be fixed by changing the border of the button. For example border: none;. Although that may destroy the size of button and it has to be set manualy. To achieve somehow similar size to default buttons you can use something like this:
background-color: <your_colour>;
border: 1px solid gray;
width: 90px; height: 25px;
margin: 1px;
font-size: 14px;
Managed layouts
To get your buttons to align into rows or columns (that depends on their orientation), add a number to the Number of columns or rows field. Here's an example with two columns on the left:
Here's another example with three columns on the left:
Note:
You can change how your buttons are aligned within rows by clicking on the button group - it will cycle through different possible configurations for you.
Making Buttons with Labels
Labels can also be used to make buttons. They are far more flexible and you can design almost any UI you can dream up considering they are simply clickable images.
We'll start by making twelve buttons along the top of our screen.
-- set a 10% margin from the top border to provide space local width, height = getMainWindowSize() setBorderTop(height/10) -- create some variable space so we don't pollute global variables MyButtons = {} -- create a label for the entire margin, for now MyButtons.Top = Geyser.Label:new({ name = "MyButtons.Top", x = 0, y = 0, width = "100%", height = "10%", }) -- create a horizontal box to organise the buttons equally MyButtons.TopHBox = Geyser.HBox:new({ name = "MyButtons.TopHBox", x = 0, y = 0, width = "100%", height = "100%", },MyButtons.Top) -- add some buttons to the HBox using a Geyser label for i=1,12 do MyButtons["MyButton"..i] = Geyser.Label:new({ name = "MyButtons.Button"..i, },MyButtons.TopHBox) MyButtons["MyButton"..i]:echo("<center>My Button "..i) end
The main function creating the button labels is Geyser.Label. You should now see the results as above. A bit plain, you could add some CSS to spark things up a bit.
-- add some buttons to the HBox using a Geyser label for i=1, 12 do MyButtons["MyButton"..i] = Geyser.Label:new({ name = "MyButtons.Button"..i, },MyButtons.TopHBox) MyButtons["MyButton"..i]:echo("<center>My Button "..i) -- colour my buttons with CSS MyButtons["MyButton"..i]:setStyleSheet([[ background-color: rgba(135,206,250,100); border-style: solid; border-width: 1px; border-color: white; border-radius: 5px; margin: 5px; qproperty-wordWrap: true; ]]) end
Much better. But currently they are just twelve pretty labels that don't perform any function. Let's make them clickable with setClickCallback
setClickCallback assigns a function to a Geyser label that will be called when the mouse is clicked on the label. This function has similar methods for double clicking, hovering, etc.. all of which can be found in the Geyser manual. Let's keep it straightforward for now with a single click. Consider the following addition;
-- add some buttons to the HBox using a Geyser label for i=1,12 do MyButtons["MyButton"..i] = Geyser.Label:new({ name = "MyButtons.Button"..i, },MyButtons.TopHBox) MyButtons["MyButton"..i]:echo("<center>My Button "..i) -- colour my buttons with CSS MyButtons["MyButton"..i]:setStyleSheet([[ background-color: rgba(135,206,250,100); border-style: solid; border-width: 1px; border-color: white; border-radius: 5px; margin: 5px; qproperty-wordWrap: true; ]]) -- make our buttons clickable MyButtons["MyButton"..i]:setClickCallback(function() echo("My Button " ..i.." clicked!\n") end) end
You should now be able to click the button and see the echo to the main screen.
Adjustable Containers for Labels
Adjustable Containers are a Geyser element that provides a flexible, user configurable, dockable window. Let's move our buttons to one of these containers and see what else we can do.
-- create some variable space so we don't pollute global variables MyButtons = {} -- create an adjustable container for more flexibility MyButtons.Top = Adjustable.Container:new({ name = "MyButtons.Top", x = 0, y = 0, width = "100%", height = "10%", }) -- create a horizontal box to organise the buttons equally MyButtons.TopHBox = Geyser.HBox:new({ name = "MyButtons.TopHBox", x = 0, y = 0, width = "100%", height = "100%", },MyButtons.Top) -- add some buttons to the HBox using a Geyser label for i=1, 12 do MyButtons["MyButton"..i] = Geyser.Label:new({ name = "MyButtons.Button"..i, },MyButtons.TopHBox) MyButtons["MyButton"..i]:echo("<center>My Button "..i) -- colour my buttons with CSS MyButtons["MyButton"..i]:setStyleSheet([[ background-color: rgba(135,206,250,100); border-style: solid; border-width: 1px; border-color: white; border-radius: 5px; margin: 5px; qproperty-wordWrap: true; ]]) -- make our buttons clickable MyButtons["MyButton"..i]:setClickCallback(function() echo("My Button " ..i.." clicked!\n") end) end
We removed the setBorderTop code because the adjustable container can be docked to a border by right clicking on the title bar and a margin is automatically created. It is docked to the top border in this example.
The container can be resized and moved around or perhaps changed to a VBox for slick left and right border docking.
This example can be further expanded to add images to the labels, highlighting when hovering over labels or even multi-state buttons with variables to track the state. Your imagination is the only limit.
Built-in aliases
The following aliases are available by default in new Mudlet profiles.
Alias | Description | Examples |
---|---|---|
lua | Run Lua code from the input line. | lua print("hello") lua 2+2 lua clearWindow() |
`echo | Simulate text from the game to test your triggers. You can use $ for a new line. |
`echo You see a rabbit cross the road. `echo line1$line2 |
If an alias on the list isn't working for you - try copying it from a new profile, since existing profiles will not get new aliases as they're introduced to Mudlet.
Misc examples
Here are some more miscellaneous examples.
Game syntax: get coins from corpse and also get coins from corpse 3. Alias Pattern: ^gcc(?:\s(\d+))?$ (can accept simply gcc and also gcc 3 for example).
send("get coins from corpse " .. (matches[2] or "") )
Game syntax: unlock northwest with steel key Alias Pattern: ^un (\w+) (.*)$
send("unlock " .. matches[2] .. " with " .. matches[3] )
See also: Mudlet Technical Manual