Comments on Comments …

Just for fun and because it’s 5:46 AM Sunday, I want to write about some advice I found in the LSL Scripting Guide. I found the guide itself by searching Google for “Linden Scripting Language Guide”. You get a downloadable HTML page and can save it to your computer. If there is a version that just displays from the web, I couldn’t find it.

The guide offers the following as an example of a well-commented program:

// This script toggles a the rotation of an object

// g_is_rotating stores the current state of the rotation. TRUE is
// rotating, FALSE otherwise.
integer g_is_rotating = FALSE;
default
{
    // toggle state during the touch handler
    touch(integer num)
    {
        if(g_is_rotating)
        {
            // turn off rotation
            llTargetOmega(<0,0,1>, 0, 0);
            g_is_rotating = FALSE;
        }
        else
        {
            // rotate around the positive z axis - up.
            llTargetOmega(<0,0,1>, 4, 1);
            g_is_rotating = TRUE;
        }
    }
}

Can we talk about this? Thanks.

I really don’t think this is a wonderful program at all. We can begin with the very first comment: “This script toggles a the rotation of an object”. Surely this is the most important comment in the script: it tells us what the script does. Yet the comment contains a typo: “a the”. I’m not concerned that this is tacky in published work–if I said that I’d wind up with a typo rihgt here. My point is that comments can lie. You can put anything at all in a comment and it doesn’t have to be true, doesn’t have to reflect the real code.

OK, fine. She’s a nitpicker. Great. Anyway, what does the script do, according to this comment? Why, that’s perfectly obvious: it toggles the rotation. You know, toggles. The rotation. It toggles it.

What the script does is this: when you touch the object, if it it rotating, it stops rotating. If it it not rotating, it starts. Toggles, you see.

Enough complaining, Janet. What’s your plan?

My plan is to rewrite this program to be more clear, so that it may need fewer comments. Your job is to read along, see what I do, and decide whether similar things would be useful to you in your scripts. I’ll leave comments open in case you care to, well, comment. Here I am, with a red cube I made to test the script as I go:

Rotating Cube
Rotating Cube

All right then. I touch the cube, and it starts to rotate. Touch again, it stops. Sort of. It doesn’t really work very well. It seems not to “toggle” reliably. Looking at the script, we can see why: it uses the touch() event. The touch event repeats as long as you hold down the mouse button. Which means this thing toggles repeatedly. You have to click it very quickly to be sure of getting just one touch() event. It should use touch_start(). It’s outside my plan to fix the darn script but here again is something about good commenting: it doesn’t make for a good program. I’ll fix it. The next time I show the script, you’ll see touch_start() in there. Works much better that way.

The first comment I’ll work on is the one that says “toggle state during the touch handler”. In my opinion, since the code is inside the touch handler, that part of it is redundant. I’ll “express intention” by extracting a function with an arguably useful name. I’m not committed to this name yet:

// This script toggles a the rotation of an object

toggleRotation() {
    if(g_is_rotating)
    {
        // turn off rotation
        llTargetOmega(<0,0,1>, 0, 0);
        g_is_rotating = FALSE;
    }
    else
    {
        // rotate around the positive z axis - up.
        llTargetOmega(<0,0,1>, 4, 1);
        g_is_rotating = TRUE;
    }
}

// g_is_rotating stores the current state of the rotation. TRUE is
// rotating, FALSE otherwise.

integer g_is_rotating = FALSE;

default
{
    touch_start(integer num)
    {
        toggleRotation();
    }
}

OK. I think that’s better. Looking around I notice that comment on g_is_rotating. Frankly I don’t think that’s helping. The comment says what the code says “is_rotating = TRUE is rotating”. I would just delete that comment and go from there:

// This script toggles a the rotation of an object

toggleRotation() {
    if(g_is_rotating)
    {
        // turn off rotation
        llTargetOmega(<0,0,1>, 0, 0);
        g_is_rotating = FALSE;
    }
    else
    {
        // rotate around the positive z axis - up.
        llTargetOmega(<0,0,1>, 4, 1);
        g_is_rotating = TRUE;
    }
}

integer g_is_rotating = FALSE;

default
{
    touch_start(integer num)
    {
        toggleRotation();
    }
}

Moving right along, what’s next? We could get rid of the two comments inside the if statement. Let’s try that:

// This script toggles a the rotation of an object

startRotation() {
    llTargetOmega(<0, 4, 1>);
    g_is_rotating = TRUE;
}

stopRotation() {
    llTargetOmega(<0, 0, 0>);
    g_is_rotating = FALSE;
}

toggleRotation() {
    if(g_is_rotating) {
        stopRotation();
    } else {
        startRotation();
    }
}

integer g_is_rotating = FALSE;

default {
    touch_start(integer num) {
        toggleRotation();
    }
}

Now I have given up some information here: the original comment for starting rotation referred to z axis up. That wasn’t entirely clear; I think what the author meant that rotation was around the z-axis, namely the up axis. Anyway I gave that up. Let’s put it back, this time in the code:

startRotation() {
    vector zAxis = <0, 0, 1>;
    llTargetOmega(zAxis, 4, 1);
    g_is_rotating = TRUE;
}

OK. I think that’s just about enough for now. In the course of doing this, however, I’ve noticed a few things that the program author seems to have missed. In particular, in what’s below, notice how the program stops the rotation. Here’s my final draft of the program:

// This script toggles a the rotation of an object

startRotation() {
    vector zAxis = <0,0,1>;
    llTargetOmega(zAxis, 4, 1);
    g_is_rotating = TRUE;
}

stopRotation() {
    llTargetOmega(<0,0,1>, 0, 0);
    g_is_rotating = FALSE;
}

toggleRotation() {
    if(g_is_rotating) {
        stopRotation();
    } else {
        startRotation();
    }
}

integer g_is_rotating = FALSE;

default {
    touch_start(integer num) {
        toggleRotation();
    }
}

What have we noticed?

I mentioned the stopRotation(). I would have to look it up, but I notice that it’s using a non-zero vector, and the other parameters are zero. According to the docs, that should work but it might be better to use ZERO_VECTOR there to make it clear what is going on. I have also read that a non-zero gain will cause the object to “try to stop all spin”, so I always use that. No matter … the function name makes clear what we’re trying to do, and if we learn a better way, we’ll use it there.

As always, once we have this function, we can–and should–use it whenever we want to stop rotation in this script as it grows. Then, if we do learn a better way, we’ll only have to fix it in one place, and meanwhile the code will be more clear.

I also noticed something else. What will the object do if, while it is rotating, you edit and save the script? It’s not obvious, is it. Well, I tried it, and what happens is that the object keeps rotating after the save. However, the script save causes the g_is_rotating variable to be reset to FALSE, so the script thinks that it is NOT rotating. So the first click sets it to rotating, which it already is. Then the second click stops it. So the object doesn’t toggle quite as you might expect.

Now why did I notice that? It might be that I’m a nitpicker. But my story is that in trying to make the code as clear as possible, I focused my attention on it, and in so doing, noticed more about the script than I would otherwise have done. On a small sample script, this may not matter. On a large complex script, every chance we get to understand it better is valuable, because somewhere in there, we may have a subtle mistake like that one.

Conclusion?

No real conclusion. The idea is to show you how I was taught to write programs, with few comments and with code as clear as I can make it. This was just a short exercise in doing that, and you can probably see things you’d do differently. I can see things I would do if I were going to do more. As always, we have to decide how much we want to put into things, and this is enough for now.

Thanks for reading! Comments are on for now.

3 thoughts on “Comments on Comments …

Add yours

  1. mmmmm now that’s some good coding! You have a talent for taming the wild spaghetti that goes beyond mere training and borders on intense satisfaction. In the Venn diagram of you, and the unruly world of (supposedly) coding standards of SL lies an intersection of clarity, and efficiency that LL would do well to emulate. Alas, that is as unlikely to happen as [insert extremely improbable event here].

  2. Thanks for the kind words, Testosterose.

    Talent may have something to do with taming the spaghetti, and I do enjoy it. Mostly, though, it comes from practice.

    I’ve had good teachers, I try, and I try, and I try. The result is scripts that look odd but that are–I believe–easier to understand and change than most.

    I find that valuable in my work, and I hope that other people will see the potential, practice a bit, and find value in their own.

    Unlikely? Perhaps, even probably. That’s OK too. I’m in SL to find joy and it brings me joy to do these small things well.

    Thanks!

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: