devxlogo

A Speed Guide to Virtual Driving in Second Life

A Speed Guide to Virtual Driving in Second Life

n Second Life (SL) users can fly nearly anywhere in superhero style. They can also teleport from one place to another in seconds—without any assistance from any sort of device. These capabilities make travel in Second Life easy; avatars have no need for vehicles. Flying and teleporting are inherent abilities that all Second Life users possess.

Curiously, despite being completely unnecessary, vehicles are still very popular in Second Life. Many SL stores offer a wide array of cars, helicopters, boats, planes, and many other types of vehicles. Several real-world carmakers also create SL versions of their vehicles, adding promotion through SL to their marketing arsenals. Figure 1 shows several cars in Second Life.

 
Figure 1: Cars in Second Life: Despite being unnecessary for travel, vehicles of all types are still popular in Second Life.

But unlike real-world vehicles, you aren’t limited to the offerings of vehicle manufacturers; with a little effort, you can create your own. This article demonstrates how to create a basic car in Second Life.

Constructing the Car Body

 
Figure 2: The Car Example: Although it may not be pretty, this wagon-like car uses the same basic script as a more attractive vehicle.

Car bodies can become very complex in Second Life. To make SL cars appear as realistic as possible, designers typically use an array of prims (primitive shapes) to create complex shapes. While you’re free to do the same, the purpose of this article is not to explain how to build a realistic—or even an aesthetic—car. Instead, the purpose of this article is to explain how to script a car—writing the code that makes it work. You’ll see how to create a reusable car script that you can use as the basis for other SL land-vehicle projects.

Therefore, the car that you’ll create in this article has a very simple wagon as its body (see Figure 2).

Building the car example is very simple—all you need is a hollow box, four wheels, and a seat. Despite its simple construction, a few elements are necessary for the car to function properly.

The Root Prim
The root prim is very important. Most objects in SL are made up of many prim objects. Even complex objects such as cars are simply a collection of prims. However, not all prims are created equal. The last prim to be added to the car becomes the root prim. For vehicles, the root prim is particularly important because:

  • The vehicle script resides in the root prim.
  • All vehicle motion is relative to the root prim.
  • All vehicle rotation is relative to the root prim.

For Second Life vehicles, the root prim is almost always the driver’s seat. You can make the vehicle construction much easier if the root prim is at rotation <0,0,0>. Because vehicle motion occurs relative to the root prim, rotating the root prim will affect how force is applied to move the vehicle.

As a car moves it rotates in all three dimensions, turning left and right (one dimension) and rolling from side to side (another dimension) when it is on uneven pavement. The car also pitches up and down as it travels hills. Second Life accomplishes all car rotation by rotating the root prim, because it “sees” the entire vehicle as only the root prim. Every other object on the car moves solely by virtue of the fact that it is attached to the root prim. For the car shown in Figure 2, the root prim is a black box that the avatar sits on.

See also  Custom Java Web Development - The Heartbeat of Modern Web Development

Selecting Car Materials
The default material type for Second Life is wood. Unless the object is going to move, the material type does not really matter. Most builders simply leave the material type set to the default wood material. Probably 95 percent of the Second Life world is made of wood. You can select the “edit” option from a prim’s menu to set the material type.

Here’s where things get interesting.

The material you choose for the tires is very important. Any part of the vehicle that comes into contact with the ground must have its material specifically set. Second Life supports the following material types: stone, metal, glass, wood, flesh, plastic, and rubber. Really, all that a material type specifies is the mass and friction of an object.

It may seem logical that the wheels should be made from rubber, but rubber is actually a bad choice for tires in Second Life, because it has the most friction of any material. In Second Life’s primitive physics system, the wheels do not actually “turn” to allow the car to move. A car with square tires could move just as easily. Think of the rubber tires as coming into contact with the ground, and the car being pushed with the parking brake on. In real life, such a car would hop along the ground in a bumpy and uncomfortable way. And if you choose rubber for your tire material type, your car will also bump along the ground, as the vehicle force overcomes the rubber resistance.

Instead of rubber, almost all land vehicles in Second Life use glass for their tire material. Glass has the least amount of resistance, so it makes sense as a wheel material type. Durability is not an issue. The glass tires will not shatter.

Understanding the Car Script
After building the simple car, you can script it. The car script begins by defining some constants that define how the car will operate. Of course Linden Scripting Language does not support “true constants.” The values below could be changed, but the car script only reads their values. For your convenience, you can download the complete script or view it in Listing 1. Here are the constants that begin the script:

   //Power used to go forward (1 to 30)   float forward_power = 15;    //Power used to go in reverse (-1 to -30)   float reverse_power = -15;    //How sharply the vehicle turns. Less is more sharply. (.1 to 10)   float turning_ratio = 2.0;    //Sit message    string sit_message = "Ride";    //Not owner message   string not_owner_message =       "You are not the owner of this vehicle ..."; 

You can change the preceding values to affect the car’s handling, making it faster or slower, or affecting its turning ability.

The car has only one state, the default state. The script for that state sets up the car:

   default   {      state_entry()      {

First, the script changes the “sit text.” This causes the option to enter the car to be “ride” rather than the default “sit” in the Second Life menu system. Additionally, the script defines a sit target for the avatar. This prevents the avatar from sitting “inside” the seat, rather than on top of it:

         llSetSitText(sit_message);         llSitTarget(<0.2,0,0.45>, ZERO_ROTATION );

The SL “camera” follows the car automatically, just as the camera automatically follows avatars. However, for the car, it’s better to move the camera 5 meters above and 8 meters behind the car. This provides both a good view of the car, and the area around it:

         llSetCameraEyeOffset(<-8, 0.0, 5.0>);         llSetCameraAtOffset(<1.0, 0.0, 2.0>);

The car uses two sounds, playing the car_start sound when the car starts up, and the car_run sound in a loop as the car runs:

         llPreloadSound("car_start");         llPreloadSound("car_run");

Second Life vehicles move using two motors. The “linear motor” moves the vehicle forward or backward. The “angular motor” turns the car about any of the three axes. You define these motors by setting vehicle parameters.

The vehicle type is set to car. This gives Second Life a hint about what vehicle type you’re creating. Setting the vehicle type also enables the two motors:

         //car         llSetVehicleType(VEHICLE_TYPE_CAR);

Here are some other vehicle parameter settings that you’ll need:

Angular deflection is the tendency of a vehicle to move in certain directions. For example, a car will tend not to move in the z-coordinate (up and down). The angular deflection efficiency determines how effective angular deflection is. A value of 0.2 specifies angular deflection at 20 percent. This allows the car to turn fairly easily:

         llSetVehicleFloatParam(            VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.2);

A value of 0.8 specifies a linear deflection power of 80 percent. The value specifies the effort it takes for the car to change its linear velocity:

         llSetVehicleFloatParam(            VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.80);

Because real-car directional changes are not instantaneous, it takes this car one tenth of a second for both linear and angular deflection to kick in:

         llSetVehicleFloatParam(            VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 0.10);            llSetVehicleFloatParam(            VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.10);

It also takes one second for the linear motor to reach full power:

         llSetVehicleFloatParam(            VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0);

The linear motor power drops off in one fifth of a second, meaning the car will not coast well:

         llSetVehicleFloatParam(            VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.2);

Remember that there are two motors. The angular motor also reaches full power in one tenth of a second:

         llSetVehicleFloatParam(            VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1);

But the angular motor power drops off in one half of a second. The car will stop turning fairly quickly when the user lets up on the control:

         llSetVehicleFloatParam(            VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.5);

Friction affects the car only in the y-coordinate, which is how the car moves forward and backwards. The car can fall or turn quickly:

         llSetVehicleVectorParam(            VEHICLE_LINEAR_FRICTION_TIMESCALE,             <1000.0, 2.0, 1000.0>);

The car rotates fairly easily in the z-coordinate, but less easily in the x and y coordinates:

         llSetVehicleVectorParam(            VEHICLE_ANGULAR_FRICTION_TIMESCALE,             <10.0, 10.0, 1000.0>);

A car should (preferably) always stay right side up. The vertical attraction setting allows this:

         llSetVehicleFloatParam(            VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.50);         llSetVehicleFloatParam(            VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 0.50);   

These values work well for a car. However, if you were building a boat or helicopter they would need to be considerably different.

Starting and Stopping the Car
Second Life calls the changed event handler whenever an avatar enters (sits in) or leaves (stands up from) the car. The changed event handler must accommodate three basic scenarios: the owner sitting down, a non-owner sitting down, or the owner standing:

      changed(integer change)      {

The changed event handler begins by checking to see if someone has sat down:

         if (change & CHANGED_LINK)         {

If someone did sit down, make sure it’s the vehicle’s owner.

            key agent = llAvatarOnSitTarget();            if (agent)            {                

If the avatar sitting down is not the owner, inform them that only the owner can drive the car, and force the avatar to stand up:

               if (agent != llGetOwner())               {                  llSay(0, not_owner_message);                  llUnSit(agent);                  llPushObject(agent, <0,0,50>,                      ZERO_VECTOR, FALSE);               }               else               {

Otherwise, the avatar is the owner, so play the car_start sound:

                  llTriggerSound("car_start",1);

After waiting for the sound to play, you need to turn physics on. Objects with physics enabled can fall and have force applied to them. Most objects in SL are non-physical:

                  llSleep(.4);                  llSetStatus(STATUS_PHYSICS, TRUE);                  llSleep(.1);

Finally, you must request permission to take the avatar’s controls. When the avatar attempts to move, the car (your script) will receive those inputs:

                  llRequestPermissions(agent,                      PERMISSION_TRIGGER_ANIMATION |                      PERMISSION_TAKE_CONTROLS);                     llLoopSound("car_run",1);               }            }            else            {

When the driver stands up, stop the sound, turn off physics, and release the controls. The llTargetOmega call stops any car movement that might be in progress:

                llStopSound();                                   llSetStatus(STATUS_PHYSICS, FALSE);                llSleep(.4);                llReleaseControls();                llTargetOmega(<0,0,0>,PI,0);                                llResetScript();            }         }                 }

Controlling the Car
The control event handler begins by setting up a few variables that the handler needs. Because cars turn differently when in reverse, you must keep a flag that indicates the current direction. Another variable holds the direction of the angular motor:

   control(key id, integer level, integer edge)   {      integer reverse=1;      vector angular_motor;

Next, the script obtains the current speed of the car, which it uses when turning. Cars do not turn when they are not in motion:

      //get current speed      vector vel = llGetVel();      float speed = llVecMag(vel);

Next, the script checks each of the relevant controls, starting with the Forward control. When the user presses Forward, the script uses the linear motor to apply force to move the car forward. Also note that the script sets the reverse variable to one:

      //car controls      if(level & CONTROL_FWD)      {         llSetVehicleVectorParam(            VEHICLE_LINEAR_MOTOR_DIRECTION, );         reverse=1;      }

If the user presses Back, then the script applies power in the opposite direction, and stores the fact that the car is in reverse by setting the reverse variable to -1:

      if(level & CONTROL_BACK)      {         llSetVehicleVectorParam(            VEHICLE_LINEAR_MOTOR_DIRECTION, );         reverse = -1;      }

For a right or left turn, you use the angular motor to rotate the car in the z-coordinate by the specified angle, being sure to take into account whether the car is in reverse:

      if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))      {         angular_motor.z -= speed /             turning_ratio * reverse;      }      if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT))      {         angular_motor.z += speed /             turning_ratio * reverse;      }

Now you can set the angular motor:

         llSetVehicleVectorParam(         VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor);      } 
 
Figure 3. Car in Motion: Here’s the author’s avatar driving the car.

Together, these event handlers let users drive the car using the same controls they use to move their avatars. Figure 3 shows my avatar, Encog Dod, driving the car.

You can get a copy of the car object described in this article in Second Life at this SLURL.

That’s all there is to creating and controlling a simple car in Second Life—but don’t feel that you’ve covered the full extent of Second Life vehicles. Other land vehicles, such as tanks, trucks, sleds, and motorcycles are also common, as are air and sea vehicles. If you’re interested in learning about other vehicle types, my book “Scripting Recipes in Second Life” covers all three types of vehicles: land, air, and sea.

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