Lesson 11: What’s Bugging me? Part 1

Bug tracing and error finding sometimes takes longer than writing the original script! Here are some examples of error messages and what they could mean….

Don’t forget the Brackets!

-- Error occurred in anonymous codeblock; filename: ; position: 20; line: 3
 -- Compile error: Unexpected end-of-script
 -- In line:
-- Error occurred in anonymous codeblock; filename: ; position: 24; line: 4
 -- Syntax error: at ), expected <factor>-- In line: )

This normally means you’ve missed out or got an extra parentheses (bracket) somewhere, brackets always go in pairs to have a look through and make sure you don’t have an odd number. See the previous post about interrupting which happens with missing brackets.

What should I do?

-- Error occurred in anonymous codeblock; filename: ; position: 54; line: 4
 -- Syntax error: at (, expected do
 -- In line: (

It can also happen when you’ve got a ‘do’ error, this error happens if you were to miss out a parameter when pressing a button for instance…

on btn_testbutton do
(
   --do something
)

which of course should be

on btn_testbutton pressed do
(
   --do something
)

Who you trying to call?

-- Type error: Call needs function or class, got: undefined
Selext $Box*

I’ve type something that Maxscript doesn’t know of… in this (simple) case it’s a typo, it should of course be ‘Select’, but recognise that using the select function is calling a function with a parameter. We could get this error when there is no typo, but actually the function we’re trying to call is out of scope, or hasn’t been defined at all.

See the below example, the testMe function is only defined within the scope of the If test, it doesn’t exist outside it, so although we’re trying to call testMe() later on which isn’t a typo, we can’t call the function because it’s not available to the scope (sometimes easiest to think indentation level with brackets (if you format your code correctly)).

(
    t = 5
    if t == 10 do
    (
        fn testMe =
        (
            print "test"
        )
    )
    testMe()
 )

This will become apparent when your scripts start to become more complicated, but good to be aware of.

Other causes of it happen when you are constructing values for example and you forget to put a + in… example…

(
    a = 4
    b = 10
    c = a b
 )

Which if we look at our MaxScript Listener….

-- Error occurred in anonymous codeblock; filename: ; position: 26
 -- Frame:
 -- a: 4
 -- c: undefined
 -- b: 10
 -- Type error: Call needs function or class, got: 4

Of course we probably meant c = a + b, but by not putting the + in MaxScript is thinking we’re trying to call a function with the name a and passing a variable b to the function.

We could have done something silly like re-using a variable name…

(
    fn a theval =
    (
        10 * theval
    )
    a = 4
    b = 10
    c = a b
)

In this instance we’ve got a function assign to the variable a but then we’ve reassigned the value a to = 4 so we can’t call our function a again, this is where clear naming conventions comes in and are really important so you know what types of variables are applied to which types of values.

How many Arguments are we going to have then?

When you call a function or a method from an interface you sometimes need to supply arguments….

viewport.setRegionRect()
-- Argument count error: SetRegionRect wanted 2, got 0

In this case a simple built-in maxscript function for setting the viewport region rendering rectangle requires two arguments but we haven’t given it any…. Looking in the help file we find..

viewport.setRegionRect <viewport index> <box2>

So it’s asking us for an index number (indexes are integers, whole numbers) and then a box2 value, which we’ll come back to another day, which for example could be

(Box2 0 0 100 100)

Defining a box 100 pixels wide and high originating in the 0,0 screen position, so to get our function to work we would need to do something like…

viewport.setRegionRect 1 (Box2 0 0 100 100)

And it’ll work…. But notice how important the brackets are in this case, it groups all the values associated with the creation of a box2 value together… otherwise max gets confused between which values are for which function….

viewport.setRegionRect 1 Box2 0 0 100 100
-- Argument count error: SetRegionRect wanted 2, got 6

In this case it’s not recognising which values to pass an an argument, if in doubt put brackets in.

However if we only gave it one argument…

viewport.setRegionRect 1
-- Argument count error: SetRegionRect wanted 2, got 1

We’d get our initial error again, but this time telling us it’s got 1 argument but wanted 2, Similarly if we gave it too many arguments (even with our box2 value in brackets)….

viewport.setRegionRect 1 (Box2 0 0 100 100) 3
-- Argument count error: SetRegionRect wanted 2, got 3

Again we get an error…. Notice that our arguments aren’t separated by commas, if you try this you’ll get the following error…

viewport.setRegionRect 1, (Box2 0 0 100 100)
-- Argument count error: SetRegionRect wanted 2, got 1
-- Syntax error: at ),, expected <factor>
-- In line: viewport.setRegionRect 1, (

Which is basically complaining that our formatting is incorrect…. If we gave it an incorrect value type….

viewport.setRegionRect 1 100
-- Unable to convert: 100 to type: Box2

Then it doesn’t know how to change the value 100 to a box2 type value…  Similarly if we tried to pass it a variable that was undefined we’d get the following error…

viewport.setRegionRect 1 thebox
— Unable to convert: undefined to type: Box2

Where is the do?

for o in theObjs o.renderable = true
-- Error occurred in anonymous codeblock; filename: ; position: 483; line: 33
 -- Syntax error: at ), expected "do" or "collect"
 -- In line: )

In this case we’ve simply missed out a do…. or a collect (Which I haven’t covered yet..)

for o in theObjs do o.renderable = true

If you are using ‘collect’ then you don’t need a ‘do’ as well or you’ll get the following error, but I’ll come back to this later in my ramblings.

myObjs = for o in geometry where o.name == "Sphere" do collect o
-- Syntax error: at collect, expected <factor>
-- In line: myObjs = for o in geometry where o.name == "Sphere" do collect o

So the following will work

myObjs = for o in geometry where o.name == "Sphere" collect o
Advertisements

About davewortley

Somewhere between an artist and a programmer, I like technical things, but being creative. I love problem solving and coming up with elaborate solutions. This blog is where I shall share ideas, tips, tutorials and anything that amuses me.
This entry was posted in 3dsmax, Lessons and tagged , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s