Mudlet Scripting Help

by Unknown

Back to Mechanic's Corner.

Unknown2010-07-13 07:34:56
I have a bunch of questions about Mudlet, so rather than start a new thread for each one I will collect them here, and hopefully other people will come out with questions too.

Just for now, I was wondering how I could make an alias like so
CODE
^kick (.*)$


That will target matches when I specify something in the alias e.g. kick rat, but when I don't specify anything, it will default to my "target" variable.

Thanks!
Sylphas2010-07-13 07:42:20
QUOTE (Shou @ Jul 13 2010, 03:34 AM) <{POST_SNAPBACK}>
I have a bunch of questions about Mudlet, so rather than start a new thread for each one I will collect them here, and hopefully other people will come out with questions too.

Just for now, I was wondering how I could make an alias like so
CODE
^kick (.*)$


That will target matches when I specify something in the alias e.g. kick rat, but when I don't specify anything, it will default to my "target" variable.

Thanks!


^kick( \\w+)?$

if matches then else end should do it
Neos2010-07-13 11:01:46
QUOTE (Shou @ Jul 13 2010, 03:34 AM) <{POST_SNAPBACK}>
I have a bunch of questions about Mudlet, so rather than start a new thread for each one I will collect them here, and hopefully other people will come out with questions too.

Just for now, I was wondering how I could make an alias like so
CODE
^kick (.*)$


That will target matches when I specify something in the alias e.g. kick rat, but when I don't specify anything, it will default to my "target" variable.

Thanks!


Tada!
Unknown2010-07-13 13:45:54
QUOTE (AquaNeos @ Jul 13 2010, 07:01 AM) <{POST_SNAPBACK}>



Your link isn't set right, it points to topic 0. I'm guessing something happened when you tried to post =)


Unknown2010-07-13 14:31:06
QUOTE (Sylphas @ Jul 13 2010, 03:42 AM) <{POST_SNAPBACK}>
^kick( \\w+)?$

if matches then else end should do it



This is correct. However, I'd like to suggest a few things which, while not necessary to make the code function, I feel you should probably at least consider while you're starting to get into it.

Apologies if this is all stuff you already know.

1.) Code formatting. I would consider this crucial. One of the things that I love about reading Treant's code is that Zarquan has done a good job of formatting it. It's -much- easier to follow code that has proper formatting. Consequently, this means it will be easier for you to debug, and to change later when you've gotten more experience. I use 2 space indentation, but four spaces, 1 tab, or really anything more than 1 space and less than about 8 should work find so long as you are consistent. Take this one code block from Stygian as an example:

CODE

function Stygian_flagBalances()
SDebug("curing", "Now to reset all flags, then flag the balances we need")
Stygian_balanceFlags = {
focus = false,
purgative = false,
salve = false,
herb = false,
balance = false
}
SDebug("curing","Running through the list of current afflictions")
for _,affliction in ipairs(Stygian_currentAfflictions) do
SDebug("curing", string.format("Now flagging for %s affliction", affliction))
if not Stygian_multiCure(affliction) then
SDebug("curing", string.format("Results came back as not multicure... only one balance will cure this(%s) and so we'll set that flag to true", Stygian_curingBals))
Stygian_balanceFlags] = true
else
SDebug("curing", "It can be cured by multiple balances, we'll have to loop and flag all of them")
for _,balance in ipairs(Stygian_curingBals) do
SDebug("curing", string.format("We're going to flag (%s) now",balance))
Stygian_balanceFlags = true
end
end
end
end


versus

CODE
function Stygian_flagBalances()
  SDebug("curing", "Now to reset all flags, then flag the balances we need")
  Stygian_balanceFlags = {
    focus = false,
    purgative = false,
    salve = false,
    herb = false,
    balance = false
  }
  SDebug("curing","Running through the list of current afflictions")
  for _,affliction in ipairs(Stygian_currentAfflictions) do
    SDebug("curing", string.format("Now flagging for %s affliction", affliction))
    if not Stygian_multiCure(affliction) then
      SDebug("curing", string.format("Results came back as not multicure... only one balance will cure this(%s) and so we'll set that flag to true", Stygian_curingBals))
      Stygian_balanceFlags] = true
    else
      SDebug("curing", "It can be cured by multiple balances, we'll have to loop and flag all of them")
      for _,balance in ipairs(Stygian_curingBals) do
        SDebug("curing", string.format("We're going to flag (%s) now",balance))
        Stygian_balanceFlags = true
      end
    end
  end
end



This is a relatively simple piece of code, and yet if I was faced with the first block, the very first thing I would do is make it look like the second block. There's no way I could work with the first one, especially if something wasn't working with it.

2.) Variable names. Try to be consistent here as well. There are two main camps... camelCase and under_score. myBashingTarget or my_bashing_target. This one is really up to you, there are arguments for and against both, but you'll find life a lot easier if you pick one and stick to it. Also, try to make the variable names have something to do with their purpose. It seems simple, but I've seen plenty of code that uses if a == blah and such like.

3.) Mudlet uses one namespace or sandbox for each profile. This means you can only have one variable named 'target' . For the most part, this is no big deal, but it does mean if you're importing several Mudlet xml files you run the risk of a variable being overwritten. I know you have the bundle I put out a few days ago. If you look at it, you'll notice pretty much all of the variables and functions start with demonnic. This way someone has to actually want to overwrite my stuff in order to do it. I've not been the absolutely best at this, as I think I still use the variable 'target' in that script. A good post regarding this can be found here: mudlet forum post, please ignore vitriol of coder types later in thread


tl;dr? Format your code, be consistent, and remember to use unique variable names if you don't want them accidentally overwritten. You can't control someone else's coding habits, but you can your own.
Unknown2010-07-13 14:35:48
err, and in that light, I'd write Sylphas' snippet as:

CODE
if matches then
  send("kick rat")
else
  send(string.format("kick %s", target))
end



Of course, I put code in, and his suggestion is still correct.
Sylphas2010-07-13 17:03:29
QUOTE (demonnic @ Jul 13 2010, 10:35 AM) <{POST_SNAPBACK}>
err, and in that light, I'd write Sylphas' snippet as:

CODE
if matches then
  send("kick rat")
else
  send(string.format("kick %s", target))
end



Of course, I put code in, and his suggestion is still correct.


Totally agree with this. I was just jotting it down quick, or I'd have looked up the actually Mudlet send coding too. tongue.gif
Unknown2010-07-13 17:15:27
Works like a charm! Thank you very much. I'll also take note of what you suggested demonnic, that helps a lot.

Edit:
A follow-up question to that, for a bit more complicated example.

So my alias is:
^chl (\\w+)?$
Which does 'chant laetitia me' if there's no target, or on the target when I specify it.

But I'd like to be able to do:
chlf
To do 'chant laetitia ' (in this case, target has already been defined).

All as a part of the same alias.

How would that look?
Sylphas2010-07-13 17:33:38
QUOTE (Shou @ Jul 13 2010, 01:15 PM) <{POST_SNAPBACK}>
Works like a charm! Thank you very much. I'll also take note of what you suggested demonnic, that helps a lot.

Edit:
A follow-up question to that, for a bit more complicated example.

So my alias is:
^chl (\\w+)?$
Which does 'chant laetitia me' if there's no target, or on the target when I specify it.

But I'd like to be able to do:
chlf
To do 'chant laetitia ' (in this case, target has already been defined).

All as a part of the same alias.

How would that look?


If I understand you correctly, this:
CODE
^chl(f)?( \\w+)?$

if matches == "f" then
  send("chant laetitia " .. target)
else
  if matches then
    send("chant laetitia " .. matches)
  else
    send("chant laetitia me")
  end
end


'chlf' chants at target, 'chl ' chants at that target, 'chl' chants at yourself.
Neos2010-07-13 18:05:38
QUOTE (demonnic @ Jul 13 2010, 09:45 AM) <{POST_SNAPBACK}>
Your link isn't set right, it points to topic 0. I'm guessing something happened when you tried to post =)


meant to link to the flexible aliases thing on the mudlet forums, can never get links right sad.gif

http://forums.mudlet.org/viewtopic.php?f=8...;hilit=flexible
Unknown2010-07-13 18:11:36
From that thread that Neos is referencing, you can't use 'if matches then' to check for an empty match. Empty matches are now (properly) stored as zero-length strings. So, 'if #matches == 0 then' would be more correct here.
Sylphas2010-07-13 18:18:11
QUOTE (Zarquan @ Jul 13 2010, 02:11 PM) <{POST_SNAPBACK}>
From that thread that Neos is referencing, you can't use 'if matches then' to check for an empty match. Empty matches are now (properly) stored as zero-length strings. So, 'if #matches == 0 then' would be more correct here.


It just worked for me, so unless I... I do have an out of date Mudlet, my bad. I did think it was odd that matches in the middle of a line were empty strings but not matches at the end.
Unknown2010-07-13 18:38:27
QUOTE (Sylphas @ Jul 13 2010, 01:33 PM) <{POST_SNAPBACK}>
If I understand you correctly, this:
CODE
^chl(f)?( \\w+)?$

if matches == "f" then
  send("chant laetitia " .. target)
else
  if matches then
    send("chant laetitia " .. matches)
  else
    send("chant laetitia me")
  end
end


'chlf' chants at target, 'chl ' chants at that target, 'chl' chants at yourself.


I think I understand Iasmos' explanation, however I used this code exactly and it worked just fine, and I'm on the latest version of Mudlet (1.1.1 final). Hmm well, I like to keep things simple... unless I'm missing something. Thanks again smile.gif
Sylphas2010-07-13 18:41:24
Hrm. Does that mean an empty string evaluates to false?
Unknown2010-07-13 19:42:29
I wonder if Heiko changed the behavior again since that thread (which was about the January time frame). In Lua, an empty string evaluates to true, as does a zero numeric value.
Unknown2010-07-13 22:22:00
QUOTE (Sylphas @ Jul 13 2010, 01:33 PM) <{POST_SNAPBACK}>
If I understand you correctly, this:
CODE
^chl(f)?( \\w+)?$

if matches == "f" then
  send("chant laetitia " .. target)
else
  if matches then
    send("chant laetitia " .. matches)
  else
    send("chant laetitia me")
  end
end


'chlf' chants at target, 'chl ' chants at that target, 'chl' chants at yourself.


I would write this as follows:

CODE
^chl(f| \\w+)?$

if matches == "f" then
  send("chant laetitia " .. target)
elseif matches ~= "" then
  send("chant laetitia " .. matches)
else
  send("chant laetitia me")
end


the " \\w+" won't match on chlf or on chl, but the alias should. Though, it may need to be () ... I'd have to try it to remember for sure, and I'm at work, so opening mudlet would be a bit of a nono. And yeah, in lua the only things which evaluate to false are the the boolean object(not the right word, but best I can come up with) false, and the special object nil.
Unknown2010-07-13 22:50:56
CODE
^chl(f| \\w+)?$

if matches == "f" then
  send("chant laetitia " .. target)
elseif matches then
  send("chant laetitia " .. matches)
else
  send("chant laetitia me")
end


Ok, final word on this, just tested with the latest and greatest -released- version of mudlet (work's done, and all the fuddy duddy folks have left). It would seem for aliases, the match entry will be nil.

I recompiled from current git just to be sure. I'll be doing further testing to make sure of how the triggers behave now.
Sylphas2010-07-13 22:55:02
The part of me that loves polished efficient code is jealous and wants to know why I didn't bother to sit and look at my solution longer instead of just throwing it up when it worked.

Of course, that part of me also doesn't care if you can read or understand the code as long as it works, so it has its own issues.
Unknown2010-07-14 18:57:29
QUOTE (Sylphas @ Jul 13 2010, 06:55 PM) <{POST_SNAPBACK}>
The part of me that loves polished efficient code is jealous and wants to know why I didn't bother to sit and look at my solution longer instead of just throwing it up when it worked.

Of course, that part of me also doesn't care if you can read or understand the code as long as it works, so it has its own issues.



It's an interesting mix, to be sure. There's sometimes a definite feeling of "Ok, I got it patchworked... no back away slowly" ... and other times where I'll just have to dig in until it stops offending me.
Unknown2010-08-16 21:40:53
Simple question here...

What's the difference between something like this:
^blah( \\w+)?$

And this?
^blah (\\w+)?$

And is it better to use (\\w+)? or (.*) - ? (question mark not intended to be part of pattern)

Oh and another one, what's wrong with this?
CODE
^dph(f)? (\\w+)?$

if matches == "f" then
    if matches == "h" then
        send("deepheal " ..friend.. " head")
    elseif matches == "c" then
        send("deepheal " ..friend.. " chest")
    elseif matches == "la" then
        send("deepheal " ..friend.. " left arm")
    elseif matches == "ra" then
        send("deepheal " ..friend.. " right arm")
    elseif matches == "ll" then
        send("deepheal " ..friend.. " left leg")
    elseif matches == "rl" then
        send("deepheal " ..friend.. " right leg")
else
    if matches == "c" then
        send("deepheal me chest")
    elseif matches == "la" then
        send("deepheal me left arm")
    elseif matches == "ra" then
        send("deepheal me right arm")
    elseif matches == "ll" then
        send("deepheal me left leg")
    elseif matches == "rl" then
        send("deepheal me right leg")
    end
end


I get an error that it's expecting an 'end' near line 1.