Introduction to Lua scripting for MUSHclient

Posted by Nick Gammon on Wed 24 Nov 2004 02:24 AM — 3 posts, 12,900 views.

Australia Forum Administrator #0
Version 3.52 of MUSHclient introduces the Lua scripting language.

Unlike the other scripting languages so far, Lua is not implemented using COM (Micosoft's Component Object Model), but rather as a direct interface between MUSHclient and the Lua script language.

Lua is supplied as two DLLs as part of the MUSHclient download (lua.dll and lualib.dll).

The reasons for doing this are:

  • Lua is a nice, fast, compact scripting language, however with surprising power
  • Since it is distributed with MUSHclient, script writers can assume that it is available (unlike, say, Perl or Python), without the end-user having to install extra languages.
  • It allows scripting for platforms (notably Wine under Linux) that may not work properly using the COM interface
  • The Lua language itself allows some very neat tricks which will be described in more posts in this section
  • You can extend it by writing your own scripts in Lua (of course) but also by writing your own C DLLs and loading them into the program address space. For example, you might write custom windows or toolbars.





First taste of Lua scripting

Lua's syntax (which is based on Pascal) is very similar to VBscript and Jscript, so that if you are used to either of those, you should have no difficulty with Lua.

As an example, let's take a simple trigger script:

Match: * goes *
Name: test
Script: mytrigger



VBscript


sub mytrigger (name, line, wildcards)

  world.Note "In trigger " & name

  world.Send ("go " & wildcards (2))  ' follow him
  world.Send ("kill " & wildcards (1))  ' attack him again

end sub





Jscript


function mytrigger (name, line, wildcardsVB)
{
  wildcards = VBArray(wildcardsVB).toArray();	

  world.Note ("In trigger " + name)

  world.Send ("go " + wildcards [1])  // follow him
  world.Send ("kill " + wildcards [0])  // attack him again

}	// end of mytrigger 





Lua

OK, Let's do the same thing in Lua ...


function mytrigger (name, line, wildcards)

  world.Note ("In trigger " .. name)

  world.Send ("go " .. wildcards [2])  -- follow him
  world.Send ("kill " .. wildcards [1])  -- attack him again

end


The syntax is very similar to the earlier examples. The major differences are:

  • functions are defined with "function", not "sub"
  • You concatenate strings with ".." rather than "+" or "&". This is a good thing, because Lua doesn't get confused when you try to add numbers (eg. "1" + "1" becomes 2, not 11).
  • Comments are started with "--"

Amended on Wed 24 Nov 2004 02:25 AM by Nick Gammon
Australia Forum Administrator #1
Things become a little more interesting in Lua when you start using named wildcards. As an extension, the Lua interface will automatically give you all named wildcards in the trigger function.

Let's convert the trigger to a regular expression:


Match: ^(?P<who>.*?) goes (?P<where>.*?)$


Now we'll redo the script with named wildcards:


function mytrigger (name, line, wildcards)

  Note ("In trigger ", name)

  Send ("go ", wildcards.where)  -- follow him
  Send ("kill ", wildcards.who)  -- attack him again

end


As another extension, some script commands (like Note, Send) can take multiple arguments under Lua, so you can just separate them with commas. Also the word "world." is optional. The script above is starting to look neater and more compact.



Australia Forum Administrator #2
Another neat aspect of Lua is multiple-line quoted strings. This make importing triggers and aliases in a script much simpler:


ImportXML
[[
<triggers>
  <trigger
   enabled="y"
   match="^(?P&lt;who&gt;.*?) goes (?P&lt;where&gt;.*?)$"
   name="test"
   regexp="y"
   script="mytrigger"
   sequence="100"
  >
  </trigger>
</triggers>
]]



The [[ ... ]] sequence indicates a multi-line quoted string. Thus, you simply paste the required trigger (or alias or whatever) between them.