Notifications
Clear all

[Closed] MaxScript == Lua ????

Hey everybody, this is my first time posting on the Maxscript forum. I’m a Maya user (please keep reading) and I use MEL intensively. I have been frustrated with the limitations of the MEL language itself and got curious today as to what scripting languages for other 3d packages look like. I downloaded a couple Max scripts and was surprised to see that they look like Lua. I am not a Lua user either (my scripting language of choice is Ruby), but I am somewhat familiar with it and this intrigues me.

If you aren’t familiar with Lua, the website is http://www.lua.org

If this is true then Maxscript is quite possibly a better language than Mel is. For example, it appears that Maxscript supports closures.


 button someButton "This button"
 on someButton pressed do (
 	-- etc...
 )
 

In Ruby we might do something like this, using the Fox gui toolkit:


 someButton = FXButton.new(parentLayout, "This Button")
 someButton.connect(SEL_COMMAND){
 	# etc...
 }
 

And here is how it would be done in mel.


 string $someButton = `button 
 	-label "This Button"
 	-command "code to execute goes here"`;
 

Mel handles that by compiling that string into a chunk of internal code that it executes when the button is pressed.

This has gotten me interested. If Maxscript is Lua, that means it has all the cool features Lua has, like Lexical closures, tail-call recursion, tables, threads, etc…

Can anyone enlighten me on this? I would appreciate all answers.

7 Replies

I’ve never used Lua (I’m a Python fan, myself), but one thing, I think, needs to be said in response. That Maxscript may appear similar to another language doesn’t automatically imply that they share the same feature-set, or that they are otherwise similar under the hood. I am not qualified to say whether Maxscript implements tail recursion or any of the other features you mentioned; I am merely warning against making deep comparisons of the languages (compiler optimizations, etc.) based on shallow attributes such as syntax and style. Someone with more low-level knowledge of Maxscript would have to answer those questions on a feature-by-feature basis.

RH

1 Reply
(@danneufeldt)
Joined: 11 months ago

Posts: 0

Agreed. I am making a shallow comparison, having little experience with either language, and that’s why I’m posting here to see if someone more familiar with Maxscript would be willing to look at the Lua site and tell me what they think. However, one thing I do know is that Lua is free, and it is very commonly used as an embedded language in a variety of programs, so it is entirely possible that the Max team decided that rather than go through the work of developing a language in addition to the Max software, to take advantage of an open source language with years of development behind it. It seems like a wise decision to me, escpecially since Lua incorporates quite a few cool features.

No, MAXScript is not Lua. Lua was developed as a light-weight external scripting language that can be licensed and integrated into applicaitons that require scripting. (Lua was used for example as base of DFscript, the Eyeon’s Digital Fusion scripting language).

MAXScript was developed as a wrapper on top of the 3ds max SDK by John Wainwright around 1996-97 and has been constantly developed further as an integral part of the 3ds max core since its inclusion into the shipping version of Release 2.

It is interesting to mention that MAXScript was developed in a similar timeframe as Lua, so they might be sharing some concepts for purely historical reasons.

Internally, MAXScript shares some similarities with expression-based languages like LISP and Mathematica. On the surface, it appears to be very similar to Basic and Lua, but I am pretty sure this has no deeper meaning.

As for MAXScript being a better language than MEL, if you would define “better” as “cooler and more relaxed”, then Yo Baby We Are Smooth!

The reality is that MEL was written as the core language of Maya and was intentionally made more restrictive and IMHO much easier to parse by a machine than by a human.

MAXScript on the other hand was developed ON TOP of 3ds max, not as the core, so it is much closer to the end user than to the core of the application. This has the negative effect of not being able to access 100% of the internal features, but being amazinlgy simple and powerful at the same time. Also, MAXScript provides a large number of higher-end functions to perform matrix transformations, read and write pixel data from bitmaps, draw graphics primitives directly to the viewports and much more.

For a very basic comparison of MEL and MAXScript, be sure to visit my pageand follow theMEL2MXS link…

Also, get the latest MAXScript Reference 7.0 Rev.1 from Discreet’s webpage and have a read:
ftp://ftp.discreet.com/pub2/web/products/3dsmax/maxscript_updated_help.exe

Have fun!

Thanks a ton Bobo, that’s exactly the kind of answer I was hoping for.

I guess “better” was not a good choice of word, at least in context. But you guessed correctly, I am referering only to characteristics of the language itself, not the levels of access to the program. MEL is really powerful for dealing with Maya, and it is incredibly useful to me. Mainly the amount of power that comes with it is what leads to frustration with the language. I’ve written fairly long scripts with MEL, 8,000+ lines of code and the need for more powerful language constructs arises.

My programming progression has been MEL–C+±-Perl–Ruby and a sidetrack to Lisp.
I use MEL for controlling maya, C++ mainly for plugins, and Ruby for everything. Perl was not for me. Lisp is really cool and it put a new perspective on things but I don’t really have any need to use it. Ruby does really well for me.

Those other higher level languages have “spoiled” me so to speak on features like closures, namespaces, classes, modules, etc and I miss them when using MEL. I can do without , but would love to have them. So when I looked at a piece of MAXScript code and saw things that hinted at some of those features I got overly excited and posted here without doing any research whatsoever.

I’m reading through the MAXScript reference and I can tell it is a cool language. I can see the Lisp influence in there. Where I currently work we use Maya only, but should I ever go to a company using Max I think I would enjoy learning and using MAXScript.

Perhaps you could answer one more question, since I haven’t seen it directly addressed yet in the reference. In that example of the button code, does that code behave as a closure, or would referencing a local variable from an outer scope cause an error on execution? Or are MAX dialogs modal? I would test this myself, but don’t currently have MAX.

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

As far as I can tell, no, the code you referenced would not qualify as a closure.
Also, MAXScript rollouts are not modal in the sense of blocking the rest of the program until exiting (although there is an option to get this behavious if needed), but they are modal in the sense of living forever in MAXScript memory and preserving the life of their locals.

Here is how MAXScript handles the example you posted internally:

*MAXscript rollouts define their own scope.
*The GUI control element definition (which creates a local variable to hold the GUI object) lives in the rollout’s scope.
*The on … pressed do() handler enables a function in the GUI control element that is called when the GUI element is operated on and can be passed 0 or more arguments depending on the control’s type.

The rollout scope has a long life expectation, so both the GUI element and its event handler function exist in it for the whole life of the rollout. This is thanks to what MAXScript calls a “Private Global” scope. Please read the explanation in “Scope of Variables”>“Local Variables as ‘Private Global’ variables”. In short, all top-level local variables in a scripted rollout, utility, plugin, scripted controller or MacroScript hold their value for the complete existance of the respective scope. These top-level locals include all GUI control elements.

The event handler function can reference any local variables from its parent scopes, plus the arguments sent to it by the internal callback generated by the GUI control element which obviously exist in the function’s scope.

For example,

rollout test “A Test”
(
spinner spn_value
on spn_value changed val do
format “Current value is %
” val
)
createDialog test

The rollout variable test will exist in this particular case in the global scope (but it could be defined in some local scope) and as long as it does not get redefined or removed, it will stay there until the end of the Max session.
The variable spn_value is local to the scope of test.
The on spn_value changed val do… expression causes a function similar to

fn changed newValue = (format “Current value is %
” newValue)

to be generated internally and implicitly in the scope of the spn_value. In fact, most MAXScript users don’t even realize they are creating an actual MAXScript function when defining an event handler.

If you would ask about it, you would get:

test.spn_value.changed
–>spn_value.changed()
classof test.spn_value.changed
–>MAXScriptFunction

If you would execute the above code and start changing the floating point value in the spinner, MAXScript would call the function test.spn_value.changed() with the new value of the spinner as the argument, causing lines like
Current value is 0.0
Current value is 0.5
Current value is 0.6
Current value is 0.7
Current value is 0.8
Current value is 0.9
Current value is 1.0
Current value is 1.1
to be printed.

Of course, you as user can also call that function, for example you could execute in the global scope of the MAXScript Listener (console):

test.spn_value.changed 10

and the function will print

Current value is 10

but this will of course not change the current value in the spinner, since the event handler function is on the receiving end and does not affect the actual value of the spinner.

As mentioned before, from inside the scope of the changed() function,
you can access the GUI control and all local variables defined in all its parent scopes. Since both the rollout and the rollout control element (the spinner in this case) live as long as the rollout is defined (often the whole Max session), there is no need for a closure.

I hope I interpreted your question correctly.

Cheers,
Bobo

Ok I see how that goes.

Your interpretation of my question was dead-on.

One question:
If you call createDialog test twice, does that create two different gui’s?

Persistent nested scopes would be a very nice thing to have in MEL. The single global environment can get very frustrating. Plus all the variables are statically typed, so if I declare a global string $variable, and meant to put [] after it to make an array… Oops, have to restart maya, or use a different variable name. In reality that problem arises infrequently, but it’s annoying when it does.

Fortunately I’ve been using Ruby a lot lately, so that’s relieved my language frustration, but really it’s just setting me up for greater frustration when I go back to MEL.

Thanks for taking the time to answer these questions Bobo, I hope they weren’t too annoying.

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

Depends.

If you simply call “createDialog test” twice, then no. createDialog is responsible for placing the already defined rollout into a dialog which is a special case of a rollout display. (Originally, back in the first version of MAXScript, you could place a rollout only on a floater or in a utility).

If you would call destroyDialog test, the dialog would be CLOSED, but the rollout would still live in MAXScript memory and you can access its controls, functions etc. For example, if you create the dialog, check a checkbutton, call destroyDialog and ask about the state of the checkbutton, you can still read the correct value… If you would call createDialog again though, all states of GUI controls will be reset back to defaults…

Now if you would call the WHOLE script again, including redefining the rollout “test” before creating the dialog UI, the old rollout definition would be lost and a new one would be created in memory. If you forgot to call destroyDialog, you will end up with two or more dialogs floating around, but you can access only the last one through the variable test, the others still work, but you have no control over them and would have to close them manually with the mouse click on [X]

Persistent nested scopes would be a very nice thing to have in MEL. The single global environment can get very frustrating. Plus all the variables are statically typed, so if I declare a global string $variable, and meant to put [] after it to make an array… Oops, have to restart maya, or use a different variable name. In reality that problem arises infrequently, but it’s annoying when it does.

This is because MEL defines a new global variable just once. MAXScript used to do this in its very first version but was thankfully changed in Max Release 3 to always redefine globals. Now you have to check yourself if you want to preserve a global:

global someVar
if someVar == undefined do someVar = “My Initial Value”

(This is documented in the MXS Reference btw.)

Thanks for taking the time to answer these questions Bobo, I hope they weren’t too annoying.

You are kidding, right? There is nothing else I would talk with more pleasure
Some people are even paying me for talking about MAXScript…
Keep the questions coming!

Cheers,
Bobo