Scripting summer drinks

Wednesday, August 20, 2008 / by

This is an article I wrote for the latest issue of SL'ang Life magazine. Since it never came out, I adapted the article a bit and decided to publish it on my blog. If the tutorial gets popular, I might write some more :)

Don't get scared or discouraged seeing all the code here - the tutorial is aimed at people who never scripted before, so I'm sure you'll understand it, just go bit by bit. And you are welcome to ask questions in the comments of course. So, here it is.

Summer Drinks

When the weather is hot and sunny, avatars can cool off by drinking refreshing beverages. Unlike real life, after they make their yummy drink, they still have some work to do before it's ready. It's because objects in SL that are supposed to interact with avatars must be scripted. Today we'll learn how to script and animate a summer drink - the easy way!

The first thing to do is to create the drink object. This is where you let your creative power flow freely - I'm sure you'll come up with a yummy looking juice or ice tea. This part is up to you - the tutorial will focus on scripting only. Take time making your drink object, and once you have it ready, let's script!

PREPARATION
Rez your drink on the floor (or table, if you prefer), right-click it, select Edit from the pie menu and go to Contents tab (if you don't see the tab, click the blue More button). You will see there's a button that says New Script - click it. The drink will greet you with 'Hello, Avatar!' phrase and you'll notice a new item in the contents, named New script. Right-click it, select Rename, type in any name you want (for example Drink script) and press Enter on your keyboard. Right-click the script again and this time select Open. You'll see a window with a default LSL script. This is where we are going to work now.

Delete the whole default script (all the text), so that you start with a blank page, and type in:


default
{

}

This indicates the default state that every script must have. When the script is first run (or reset), it enters this state and does what is listed in here. The brackets indicate where the list of tasks starts and ends. We are going to put our tasks inside the brackets.

PERMISSION TO ANIMATE
The first thing we need to do in our drink script is to check whether the object (drink) containing the script is attached to an avatar. We'll use attach event handler, which is activated when an object is attached to or detached from an avatar.

default
{
attach (key id)
{

}
}

Attach event handler has one parameter - a key named id. Parameters in LSL are used to store values important for various functions, in this case a key. Each avatar has a unique key that identifies him in Second Life. So in this case the id parameter stores the key of an avatar who attached the object with the script. If the object is not attached to any avatar, the id parameter will store an empty key: NULL_KEY. We can use that information to tell the script what to do in both cases. If the script finds out that the object is not attached (id stores NULL_KEY), we're not going to do anything (for now). Otherwise (if it is attached), we want the script to ask the avatar for permission to animate him.

default
{
attach (key id)
{
if (id == NULL_KEY)
{

}
else
{
llRequestPermissions (id, PERMISSION_TRIGGER_ANIMATION);
}
}
}

Note that we use "==", not "=" to compare whether two values are equal. The latter ("=") would assign the value to the parameter.

When an avatar attaches an object, the permission to animate is granted automatically (user don't get the dialog box with the question), but the script has to ask for the permission first anyway. To ask for permission we'll use llRequestPermissions function. It needs two pieces of information: whom to ask (we need to give an avatar's key) and what type of permissions it should ask for (there are various types of permissions, like permission to animate, permission to track avatar's camera, permission to take money etc. - they are all described in LSL Portal). We want to request permission from the avatar who attached the object, so we will use the id parameter here. And since we need a permission to animate him, we'll use PERMISSION_TRIGGER_ANIMATION flag. Remember you need to place ; (a semicolon) at the end of every function, otherwise you won't be able to save your script (it will give an error).

HOLD THE GLASS
Now we have to tell the script what to do when the permissions are granted. We need the
run_time_permissions event handler, which is triggered when the avatar responds to permissions request - either gives or doesn't give the permission. That's why we also have to make sure the permission was granted. Run_time_permissions event handler has one parameter - perm. If no permissions are set, this parameter has value of 0. Otherwise it stores the granted permissions flags. So, what we need is a situation where perm == PERMISSIONS_TRIGGER_ANIMATION. To check that we'll use an if statement similar to the one we used in attach event handler (note that else statement is optional).

Once we're sure the permission was granted, we want to animate the avatar, so that he is holding the drink. You can create your own holding animation and place it in your drink's contents or use one of SL built-in animations (they are listed on the wiki). The built-in animation "hold_R_handgun" is perfect for holding a drink and that's what we are going to use. To start the animation, use llStartAnimation function.

default
{
attach (key id)
{
if (id == NULL_KEY)
{

}
else
{
llRequestPermissions (id, PERMISSION_TRIGGER_ANIMATION);
}
}

run_time_permissions (integer perm)
{
if (perm == PERMISSION_TRIGGER_ANIMATION)
{
llStartAnimation ("hold_R_handgun");
}
}
}

LET ME TAKE A SIP
So far, so good, but we still need a bit more scripting. Holding animation is not enough, as we want our avatar to take a sip every few seconds. That's why we are going to set up a timer in our script. Let's say we want the avatar to sip the drink every 15 seconds. We'll use llSetTimerEvent function (set to 15 seconds) in run_time_permissions event handler, right after we start the holding animation. So now when permissions are granted, the script will start the holding animation and then will start up the timer. And you probably have guessed now that we need another event handler: timer, which will be triggered every 15 seconds (the time we set) and where we'll list the tasks to be done. Timer doesn't have any parameters, as it doesn't really need any. Inside this event handler we only need one task: trigger a drinking animation. We'll use again a built-in animation: "drink", but you might want to create your own animation and drag it from your inventory into your object contents.

default
{
attach (key id)
{
if (id == NULL_KEY)
{

}
else
{
llRequestPermissions (id, PERMISSION_TRIGGER_ANIMATION);
}
}

run_time_permissions (integer perm)
{
if (perm == PERMISSION_TRIGGER_ANIMATION)
{
llStartAnimation ("hold_R_handgun");
llSetTimerEvent (15);
}
}

timer()

{
llStartAnimation ("drink");
}

}

I FINISHED DRINKING
The script is almost finished but there's one more thing we need to do - tell the script what tasks to perform when the object is detached from the avatar. We are going to place these in the attach event handler. If the script finds out that the object is detached (id stores NULL_KEY), it should stop the holding animation, stop the drinking animation and stop the timer. To stop the animations, we'll use llStopAnimation function and to stop the timer, we'll set the timer event to 0.

default
{
attach (key id)
{
if (id == NULL_KEY)
{
llStopAnimation ("drink");
llStopAnimation ("hold_R_handgun");
llSetTimerEvent (0);
}

else
{
llRequestPermissions (id, PERMISSION_TRIGGER_ANIMATION);
}
}

run_time_permissions (integer perm)
{
if (perm == PERMISSION_TRIGGER_ANIMATION)
{
llStartAnimation ("hold_R_handgun");
llSetTimerEvent (15);
}
}

timer()

{
llStartAnimation ("drink");
}

}

SAVE
Our script is now ready to save! Click the Save button at the bottom of the window. You should see a message Compile successful, saving... Wait until you'll see another message: Save complete. Note: if you can't save the script because it gives you a syntax error, or any other error, make sure you typed everything correctly. If you accidentally omit one semicolon, or make one spelling mistake, the script won't save. Just go through the script, try to find your mistake (there might be more than one) and click the Save button again.

Once the script is saved you can close the window and take your drink object to your inventory. Right-click it in your inventory and attach it to your right hand (you need to do it only the first time - later you can just use Wear option, as the drink will remember where to attach). You might need to rotate and adjust the glass while it's attached to your avatar. And that's it. Your drink is ready and your avatar should be holding it and drinking properly. Congratulations, you have compiled your first script!

OH, THE POSSIBILITIES
Note that you can script ice cream cones exactly the same way. It's a basic script for eating and drinking in Second Life, although many designers come up with their own, more sophisticated scripts. Which is something you might want to do as well. Just do trial and error, lookup new functions on LSL Portal or try various animations. Scripting is easy and fun and I'm sure you can learn it fast.

If you have any problems with this tutorial, you're welcome to ask a question in the comments. And if you decide to throw a party and serve your freshly scripted drinks, be sure to invite me!

You May Also Like

4 comments

  1. Really nice tutorial !

    I just finish hacking some scripts I found... and reading this tutorial before would saved me a lot of time :)

    Thanks again.

    ReplyDelete
  2. I'm glad you enjoyed the tutorial, Fabio. I'm not sure what you mean by 'hacking', but I hope it's not trying to steal other people's work, cause it's wrong. I wouldn't want my tuts to be used in a wrong way - they're for positive use only :)

    ReplyDelete
  3. I did get my own drinking script from the second life marketplace and have modify permissions. What I'm wanting to know is how you would make it so when someone finishes a drink, they can't use the same one. They would have to go back to the cooler and get a new drink. I've seen a few creators do it, but I don't get how to.

    ReplyDelete
  4. There are many ways of doing this. For example you could make a variable that will store information (TRUE/FALSE) about the drink. The variable is set to TRUE in the beginning and it should change to FALSE when user finishes/detaches the drink. And you just run a simple if/else - if TRUE, the drink works as it should, if FALSE, the drink detaches and perhaps say a message it expired or so. I might write a tutorial on this when I have more time in RL but it's kind of hard to do it in the comment ;)

    ReplyDelete