Difference between revisions of "LSL 101/The Structure of a Script"

From Second Life Wiki
Jump to navigation Jump to search
m (added LSL Tip)
m (<lsl> tag to <source>)
 
(2 intermediate revisions by one other user not shown)
Line 6: Line 6:
Here is the simplest possible valid LSL script.  It doesn't actually ask the computer to do anything but all scripts have, at minimum, this structure:
Here is the simplest possible valid LSL script.  It doesn't actually ask the computer to do anything but all scripts have, at minimum, this structure:


<lsl>
<source lang="lsl2">
default  
default  
{
{
Line 13: Line 13:
     }
     }
}
}
</lsl>
</source>


In order to explain even this short piece of code we need to introduce a few terms.
In order to explain even this short piece of code we need to introduce a few terms.
Line 21: Line 21:
We'll use ''comments'' (two forward // slashes) to talk inside the script.  Anything on a line after // will not execute so you can leave yourself notes like this:
We'll use ''comments'' (two forward // slashes) to talk inside the script.  Anything on a line after // will not execute so you can leave yourself notes like this:


<lsl>
<source lang="lsl2">
default                                //  this is the only *state* in this script
default                                //  this is the only *state* in this script
{                                      //  opening bracket for default state
{                                      //  opening bracket for default state
Line 29: Line 29:
     {                                  //  opening bracket for this *event*
     {                                  //  opening bracket for this *event*


       llOwnerSay("Hello, creator!");  //  this is the only *function* inside the event
       llOwnerSay("Hello, creator!");  //  this is the only *statement* inside the event. It is invoking a library function.


     }                                  //  closing bracket for this *event*
     }                                  //  closing bracket for this *event*


}                                      //  closing bracket for default state
}                                      //  closing bracket for default state
</lsl>
</source>


Always formatting like this makes it a lot easier to read and debug your code later. There is no "right" or "wrong" in the actual arrangement of white space on the page, in fact, some scripters prefer a more compact style.
Always formatting like this makes it a lot easier to read and debug your code later. There is no "right" or "wrong" in the actual arrangement of white space on the page, in fact, some scripters prefer a more compact style. However careful attention to indenting will greatly help you to see what lines "belong together" and as the placement of { and } is so important, and their pairing is vital, it can greatly help if you code matching pairs so that they appear in the same column, giving visual vertical alignment.


''For more information on this section, please see''  
''For more information on this section, please see''  
*[[LSL 101/Simple Script Skeleton | Simple Script Skeleton]]
*[[LSL 101/Simple Script Skeleton | Simple Script Skeleton]]
*[[LSL 101/Comments, White-space and Formatting | Comments, White-space and Formatting]]
*[[LSL 101/Comments, White-space and Formatting | Comments, White-space and Formatting]]


==[[State |States]]==
==[[State |States]]==


{{LSL Tip|Do '''NOT''' use more than one state (the default state) when relying on high performance for scripts. LSL never really acts a 100% as you think it should and switching states / multiples states would be such a situation. Instead use a global integer called '''integer mode''' or something and then switch that integer to different values and while using conditional statements (if, else if, else...) act accordingly.}}
While the majority of LSL scripts can and are written with just one ''State'' (the default state), it is possible (and at times useful) to define additional states yourself, perhaps to focus your coding on the processing required at a particular stage of proceedings.


A ''State'' in LSL contains events which relate to each other.  For example, cars can either be moving or stopped. When the car is in *state moving* it's going forward and when it's at rest it is in *state stopped*.  There may be other states (*state reverse, *state stolen, *state wrecked, *state repaired) but *state moving* and *state stopped* are probably the most common states for a car!   
A ''State'' in LSL contains events which relate to each other.  For example, cars can either be moving or stopped. When the car is in *state moving* it's going forward and when it's at rest it is in *state stopped*.  There may be other states (*state reverse, *state stolen, *state wrecked, *state repaired) but *state moving* and *state stopped* are probably the most common states for a car!   
For practical LSL purposes, one state might be used for setting up (e.g. reading a configuration notecard, seeking run time permissions etc.) and another state for the rest of the script, processing that would be inappropriate or impossible until after the set-up stage has been completed.


All LSL scripts have at least one state: the ''default'' state. This is the state when no other states are active.  You can see in the code above the word ''default'' is used to tell the script about what happens in the default state.
All LSL scripts have at least one state: the ''default'' state. This is the state when no other states are active.  You can see in the code above the word ''default'' is used to tell the script about what happens in the default state.
Line 53: Line 54:
Here is an example of a script with two states:
Here is an example of a script with two states:


<lsl>
<source lang="lsl2">
/* state */ default
/* state */ default
{
{
Line 61: Line 62:
//  }
//  }


     touch_start(integer num_detected)
     touch_end(integer num_detected)
     {
     {
         llOwnerSay("Switching to 'state happy'.");
         llOwnerSay("Switching to 'state happy'.");
Line 81: Line 82:
//  }
//  }


     touch_start(integer num_detected)
     touch_end(integer num_detected)
     {
     {
         llOwnerSay("Switching to state 'default'.");
         llOwnerSay("Switching to state 'default'.");
Line 93: Line 94:
//  }
//  }
}
}
</lsl>
</source>


Notice the happy state needs the word ''state'', so that the script knows this describes a state rather than something else.  The default state does not need the word state in front of it because it is built into lsl and is required in every script. The reason you need the word ''state'' before happy is because this is a user-created state and you have to be specific or the server will not know your intent.   
Notice the happy state needs the word ''state'', so that the script knows this describes a state rather than something else.  The default state does not need the word state in front of it because it is built into lsl and is required in every script. The reason you need the word ''state'' before happy is because this is a user-created state and you have to be specific or the server will not know your intent.   


Next, notice the curly braces '{' and '}'.  These tell the script which lines are part of the default state, which are part of the happy state, and which lines belong to the touch_start {event handlers}.
Next, notice the curly braces '{' and '}'.  These tell the script which lines are part of the default state, which are part of the happy state, and which lines belong to the touch_start {event handlers}.
Notice also that in the above example we used touch_end events rather than touch_start. This is not the place to go fully into the reasons why, just note that is advisable not to do state changes from within the touch_start event.


'''The tutorial continues with [[LSL_101/Simple Script Skeleton|Simple Script Skeleton]].'''
'''The tutorial continues with [[LSL_101/Simple Script Skeleton|Simple Script Skeleton]].'''

Latest revision as of 13:47, 24 January 2015

← A Gentle Introduction ↑̲  LSL 101  ̲↑ Simple Script Skeleton →

The Structure of a Script

Here is the simplest possible valid LSL script. It doesn't actually ask the computer to do anything but all scripts have, at minimum, this structure:

default 
{
     state_entry() 
     {
     }
}

In order to explain even this short piece of code we need to introduce a few terms.

LSL scripts use states, events, functions and variables. We'll use this example to show how they work together and go into detail below.

We'll use comments (two forward // slashes) to talk inside the script. Anything on a line after // will not execute so you can leave yourself notes like this:

default                                 //  this is the only *state* in this script
{                                       //  opening bracket for default state

     state_entry()                      //  this is the only *event* in this script

     {                                  //  opening bracket for this *event*

       llOwnerSay("Hello, creator!");   //  this is the only *statement* inside the event. It is invoking a library function.

     }                                  //  closing bracket for this *event*

}                                       //  closing bracket for default state

Always formatting like this makes it a lot easier to read and debug your code later. There is no "right" or "wrong" in the actual arrangement of white space on the page, in fact, some scripters prefer a more compact style. However careful attention to indenting will greatly help you to see what lines "belong together" and as the placement of { and } is so important, and their pairing is vital, it can greatly help if you code matching pairs so that they appear in the same column, giving visual vertical alignment.

For more information on this section, please see

States

While the majority of LSL scripts can and are written with just one State (the default state), it is possible (and at times useful) to define additional states yourself, perhaps to focus your coding on the processing required at a particular stage of proceedings.

A State in LSL contains events which relate to each other. For example, cars can either be moving or stopped. When the car is in *state moving* it's going forward and when it's at rest it is in *state stopped*. There may be other states (*state reverse, *state stolen, *state wrecked, *state repaired) but *state moving* and *state stopped* are probably the most common states for a car!

For practical LSL purposes, one state might be used for setting up (e.g. reading a configuration notecard, seeking run time permissions etc.) and another state for the rest of the script, processing that would be inappropriate or impossible until after the set-up stage has been completed.

All LSL scripts have at least one state: the default state. This is the state when no other states are active. You can see in the code above the word default is used to tell the script about what happens in the default state.

Here is an example of a script with two states:

/* state */ default
{
//  state_entry()
//  {
//      llOwnerSay("Entering state 'default'.");
//  }

    touch_end(integer num_detected)
    {
        llOwnerSay("Switching to 'state happy'.");

        state happy;
    }

//  state_exit()
//  {
//      llOwnerSay("Leaving state 'default'.");
//  }
}

state happy
{
//  state_entry()
//  {
//      llOwnerSay("Entering 'state happy'.");
//  }

    touch_end(integer num_detected)
    {
        llOwnerSay("Switching to state 'default'.");

        state default;
    }

//  state_exit()
//  {
//      llOwnerSay("Leaving 'state happy'.");
//  }
}

Notice the happy state needs the word state, so that the script knows this describes a state rather than something else. The default state does not need the word state in front of it because it is built into lsl and is required in every script. The reason you need the word state before happy is because this is a user-created state and you have to be specific or the server will not know your intent.

Next, notice the curly braces '{' and '}'. These tell the script which lines are part of the default state, which are part of the happy state, and which lines belong to the touch_start {event handlers}.

Notice also that in the above example we used touch_end events rather than touch_start. This is not the place to go fully into the reasons why, just note that is advisable not to do state changes from within the touch_start event.

The tutorial continues with Simple Script Skeleton.