skimi3d Grid Log in Visit the grid
All scripts
Light a place

Light Switch

A lamp you can switch. One touch lights the room, makes the shade glow and turns it bright, so it looks lit rather than merely useful.

Goes inThe lamp itself
Setup11 to set
Code146 lines
Open toOpen to everyone

What it does

It does three things in a single write: casts a light, adds a little glow to the face you choose, and makes that face ignore the region's own light so it stays bright at midnight. All three together are what reads as a lamp being on. Sent as one change rather than three, the lamp simply comes on instead of flickering through the middle steps, which is what happens when a script sets them one after another.

What you can build with it

Table lamps, street lights you can switch off, a lantern by a door, a neon sign, the light over a workbench, a torch on a wall. Set WHO_MAY_SWITCH to 2 and it becomes a light only your group can turn off, which is the usual arrangement in a shared build.

How to use it

1 Drop this script into the lamp. Touch it: it should light up.
2 Set COLOUR for the kind of bulb. Warm is the default; white is <1.0, 1.0, 1.0>, moonlight is <0.6, 0.75, 1.0>.
3 Set RADIUS for how far the light reaches, up to 20 metres, and INTENSITY for how bright.
4 If only the glass of your lamp should light up and not the metal, put that face's number into FACE instead of -1.
5 If you want a click, drop a sound into the lamp's Contents and write its name into SOUND.

Settings you can change

11

Edit these at the top of the script. Everything works on the defaults · change them only when you need to.

COLOUR The colour of the light it casts. Warm bulb by default; white is 1,1,1 and moonlight is about 0.6, 0.75, 1.0. <1.0, 0.85, 0.6>
INTENSITY How bright the cast light is, from 0.0 to 1.0. 0.7
RADIUS How far the light reaches, in metres. The most a viewer will honour is 20. 8.0
FALLOFF How quickly it fades with distance, from 0.0 to 1.0. Higher fades faster and keeps the light close to the lamp. 0.6
FACE Which face is the shade or the bulb, the part that should look lit. -1 means every face; give a single face number if the glass should light up and the metal should not. -1
GLOW How much the lit face glows, from 0.0 to 1.0. A little goes a long way: 0.15 reads as lit, 0.5 reads as a fault. 0.15
FULLBRIGHT Make the lit face ignore the region's own light so it stays bright at midnight. This is what sells a lamp as switched on. TRUE
START_ON Whether it is already lit when it is rezzed. TRUE
WHO_MAY_SWITCH 0 for everyone, 1 for the owner alone, 2 for anyone wearing the same group tag. 0
SOUND Name of a sound in the lamp's Contents, played on each click. Empty for a silent switch. (empty)
VOLUME How loud that click is, from 0.0 to 1.0. 0.4
The code LSL · 146 lines · updated 8 Sep 2026 Download .lsl
// =====================================================================
//  Light Switch
//  skimi3d script library
//  https://grid.skimi3d.com/scripts/light-switch
//
//  A lamp you can switch. Touch it and it lights the room, glows, and
//  turns its own shade bright so it looks lit rather than merely
//  illuminating; touch it again and all three go out together.
//
//  The three parts matter. A light with no glow is a room that brightens
//  around a dark lamp. Glow with no light is a lamp that shines on
//  nothing. Doing them separately is how most lamps end up looking
//  wrong.
//
//  Plain LSL.
// =====================================================================


// ---------------------------------------------------------------------
//  Settings
// ---------------------------------------------------------------------

// The colour of the light it casts. <1.0, 0.85, 0.6> is a warm bulb,
// <1.0, 1.0, 1.0> is white, <0.6, 0.75, 1.0> is moonlight.
vector COLOUR = <1.0, 0.85, 0.6>;

// How bright, from 0.0 to 1.0.
float INTENSITY = 0.7;

// How far the light reaches, in metres. Up to 20.
float RADIUS = 8.0;

// How quickly it fades with distance, from 0.0 to 1.0. Higher fades
// faster and keeps the light close to the lamp.
float FALLOFF = 0.6;

// Which face of the prim is the shade or the bulb, the part that should
// look lit. -1 means every face. Use the number of a single face if
// only the glass should light up and the metal should not.
integer FACE = -1;

// How much the lit face glows, from 0.0 to 1.0. A little goes a long
// way; 0.15 reads as lit, 0.5 reads as a fault.
float GLOW = 0.15;

// Make the lit face ignore the region's own light, so it stays bright
// at midnight. This is what sells a lamp as switched on.
integer FULLBRIGHT = TRUE;

// Is it already on when it is rezzed?
integer START_ON = TRUE;

// Who may switch it. 0 = everyone, 1 = only the owner, 2 = only people
// wearing the same group tag.
integer WHO_MAY_SWITCH = 0;

// Name of a sound in the lamp's Contents, played on each click. Leave
// empty for a silent switch.
string SOUND = "";
float  VOLUME = 0.4;


// ---------------------------------------------------------------------
//  Everything below here is the machinery
// ---------------------------------------------------------------------

integer gOn = FALSE;


// One write, not three.
//
// OpenSim gathers object updates and sends them in bundles. Setting the
// light, then the glow, then the brightness in three calls can reach a
// viewer as three separate flickers. Sent together they arrive as one
// change, and the lamp simply comes on.
switchTo(integer on)
{
    float glow = 0.0;
    integer bright = FALSE;

    if (on)
    {
        glow = GLOW;
        bright = FULLBRIGHT;
    }

    list p = [PRIM_POINT_LIGHT, on, COLOUR, INTENSITY, RADIUS, FALLOFF,
              PRIM_GLOW, FACE, glow];

    // PRIM_FULLBRIGHT wants a plain on or off, and only when the lamp
    // is meant to use it at all. A lamp with FULLBRIGHT switched off in
    // the settings should never have its faces touched.
    if (FULLBRIGHT) p += [PRIM_FULLBRIGHT, FACE, bright];

    llSetLinkPrimitiveParamsFast(LINK_THIS, p);

    gOn = on;
}


integer maySwitch(key who)
{
    if (WHO_MAY_SWITCH == 1) return who == llGetOwner();
    if (WHO_MAY_SWITCH == 2) return llSameGroup(who);
    return TRUE;
}


default
{
    state_entry()
    {
        switchTo(START_ON);
    }

    touch_start(integer total)
    {
        key who = llDetectedKey(0);
        if (!maySwitch(who))
        {
            llRegionSayTo(who, 0, "This one is not yours to switch.");
            return;
        }

        if (SOUND != "")
        {
            if (llGetInventoryType(SOUND) == INVENTORY_SOUND)
            {
                llPlaySound(SOUND, VOLUME);
            }
            else
            {
                llOwnerSay("There is no sound called \"" + SOUND + "\" in my Contents.");
            }
        }

        switchTo(!gOn);
    }

    on_rez(integer start)
    {
        // A rezzed copy carries the light state it was taken in, which
        // may not be the one the settings ask for. Say it again.
        switchTo(START_ON);
    }
}

Copy it, make a new script inworld, paste over what is there and save. Nothing here phones home.