Execute some statement(s) if a condition is true, else some other statement(s) if it is false. This is essentially the “bread and butter” of coding: the decision making inside a script.
if (condition) statement else statement if (condition) { statements } else { other statements }
Notes:
- The else and its statements are optional.
- If there’s only one statement in the block of code then the encompassing curly braces (‘{‘ and ‘}’) are also optional.
- Conditional chains are limited to a total of 23 elses. (1 if and 23 elses)
Syntax
There are no semicolons at the end of the conditional statement! The mistake will compile (save), but unintended incorrect results will happen when you execute.
Incorrect Example (Do NOT do This!)
if (condition); { statement; } if (condition); { statement2; }
Using a semicolon after the if statement will cause the code inside the curly braces to execute regardless of the result of the conditional statement. The reason being that the semi-colon tricks the compile into thinking that the use wanted a single line conditional result (see below for an example) and not one with braces, the result of this being that the curly braces are treated as a sub-scope unassociated with the conditional.
Example:
if (llFrand(1.0) >= 0.5) llSay(0, "heads"); else llSay(0, "tails");
This code checks to see if a random number between 0.0 and 1.0 is greater than 0.5. If it is, the script says “heads”, if it’s not, the script says “tails”
Note: Only up to 23 else statements may be in a conditional chain. (a total of 24 conditionals: 1 if and 23 elses) Any more, and a syntax error will occur when the script is saved/compiled. For example, the following attempt at a poor man’s case statement replacement is valid until you uncomment the last line:
integer i = 24; default { state_entry() { if (i == 1) llOwnerSay((string) i); else if (i == 2) llOwnerSay((string) i); else if (i == 3) llOwnerSay((string) i); else if (i == 4) llOwnerSay((string) i); else if (i == 5) llOwnerSay((string) i); else if (i == 6) llOwnerSay((string) i); else if (i == 7) llOwnerSay((string) i); else if (i == 8) llOwnerSay((string) i); else if (i == 9) llOwnerSay((string) i); else if (i == 10) llOwnerSay((string) i); else if (i == 11) llOwnerSay((string) i); else if (i == 12) llOwnerSay((string) i); else if (i == 13) llOwnerSay((string) i); else if (i == 14) llOwnerSay((string) i); else if (i == 15) llOwnerSay((string) i); else if (i == 16) llOwnerSay((string) i); else if (i == 17) llOwnerSay((string) i); else if (i == 18) llOwnerSay((string) i); else if (i == 19) llOwnerSay((string) i); else if (i == 20) llOwnerSay((string) i); else if (i == 21) llOwnerSay((string) i); else if (i == 22) llOwnerSay((string) i); else if (i == 23) llOwnerSay((string) i); //else if (i == 24) llOwnerSay((string) i); // uncomment to cause syntax error } }
Note: This no longer seems to be accurate. I was able to put well over one hundred if-else statements in one script without recieving any error.
However, a workaround to this is to nest conditionals, or, if that’s not possible, split the conditional chain into a series of distinct if statements: at the end of each if(){} block, put a jump or return as the last statement so that the remaining if statements that would have otherwise been “else if” statements are skipped.
Note: Only 4 levels of nesting are allowed. A syntax error will be displayed on the first IF in the 5th nested level.
Boolean Operators
By using boolean operators to AND or IF conditions together, code will be more efficient and use less memory than it would otherwise. Suppose a variable i is FALSE and another variable j is TRUE:
Compare this:
integer i = FALSE; integer j = TRUE; if (i) { // we will not reach here. } else if (j) { llOwnerSay((string)llGetFreeMemory()); }
And this:
integer i = FALSE; integer j = TRUE; if (!i) { if (j) { llOwnerSay((string)llGetFreeMemory()); } }
To this:
integer i = FALSE; integer j = TRUE; if (!i && j ) // if i equals FALSE AND j equals TRUE. llOwnerSay((string)llGetFreeMemory());
See?
Operators in LSL are not short-circuited.
In some other languages, one must formally end the IF statement with endif or something similar. LSL does not.
Example:
// A simple method to say if the method was called. integer test() { llOwnerSay("Test method called!"); return TRUE; } default { touch_start(integer total_number) { if (FALSE && test()) { // If the test is short-circuit optimized then the test() method should never be called. // Will never get here. } } }
In a short-circuited language if the left-hand side of a logical AND (&&) is FALSE the right-hand side is never tested since the entire test would always return a FALSE output no matter what the value of the right-hand side. Since LSL is not short circuited, both the left and the right-hand sides are tested all the time.
If your application requires or would greatly benefit from a short-curcuit method, for example if test above was a process intensive function and the code would be called regularly or repeatedly, you can emulate with additional if’s, despite the fact it doesn’t look pretty or proper.
Example:
default { touch_start(integer total_number) { if (FALSE) { if (test()) // Will never get here. // Will never get here either. } } }
Note: Because of the way LSL parser works (more details: http://w-hat.com/stackdepth), conditions in LSL are evaluated left to right, instead of right to left as in most programming languages. Check example on condition page.
Credit to: Lslwiki.net (not working) with changes made for brevity and clarity.