Linden Scripting Language
Tags: secondlife, java, c, games
Published: 2020-03-24 01:11:04

## Into the Metaverse

Way back in 2006 while watching TechTV I got my first glimpse at Second Life, the online social game that would take up huge chunks of my life from then on. At the time, and in a lot of ways even now, it was the coolest thing I had ever seen. This huge 3D world where everything was made by the users. The clothes you wear, the places you visit, and most importantly, the scripts that make everything run were all created by the people playing the game.

The scripting part in particular took my interest, and it's one of the primary reasons I started to learn coding. Making interactive creations, no matter how simple or silly they were, and watching them work was like magic. Now I just do it with mobile phones and browsers but the spark that created it all started off in Second Life.

It's for that reason I'm going to give you all a brief glimpse into the code that runs that digital world, LSL, or Linden Scripting Language. 

## What is LSL?
 
LSL is the language that all the scripts in Second Life run on. These sets of instructions can be put into any object you create inside of the game. It can be used to make all kinds of crazy things, from cars, guns, lights, doors, even games inside a game (meta, right?).

These scripts can be written and compiled in an in-game editor where they are executed by the game's servers. It's structure is largely based on Java and C but with an emphasis on states and events. But besides that it has many of the features you'd come to expect from a programming language: functions, flow-control with if and while statements, and operators.

If you want to script a door, it can have a state such as "open" or "closed", a lamp would have the states of "on" and "off", a digital firearm can be "loaded" or "empty", etc etc.

Events are the triggers in Second Life that fire off functions and change the state of an object. These event can be a variety of things, saying a certain string in the chatbox, clicking or bumping into an object, etc.

## Hello ~~World~~ Avatar

Here is the most basic script in LSL, a simple "Hello World" that fires off when the object is "rezzed", or loaded into the world, and a chat message of "touched" when a user clicks on the object.

```
default
{
    state_entry()
    {
        llSay(0, "Hello, Avatar!");
    }
 
    touch_start(integer total_number)
    {
        llSay(0, "Touched.");
    }
}
```

And here's a breakdown of whats happening on each line:

```
default // All Scripts need a Default State
 
{ // this open curly bracket denotes the start of the state
    state_entry() // an event
    {
        llSay(0, "Hello, Avatar!"); // a function inside the event's curly brackets
    } // closed curly bracket closes the state_entry event
 
    touch_start(integer total_number)  // another event inside default state
    {
        llSay(0, "Touched."); // a function between the brackets of the touch_start body
    } // end of touch start
} // Code end
```

And here's an example of script that turns an object from a white texture to black on click, something that could be useful for, say, a lamp or light fixture:

```
default //default state is mandatory
{
    state_entry() // runs each time the state is entered
    {
        llSay(0, "turning on!"); //object speaks!
        llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES); // sets no tint (white)
        // note the semicolons at the end of each instruction
        // (do not put them at the end of "if" statements)
    }
 
    touch_end(integer total_number) // another event with only one function inside
    {
        state off; // sets the script to a new "state" and starts running "state off"
    }
} // this curly bracket ends the body of the default state.
 
state off // a second state besides "default"
{
    state_entry() // this is run as soon as the state is entered
    {
        llSay(0, "turning off!");
        llSetColor(<0.0, 0.0, 0.0>, ALL_SIDES); // sets black tint
    }
 
    touch_end(integer total_number)
    {
        state default;
    }
}
```

Finally, here's something I created. This script takes an image consisting of each still frame of an animated gif and modifies it's positioning on each tick to create an animated texture in game, which I then tossed into a pair of sunglasses someone made to create this cool static effect on the lenses. 

<video autoplay src="https://i.gyazo.com/d15b9a92defeb1d6b0af2aaef89fc2a9.mp4">

```
 integer animOn = TRUE; //Set to FALSE and call initAnim() again to stop the animation.
  5 //Effect parameters: (can be put in list together, to make animation have all of said effects)
  6 //LOOP - loops the animation
  7 //SMOOTH - plays animation smoothly
  8 //REVERSE - plays animation in reverse
  9 //PING_PONG - plays animation in one direction, then cycles in the opposite direction
 10 list effects = [LOOP];
 11 //Movement parameters (choose one):
 12 //ROTATE - Rotates the texture
 13 //SCALE - Scales the texture
 14 //Set movement to 0 to slide animation in the X direction, without any special movement.
 15 integer movement = 0;
 16 integer face = ALL_SIDES; //Number representing the side to activate the animation on.
 17 integer sideX = 1; //Represents how many horizontal images (frames) are contained in your texture.
 18 integer sideY = 1; //Same as sideX, except represents vertical images (frames).
 19 float start = 0.0; //Frame to start animation on. (0 to start at the first frame of the texture)
 20 float length = 0.0; //Number of frames to animate, set to 0 to animate all frames.
 21 float speed = 10.0; //Frames per second to play.
 22 initAnim() //Call this when you want to change something in the texture animation.
 23 {
 24     if(animOn)
 25     {
 26         integer effectBits;
 27         integer i;
 28         for(i = 0; i < llGetListLength(effects); i++)
 29         {
 30             effectBits = (effectBits | llList2Integer(effects,i));
 31         }
 32         integer params = (effectBits|movement);
 33         llSetTextureAnim(ANIM_ON|params,face,sideX,sideY,     start,length,speed);
 34     }
 35     else
 36     {
 37         llSetTextureAnim(0,face,sideX,sideY, start,length,speed);
 38     }
 39 }
 40 
 41 fetch()
 42 {
 43      string texture = llGetInventoryName(INVENTORY_TEXTURE,0);
 44             llSetTexture(texture,face);
 45             list data  = llParseString2List(texture,[";"],[]);
 46             llOwnerSay( llDumpList2String(data ,","));
 47             string X = llList2String(data,1);
 48             string Y = llList2String(data,2);
 49             string Z = llList2String(data,3);
 50             
 51             // llOwnerSay("X=" + X + " Y=" + Y + " Z = " + (string) Z);
 52             
 53             sideX = (integer) X;
 54             sideY = (integer) Y;
 55             speed = (float) Z;
 56             if(speed) 
 57                 initAnim();
 58 }
 59 
 60 default
 61 {
 62     state_entry()
 63     {
 64         llSetTextureAnim(FALSE, face, 0, 0, 0.0, 0.0, 1.0); // V2 - remove all anims
 65         fetch();
 66     }
 67     changed(integer what)
 68     {
 69         if(what & CHANGED_INVENTORY)
 70         {
 71             fetch();
 72         }
 73     }
 74 }
```

And this is, obviously, just the tip of the iceberg of what you can do with LSL. Better coders than I have made some truly amazing things in the game. If you'd like to know more about LSL check out the SL [wiki](http://wiki.secondlife.com/wiki/LSL_Portal) and maybe even download the game and give it a shot (just, uh, avoid the adult sims).