| Message | | 
 The directory "lua" which is created as part of a MUSHclient standard installation contains the following Lua "modules":
 
 
 
 
addxml.lua - add triggers, timers, aliases, macros by supplying a table (and convert back to a table)
alphanum.lua - sort names into a more "natural" order
check.lua - check a world function return code
commas.lua - rounding, duration and comma functions
copytable.lua - does a deep or shallow copy of a Lua table
declare.lua - ensure variables in a function are declared
getlines.lua - iterator to convert a block of text into lines
getstyle.lua - finds a style run corresponding to a given column 
getworld.lua - finds another world, and lets you send text to it
movewindow.lua - lets you drag miniwindows around
pairsbykeys.lua - iterator to traverse a table, sorted by key order
serialize.lua - serialize Lua variables into a string
strict.lua - enforce use of local variables inside functions
tabbed_window.lua - lets you make miniwindows with tabs
tprint.lua - table printer
var.lua - use MUSHclient variables as if they are Lua variables
wait.lua - for pausing scripts until time elapsed, or certain text arrives from the MUD
 
 This thread describes the purpose of each one, and where to find out more about them.
 
 The general way to use any of these modules is to "require" the module, which is the file name above without the ".lua" part, and then go ahead and use the documented functions in the module.
 
 For example:
 
 
 
require "tprint"
tprint (math)  --> lists all the math functions in the output window
 It is a feature of the way that "require" works, that you can use it repeatedly with very little overhead. Lua first checks to see if the wanted function has already been loaded, and if so, does not reload it from disk.
 
 Thus you could conceivably do a require "serialize" in every function that needs to use it, rather than fiddling around trying to do it once in a central place, if that makes coding easier.
 
 Documentation
 
 Each of the modules tries to be self-documenting, so if you open them up in a text editor, there may be further examples and suggestions for using them, in addition to what is written below.
 
 
 
 addxml.lua
 
 This lets you add triggers, aliases, timers, or macros by specifying each parameter in a Lua table, which is easier in many ways than getting the correct arguments to AddTrigger etc.
 
 You can also use the addxml.save to do the inverse operation - save an existing trigger, alias, timer or macro as a table.
 
 See forum thread: http://www.gammon.com.au/forum/?id=7123
 
 Exposed functions are:
 
 
 
 
addxml.trigger (t) --> add a trigger
addxml.alias (t)   --> add an alias
addxml.timer (t)   --> add a timer
addxml.macro (t)   --> add a macro
addxml.save (type, name)  --> convert one of the above back into a table
 
 Example:
 
 
 
require "addxml"
addxml.trigger {
  enabled = 'y',
  custom_colour = '17',
  sequence = '100',
  other_text_colour = 'salmon',
  match = '[Public] * says, "*"',
  name = 'mytrigger',
  }
 This adds a new trigger with all the appropriate values as specified.
 
 
 
 alphanum.lua
 
 This lets you sort strings with numbers in them into a more "natural" order. For example, normal sorting would put "a100" before "a2". This module provides a comparison routine that "chunks" up strings into batches of letters and numbers, and sorts them individually.
 
 See forum thread: http://www.gammon.com.au/forum/?id=8698
 
 Exposed function is alphanum.
 
 Example:
 
 
 
require "alphanum"
t={
"z18.doc","z19.doc","z2.doc","z16.doc","z17.doc",
"z1.doc","z101.doc","z102.doc","z11.doc","z12.doc",
"z13.doc","z14.doc","z15.doc","z20.doc","z3.doc",
"z4.doc","z5.doc","z6.doc","z10.doc","z100.doc",
"z7.doc","z8.doc","z9.doc", "Z9A.doc",
}
table.sort(t, alphanum (t))
for i=1, #t do
   print(t[i])
end
 
 
 check.lua
 
 This implements a simple check function, that checks the return codes from the many MUSHclient script functions that return a "status code". This can be useful for catching errors in things like AddTrigger, which would otherwise silently fail.
 
 See forum thread: http://www.gammon.com.au/scripting - look about halfway down at the posting about "Checking return codes".
 
 Exposed functions are:
 
 
 
 
check (code) --> checks argument is zero, if not raises an error
 
 The error message is the correct message from this page:
 
 http://www.gammon.com.au/scripts/doc.php?general=errors
 
 Note that this function is built into MUSHclient from version 4.28 onwards, so you don't need to "require" it.
 
 Example:
 
 
 
require "check"
check (SetVariable ("abc", "def"))  --> works ok
check (SetVariable ("abc-", "def")) --> Error: The name of this object is invalid
 
 
 commas.lua
 
 This implements four useful functions:
 
 
 
 
round - to round a floating-point number to the nearest integer
convert_time - express an interval of seconds as days/hours/minutes etc.
commas - add commas to big numbers
scan_dir - directory scanner
 
 See forum thread: http://www.gammon.com.au/forum/?id=7805
 
 If you can't find commas.lua in your distribution, there is a copy of it in that thread.
 
 Exposed functions are:
 
 
 
 
round (x) - rounds the argument to the nearest integer
convert_time (secs) - converts a numbers of seconds to the nearest relevant interval (eg. 65 seconds becomes "1 m" whereas 119 seconds becomes "2 m")
commas (num) - takes a number and adds commas to it (eg. 123456 becomes "123,456")
scan_dir (path, f) - scans disk starting at "path" calling function "f" for each file
 
 
 Example:
 
 
 
require "commas"
print (round (1.5))   --> 2
print (round (-99.8)) --> -100
print (convert_time (70))     --> 1 m
print (convert_time (1000))   --> 17 m
print (convert_time (10000))  --> 3 h
print (convert_time (100000)) --> 1 d
print (commas (123456789)) --> 123,456,789
scan_dir (GetInfo (60),  function (name, stats) print (name, stats.size) end)
 More information about the scan_dir function:
 
 http://www.gammon.com.au/forum/?id=9906
 
 
 
 
 copytable.lua
 
 Implements a deep or shallow copy of a Lua table.
 
 See forum thread: http://www.gammon.com.au/forum/?id=8042
 
 Normally in Lua if you simply assign a table variable to another variable, you get the original table, not a copy. However by using copytable you actually get a copy of the table.
 
 Exposed functions are:
 
 
 
 
copytable.shallow (t) --> shallow copy of first level values
copytable.deep (t) --> copies table, and any nested tables are also copied
 
 For tables which themselves contain nested tables, you may wish to use copytable.deep which effectively "recurses" to make a copy of those tables as well.
 
 Example:
 
 
 
t1 = {5, 6, 7}
t2 = t1 
t2 [3] = 8  --> change t2
print (t1 [3])  --> prints 8, not 7
print (t2 [3])  --> prints 8, as expected
 However by using copytable, you get a completely new table:
 
 
 
require "copytable"
t1 = {5, 6, 7}
t2 = copytable.shallow (t1)
t2 [3] = 8
print (t1 [3])  --> prints 7
print (t2 [3])  --> prints 8
 
 
 declare.lua
 
 Forces you to declare variables (by using the "local" keyword), rather than relying upon "on-the-fly" creation of new variables, which Lua normally does.
 
 See forum thread: http://www.gammon.com.au/forum/?id=7327
 
 Exposed functions are:
 
 
 
 
force_declarations () --> after calling this, all variables must be declared
 
 Example:
 
 
 
require "declare"
a = 42  --> works OK, we haven't called "force_declarations" yet
force_declarations ()  --> from now on, we have to declare variables
local b = 55  --> works OK, we used "local" to declare the variable "b"
c = 66  --> Error: assign to undeclared variable 'c'
 The purpose of this is to catch spelling errors in functions, for example, in the above code, if we really meant to say "b = 66" rather than "c = 66" then the error message would alert us.
 
 Also see "strict.lua" below for doing this a bit differently.
 
 
 
 getlines.lua
 
 Provides an iterator function to break a string into individual lines.
 
 See forum thread: http://www.gammon.com.au/forum/?id=6544
 
 Exposed functions are:
 
 
 
 
getlines (s) --> iterator to be used in a for loop
 
 Example:
 
 
 
require "getlines"
 
s = [[
every good
boy
deserves 
fruit]]
for line in getlines (s) do
  print (line)  --> print each line
end -- for loop
 
 
 getstyle.lua
 
 Finds a style run corresponding to a given column. This is intended to be used in situation (like triggers) where you have a "style run" table provided by MUSHclient, and want to find the style of a column (eg. column 15).
 
 You might use this to see if a particular word in a particular column is a certain colour (eg. is the word "bleeding" in red?).
 
 See forum thread:  http://www.gammon.com.au/forum/?id=7818
 
 Exposed functions are:
 
 
 
 
GetStyle (styles, column)  --> get style items for this column
 
 
 Example:
 
 
 
 
require "getstyle"
function my_trigger (name, line, wildcards, styles)
 
  -- find location of word
  col = string.find (line, "bleeding")
  if not col then
    return
  end -- word not found
  -- get style at that location
  style = GetStyle (styles, col)
  -- display it
  print ("word is in", RGBColourToName (style.textcolour))
 
end -- function my_trigger
 The above example trigger function uses the style runs table supplied as the fourth argument to a trigger function. It first locates the column in which "bleeding" is, and then finds the style of that column.
 
 It then displays the colour in which the (first letter of) the word "bleeding" is.
 
 Note - capitalization of the function name is "GetStyle", but the module is "getstyle".
 
 
 
 getworld.lua
 
 Lets you get a reference to another MUSHclient world, loading it from disk if necessary. Also lets you send trigger data from one world to another.
 
 See forum thread: http://www.gammon.com.au/forum/?id=7991&page=3
 
 Exposed functions are:
 
 
 
 
get_a_world (name) --> returns a "world object" for operating on the named world
 
 The world file is opened if not already opened by appending ".mcl" to the name, and looking in the default MUSHclient worlds directory. If the world cannot be opened nil is returned.
 
 Example:
 
 
 
require "getworld"
local w = GetWorld ("SMAUG chats")
if w then  -- if found
    w:DeleteOutput ()
end -- if
 
 
 
send_to_world (name, styles) --> sends the style runs to the named world
 
 Sends the style runs to the named world. It first calls get_a_world (above) and if successful, sends the style runs to it. This effectively lets you write a trigger that sends the matching line, including all colours, to another world window. For example, to filter chats, who lists, and suchlike.
 
 Example:
 
 
 
function mytrigger (name, line, wildcards, styles)
  require "getworld"
  send_to_world ("SMAUG chats", styles)
end -- function
 
 
 movewindow.lua
 
 This lets you attach a "drag handler" to a miniwindow, letting you drag the window around on the screen to reposition it.
 
 See forum thread: http://www.gammon.com.au/forum/?id=9594
 
 Exposed functions are:
 
 
 
 
movewindow.install (win, default_position, default_flags, nocheck, friends, preprocess, start_position)
 
 Example:
 
 
 
  require "movewindow" 
  windowinfo = movewindow.install (win, miniwin.pos_center_right, 0)  -- default position / flags
 The values in "windowinfo" table can now be used to create the miniwindow in the desired position. For example:
 
 
 
  WindowCreate (win, 
                windowinfo.window_left, 
                windowinfo.window_top, 
                WINDOW_WIDTH,    
                WINDOW_HEIGHT,  
                windowinfo.window_mode, 
                windowinfo.window_flags, 
                ColourNameToRGB "slategray") 
 
 
 
movewindow.add_drag_handler (win, 0, 0, 0, 0, miniwin.cursor_both_arrow) 
 
 Installs the drag handler for the miniwindow. Part or all of the window can be designated as the "drag zone". In the above example, the entire window is the drag zone. Typically you would use the title bar (if the window has one) as the drag zone.
 
 
 
 
movewindow.save_state (win) 
 
 This is used to save the window position when saving the plugin state (if you do that). For example:
 
 
 
function OnPluginSaveState ()
  -- save window current location for next time  
  movewindow.save_state (win)
end -- function OnPluginSaveState
 
 
 pairsbykeys.lua
 
 Provides an iterator function to access a table in alphabetic order, by key.
 
 See forum thread: http://www.gammon.com.au/forum/?id=6036
 
 Exposed functions are:
 
 
 
 
pairsByKeys  (t, f) --> iterator to be used in a for loop using optional comparison function f
 
 Example:
 
 
 
require "pairsbykeys"
-- This prints the math functions in key order
for k, v in pairsByKeys (math) do
  print (k, v)
end -- for
 The iterator function works by making a temporary table into which it copies all the keys, sorts this temporary table, and then returns each one per iteration, in alphabetic order.
 
 You can provide your own comparison function (less-than function) if you want to compare in some other sequence (eg. descending). For example:
 
 
 
require "pairsbykeys"
function gt (a, b)
  return a > b
end -- gt
-- This prints the math functions in descending key order
for k, v in pairsByKeys (math, gt) do
  print (k, v)
end -- for
 This example reverses the normal sort sequence, because the supplied function is supposed to compare for "less than" but we compare for "greater than".
 
 Note - capitalization of the function name is "pairsByKeys", but the module is "pairsbykeys".
 
 
 
 serialize.lua
 
 Converts a table into a string, suitable for storing to disk.
 
 See forum thread: http://www.gammon.com.au/forum/?id=4960
 
 Exposed functions are:
 
 
 
 
serialize.save  (name, v, t) --> complex serialization
serialize.save_simple (v)  --> serialize simple tables
 
 Read the forum thread for full details, but basically if you have a table of iteme (eg. mob names, and how many HP each one has) you can use serialize.save to turn that table into a string. It can then be sequently loaded back as a Lua table by doing a "loadstring".
 
 Example:
 
 
 
require "serialize"
mobs = {}  -- create mobs table
mobs.kobold = {
  name = 'killer',
  hp = 22,
  gold = 5,
  location = 'city square',
  treasure = { "sword", "gold", "helmet" } -- sub table
  }
-- and another one ...
mobs.worm = {
  name = 'gordon',
  hp = 4,
  gold = 15,
  location = 'underground',
  treasure = { "food", "knife" },
  attacks = { "bite", "poison" }
  }
s = serialize.save ("mobs")
print (s)
 This prints:
 
 
 
mobs = {}
  mobs.kobold = {}
    mobs.kobold.treasure = {}
      mobs.kobold.treasure[1] = "sword"
      mobs.kobold.treasure[2] = "gold"
      mobs.kobold.treasure[3] = "helmet"
    mobs.kobold.name = "killer"
    mobs.kobold.gold = 5
    mobs.kobold.location = "city square"
    mobs.kobold.hp = 22
  mobs.worm = {}
    mobs.worm.attacks = {}
      mobs.worm.attacks[1] = "bite"
      mobs.worm.attacks[2] = "poison"
    mobs.worm.treasure = {}
      mobs.worm.treasure[1] = "food"
      mobs.worm.treasure[2] = "knife"
    mobs.worm.name = "gordon"
    mobs.worm.gold = 15
    mobs.worm.location = "underground"
    mobs.worm.hp = 4
 In the above example, we can get our table back like this:
 
 
 
mobs = nil  --> table gone now
assert (loadstring (s)) ()  --> load string "s"
require "tprint"  --> for printing
tprint (mobs) --> table exists, see below
 This prints (using tprint described later on):
 
 
 
"kobold":
  "treasure":
    1="sword"
    2="gold"
    3="helmet"
  "name"="killer"
  "gold"=5
  "location"="city square"
  "hp"=22
"worm":
  "attacks":
    1="bite"
    2="poison"
  "treasure":
    1="food"
    2="knife"
  "name"="gordon"
  "gold"=15
  "location"="underground"
  "hp"=4
 This shows that we have recreated our mobs table, from the string we got after doing a serialize.
 
 We can also use serialize.save_simple to make a simpler looking table than the one earlier, like this:
 
 
 
s = "mobs = " .. serialize.save_simple (mobs)
print (s)
 This prints (for the same mobs table as before) the following:
 
 
 
mobs = {
  kobold = {
    treasure = {
      [1] = "sword",
      [2] = "gold",
      [3] = "helmet",
      },
    name = "killer",
    gold = 5,
    location = "city square",
    hp = 22,
    },
  worm = {
    attacks = {
      [1] = "bite",
      [2] = "poison",
      },
    treasure = {
      [1] = "food",
      [2] = "knife",
      },
    name = "gordon",
    gold = 15,
    location = "underground",
    hp = 4,
    },
  }
 Notice how this example looks less "wordy" then doing serialize.save.
 
 I also needed to concatenate  "mobs = " to the string returned by serialize.save_simple as this works slightly differently in that it doesn't know the name of the variable, thus I have to supply it.
 
 
 
 strict.lua
 
 This function was written by Roberto Ierusalimschy, the developer of Lua. Once you "require" it, it modifies the "global namespace" so that you must declare variables before using them. To "declare" a variable you simply assign to it in global scope. Until you have done that, you are not allowed to read from "undeclared" variables.
 
 See forum thread: http://www.gammon.com.au/forum/?id=7335
 
 If you can't find strict.lua in your distribution, there is a copy of it in that thread.
 
 This works a bit differently from declare.lua described earlier. Here, you simply need to assign something to a variable in global scope (that is, not inside a function) for it to become declared.
 
 Exposed functions are:
 
 
 
 
(none) - you simply "require" it to get the functionality
 
 Example:
 
 
 
require "strict"
a = 20  --> declare "a" by assigning to it
print (a)  --> prints 20
print (b)  --> Error: variable 'b' is not declared
 
 
 tabbed_window.lua
 
 This lets you set up a miniwindow with "tabs". That is, you can have selectable panes of information which display depending on which tab you click on.
 
 See forum thread: http://www.gammon.com.au/forum/?id=14161
 
 Exposed functions are:
 
 
 
 
init (context) - initialize the module
draw_window (context, which_tab) - draws the window, switching to which_tab
hide_window (context) - hides the window
save_state  (context) - to be called from OnPluginSaveState
 
 Example:
 
 
 
require "tabbed_window"
function DrawFoo (win, left, top, right, bottom, context)
  WindowText (win, context.tabfont.id, "This is the foo tab", 
             left + 10, top + 10, 0, 0, ColourNameToRGB "green")
end -- DrawStats
function DrawBar (win, left, top, right, bottom, context)
  WindowText (win, context.tabfont.id, "This is the bar tab", 
              left + 10, top + 10, 0, 0, ColourNameToRGB "darkblue")
end -- DrawEquipment
context = { 
 win = "tabbed_window" .. GetPluginID (),
 tabs = {
      { name = "Foo",       handler = DrawFoo },
      { name = "Bar",       handler = DrawBar },
      } -- end of tabs
    }  -- end of context
    
        
tabbed_window.init (context)
tabbed_window.draw_window (context, 1)
 
 
 tprint.lua
 
 Table printer - prints a Lua table recursively - that is, it shows every item in the table, and then recurses to show sub-tables.
 
 See forum thread: http://www.gammon.com.au/forum/?id=4903
 
 Exposed functions are:
 
 
 
 
tprint (t) - print table t
 
 Example:
 
 
 
require "tprint"
mobs = {}  -- create mobs table
mobs.kobold = {
  name = 'killer',
  hp = 22,
  gold = 5,
  location = 'city square',
  treasure = { "sword", "gold", "helmet" } -- sub table
  }
-- and another one ...
mobs.worm = {
  name = 'gordon',
  hp = 4,
  gold = 15,
  location = 'underground',
  treasure = { "food", "knife" },
  attacks = { "bite", "poison" }
  }
tprint (mobs)
 This prints the mobs table as follows:
 
 
 
"kobold":
  "treasure":
    1="sword"
    2="gold"
    3="helmet"
  "name"="killer"
  "gold"=5
  "location"="city square"
  "hp"=22
"worm":
  "attacks":
    1="bite"
    2="poison"
  "treasure":
    1="food"
    2="knife"
  "name"="gordon"
  "gold"=15
  "location"="underground"
  "hp"=4
 Note the way that nested tables are indented. If the key is a string it is quoted, otherwise it is shown not quoted. This helps distinguish a table key 10 (the number) from "10" (the string).
 
 
 
 var.lua
 
 This creates a special table "var" which lets you access MUSHclient variables as if they were inside a Lua table.
 
 See forum thread: http://www.gammon.com.au/forum/?id=4904
 
 Exposed items are:
 
 
 
 
 Example:
 
 
 
require "var"
var.target = "kobold"   -- set MUSHclient variable 'target' to 'kobold'
print (var.target)      -- print contents of MUSHclient variable 'target'
 If the table item does not exist, nil is returned. You can delete an item by assigning nil to it. For example:
 
 
 
print (var.foo)   -- nil (foo does not exist)
var.target = nil  -- delete the variable "target"
 
 
 wait.lua
 
 Lets you script pauses inside triggers and aliases, where you wait for time to elapse, or some text to arrive from the MUD.
 
 
 See forum thread: http://www.gammon.com.au/forum/?id=4956  (waiting for time)
 and: http://www.gammon.com.au/forum/?id=4957 (waiting for text from the MUD)
 
 Exposed functions are:
 
 
 
 
wait.make (f) - make and calls a function which can pause (a coroutine)
 
line, wildcards, styles = wait.regexp (regexp, timeout) - wait for a trigger with a regular expression
 If no match (ie. a timeout) then the returned values: line, wildcards, styles are all nil.
 
 
line, wildcards, styles = wait.match (what, timeout) - wait for a trigger with "normal" match text
 If no match (ie. a timeout) then the returned values: line, wildcards, styles are all nil.
 
 
wait.time (secs) - wait for some time to elapse
 
 (The timeouts are optional and can be omitted).
 
 Example:
 
 
 
require "wait"
wait.make (function ()  --- coroutine below here
  repeat
    Send "cast heal"
    line, wildcards = 
       wait.regexp ("^(You heal .*|You lose your concentration)$", 10)
  until line and string.match (line, "heal")
  -- wait a second for luck
  wait.time (1) 
  Note ("heal done!")
end)  -- end of coroutine
 The above example uses make.wait to make an inline (anonymous) function that does the actual waiting. This is needed to create a coroutine which can be paused.
 
 Inside the function we do wait.regexp to wait for certain text to arrive fromt he MUD, with a timeout of 10 seconds. If we successfully heal someone we then use wait.time to wait a further second, and we are done.
 
 If we don't successfully heal, the coroutine loops and casts another "heal".
 |  | - Nick Gammon
 
 www.gammon.com.au, www.mushclient.com
 |  | Top | 
 |