Home Technical Talk

Self installing maxscript mzp doesn't work properly

polycounter lvl 6
Offline / Send Message
TweaK polycounter lvl 6
Hi to everyone !

I'm currently trying to create a self installing maxscript file but no matter what I try I feel like it's a never-ending story.

Here's what I currently have:

1 maxscript file containing the functions
1 macroscript file containing the UI

when I evaluate the maxscript file and the macroscript file, everything is working properly.

I then created a mzp file using some infos found on polycount and cgsociety, as well as on the maxscript help, but there's a lot of thing to master ! I also checked the amazing textools install.ms file to see how it was done (since I find it very easy to install !).

So I used the same process: the install.ms script finds the files to install, everything's copied to the proper place.
I am then able to launch the UI macroscript, but the functions called in the maxscript file doesn't work if there are not put in the right order, i.e. if I write:

fn a = ()
fn b = (
 fn a()
)

it work, but

fn b = (
 fn a()
)
fn a = ()

will throw an error because a() is undefined ???

I can deal with it by placing everything inside the last function, but that's weird. I found that including the maxscript file at the beginning of the macroscript file solved the problem, but that's dirty.  :/

Now things are becoming a little more complicated: if I quit 3dsmax and reopen it, I can launch the UI, but nothing work.

As far as I investigated, I need to re-evaluate both the maxscript file AND the macroscript file, even if the macroscript file should be evaluated automatically at startup. So I tried to do that and I used a conditionnal statement on the execute handler of the macroscript, this way:

on execute do
(
if (functionName == undefined) then -- the rollout and the functions must be loaded in ram for later use
(
filein ((pathConfig.GetDir #userScripts)+"\\myMaxScript.ms") -- register the script
filein ((pathConfig.GetDir #userMacros)+"\\myMacroScript.mcr") -- register the UI
)
-- UI stuff
...
)

the problem is: even if functionName is undefined, the if statement acts as if the function exists... And if I don't add any conditionnal statement the file is self-including itself indefinitely.

I don't know where to go from that point, since it's already hacky I'm asking for some help here !

Thank you to anyone interested in solving this issue :blush: 

Replies

  • PolyHertz
    Options
    Offline / Send Message
    PolyHertz polycount lvl 666
    TweaK said:
    fn b = (
     fn a()
    )
    fn a = ()

    will throw an error because a() is undefined ???
    Just fyi, you don't add 'fn' before calling a function, it's only used when defining it.
  • TweaK
    Options
    Offline / Send Message
    TweaK polycounter lvl 6
    Thanks PolyHertz, yes you're right !

    I didn't pay attention enough when writing this !
    I only put this as an example since the actual script is very large I thought it would be best suited for understanding.

    Do you know what may cause this strange behavior anyway ?
  • PolyHertz
    Options
    Offline / Send Message
    PolyHertz polycount lvl 666
    I can't say for sure without seeing the actual script (and I'm not sure what you'd call 'very large', I personally try to keep files at 2k lines or less before breaking them up, but I know others that are ok with 15k+ lines of code in a single maxscript file).

    One tip I can give is to use "do" instead of "then" in your conditionals that aren't using an "else" afterwords. Most Max scripters say they are interchangeable, but from my experience "then" conditionals are far more prone to strange errors, and should only be used when necessary.
  • spacefrog
    Options
    Offline / Send Message
    spacefrog polycounter lvl 15
    PolyHertz said:
    . Most Max scripters say they are interchangeable, but from my experience "then" conditionals are far more prone to strange errors, and should only be used when necessary.
    That's very true - with "if..then" the maxscript compiler expects a following "else" block - if thats not coming it throws an exception internally, which is bad for performance too. You can easily verify that by testing the following in the maxscript listener and hit enter:
    if 2<5 then print "hello"


    The listener will hang until you hit ESC, which produces an "** interrupted **" exception
  • TweaK
    Options
    Offline / Send Message
    TweaK polycounter lvl 6
    Thank you for the tip. This is a very bad design if you'd ask me ! ^^

    I tried to replace the "then" by a "do", and also add an "else" block but it didn't change anything.
    Hopefully I finally managed to make it work. It seems that's because I had to include the functions inside the macroscript declaration, but outside the rollouts. That's a bit hacky and I don't really get it since when I manually evaluate the scripts everything is working properly.

    So here's what I have:

    macroScript macroName
    (
     filein "myFunctions.ms"
     if (myFunctionName == undefined) then filein "myUI.mcr"
     ... -- Some script
     on execute do
     (
      ... -- Some script
     )
    )

    I'm not sure this is how it's supposed to work, but it does ! :blush: 
    If you think there's a better way, I can send you the mzp file for further investigation :smile: 

    I hope this will help someone too :)
  • monster
    Options
    Offline / Send Message
    monster polycounter
    Just post an MZP. I have time to look.

    What I do, and I think it might be the right way (SpaceFrog can correct me), use your Install.ms to move MyFunctions.ms to a Plugins folder (not a script or macro folder) and put MyUI.mcr in $UserMacros. Then fileIn the function. Finally, fileIn the Macro.

    This evals the scripts for Max's current session and they are in the correct eval order when the user restarts.

    Also, your macroscript definition won't need anything but On Execute...
  • TweaK
    Options
    Offline / Send Message
    TweaK polycounter lvl 6
    Thank you for the reply monster !

    I sent you the mzp file if you still have some time to look into it.

    Actually I wanted to keep the files out of the Plugins folder (like stdplugs/stdscripts/...). But this might be the only valid place even if there's a userScript folder. I wanted to know why it was like that, and how the userScript folder would be useful if not by putting external scripts inside !

    I also read somewhere that putting anything inside the userMacros folder was a mistake because 3dsmax is generating a macroscript by itself if the function script contains any macroscript declaration. Anyway, I tried that, and 3dsmax produced a blank macroscript, so something went wrong...

    At this point, if anything is working properly I feel so happy :blush: 
Sign In or Register to comment.