Difference between revisions of "LSL Style Guide"
Kireji Haiku (talk | contribs) m (this page really needs a complete rewrite with better examples and more information as to why one should do what.......for now some minor layout fixes) |
Omei Qunhua (talk | contribs) m (sundry tweaks) |
||
Line 1: | Line 1: | ||
{{LSL Header|ml=*}}{{RightToc}} | {{LSL Header|ml=*}}{{RightToc}} | ||
Effective programming in LSL requires that developers use a disciplined | Effective programming in LSL requires that developers use a disciplined approach to formatting and other conventions in their scripts. | ||
These guidelines, referred to collectively as a Style Guide, are not as rigid as the rules required by the language compiler but nonetheless are critical to creating maintainable code. The most critical aspect of a style is that you apply it consistently to the code you write. | These guidelines, referred to collectively as a Style Guide, are not as rigid as the rules required by the language compiler but nonetheless are critical to creating maintainable code. The most critical aspect of a style is that you apply it consistently to the code you write. | ||
Line 7: | Line 7: | ||
==General Guidelines== | ==General Guidelines== | ||
Most people, when they start programming on their own, will have programs that are UGLY to look at; to put it nicely. | Most people, when they start programming on their own, will have programs that are UGLY to look at; to put it nicely, sometimes mistakenly thinking that such scripts occupy less space when compiled. Such scripts typically look like the following: | ||
<lsl> default {state_entry(){llSay( | <lsl> default {state_entry(){llSay(0,"Hello World.");}}</lsl> | ||
However, that code is | However, that code is difficult to read (or at least to ''follow'') when one is writing a ten thousand word program. Two common styles as to bracketing and indenting have emerged. | ||
{| class="sortable" {{Prettytable}} | {| class="sortable" {{Prettytable}} | ||
Line 21: | Line 21: | ||
default { | default { | ||
state_entry() { | state_entry() { | ||
llSay(0, "Hello World."); | |||
llSay( | |||
} | } | ||
} | } | ||
Line 32: | Line 31: | ||
state_entry() | state_entry() | ||
{ | { | ||
llSay(0, "Hello World."); | |||
llSay( | |||
} | } | ||
} | } | ||
Line 39: | Line 37: | ||
|} | |} | ||
'''method one''' conserves space, however '''method two''' is easier to read | '''method one''' conserves space - IN THE SOURCE CODE ONLY, however '''method two''' is easier to read and easier to visually bracket-match. Once a scripter is in the practice of using a particular style, reading code in that style will become easier. Consistent indenting makes reading both styles easier. In both methods, indenting is the key indicating factor of levels of scope. | ||
==Naming Conventions== | ==Naming Conventions== | ||
Line 53: | Line 51: | ||
</lsl> | </lsl> | ||
Others prefer to distinguish between global and local variables, defining globals in the following manner:- | |||
<lsl> | |||
integer gIndex; | |||
string gName = "Please set one"; | |||
</lsl> | |||
Constant variables should be in ALL CAPS. For example: | Constant variables should be in ALL CAPS. For example: | ||
Line 58: | Line 62: | ||
<lsl> | <lsl> | ||
integer DIALOG_CHANNEL = -517265; | integer DIALOG_CHANNEL = -517265; | ||
vector RED = <1.0, 0.0, 0.0>; | |||
</lsl> | </lsl> | ||
Line 69: | Line 73: | ||
listen(integer channel, string name, key id, string message) | listen(integer channel, string name, key id, string message) | ||
{ | { | ||
key | key OwnerKey = llGetOwner(); | ||
if (channel == 1 | if (channel == 1 && id == OwnerKey) | ||
llOwnerSay("Hello Avatar"); | llOwnerSay("Hello Avatar"); | ||
} | } | ||
Line 86: | Line 90: | ||
default { | default { | ||
touch_start(integer n) { | touch_start(integer n) { | ||
integer i | integer i; | ||
integer index = llListFindList(lst, [llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1))]); | integer index = llListFindList(lst, [llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1))]); | ||
if (!~llListFindList(lst, [llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1))])) | if (!~llListFindList(lst, [llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1))])) | ||
Line 111: | Line 115: | ||
integer index = llListFindList(listOfStrings, [startPart]); | integer index = llListFindList(listOfStrings, [startPart]); | ||
if (!~index) | if (!~index) // if index is equal to -1 | ||
// | { | ||
listOfStrings += startPart; | listOfStrings += startPart; | ||
} | |||
// send a message to the owner, only reaches owner if online and within the same sim | // send a message to the owner, only reaches owner if online and within the same sim | ||
Line 122: | Line 126: | ||
</lsl> | </lsl> | ||
LSL lacks an optimizing compiler. For this reason it may be necessary to balance the two style to get faster code. Line combination optimization should only be done after the code is working & bug free. Improper optimization can lead to wrong results. Always test optimized code thoroughly. | LSL lacks an optimizing compiler. For this reason it may be necessary to balance the two style to get faster, more compact executable code. Line combination optimization should only be done after the code is working & bug free. Improper optimization can lead to wrong results. Always test optimized code thoroughly. | ||
==Script Structure== | ==Script Structure== |
Revision as of 03:42, 11 February 2013
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Effective programming in LSL requires that developers use a disciplined approach to formatting and other conventions in their scripts.
These guidelines, referred to collectively as a Style Guide, are not as rigid as the rules required by the language compiler but nonetheless are critical to creating maintainable code. The most critical aspect of a style is that you apply it consistently to the code you write.
General Guidelines
Most people, when they start programming on their own, will have programs that are UGLY to look at; to put it nicely, sometimes mistakenly thinking that such scripts occupy less space when compiled. Such scripts typically look like the following:
<lsl> default {state_entry(){llSay(0,"Hello World.");}}</lsl>
However, that code is difficult to read (or at least to follow) when one is writing a ten thousand word program. Two common styles as to bracketing and indenting have emerged.
method one | method two |
---|---|
<lsl>
default { state_entry() { llSay(0, "Hello World."); } } </lsl> |
<lsl> default { state_entry() { llSay(0, "Hello World."); } } </lsl> |
method one conserves space - IN THE SOURCE CODE ONLY, however method two is easier to read and easier to visually bracket-match. Once a scripter is in the practice of using a particular style, reading code in that style will become easier. Consistent indenting makes reading both styles easier. In both methods, indenting is the key indicating factor of levels of scope.
Naming Conventions
There are many naming conventions in Second Life. Only the most used ones will be listed below.
Global Variables (variables used through out the entire program) should be lowercase. For example:
<lsl> integer index = 0; string name = "Please set one"; </lsl>
Others prefer to distinguish between global and local variables, defining globals in the following manner:-
<lsl> integer gIndex; string gName = "Please set one"; </lsl>
Constant variables should be in ALL CAPS. For example:
<lsl> integer DIALOG_CHANNEL = -517265; vector RED = <1.0, 0.0, 0.0>; </lsl>
Arguments used within a or one of the standard events should be named with easily readable and meaningful names. When using events, please use the standard names as listed here on the official wiki. An overview of all events can be found here. Below is an example as can be found for the listen event:
<lsl> // ...
listen(integer channel, string name, key id, string message) { key OwnerKey = llGetOwner(); if (channel == 1 && id == OwnerKey) llOwnerSay("Hello Avatar"); }
// ... </lsl>
Separating Code
Many people will start out doing many, many function calls on one line. This makes the code hard to read, and almost impossible to debug. The following is an example of one such program: <lsl> list lst; integer numDigits = 10;
default {
touch_start(integer n) { integer i; integer index = llListFindList(lst, [llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1))]); if (!~llListFindList(lst, [llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1))])) lst += llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1)); llOwnerSay(llList2CSV(lst)); }
} </lsl>
Now here is the code, with the exact same features, in a simpler way. While hardly anyone could tell you what the above code did, almost everyone can tell you what the below code does.
<lsl> list listOfStrings; integer numDigits = 10;
default {
touch_start(integer n) { string name = llKey2Name(llDetectedKey(0)); list nameAsList = llParseString2List(name, [" "], []); string firstName = llList2String(nameAsList, 0); string startPart = llToLower(llGetSubString(firstName, 0, numDigits - 1)); integer index = llListFindList(listOfStrings, [startPart]);
if (!~index) // if index is equal to -1 { listOfStrings += startPart; }
// send a message to the owner, only reaches owner if online and within the same sim
llRegionSayTo(llGetOwner(), PUBLIC_CHANNEL, llList2CSV(listOfStrings)); }
} </lsl>
LSL lacks an optimizing compiler. For this reason it may be necessary to balance the two style to get faster, more compact executable code. Line combination optimization should only be done after the code is working & bug free. Improper optimization can lead to wrong results. Always test optimized code thoroughly.
Script Structure
LSL scripts are comprised of expressions, functions, statements, event handlers and states. The LSL compiler mandates a certain structure to scripts:
- User Defined Variables (see LSL_Variables)
- User Defined Functions (see User-defined_functions)
- default State (see State)
- User Defined States
Editor
There are many 3rd party editors with LSL syntax files. See LSL Alternate Editors for more information.