Class 5 of 8

Conditionals

Make your scripts smart — decisions, branching, and access control.

Step 1 of 6
Step 1

Boolean Logic

Before we can make decisions, we need to understand boolean logic. A boolean is simply TRUE or FALSE — yes or no. In LSL, TRUE = 1 and FALSE = 0 (they're just integer constants).

You create boolean expressions using comparison operators. These compare two values and return TRUE or FALSE:

Comparison operators
==
Equal to. 5 == 5 is TRUE
!=
Not equal to. 5 != 3 is TRUE
< >
Less than / greater than
<= >=
Less than or equal / greater than or equal
Common mistake

Don't confuse = (assignment — sets a value) with == (comparison — tests equality). Using = inside an if is a bug that's hard to spot.

Step 2

The if Statement

The if statement runs a block of code only when a condition is TRUE:

LSLBasic if
default
{
    touch_start(integer num_detected)
    {
        integer score = 75;

        if (score >= 50)
        {
            llSay(0, "You passed!");
        }
    }
}

The curly braces { } wrap the code that runs when the condition is true. For a single line, the braces are optional — but using them is good practice because it prevents bugs when you add more lines later.

Step 3

if / else

Add an else block to handle the case when the condition is FALSE:

LSLOwner check with if/else
default
{
    touch_start(integer num_detected)
    {
        key toucher = llDetectedKey(0);
        key owner   = llGetOwner();

        if (toucher == owner)
        {
            llOwnerSay("Welcome back, owner.");
        }
        else
        {
            llSay(0, "Sorry, only the owner can use this.");
        }
    }
}

This is one of the most common patterns in all of LSL — checking whether the person interacting with your object is its owner. You'll write this dozens of times.

Step 4

else if Chains

When you have more than two possible outcomes, chain multiple conditions with else if. LSL checks them from top to bottom and runs the first one that matches:

LSLGrade tier example
default
{
    touch_start(integer num_detected)
    {
        integer score = 82;

        if (score >= 90)
        {
            llSay(0, "Grade: A — Excellent!");
        }
        else if (score >= 80)
        {
            llSay(0, "Grade: B — Good work.");
        }
        else if (score >= 70)
        {
            llSay(0, "Grade: C — Passing.");
        }
        else if (score >= 60)
        {
            llSay(0, "Grade: D — Barely.");
        }
        else
        {
            llSay(0, "Grade: F — Try again.");
        }
    }
}

Once a condition matches, the rest of the chain is skipped. So when score is 82, the second condition (score >= 80) matches and the script says "Grade: B". The remaining checks don't run.

Step 5

Logical Operators

You can combine multiple conditions into one expression using logical operators:

Logical operators
&& (AND)
Both conditions must be TRUE. age > 18 && verified == TRUE
|| (OR)
At least one condition must be TRUE. isOwner || isAdmin
! (NOT)
Inverts the result. !active is TRUE when active is FALSE
LSLOwner OR same group gets access
default
{
    touch_start(integer num_detected)
    {
        key     toucher   = llDetectedKey(0);
        key     owner     = llGetOwner();
        integer sameGroup = llSameGroup(toucher);

        if (toucher == owner || sameGroup)
        {
            llOwnerSay("Access granted.");
            // do the thing
        }
        else
        {
            llSay(0, "Access denied.");
        }
    }
}
Step 6

Practical: Owner-Only Lock

Let's build a complete, practical example: an object with a toggle that only the owner can activate. It demonstrates everything from this class working together.

LSLOwner-only toggle script
integer isActive = FALSE;

default
{
    state_entry()
    {
        llOwnerSay("Object ready. Touch to toggle (owner only).");
    }

    touch_start(integer num_detected)
    {
        key toucher = llDetectedKey(0);
        key owner   = llGetOwner();

        // Guard: reject non-owners immediately
        if (toucher != owner)
        {
            llSay(0, "Only the owner can control this.");
            return;   // Stop executing the rest of this event
        }

        // Owner: toggle the state
        if (!isActive)
        {
            isActive = TRUE;
            llSetColor(<0.0, 1.0, 0.0>, ALL_SIDES);   // Green = on
            llOwnerSay("Activated.");
        }
        else
        {
            isActive = FALSE;
            llSetColor(<1.0, 0.0, 0.0>, ALL_SIDES);   // Red = off
            llOwnerSay("Deactivated.");
        }
    }
}

Notice the return statement — it exits the event handler early. This "guard clause" pattern keeps the main logic clean by handling the rejection case first and returning, rather than wrapping everything in an extra else block.