Intro

Posted by Sredmon on Mon 17 Mar 2008 05:07 AM — 15 posts, 38,331 views.

#0
I was wondering if anyone knows of a good introduction that I can use to learn Lua. I started reading one...but it made no sense to me so I am looking for one that is in like as simple english as possible please.

The previous one is http://www.lua.org/manual/5.1/manual.html.

Thanks.
Australia Forum Administrator #1
You want "Programming In Lua" - that is much more readable. The one you had is a reference for looking up obscure facts.

http://www.lua.org/pil/

The book "Programming In Lua" is excellently written, and is worth buying the hard copy of. However the online version is very good too.
USA #2
Oh, goodness. The manual is definitely not a good place to start... it's really a reference, not a tutorial. :)

I'd definitely recommend the book Programming in Lua by Roberto Ierusalimchy, one of the Lua authors:
http://www.lua.org/pil/

Although the only book is for version 5.0, not 5.1, nearly all of the concepts apply.




EDIT:
*shakes his fist at Nick for posting at the same minute!*
:-)
Amended on Mon 17 Mar 2008 05:37 AM by David Haley
#3
First off thanks for the link. That one is a whole lot easier to understand.

I'm working on an if then statement and ran across this error...
Quote:

Error number: 0
Event: Compile error
Description: [string "Timer: "]:1: unexpected symbol near '@'
Called by: Immediate execution


This is the coding I am using...


if @stupidity = 1 then
  Send (outr pennyroyal)
  Send (eat pennyroyal)
end


the Send to box is set for script and I tried setting the Variable box to have stupidity in it but it won't work.

Also tried it this way...


if @stupidity=1 then
  Send (outr pennyroyal)
  Send (eat pennyroyal)
end


I'm sure it is probably a dumb mistake I am missing but I just can't find it. Anything you can tell me is appreciated whether it is how to fix it or suggestions on what I might need to look at to find out on my own how to solve it...either way thanks in advance.

Australia Forum Administrator #4
OK, first question, is "stupidity" a MUSHclient variable or a Lua variable? The distinction is that MUSHclient variables are part of the world file (and saved when you save the world), and Lua variables are just for the current session.

If it was a Lua variable, I would write this (note various syntax changes as well):


if stupidity == 1 then
  Send ("outr pennyroyal")
  Send ("eat pennyroyal")
end


If it is a MUSHclient variable, I would write this:


if GetVariable ("stupidity") == "1" then
  Send ("outr pennyroyal")
  Send ("eat pennyroyal")
end


A few things to be careful about:

  • Lua treats numbers and strings as different (as do most languages), so if a variable has 1 in it, comparing to "1" will fail.
  • The test for equality is "==" not just "=". So in your "if" statement you need to test "if this == that".
  • Stuff you send to the MUD is a string and has to be quoted.





You can use the "if @stupidity == 1 then" approach, however then you have to check "expand variables" in the trigger / alias. That applies to MUSHclient variables, not Lua variables.
Amended on Mon 17 Mar 2008 11:22 PM by Nick Gammon
#5
Sorry, forgot to specify that I am trying to do this in a timer.

Since I couldn't get it working that way so I tried to make a trigger off of regaining herb balance...

Now I get this message...

Quote:

Error number: 0
Event: Compile error
Description: [string "Trigger: "]:1: 'then expected near '='
Called by: Immediate execution


The code I am using is again...


if @stupidity = 1 then
    Send ("outr pennyroyal")
    Send ("eat pennyroyal")
end


I have it set to send to script, regex, and expand variables. Not sure what else to try or do.

Heh. Just read your post Nick and it is a Mushclient variable. Will try what you suggested and see if that works.

Thanks.
USA #6
Note that you need == to test for equality, not =. = is assignment, == is a test for equality. Lua does not allow assignment in if statements (which is rarely what people mean anyhow).
#7
If I wish to do a multiple string of if then statements...could I do it this way?


if GetVariable ("stupidity") == "1" then
   Send ("outr pennyroyal")
   Send ("eat pennyroyal")
end
if GetVariable ("paralysis") == "1" then
   Send ("focus body")
end


Of would I use elseif statements? Which would be quicker and cleaner too?

If I go elseif statements it would look like this right?


if GetVariable ("stupidity") == "1" then
   Send ("outr pennyroyal")
   Send ("eat pennyroyal")
elseif GetVariable ("paralysis") == "1" then
   Send ("focus body")
end
Australia Forum Administrator #8
Yes your elseif has the correct syntax, however I should point out that the two examples will work differently.

The first one, with two if statements, will be independent. For example, if "stupidity" and "paralysis" are both set (that is, "1") then it will send both responses.

The second example (with the elseif) will only look for "paralysis" if "stupidity" is not set. So the real question is, which do you actually want to have happen?
#9
Hmmm...

Well in the game I can focus and do the herbal curing I believe...so I guess I could do the focus alone and then elseif all the herbal cures...thank you for pointing that out.

Alright for now I'll toy with what I have learned so far. Thanks for all the help everyone
#10
okay so I am trying to improve my system and was wondering if I have the coding right for this...


if GetVariable ("herbblance") == "0" then
if GetVariable ("slickness") == "1" then
   Send ("outr calamus")
   Send ("eat calamus")
if GetVariable ("slickness") == "0" then
if GetVariable ("stupidit") == "1" then
   Send ("outr pennyroyal")
   Send ("eat pennyroyal")
end
end 
end
end


Got a feeling that this is wrong somewhere that is why I decided to double check here first.

Thanks all
USA #11
If you want to test several things at once, you can use "and" -- it makes the code a fair bit clearer.

So instead of:


if a then
  if b then
    doSomething()
  end
end

you have:
if a and b then
doSomething()
end
Australia Forum Administrator #12
Quote:

I am trying to improve my system and was wondering if I have the coding right for this ...


The syntax looks OK, the question is, what do you really want to achieve?

It would help if you indented your code a bit, like this:


if GetVariable ("herbblance") == "0" then
  if GetVariable ("slickness") == "1" then
    Send ("outr calamus")
    Send ("eat calamus")
    if GetVariable ("slickness") == "0" then
      if GetVariable ("stupidit") == "1" then
        Send ("outr pennyroyal")
        Send ("eat pennyroyal")
      end
    end 
  end
end


This is the same code, and it will do the same thing, however it makes it clearer that nothing will happen if the variable "herbblance" is not zero. Maybe or maybe not this is what you want.

It might help to write out in English what you are hoping to do, and then code from that. For example, what you effectively have is this:

  • If "herbblance" is not zero, do nothing at all.
  • If "slickness" is not one, do nothing at all.
  • Otherwise, send "outr calamus" and then "eat calamus"
  • If "slickness" is not zero, and "stupidit" is not one, do nothing more
  • Otherwise, send "outr pennyroyal" and then "eat pennyroyal"


Is that really what you mean?

I should also point out, that both "herbblance" and "stupidit" look like misspellings to me. That is OK if they are simply variables and you are consistent, but if not, you will have other problems.
#13
Alright appreciate the help.

To specify...

I want the code to check for herbbalance. If the herbbalance is 1 then don't do anything. If it is 0 then move on to check slickness. If slickness is 1 then cure it if it is 0 then move on to check stupidity and so forth. I will later add in things like sleeping and aeon and anorexia but for now starting small and gradually working up.

Thanks all.
Australia Forum Administrator #14
Probably the simplest way of expressing that is to use the "return" statement, which exits the current script level. Here is an example:


-- if herbbalance is 1 do nothing
if GetVariable ("herbbalance") == "1" then
  return
end -- if herbbalance is 1

-- cure slickness if necessary
if GetVariable ("slickness") == "1" then
  Send ("outr calamus")
  Send ("eat calamus")
end  -- if slickness is 1

-- cure stupidity if necessary
if GetVariable ("stupidity") == "1" then
   Send ("outr pennyroyal")
   Send ("eat pennyroyal")
end -- if stupidity is 1


See how this removes the need for lots of nested ifs?

However I sense a lot of repetition coming up here, how about making a function to make things simpler? Here is an example:


function checkfor (problem, cure)
  if GetVariable (problem) == "1" then
    Send ("outr " .. cure)
    Send ("eat " .. cure)
  end -- if we have that problem
end -- checkfor 


checkfor ("slickness", "calamus")
checkfor ("stupidity", "pennyroyal")


The function "checkfor" checks for a problem, and if it exists, does "outr" of the appropriate cure, and then eats it. Now you only need one line for each possible ailment. This will save typing and look neater.