Lua basics

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Thanks Vern.

Quick question: Is it best practice to use double over single quotes? Lua uses either, but I see more double. Is this just a habit from other languages?
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Good question. I have absolutely no idea. I just use double quotes because all the examples I've seen use them.

;)

p.s. Single quotes are "faster" to type. So sometimes I get lazy.

-vern
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Well the Lua reference just says to be consistent. I guess it only matters to keep sub-quotes straight.

Code: Select all

> print("one line\nnext line\n\"in quotes\", 'in quotes'")
    one line
    next line
    "in quotes", 'in quotes'
    > print('a backslash inside quotes: \'\\\'')
    a backslash inside quotes: '\'
    > print("a simpler way: '\\'")
    a simpler way: '\'
I've started over from the beginning. I think that bit you explained gave me just enough of a handle on the subject to start understanding it. I'm getting so much more of it now. Thanks Vern. :wink:



p.s. I quoted this code the first time and got a server error. :oops:

Code: Select all

a = {p = print}
    a.p("Hello World") --> Hello World
    print = math.sin  -- `print' now refers to the sine function
    a.p(print(1))     --> 0.841470
    sin = a.p         -- `sin' now refers to the print function
    sin(10, 20)       --> 10      20
Just read this bit. It actually made me laugh. Within a table, 'print' is a variable that can be reassigned?!! :shock: :lol:
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Question:

Can regex searches be internally concatenated, or would I just need to concat variables of two separate regex searches?
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

It's just easier to concat the variables... it makes my head spin thinking of the other way. ;)

-vern
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Also, I'm a bit hazy about functions. Predefined functions( like 'print()' ) are called from the lua library? So the name 'print' is the identifier, the '()' signifies the call, and within the closure are function modifying parameters?

Let me know if that's close.
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

heyvern wrote:It's just easier to concat the variables... it makes my head spin thinking of the other way. ;)

-vern
Yeah I figured it was easier that way, but it is possible?

I guess the middle ground would be concating the regex searches into a single variable to begin with.
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

print() is a special type of function because it is part of lua. It just needs to be "called" directly. You pass arguments to a function using the paranths ().

You can create your own functions in AS scripts. Just say:

Code: Select all

function HV_CustomTool:MyCustomFunction(a, b, c)
...
end
And put in the code you want to happen. Later you can call that function and pass whatever arguments you've defined for the function in the parenths () separated by commas.

You can leave the first part off (HV_tool:) That just makes the function belong to the specific tool, in case you use the same thing in another tool but want it to do something different. That is how the tools work now. A tool like Rotate Bones can also select bones. Instead of repeating the same code it calls the function IN the select bone tool.

The AS "DrawMe()" tool script function is similar. Each tool has this available without actually creating the function. It's built in to the AS script interface. You call it to redraw the screen after a script has made changes (lke dragging a bone or points).

However you can put in a "DrawMe()" function in your tool script if you want it to do more stuff.

Another trick is to put often used functions in a utility script. Fazeks tools use this (as well as LM of course). Fazek created his own set of "global" functions in one utility script that ALL the tools can make use of.

You can modify these scripts to add to it or make them work differently.

I used this myself for my own custom "Bone Groups" tools. All the bone grouping and colorizing on screen is done in my utility script. Each tool was modified with just one line of code calling my custom function. It is actually using the "HV_utilities:DrawMe()" function I mentioned but it also draws custom bone shapes on the screen because of the code in the utility script.

that's the main reason I haven't released the bone groups script. It requires all new tools and it's just too much effort to maintain that over the long term. If AS changes in the future to allow the utility scripts to do more on their own that would be great. Right now they load and the functions and variables are in memory but nothing happens unless a layer or tool script calls them.

-vern
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

So functions are kind of like an operational variable?

I may have to hunt up some explicitly written out functions to get this.
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

All the tools are full of functions. Everything in a tool script is a function of some sort. That is the basis of lua in AS. If code is not contained in a function it just runs immediately. By putting it in a function it only runs when something specific happens.

There are custom built in functions that a tool can have access to. Like "OnKeyDown(moho, keyEvent, view)" to check if a key is pressed and what key is it (the keyEvent variable). Or OnMouseDown(), etc. (I am not looking up these functions so I may have typed them incorrectly).

For example, this is the first line of the main function for my "Action Commander" script:

Code: Select all

function HV_Action_Commander:OnKeyDown(moho, keyEvent, view)
....
end
This function will check first if the CMD key or ALT key is down (the keyEvent). Next it checks if the keys 0-9 are ALSO down (also the keyEvent). After that it does a bunch of stuff to load an action.

That function is never called unless a key is pressed AND the keys pressed match what I've set up in the function.

Functions are lua. Study lua references to learn about functions.

-vern
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

If code is not contained in a function it just runs immediately. By putting it in a function it only runs when something specific happens.
Ah, thanks Vern. That's what I was missing. Sorry if I'm being too dense. I'm studying the Programming in Lua online book, and using the interactive interpreter. But it's slow going. Thanks for the patience.
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

I use AS as my "lua interpreter". Not as full featured but since my only scripting is for AS it just makes sense to me. The version of lua you are playing with right now probably has a few things that are "different" from what is used in AS.

It's not the end of the world. Most of the stuff changed in the latest version can be easily changed if AS gets updated.

For example:

Code: Select all

string.gfind(s, pat)
Was changed to:

Code: Select all

string.gmatch(s, pat)
As far as I know they do the same thing. It's just confusing until you get the hang of it. I never even HEARD of string.gfind() until I found a reference in a newer online reference that mentioned it was changed to string.gmatch(). I just assumed the lua in AS didn't have that ability at all.

The lua in AS just chokes on string.gmatch().

Some other subtle things were changed with some stuff that just behaves differently. A few things were deprecated so if you find some nifty code snippet it might not work the way you expect it to. There is some stuff regarding table size and "getn" and "setn" that still has me scratching my head. Often I can't tell if it's my bad code or deprecated stuff in lua.

It's weird, it could be the version of lua in AS is "between" 5.0 and 5.1 so I just go with 5.0 to be safe.

I use this as my reference since it sticks pretty close to the version of lua used in AS.

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

Another FANTASTIC resource I like is the "MUSHclient" forum (whatever "mushclient" is). It has a lot of good info. I learned all about tables and strings on that site. Very down to earth easy to understand explanations and examples. Tables are wicked hard to get your head around (they were for me anyway) but you MUST understand lua tables to do ANYTHING really cool with AS.

Tables:
http://www.gammon.com.au/forum/?id=6036

Strings:
http://www.gammon.com.au/forum/?id=6034

-vern
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Yeah, I'm using that same lua reference.
http://www.lua.org/pil/
Thanks for those other resources. I'm sure they'll be handy.
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Code: Select all

 . --- (a dot) represents all characters. 
%a --- represents all letters. 
%c --- represents all control characters. 
%d --- represents all digits. 
%l --- represents all lowercase letters. 
%p --- represents all punctuation characters. 
%s --- represents all space characters. 
%u --- represents all uppercase letters. 
%w --- represents all alphanumeric characters. 
%x --- represents all hexadecimal digits. 
%z --- represents the character with representation 0.
Why is it there don't seem to be any complete lua references? The page I took this from also uses '%b' for balanced pairs, but hardly explains.

Makes me feel like I am missing alot of the details. :roll:
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Woohoo!! My first script contribution!

http://www.mediafire.com/?aiilpsnexmm

Vern, thanks for doing that modification of meshinstance. That gave me just enough info, and with some research, I was able to free up the naming convention more.

This version of meshinstance allows you to name your instances with a bit more flexibilty.

"original layer name.anything or nothing.dup"

For example, the original layer named "rt_arm" can be:
"rt_arm.upper.dup"
"rt_arm.between the hand and elbow.dup"
or just plain "rt_arm.dup"

This way it still works like the original script if you don't need the multiple instances. And since duplicating your original layer automatically uses the same name plus a number, all you have to do is replace the number with your extension, as the fa script.



p.s. Vern, if you look at this script, you'll see what I was trying to do commented out. I never could get the regex to find only the ".dup" so I cheated and just assigned the ".dup" directly to that variable. You may get a kick out of my variables too. (How else do you bob?):wink:

I know I may be the only person who needs this, but I'm proud of it anyway.
Post Reply