The content on this site is my own and does not necessarily represent my employer’s positions, strategies or opinions.


Recent Tweets


Creative Commons License


This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License, unless otherwise specified.

Scripting a Phantom Door

So far we’ve created a one-prim sliding door and a two-prim swinging door. The scripts associated with these can be used in many ways. A door might slide up and sideways instead of just left or right. You could build a castle door and bridge over a moat by having a heavy wooden door swing down over a gap, pivoting on a “hinge” at the base of the door.

The basic door on which we will work

In this section we’re going to work with the door pictured on the right. It’s a simple 2m wide and 4m high door that has a purchased door texture on it. For a bit of extra detail, I also made a round doorknob and linked it to the door itself.

If there were no door and just a door opening, everyone would be free just to walk through that. It doesn’t give much privacy, but it allows passage through what would otherwise be a solid wall. If you do want a door but don’t want the trouble of having it slide or swing out of the way, the simplest approach would just to make it into a phantom object.

A phantom object looks like any other object except that it doesn’t collide with other objects or avatars. That is, if you walk into a phantom object you won’t crash into or bounce off it. Rather, you’ll just pass right through it as if you (or it) were a ghost.

Standing in a phantom door

The picture on the right shows me standing in the middle of the door. If the door were not phantom, I couldn’t do this, and I would have to be on one side of the door or the other. When prims are linked together, either they all are phantom or none are. That is, you cannot have just one prim being phantom and linked to others that are not.

The dialog box showing th phantom box checked

While building, you turn the phantom property on and off via a checkbox on the Object tab of the Edit dialog box. See the picture on the right.

When I am constructing a building, I sometimes temporarily make a wall or a roof phantom so that I can easily get inside or outside. Then, once I have have added doors, I’ll go back and remove the phantom status, for security. Since people won’t know if an object is phantom unless they try to pass through it, you can keep certain walls or wall sections phantom so you can “disappear” through them whenever you want to!

It’s very common to make landscape objects like trees phantom so that people can walk or fly through them without getting tangled up in the branches.

If you just want to have a visible door that you can walk through, we’re done. Just check the phantom box and you can pass right through.

We can do more, though. How could we accomplish the following?

  • Have the door normally be solid, but toggle phantomness on and off by clicking the door.
  • Give some sort of clue that the door is phantom.
  • Only allow the owner of the door to turn the phantom property on and off.
  • Only allow members of the group to which the door object is assigned to turn the phantom property on and off.
  • Allow named avatars to turn the phantom property on and off.
  • Have the door automatically go phantom for certain people, and then return to a solid state after a set period of time.

There are a lot of other options and combinations possible. I’ll tackle the first two tasks here and then turn to authorization in the next section. Let’s start with the first job of controlling phantomness.

The function we will use to control whether the door is phantom or solid is llSetStatus together with the STATUS_PHANTOM flag. When we set the phantom status to true, the door becomes phantom, as you might expect. When we set it to false, the door becomes solid.

This script handles turning the phantom property on and off.

// Phantom door LSL script #1
// Handles the touch event.

// Processing for the script when it first starts up

default {
    // What we do when we first enter this state

    state_entry() {
        state closed;                       // Move to the closed state
    }
}

// Processing for the script when it is in the closed state

state closed {
    // What we do when we first enter this state

    state_entry() {
        llSetStatus(STATUS_PHANTOM,FALSE);  // Turn off phantom property
    }

    // What we do when the door is clicked ("touched") with the mouse

    touch_start(integer total_number) {
        state open;                         // Move to the open state
    }
}

// Processing for the script when it is in the open state

state open {
    // What we do when we first enter this state

    state_entry() {
        llSetStatus(STATUS_PHANTOM,TRUE);   // Turn on phantom property
    }

    // What we do when the door is clicked ("touched") with the mouse

    touch_start(integer total_number) {
        state closed;                       // Move to the closed state
    }
}

When the script starts, we move into the “closed” state, which here means that the door is solid, not phantom. When the closed state begins, we set the phantom status of the door to false via

        llSetStatus(STATUS_PHANTOM,FALSE);  // Turn off phantom property

When the closed solid door is touched, that is, clicked with the mouse, we move to the “open” state. When the open state begins, we set the phantom status of the door to true via

        llSetStatus(STATUS_PHANTOM,TRUE);   // Turn on phantom property

If the open phantom door is clicked, we move to the closed solid state. And so on and so on.

This is pretty much the most basic script on an object that toggles some behavior when the object is clicked. It is similar to the first sliding door script, but there we needed to save some extra information about the previous position of the door and know how much to move it. All the real action in this script takes place in the state_entry functions for the open and closed states.

The door showing partial transparency

It is in these functions where we could add some kind of state indicator to show whether the door is solid or phantom. One possibility is that we create a separate light over the door that is green when the door is phantom and red when solid. That’s a bit complicated at this point, so let’s go with a simpler plan.

At the beginning of this section I referred to the phantom property as being ghostly because avatars can just pass right through. How about we make the door partially transparent when it is phantom and then non-transparent when it is solid?

If we make the door completely transparent, people might not know that it is even there. If we don’t make it transparent enough, then they won’t be able to notice any real difference. What value of alpha will work for us? In this particular case, using 0.75 seems about right and that’s what is pictured to the right. For your particular door, you should experiment until you get something that works for your situation. Remember to look at it in different lighting conditions.

There’s a technical point I need to make here that you might want to skip on first reading. The alpha value applies to each side in each prim in your object. In a one-prim door, there are 6 sides: front, back, top, bottom, left side, and right side. If we link in more prims, we must deal with each of their sides as well. LSL makes it easy to set the alpha values for all the sides on all the prims at once. However, it makes no sense to ask for THE single alpha for an object, because there is one for each contained side. They might happen to be all the same, but in the general case they will be different.

In our example here I’m going to make a significant simplifying assumption: we can set the alpha value to 1.0 for every side in every linked prim when we want the door to be solid.

I’ll do this by changing the alpha value for the door. When this is set to 0.0, we have have complete transparency. When it is 1.0, we have no transparency other than what might be in the textures themselves.

Here is the version of our script that includes transparency:

// Phantom door LSL script #2
// Handles the touch event.
// Handles partial transparency when the door is in phantom mode.

// Processing for the script when it first starts up

float alpha = 0.75;                         // alpha value for partial transparency
                                            // of the door when in phantom mode.
                                            // 1.0 is solid, 0.0 is transparent.

default {
    // What we do when we first enter this state

    state_entry() {
        state closed;                       // Move to the closed state
    }
}

// Processing for the script when it is in the closed state

state closed {
    // What we do when we first enter this state

    state_entry() {
        llSetStatus(STATUS_PHANTOM,FALSE);  // Turn off phantom property

        llSetLinkAlpha(LINK_SET,            // Turn off transparency
          1.0, ALL_SIDES);
    }

    // What we do when the door is clicked ("touched") with the mouse

    touch_start(integer total_number) {
        state open;                         // Move to the open state
    }
}

// Processing for the script when it is in the open state

state open {
    // What we do when we first enter this state

    state_entry() {
        llSetStatus(STATUS_PHANTOM,TRUE);   // Turn on phantom property

        llSetLinkAlpha(LINK_SET,            // Turn on partial transparency
          alpha, ALL_SIDES);
    }

    // What we do when the door is clicked ("touched") with the mouse

    touch_start(integer total_number) {
        state closed;                       // Move to the closed state
    }
}

I put the declaration and definition of alpha at the top of the script so that it can be easily found and changed. When programming it’s important to do this and not embed magic numbers like “0.75″ somewhere in the code. They can be hard to find and change, especially if a lot of time goes by or someone other than the original author is trying to use the script.

float alpha = 0.75;                         // alpha value for partial transparency
                                            // of the door when in phantom mode.
                                            // 1.0 is solid, 0.0 is transparent.

When the door is closed, that is, solid, we turn off transparency using llSetLinkAlpha:

        llSetLinkAlpha(LINK_SET,            // Turn off transparency
          1.0, ALL_SIDES);

When the door is open, that is, phantom, we turn on partial transparency using our chosen alpha value:

        llSetLinkAlpha(LINK_SET,            // Turn on partial transparency
          alpha, ALL_SIDES);

This function call used two special LSL constants. LINK_SET means that the operation, here setting the alpha value, should be applied to every prim that is linked together into our door. This works even if there is only one prim. ALL_SIDES means that for each prim to which the operation is applied, all sides of the prim should be processed. It’s possible using llSetLinkAlpha to reach in and change the alpha value on one particular side of one particular prim linked into the object. We don’t need that here given my simplifying assumption above.


← Previous ↑ Up Next →