Building: Basic Lua
Traps / Event Handlers
Once you have all your objects created, you might want people to be able to interact with them in unusual ways. This is where event handlers, or traps (sometimes known as "specials" on other muds) come in.
Event driven programming
In a traditional, "functional" programming method, your programs have a beginning, a middle and an end and you control what sections of the program get executed at what time.
In event driven programming, your program spends 99% of it's time being idle and only does anything in reaction to something that has just happened. The thing which is being reacted to is called an "event".
What are event handlers/traps?
Event handlers, or "traps", are short programs that get triggered by a specific event, like a button being pushed.
What can I trap on?
Almost anything. There is a long list here. If you need to trap on something which isn't in that list, ask someone - it's trivial to add new traps.
What can I do in a trap?
Again, almost anything. here's our library docs. Typically, people use them to send messages to users, to move objects about or to change an object's properties. It is also simple to get new functionality added if you need it, but you're not likely to need it.
Lua
We use a programming language called Lua for our traps. It has a straight-forward syntax, so if you have done any programming before then it shouldn't be too much of a shock. [FIXME: find a link to an "introduction to programming" page?]
Hello World
If you have an object called
test_button_1
and you wanted to do things when someone pushes it, you would put some code inside its
lua.push
property using "change" by typing:
chstr test_button_1 lua.push act(pl,"%1 just pushed a ^obutton^n")
[FIXME: make change understand lua :) ]
Explanation
The lua code in the above example is
act(pl,"%1 just pushed a ^obutton^n")
In this code, act is a function and pl and "%1 just ...." are parameters which are passed to it. pl is a special variable which means the player who triggered the trap (i.e. who pushed the button) and the text inside "s is a string.
From looking at this list we can see that act takes two parameters. The first is the player (or object) to perform the action as, and the second as the action format string.
It will format the text and then display it to everyone in the same room as the player (including themselves) you passed in.
The %1 is a special variable which expands to different things depending on the user's point of view.
There is a list of all the %
codes you can use. Don't worry if you don't understand what all of them mean
just yet.
The player pushing the button will see "You just pushed a button"
and any other players in the room will see "PlayerName just pushed a
button". [FIXME: mention %[a/b] constructs]
return
If you try the above example, you will see that it says "Nothing happens when you do that" after the message we want. That is the default message which is shown if you push a normal object. In order to suppress that message, change the code to:
act(pl,"%1 just pushed a ^obutton^n") return 1
"return 1" is another command which skips the rest of the trap and instructs the mud not to perform any additional processing afterwards. This works in most traps that occur before an action has occured. For example, if you put "return 1" in a "drop" trap, the object will not be dropped - because the trap gets called before the drop actually happens. This might not be what you intended. There is a matching "after_drop" trap for this reason which gets called after the object has been dropped.
Variables
pl, o1, o2, txt
There are some variables you can always rely on being there in your traps.
"pl" is the player (or mobile) who is triggering the trap.
"o1" is the object the trap is being run on.
"o2" and "txt" are the "second object" and optional text. The contents of
these variables depends on the trap. See the list of
traps for details.
Local variables
Because of the way we are using Lua, all traps are executed in the same scope, with the same global variables, so we have restricted who can set global variables. Don't worry if you don't understand what that means, it just means you can't set variables in a trap which will still be there the next time the trap is triggered. If you need to do that, set a property in your object. You probably don't need to do it though. Understand what the once() function does before you start using objects as variable storage - it probably does what you want.
You can, however, store data in variables and use them later on in the same trap. This is not so useful in simple traps, but in large and complex traps it helps to maintain readability. The syntax is "local i = 1".
You can also write local functions if you find yourself needing to do the same thing several times in the same trap. This isn't as useful as it sounds, but if you find yourself using it a lot and you think other people will be needing to do the same thing, then we can add your function as a global one - so it is accessible from all traps.
Conditionals
Lua uses if then else end for conditionals, like so:
if obj.once(o1) then send(pl, "Something happens!") else send(pl, "Something already happened so it isn't happening again.") end
Loops
for key, value in ipairs(children(o1)) do somethign(value) end