Difference between revisions of "Manual:Using Variables in Mudlet"

From Mudlet
Jump to navigation Jump to search
(→‎Using Variables in Mudlet: fixed syntax highlighting)
Line 3: Line 3:
  
 
One of the major design goals in Mudlet was to integrate scripts and variables into triggers/aliases/buttons etc. as seamlessly as possible. The usage of variables in Mudlet is distinctly different from the other major clients, as native Lua scripting has been integrated into Mudlet from the ground up. As scripts are so closely intertwined with the core of Mudlet, variables do not need any special treatment as in other clients i.e. there is no need for code such as:
 
One of the major design goals in Mudlet was to integrate scripts and variables into triggers/aliases/buttons etc. as seamlessly as possible. The usage of variables in Mudlet is distinctly different from the other major clients, as native Lua scripting has been integrated into Mudlet from the ground up. As scripts are so closely intertwined with the core of Mudlet, variables do not need any special treatment as in other clients i.e. there is no need for code such as:
<lua>
+
<syntaxhighlight lang="lua">
 
totalKills = getVariable("killedMonsters") + getVariable("killedVillains")
 
totalKills = getVariable("killedMonsters") + getVariable("killedVillains")
 
echo( "kills=" .. totalKills )
 
echo( "kills=" .. totalKills )
</lua>
+
</syntaxhighlight>
 
In Mudlet, the above code translates into:
 
In Mudlet, the above code translates into:
<lua>
+
<syntaxhighlight lang="lua">
 
totalKills = killedMonsters + killedVillains
 
totalKills = killedMonsters + killedVillains
 
echo( "kills=" .. totalKills )
 
echo( "kills=" .. totalKills )
</lua>
+
</syntaxhighlight>
 
If you define a variable in any given script in Mudlet, be it a trigger, a button, an alias key, an event handler, a free function, etc. It can be used from within any context without any special getVariable() type of function or any special variable symbols, such as @myVar etc.. In Mudlet all variables are native Lua variables. Each session (= profile/connection tab) runs in its own dedicated Lua interpreter. Consequently, all scripts of a profile are compiled into the same Lua interpreter and thus their code runs in the same variable space. All scripts from another simultaneously opened profile will not interfere because each profile uses its own Lua interpreter.
 
If you define a variable in any given script in Mudlet, be it a trigger, a button, an alias key, an event handler, a free function, etc. It can be used from within any context without any special getVariable() type of function or any special variable symbols, such as @myVar etc.. In Mudlet all variables are native Lua variables. Each session (= profile/connection tab) runs in its own dedicated Lua interpreter. Consequently, all scripts of a profile are compiled into the same Lua interpreter and thus their code runs in the same variable space. All scripts from another simultaneously opened profile will not interfere because each profile uses its own Lua interpreter.
Note Everything shares the same variables & functions.
+
Note Everything shares the same variables & functions.
  
 
To give you an example: Let’s make a little trigger that counts how many monsters you have killed. Each time you have made a new kill, the trigger matches on the kill message and runs a little script that increases the amount of kills by one each time the trigger fires - in other words, each time you kill a monster and the kill message is sent from the MUD. For the kill counter we declare a variable and call it myKills. This variable is going to hold the number of kills we’ve made so far. The script will look like this:
 
To give you an example: Let’s make a little trigger that counts how many monsters you have killed. Each time you have made a new kill, the trigger matches on the kill message and runs a little script that increases the amount of kills by one each time the trigger fires - in other words, each time you kill a monster and the kill message is sent from the MUD. For the kill counter we declare a variable and call it myKills. This variable is going to hold the number of kills we’ve made so far. The script will look like this:
<lua>
+
<syntaxhighlight lang="lua">
 
myKills = myKills + 1
 
myKills = myKills + 1
</lua>
+
</syntaxhighlight>
 
Then we add a little alias, a button or a keybindings that executes another little script that prints your current kill statistics on the screen. The attached script would look like this:
 
Then we add a little alias, a button or a keybindings that executes another little script that prints your current kill statistics on the screen. The attached script would look like this:
<lua>
+
<syntaxhighlight lang="lua">
 
echo( "I have killed " .. myKills .. " monsters today." )
 
echo( "I have killed " .. myKills .. " monsters today." )
</lua>
+
</syntaxhighlight>
  
 
Lua variables can be either a string or a number. They are whatever there were initially initialized with or what data type they can be converted to.
 
Lua variables can be either a string or a number. They are whatever there were initially initialized with or what data type they can be converted to.
<lua>
+
<syntaxhighlight lang="lua">
 
a = "Jim"
 
a = "Jim"
 
b = "Tom"
 
b = "Tom"
Line 36: Line 36:
 
e = a .. b and e will equal "JimTom"  
 
e = a .. b and e will equal "JimTom"  
 
e = a .. c and e will equal "Jim350"
 
e = a .. c and e will equal "Jim350"
</lua>
+
</syntaxhighlight>
 
Note: You can't use a + b to concatenate string values. For this you must use the double-dot: ..
 
Note: You can't use a + b to concatenate string values. For this you must use the double-dot: ..
  
Line 42: Line 42:
  
 
Let’s get back to our example. The trigger script expects myKills to be a number so you have to initialze the variable myKills to 0 before running the script for the first time. The best place to initialize variables is in script script outside of a function definition as this code is executed when the session is loaded or if you compile the script again after you have edited it. To do this click on the "Scripts" icon and select the standard script "My Global Variable Definitions". If you are using an older version of Mudlet or a profile that doesn’t have this script item, simply click on the "Add" icon and make your own script. You can call it whatever you want to. Add following code to initialize your new variable myKills to a number and set its value to 0:
 
Let’s get back to our example. The trigger script expects myKills to be a number so you have to initialze the variable myKills to 0 before running the script for the first time. The best place to initialize variables is in script script outside of a function definition as this code is executed when the session is loaded or if you compile the script again after you have edited it. To do this click on the "Scripts" icon and select the standard script "My Global Variable Definitions". If you are using an older version of Mudlet or a profile that doesn’t have this script item, simply click on the "Add" icon and make your own script. You can call it whatever you want to. Add following code to initialize your new variable myKills to a number and set its value to 0:
<lua>
+
<syntaxhighlight lang="lua">
 
myKills = 0
 
myKills = 0
</lua>
+
</syntaxhighlight>
 
Whenever you edit this script, it will be recompiled and the code will be run as it is not part of a function definition. This is the major difference between trigger-scripts, alias-scripts etc. and script-scripts. Script-scripts can contain an unlimited amount of function definitions and also free code i. e. code outside of a function definition - code that is not enclosed by function xyz() …. end. On saving the script the script gets compiled and the free code is run instantly. All other item scripts, i. e. trigger-scripts etc., secretly define a function name for the script and thus the script is not free code, but function code. When a trigger fires Mudlet calls this invisible function name to run the script e.g. trigger738(), button82(), alias8(). This means that if you define variables inside a trigger script the variable will not be defined before the trigger runs for the first time. However, if you define this variable as free code in a script-script the definition becomes available immediately on script save. Now, whenever you add new variables to your variable definition script, the script gets run and your old variables will be reinitialized and reset to 0. This will be no big problem in most cases as you won’t work on your systems while really playing in most cases. To solve this problem you have two options:
 
Whenever you edit this script, it will be recompiled and the code will be run as it is not part of a function definition. This is the major difference between trigger-scripts, alias-scripts etc. and script-scripts. Script-scripts can contain an unlimited amount of function definitions and also free code i. e. code outside of a function definition - code that is not enclosed by function xyz() …. end. On saving the script the script gets compiled and the free code is run instantly. All other item scripts, i. e. trigger-scripts etc., secretly define a function name for the script and thus the script is not free code, but function code. When a trigger fires Mudlet calls this invisible function name to run the script e.g. trigger738(), button82(), alias8(). This means that if you define variables inside a trigger script the variable will not be defined before the trigger runs for the first time. However, if you define this variable as free code in a script-script the definition becomes available immediately on script save. Now, whenever you add new variables to your variable definition script, the script gets run and your old variables will be reinitialized and reset to 0. This will be no big problem in most cases as you won’t work on your systems while really playing in most cases. To solve this problem you have two options:
  
 
First option: Add a script group (a folder) and add a new script item for each variable you define. This way, editing a variable definition will only reset the edited variable and none of the others that are defined in different scripts. This has the added advantage that you have a nice graphical overview of your defined variables.
 
First option: Add a script group (a folder) and add a new script item for each variable you define. This way, editing a variable definition will only reset the edited variable and none of the others that are defined in different scripts. This has the added advantage that you have a nice graphical overview of your defined variables.
Note Organize your variables
+
Note Organize your variables
  
 
Second option (more advanced): Change the variable initialization to only initialize the variable if it hasn’t been initialized before, thus keeping the values of previously defined variables. The following code initializes the variable myKills (to the number 0) but only if it hasn't been initialized before. This would look like this:
 
Second option (more advanced): Change the variable initialization to only initialize the variable if it hasn’t been initialized before, thus keeping the values of previously defined variables. The following code initializes the variable myKills (to the number 0) but only if it hasn't been initialized before. This would look like this:
<lua>
+
<syntaxhighlight lang="lua">
 
if myKills == nil then     
 
if myKills == nil then     
 
     myKills = 0
 
     myKills = 0
 
end
 
end
</lua>
+
</syntaxhighlight>
 
In Lua all undefined variables are initialized to the value nil. The value nil is not the same thing as the number 0 or the empty string "". What it means is that a variable that has the value nil has not been declared yet and does not exist. If a variable does not exist, it cannot be used as its value is undefined at this point. Consequently, increasing the value of nil by one is impossible as the variable doesn’t exist yet and will lead to a Lua error. The above script simply checks if the variable myKills has been defined yet and if it hasn’t, it will declare the variable and set its value to 0.  
 
In Lua all undefined variables are initialized to the value nil. The value nil is not the same thing as the number 0 or the empty string "". What it means is that a variable that has the value nil has not been declared yet and does not exist. If a variable does not exist, it cannot be used as its value is undefined at this point. Consequently, increasing the value of nil by one is impossible as the variable doesn’t exist yet and will lead to a Lua error. The above script simply checks if the variable myKills has been defined yet and if it hasn’t, it will declare the variable and set its value to 0.  
 
=== Tables as Lists ===
 
=== Tables as Lists ===
 
Having variables that hold a single value is the most important usage of variables, but very often you’ll like to define variables that hold a list of values e. g. a list of your enemies, a list the items you are currently carrying etc.. To define a variable to be a list you need to declare it to be a Lua table. Let’s declare the variable myEnemies as a list containing the names of your enemies:
 
Having variables that hold a single value is the most important usage of variables, but very often you’ll like to define variables that hold a list of values e. g. a list of your enemies, a list the items you are currently carrying etc.. To define a variable to be a list you need to declare it to be a Lua table. Let’s declare the variable myEnemies as a list containing the names of your enemies:
<lua>
+
<syntaxhighlight lang="lua">
 
myEnemies = {}
 
myEnemies = {}
</lua>
+
</syntaxhighlight>
 
You can now add new enemies to this list by calling the Lua function <code>table.insert( listName, item )</code> e.g.
 
You can now add new enemies to this list by calling the Lua function <code>table.insert( listName, item )</code> e.g.
<lua>
+
<syntaxhighlight lang="lua">
 
table.insert( myEnemies, "Tom" )
 
table.insert( myEnemies, "Tom" )
 
table.insert( myEnemies, "Jim" )
 
table.insert( myEnemies, "Jim" )
</lua>
+
</syntaxhighlight>
 
To print the contents of your enemy list on the screen you can run this script
 
To print the contents of your enemy list on the screen you can run this script
<lua>
+
<syntaxhighlight lang="lua">
 
display( myEnemies )
 
display( myEnemies )
</lua>
+
</syntaxhighlight>
 
Now let’s make a little alias that adds a new name to your enemy list when you type "add enemy " followed by the name of the enemy e. g. "add enemy Peter" Open the alias editor by clicking on the alias icon. Click on the "Add" icon to add a new alias. Choose any name you like for your alias e.g. "add new enemy" and then define following pattern for the alias: ^add enemy (.*) Then add this little script in the script editor below:
 
Now let’s make a little alias that adds a new name to your enemy list when you type "add enemy " followed by the name of the enemy e. g. "add enemy Peter" Open the alias editor by clicking on the alias icon. Click on the "Add" icon to add a new alias. Choose any name you like for your alias e.g. "add new enemy" and then define following pattern for the alias: ^add enemy (.*) Then add this little script in the script editor below:
<lua>
+
<syntaxhighlight lang="lua">
 
table.insert( myEnemies, matches[2] )
 
table.insert( myEnemies, matches[2] )
 
echo( "Added a new enemy:" .. matches[2] .. "\n" )
 
echo( "Added a new enemy:" .. matches[2] .. "\n" )
</lua>
+
</syntaxhighlight>
 
Save the alias and try. Alias are explained in detail below. Another way to declare a list is to define its values directly.
 
Save the alias and try. Alias are explained in detail below. Another way to declare a list is to define its values directly.
<lua>
+
<syntaxhighlight lang="lua">
 
myEnemies = { "Peter", "Jim", "Carl", "John" }
 
myEnemies = { "Peter", "Jim", "Carl", "John" }
</lua>
+
</syntaxhighlight>
 
To remove an item from the list you can use the function <code>table.remove( listName, item index )</code>.
 
To remove an item from the list you can use the function <code>table.remove( listName, item index )</code>.
  
Line 94: Line 94:
  
 
The title sounds a bit complicated, but that's pretty much what you do. Go to Scripts, click `Add Item`, and create your variables like so:
 
The title sounds a bit complicated, but that's pretty much what you do. Go to Scripts, click `Add Item`, and create your variables like so:
<lua>
+
<syntaxhighlight lang="lua">
 
myname = "Bob"
 
myname = "Bob"
 
mypack = "pack1234"
 
mypack = "pack1234"
 
rapierID = 67687
 
rapierID = 67687
</lua>
+
</syntaxhighlight>
  
 
Now, since scripts are are when the profile is started, these variables will be created and assigned to those values. This was simple to do, but it has one problem - if you want to change the value of the variables to be saved, you have to edit the script by hand each time; and if you change the value of variables while playing via scripting, the new values won't be recorded.
 
Now, since scripts are are when the profile is started, these variables will be created and assigned to those values. This was simple to do, but it has one problem - if you want to change the value of the variables to be saved, you have to edit the script by hand each time; and if you change the value of variables while playing via scripting, the new values won't be recorded.
Line 108: Line 108:
 
<code>table.save(where to save, what table to save)</code> takes the location of a file to save variables to, and a table containing your variables to save. Location can be anywhere on your computer, but a good default place is your profile folder, whose location can be obtained with getMudletHomeDir().
 
<code>table.save(where to save, what table to save)</code> takes the location of a file to save variables to, and a table containing your variables to save. Location can be anywhere on your computer, but a good default place is your profile folder, whose location can be obtained with getMudletHomeDir().
  
<lua>
+
<syntaxhighlight lang="lua">
 
mychar = {
 
mychar = {
 
   name = "Bob",
 
   name = "Bob",
Line 118: Line 118:
 
-- sample echo to show where the file went:
 
-- sample echo to show where the file went:
 
echo(string.format("Variables saved in: '%s'", getMudletHomeDir() .. "mychar"))  
 
echo(string.format("Variables saved in: '%s'", getMudletHomeDir() .. "mychar"))  
</lua>
+
</syntaxhighlight>
  
 
<code>table.load(where to load from, what table to use)</code> is similar - it takes the location of the file to load, and a table name to use for the loaded variables.
 
<code>table.load(where to load from, what table to use)</code> is similar - it takes the location of the file to load, and a table name to use for the loaded variables.
  
<lua>
+
<syntaxhighlight lang="lua">
 
mychar = mychar or {}
 
mychar = mychar or {}
 
table.load(getMudletHomeDir() .. "/mychar", mychar)
 
table.load(getMudletHomeDir() .. "/mychar", mychar)
 
display(mychar)
 
display(mychar)
 
echo("My name is: ".. tostring(mychar.name))
 
echo("My name is: ".. tostring(mychar.name))
</lua>
+
</syntaxhighlight>
  
 
Now that you have a way to save and load your tables, you can create triggers to load and save your variables at appropriate times, and you'll be set.
 
Now that you have a way to save and load your tables, you can create triggers to load and save your variables at appropriate times, and you'll be set.
  
 
[[Category:Mudlet Manual]]
 
[[Category:Mudlet Manual]]

Revision as of 05:12, 29 June 2017

Using Variables in Mudlet

One of the major design goals in Mudlet was to integrate scripts and variables into triggers/aliases/buttons etc. as seamlessly as possible. The usage of variables in Mudlet is distinctly different from the other major clients, as native Lua scripting has been integrated into Mudlet from the ground up. As scripts are so closely intertwined with the core of Mudlet, variables do not need any special treatment as in other clients i.e. there is no need for code such as:

totalKills = getVariable("killedMonsters") + getVariable("killedVillains")
echo( "kills=" .. totalKills )

In Mudlet, the above code translates into:

totalKills = killedMonsters + killedVillains
echo( "kills=" .. totalKills )

If you define a variable in any given script in Mudlet, be it a trigger, a button, an alias key, an event handler, a free function, etc. It can be used from within any context without any special getVariable() type of function or any special variable symbols, such as @myVar etc.. In Mudlet all variables are native Lua variables. Each session (= profile/connection tab) runs in its own dedicated Lua interpreter. Consequently, all scripts of a profile are compiled into the same Lua interpreter and thus their code runs in the same variable space. All scripts from another simultaneously opened profile will not interfere because each profile uses its own Lua interpreter. Note Everything shares the same variables & functions.

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

myKills = myKills + 1

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

echo( "I have killed " .. myKills .. " monsters today." )

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

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

--Then you can write:

e = c + d and e will equal 351
e = a .. b and e will equal "JimTom" 
e = a .. c and e will equal "Jim350"

Note: You can't use a + b to concatenate string values. For this you must use the double-dot: ..

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

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

myKills = 0

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

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

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

if myKills == nil then    
    myKills = 0
end

In Lua all undefined variables are initialized to the value nil. The value nil is not the same thing as the number 0 or the empty string "". What it means is that a variable that has the value nil has not been declared yet and does not exist. If a variable does not exist, it cannot be used as its value is undefined at this point. Consequently, increasing the value of nil by one is impossible as the variable doesn’t exist yet and will lead to a Lua error. The above script simply checks if the variable myKills has been defined yet and if it hasn’t, it will declare the variable and set its value to 0.

Tables as Lists

Having variables that hold a single value is the most important usage of variables, but very often you’ll like to define variables that hold a list of values e. g. a list of your enemies, a list the items you are currently carrying etc.. To define a variable to be a list you need to declare it to be a Lua table. Let’s declare the variable myEnemies as a list containing the names of your enemies:

myEnemies = {}

You can now add new enemies to this list by calling the Lua function table.insert( listName, item ) e.g.

table.insert( myEnemies, "Tom" )
table.insert( myEnemies, "Jim" )

To print the contents of your enemy list on the screen you can run this script

display( myEnemies )

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

table.insert( myEnemies, matches[2] )
echo( "Added a new enemy:" .. matches[2] .. "\n" )

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

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

To remove an item from the list you can use the function table.remove( listName, item index ).

Saving variables

You might notice that Mudlet doesn't save your variables between profiles restarts. The reasons for this are technical, but all it means is that you have flexibility in how to deal with them. There are several ways, so the most common and easiest ones will be explained here.

Tick the box in the variables view

Head to the variables view in the Mudlet editor and tick the box besides a variable - Mudlet will remember it between restarts now!

Saving variables.png

Saving by coding them in a script

The title sounds a bit complicated, but that's pretty much what you do. Go to Scripts, click `Add Item`, and create your variables like so:

myname = "Bob"
mypack = "pack1234"
rapierID = 67687

Now, since scripts are are when the profile is started, these variables will be created and assigned to those values. This was simple to do, but it has one problem - if you want to change the value of the variables to be saved, you have to edit the script by hand each time; and if you change the value of variables while playing via scripting, the new values won't be recorded.

Saving via table.save & table.load

Next, enter a more proper solution. This'll actually save the variables to a file and load them from it - so if you change the variable values, the current ones will be saved, and will be loaded next time properly. This method works with a table containing your variables though, not individual variables themselves - see Lua tables tutorial on how to create and use those.

table.save(where to save, what table to save) takes the location of a file to save variables to, and a table containing your variables to save. Location can be anywhere on your computer, but a good default place is your profile folder, whose location can be obtained with getMudletHomeDir().

mychar = {
  name = "Bob",
  age = 26,
  sex = "male"
}

table.save(getMudletHomeDir() .. "/mychar", mychar)
-- sample echo to show where the file went:
echo(string.format("Variables saved in: '%s'", getMudletHomeDir() .. "mychar"))

table.load(where to load from, what table to use) is similar - it takes the location of the file to load, and a table name to use for the loaded variables.

mychar = mychar or {}
table.load(getMudletHomeDir() .. "/mychar", mychar)
display(mychar)
echo("My name is: ".. tostring(mychar.name))

Now that you have a way to save and load your tables, you can create triggers to load and save your variables at appropriate times, and you'll be set.