devxlogo

Programming Second Life with the Linden Scripting Language

Programming Second Life with the Linden Scripting Language

econd Life (SL) is an extremely popular, massively-multiplayer online game (MMOG) produced by Linden Labs. Many consider Second Life to be much more than a game. If you’re unfamiliar with Second Life, it’s a little like the movie “The Matrix,” in which people live and work in a simulation of the world around them. Second Life is very similar; your computer player, called an avatar, lives in Second Life’s 3D world.

There is no specific objective to Second Life, what happens there depends entirely on what you want to make of it. Additionally, Second Life is free to play. You do have to register, but you only have to subscribe if you want to own land.

However, unlike “The Matrix,” current computer technology is not advanced enough to comprehensively simulate a physical world, so Second Life has two important shortcomings. First, you see the world of Second Life through a computer screen, which?even though it uses state-of-the-art 3D graphics?gives the simulation a somewhat cartoonish look. Despite that, many areas in Second Life are visually stunning.

Second, the simulation of Second Life is not a complete physical simulation. Important elements, such as gravity, are present. However, you could not completely simulate something as complex as an automobile in Second Life, it’s simply still too difficult to simulate all the aspects of the internal combustion engine and electrical components of a car. Modern computers are just not powerful enough to do this. Still, there are cars and many other sorts of vehicles in Second Life, as you’ll see in this article.

You access Second Life through a free client that’s available for a wide variety of OSs, including Windows, Macintosh, and UNIX. Additionally, Linden Labs recently released the client as open source, which opens Second Life for third-party developers to create a wide range of additions to and enhancements for the Second Life client.

Introducing Linden Scripting Language
Second Life provides a scripting programming language called the Linden Scripting Language (LSL) to fill in the gaps left by Second Life’s simple physics engine. Rather than simulate every aspect of a car, a programmer creates a script that tells the car how it should move. This script can play sounds, turn the car, and even detect collisions. For example, to add realism, a car script could prevent the car from turning when not in motion.

This article provides an introduction to LSL. For the greatest benefit, I recommend that you have a basic knowledge of “building,” but that’s not required to understand the article code. Building is the process by which you place 3D primitives into the Second Life world. Builders have created everything that you see in Second Life.

This article assumes you are already somewhat familiar with the building process in Second Life. It is not terribly difficult to build simple objects in Second Life, but you do have to be “in” Second Life to build things. To try it out, simply click the “Build” button at the bottom of your Second Life window and begin experimenting.

LSL Basics
The Linden Scripting Language looks much like C at first glance. However, it is much easier to program than C. There are no pointers and you can do direct string comparisons without using functions such as strcmp. LSL is not object-oriented; you cannot create your own objects, and the language provides only a few 3D-related objects for you. LSL is state based. Every LSL script has a specific state and carries out its functions by moving through a series of states. This is quite a different concept from most programming languages. While you can build state machines in most languages, in LSL the concept of a state machine is inherently part of the language.

LSL scripts reside inside 3D primitives in Second Life. Objects are collections of primitives. For example, a car in Second Life would be a single object. However, the car object would be made up of many primitives, each of which may contain its own script. Additionally, these primitives can communicate with each other or even with human players. With more advanced programming primitives can even communicate with web pages external to SL.

LSL is also event driven. Most objects in Second Life work by progressing through states driven by events. Second Life provides many different event types. Most are user-based, such as when a user touches or sits on an object; however, it also supports timer events that require no user interaction.

In the rest of this article, I’ll show you how to activate an elevator in Second Life.

Building a Simple Elevator
As an example, this article shows how to create an elevator that can move up and down in a skyscraper in Second Life. Figure 1 shows the skyscraper to which this elevator is attached.

 
Figure 1. A Skyscraper in Second Life: Here’s the skyscraper to which the elevator described in this article is attached.

You can see this elevator in action live in the game in the “Gyeonu” region at an X location of 51 and a Y location of 79. Second Life uses special URL’s called “SLURLs.” You can visit the elevator directly if you’ve installed the SL client. If the SLURL link doesn’t work for you, click the map button in the SL client, search for “Gyeonu”, and then type the coordinates 95, 23, and 44 into the coordinate fields.

Following the link takes you to a web site that displays an overhead map of the area where the elevator is. If you have Second Life installed, you can choose “Teleport Now” to teleport to that location. The elevator allows you to travel to all of the floors of the skyscraper, as well as the roof. To use the elevator, you simply “sit on it,” which is one of the built-in actions that appears on a popup menu when you right-click an object in the game. The elevator popup menu lets you choose where the elevator should go. You’ll also find there’s a green cone on each floor of the skyscraper that lets you call the elevator to that floor.

Two scripts control the elevator. The first script, Elevator.lsl causes the elevator to actually move and interact with avatars (see Listing 1). The script in Listing 2 (CallElevator.lsl) applies to the green elevator call cones on each floor of the skyscraper. It communicates with the main elevator script and summons the elevator car. Although the listings (and the downloadable code) contain the full scripts, I’ll walk you through the main elevator script so you can see how it responds to a sit event and how it displays a menu.

Configuring the Elevator and Setup
You will notice some “constants” near the top of the elevator script:

   integer CHANNEL = 42; // dialog channel   list MENU_MAIN = ["Floor 1", "Floor 2", "Floor 3", "Floor 4", "Floor 5", "Floor 6", "Floor 7"]; // the main menu      float BOTTOM = 27.300;   float FLOOR_HEIGHT = 10;   float SPEED = 1;

LSL does not actually support constants so these are really only “logical” constants. The values shown fit the skyscraper, but you could modify these constants to configure the elevator for your own building.

The CHANNEL defines what channel the elevator car uses to communicate with the elevator call cones. MAIN_MENU defines the buttons for each floor. Note that this is also how you define how many floors the elevator will visit. BOTTOM is the z-coordinate of the ground floor of your building. SPEED is the speed at which the elevator moves.

To setup the elevator the state_entry event is fired. This event is fired whenever a state is entered. As you can see from Listing 1 (or the code below), the state_entry is placed in the default state. Since the default state is the first state that a LSL script starts in, this event runs when the elevator starts up. The system fires a state_entry event whenever an object enters a new state. Because all objects start up in the “default” state the state_entry event for the default state always fires first when the program starts. Here’s the event code:

   state_entry()   {      // listen for dialog answers (from multiple users)      llListen(CHANNEL, "", NULL_KEY, "");       llSitTarget(<0,-0.5,0.5>, llEuler2Rot(<0,0,-90>) );      llSetText("Sit Here to Ride Elevator",<0,0,0>,1.0);      target = BOTTOM;   }

The llListen command tells the script to begin listening on the specified channel, causing the script to begin receiving events when a user calls the elevator. The llSitTarget event allows an object to say, in x, y, z coordinates, where a user should sit on the object. The first vector <0,-0.5,0.5> specifies a position relative to the center of the elevator car. The second vector <0,0,-90> specifies how to rotate the user’s avatar relative to the object. This will rotate the avatar -90 degrees on the z axis. The z-axis is the axis that goes up and down. Therefore rotating on the Z axis causes the avatar to change the direction they are facing, yet keep their feet on the ground. Think of the z-axis as an imaginary like drawn from above your head to below your feet. Additionally, calling llSitTarget allows the object to receive events when users sit on the object.

The llSetText method causes an object to display instructional text above it?in this case, letting users know that they should sit on the elevator to ride it. Finally, the script initializes the elevator’s target z-coordinate (stored in the target variable) to BOTTOM?the ground floor.

Displaying a Menu
When a user sits on the elevator, Second Life sends a changed event to the elevator script. Here’s the event handler code:

 
Figure 2. Elevator Ride: The figure shows my avatar at the base of the skyscraper waiting for the elevator to start.
   changed(integer Change)    {     llDialog(llAvatarOnSitTarget(), "Where to?",         MENU_MAIN, CHANNEL);   }

The llDialog method displays a simple menu to the user. You can see this menu in Figure 2, which shows my in-game character “Encog Dod” waiting for the elevator to start.

When the user selects a floor, the listen event will fire, as shown below:

   listen(integer channel, string name, key id, string message)    {     integer idx = llListFindList(MENU_MAIN, [message]);     if( idx!=-1 )     {       llSay(0,"Elevator heading to " + message + "." );       target = BOTTOM + (idx*10);       state moving;     }    } 

When the listen event fires, the message event parameter will contain the menu-item text that the user selected. The listen event first determines the index of the selected item in the MAIN_MENU array, setting the integer variable idx to the zero-based index of the floor the user selected. The elevator then reports that it is heading to that floor and sets the target variable. Finally, it changes the state to moving.

It is possible that more than one avatar might sit on the elevator at once. In this case, Second Life presents all the avatars with a popup to choose a destination floor. The elevator does not “queue” floors like a real elevator would; instead, whichever avatar is the last to select a floor dictates where the elevator goes. However, all avatars will share the ride.

Moving Objects
There are two ways to move an object in Second Life. You can move objects physically, using thrust, or directly, using x, y, z coordinates. Moving objects directly is somewhat easier than moving them physically, so I’ll focus on direct coordinate-based movement here. Fortunately, that’s rather simple for an elevator because it moves in only one dimension: up and down. As you’d expect, in Second Life, that’s the z-coordinate.

When the elevator enters the moving state, the elevator will begin moving. The moving state begins when its state_entry event fires.

   state moving   {      state_entry()      {         llSetTimerEvent(0.1);      }   ...

The state_entry event registers a timer that “ticks” ten times per second. Each tick causes the timer event to fire. The code in the timer event causes the elevator to move. The timer begins by getting the current position of the elevator as follows.

   timer()   {      vector pos = llGetPos();      ... 

If the z-coordinate is not at the desired target then the script moves the elevator either up or down towards the target. The SPEED constant controls how fast the elevator will reach its target.

      if( pos.z!=target )      {         if( pos.z>target )         {            pos.z = pos.z - SPEED;         }         else         {            pos.z = pos.z + SPEED;         }      }

This continues with each timer tick until the position check determines that the elevator is very close to the target?less than the distance covered by the SPEED constant. In that case, the script moves the elevator exactly to the target, stops the timer, notifies the user, and returns the elevator state to the default state.

      if(  llFabs(pos.z - target) < SPEED )      {         pos.z = target;         llSetTimerEvent(0);         llSetPos(pos);         llSay(0,"Elevator has reached its target." );         state default;      }   

Otherwise, the elevator is not close to its target and must continue moving, so the timer script moves the elevator to the new calculated position.

      llSetPos(pos);

In addition to being controlled by users sitting on the elevator, the elevator can also be called to a specific floor by one of the green elevator-call cones in the skyscraper, which requires communication between objects.

Communicating Between Objects
Objects in Second Life communicate with each other in almost exactly the same way that avatars in Second Life communicate. Avatars can "say" something that will be heard by nearby avatars; they can also shout something for greater distance. Everything said in Second Life uses a specific channel. Avatars normally speak on channel zero. If an object were to listen on channel zero it would hear nearby users speaking! Similarly, if an object speaks on channel zero, nearby users will hear it speak.

On each floor of the skyscraper there is a green cone that will call the elevator. The cones are very simple. They simply call the elevator by transmitting which floor the elevator has been called to. This is done in exactly the same manner as the elevator's menu.

Each of the floor cones contains a touch_start event, fired whenever a user touches the cone. Here's the touch_start event for the first floor cone.

   touch_start(integer total_number)   {     llShout(CHANNEL, "Floor 1");   }

Note that the script shouts the message. This gives it greater distance than the llSay method, which is necessary because the skyscraper may be very tall. The elevator will pick up this communication with its listen event and begin traveling to the specified floor.

In this article you saw how to create an elevator in Second Life. This is only the beginning. There are many methods in the LSL library to allow you to create an almost endless array of in-game objects. You can create objects to perform commerce and sell other objects. You can create weapons for games within Second Life. Your objects can even interact with external web servers, letting you use external resources in your scripts.

If you are interested in learning more about LSL, Linden Labs maintains a Wiki about LSL programming where you can find more information.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist