Don't click here unless you want to be banned.

LSL Wiki : LSL101Chapter1

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are
<Foreword: How To Use This Wiki>
<Table of Contents>
<Next chapter: States And Events>

Hello, Avatar!

A Simple Script, Line By Line

In the beginning, there was only Philip Linden.
Philip gazed upon the empty sims,
Devoid of life and people,
And was Sad.

Then, Philip had an Idea.
Populating the vast world with people,
Philip chose to give them the power to change the world.
That power was but one Word.

That Word was "LSL."
And it was Good.

LSL is appropriately the stuff of gods in Second Life, though you needn't be a god to master it!

Creating A Script

To begin writing code, you need to know how to create a script. For our purposes, you can create a script in one of three ways:

1. Right-click the ground, and select create from the pie menu, then left-click on the ground. This should create a default cube prim and open the Edit window.
Click the "More >>" button in the lower right hand corner of the edit window (if it is shown).
Click the "Content" tab, and then click the "New Script..." button.
The script editor window should appear.

2. (PC Users and Mac users with more than one mouse button) Right-Click a folder in your Inventory, and select "New Script."
Double-Click the newly created script.
The script editor window should appear.

3. Create a script in an outside editor, then copy and paste it into SL via the above methods.

(From now on, "Create a script" will mean any of the above. "Object" will mean either a prim or a set of linked prims.)

Do #1 now. What is this? Some code appeared!

It should look like this:
        llSay(0, "Hello, Avatar!");

    touch_start(integer total_number)
        llSay(0, "Touched.");

The classic introduction to a programming language is a program that says "Hello, world!" It also gives you a starting point on which to build your own program. Such was the wisdom of Philip that you get a ready-to-run "Hello, Avatar" script automatically whenever you create a new script.

Don't panic! This stuff is easier than it looks!

The Default State

The first thing you see in your new script is the word "default". This is what's called a "state" -- as in "state of being". Every LSL script must contain a default state, aptly named "default", and code within it in order to work. A script can contain multiple states, but we'll get to that later on.

The default state contains code that runs first. "default" tells the compiler (the program that converts your code into something that will run in SL) "okay folks, we're starting in here." On the line following default, you should see an open brace ({). This tells the compiler that the information after it is contained within default. If you follow the edge of the screen straight down from the first open brace after default you'll find default's closing brace (}) on the last line in the script. Default's closing brace tells the compiler "default's code ends here." The space between a set of braces is called a scope (or code-block ). All the text between the default state's opening and closing braces is said to be contained within its scope.

A scope can contain other ("nested") scopes. In this example, default's scope contains both state_entry's and touch_start's scope. As you can see, each scope has its own opening and closing brace. Every scope that is opened with an opening brace must be closed with a closing brace, or else the script edit window will display "Syntax error" when you try to save your script.

See? This isn't so hard!


An event is a named code-block that is triggered (and the code within its scope run) by something that happens within Second Life. When we add code inside an event's scope, we create an "event handler;" this code will respond to the event's occurrece by handling it.

Event state_entry

The first bit of code that actually does something is included within event state_entry's scope. Let's take a closer look at it:

// <snip>
        llSay(0, "Hello, Avatar!");
// <snip>

Whenever the script enters its default state, this triggers the state_entry event. So, the code within state_entry's scope is the first thing that runs. Here are ways in which this can happen:

1) Compiling (saving) the script.
2) Resetting the script. There is a "Reset" button in the script editor window. Also, LSL provides function llResetScript that you can use to make a script reset itself.

(From now on, "reset the script" will mean any of the above.)

* Taking the containing object into your inventory, or rezzing it in-world, does not reset its script. See the article about event on_rez for a helpful discussion of this point.

The event's name is followed by a pair of parentheses. for now, let's leave their purpose a mystery! A pair of curly brackets marks the start and end of state_entry's scope. One statement is within its scope.


The line beginning with "llSay" is a statement. Statements are chunks of text that do something. Each statement must end with a semicolon (;). Think of the semicolon at the end of a statement like the period at the end of a sentence (and think of the compiler as your pedantic 3rd grade grammar teacher.) Usually, every statement consists of a single line of text.

Saving The Script

In the script editor, click "Save". This compiles and resets the script. If the script is in an object rezzed in world, you should see a Chat message like this:

Object: Hello, Avatar!

No, the object isn't just saying "hi" by coincidence. This is happening because resetting the script triggered the default state's state_entry event, whose scope includes the statement that begins with llSay.


By now, in the spirit of science, you may have "touched" the object to see if it will say "Hello, Avatar!" again. Instead, it says "Touched." That reply comes from the touch_start event. Why didn't the state_entry event reply?

1) You touched the object, so that's the event to which it responded.
2) Our new script hasn't "ended;" it is already in its default state, and nothing has happened to trigger default's state_entry event again. Even if you quit SL and reconnected, you'd still find that the script is already in its default state.

An LSL script is "persistent." Its state persists. The current values of its variables persist. You can reset it, of course, but that doesn't "stop" an LSL script from persisting; it just resets its state. Once saved, an LSL script only desists from persisting if you:

1) Delete the script from the object that contains it.
2) Remove the containing object from the SL world by deleting it.

(From now on, "Removing the script" means either of the above.)

* Taking the containing object from in-world into your inventory does not interrupt its persistence. Taking the object only makes its script inactive. When you later rez the object from your inventory in-world, its status will be just as it was when you took it.


The statement starting with llSay is a call to function llSay. A function is a named code-block that does something interesting when you give it the information it wants. It might be a code-block located inside of your script; or it might reside outside of your script in "some sharable place."

Any function whose name starts with two lowercase L's is a Linden function that resides in the SL environment. So, llSay is a Linden function. These bits of code are created by the Lindens to provide scripters with new abilities. In practice, Linden functions will do the heavy lifting in all of your scripts.

Passing Parameters

The pieces of information you give a function are called parameters.

When you call a function, or any other type of named code-block, and give it pieces of information, you are "passing parameters" to it. You pass parameters within the call's parentheses (()). The parentheses and any parameters they enclose make up a "parameter list."

Code-blocks need varying information. To make one work right, you have to pass it exactly the parameters it needs in the order that it expects them. If you are passing more than one parameter, separate each parameter from the next with a comma. If a parameter is optional, and you don't include it in your call, the code-block will assign it a default value.

If you aren't going to pass any parameters, put a pair of parentheses in the call anyhow, with nothing inside of them. This empty parameter list tells the code-block "Don't look at me! You'll have to get your information somewhere else." (Now you may be starting to suspect what the parentheses in event state_entry() are for!)

Function llSay

Let's dissect llSay! (Or, more precisely, our script's call of function llSay.)
// <snip>
        llSay(0, "Hello, Avatar!");
// <snip>

llSay is a function that chats text on a channel that can be "heard" by objects or avatars from about 20 meters away.

llSay expects you to give it two parameters, the channel on which to talk on and the text to say. Avatars chat on channel 0, which is why "Hello, Avatar!" appears on your screen and in your chat history when the script is reset. Objects can chat on channels other then 0, but the chat won't appear onscreen. So, non-0 channels are useful for private communication between two (or more) objects.

The text to say is surrounded in double-quotes ("). These tell the compiler "all the text within these double-quotes is a single value. Take it literally -- that is, don't try and make it into statements, events, or even mashed potatoes -- give it to the function *just* as it is." That's why text in double-quotes, and numbers that are off by themselves, are called literals. They're information you want the compiler to use literally. We'll get to non-literals (variables) later on.

Remember to end the statement with a semicolon (;)! Forgetting this semicolon is the most common mistake in an LSL script.

Event touch_start

The next event you will see is touch_start. Strictly speaking, this event doesn't contribute anything to the saying of "Hello, Avatar!" Apparently, Philip in his wisdom realized that newbies would like to see an example of a different kind of event. This code looks very similar to the preceding commands:

touch_start(integer total_number)
    llSay(0, "Touched.");

This event looks like a function call, because its name seems to be followed by a parameter list. Actually, an event is akin to a function rather than a function call. (Don't feel bad; you've never seen a function. How could you have known?) Instead of parameters, this list contains a variable: integer total_number.

As with a function, this variable is set to the value of a parameter. One interesting difference; Second Life itself supplies the parameters for events! When defined in an event, variables are given values by actions the sim has taken. This is very useful, especially in events like money. In this case, total_number defines the number of people touching the object at that time. The advantages of knowing the number of "touchers" may seem dubious right now! Please take it on faith that we need this number for detected functions, and that someday you may be glad to know it!

But for now, all we're doing is calling function llSay to say "Touched" every time "Touch" in the object's pie-menu is clicked on by any user. Here is our old friend llSay again! We're passing llSay a parameter list that's pretty much like the one we used before: channel 0, and text "Touched".

Congratulations! You've successfully deciphered your first script!

<Next chapter: States And Events>
<Table of Contents>

Homepage | LSL101 | Tutorial | CrashCourse | Glossary
There are 5 comments on this page. [Display comments/form]