Your First Interactive Object - Learn the fundamentals of LSL scripting and bring your creations to life with interactive behaviors.
Sorin Todys - Advanced LSL Expert
With over 20 years of experience in virtual worlds, Sorin specializes in making complex scripting concepts accessible to beginners. All classes take place at our dedicated Alife Virtual School region.
Welcome to the exciting world of LSL scripting! This course transforms you from a builder of static objects into a creator of interactive experiences.
Upon completion, you will be able to:
A script is a set of instructions that lives inside an object and controls its behavior. Think of it as the "brain" that gives your creation intelligence and interactivity.
Scripts wait for events to happen (like touches, timers, or messages), then execute the appropriate response code.
Every script has states that contain events which execute functions.
A script is always in a specific state. The starting state is always called default. States help organize complex behaviors.
default // This is a state
{
// Events go here
}
Events are triggers that cause code to execute. Common examples:
state_entry() - Runs when script starts or resetstouch_start() - Runs when object is touchedtimer() - Runs at regular intervalslisten() - Runs when chat is heardFunctions are commands that perform actions. Every function call must end with a semicolon ;
llSay() - Makes object speak in chatllSetColor() - Changes object colorllSetText() - Displays floating textLet's create an object that says "Hello, World!" when touched.
Right-click the ground, select Create, then click to rez a cube.
Right-click your cube and select Edit.
In the Edit window, click the Content tab to view the object's inventory.
Click New Script. The script editor opens with default code.
The default script looks like this:
default
{
state_entry()
{
llSay(0, "Hello, Avatar!");
}
touch_start(integer total_number)
{
llSay(0, "Touched.");
}
}
What's happening?
state_entry() runs once when the script startstouch_start() runs every time someone touches the objectllSay(0, "text") makes the object speak on channel 0 (public chat)Delete everything and replace with this simpler version:
// My First Interactive Object
// This script makes the object greet when touched
default
{
touch_start(integer total_number)
{
llSay(0, "Hello, World! You touched me.");
}
}
// are comments. The script ignores them—they're notes for you and other scripters!
Click Save. If successful, the button grays out. If there are errors, they appear in chat below the code.
Close the editor and click your cube. Check local chat—you should see: [YourObjectName]: Hello, World! You touched me.
;{ needs a closing }" for strings, not single quotesVariables are named containers that store information. Think of them as labeled boxes where you keep data for later use.
| Type | Description | Example |
|---|---|---|
integer |
Whole numbers | 42, -10, 0 |
float |
Decimal numbers | 3.14, -0.5, 1.0 |
string |
Text in quotes | "Hello", "Sorin Todys" |
vector |
3 floats (position, color) | <1.0, 0.0, 0.0> (red) |
key |
Unique identifier (UUID) | Avatar or object ID |
list |
Collection of values | [1, 2.5, "text"] |
Colors are represented as vectors with RGB (Red, Green, Blue) values from 0.0 to 1.0.
// Common Colors
vector RED = <1.0, 0.0, 0.0>;
vector GREEN = <0.0, 1.0, 0.0>;
vector BLUE = <0.0, 0.0, 1.0>;
vector WHITE = <1.0, 1.0, 1.0>;
vector BLACK = <0.0, 0.0, 0.0>;
vector YELLOW = <1.0, 1.0, 0.0>;
vector PURPLE = <1.0, 0.0, 1.0>;
vector CYAN = <0.0, 1.0, 1.0>;
vector ORANGE = <1.0, 0.5, 0.0>;
Let's make an object that changes color when touched.
// Color-Changing Block Script
// Changes to red when touched
default
{
touch_start(integer total_number)
{
// Announce the change
llSay(0, "Ouch! You touched me, turning red!");
// Define red color
vector redColor = <1.0, 0.0, 0.0>;
// Apply color to all sides
llSetColor(redColor, ALL_SIDES);
}
}
vector colorALL_SIDES is a constant that means "all faces"0, 1, 2, etc.Let's make the object cycle through colors on each touch.
// Rainbow Color Cycler
// Cycles through colors on each touch
integer colorIndex = 0; // Track current color
list colors = [
<1.0, 0.0, 0.0>, // Red
<1.0, 0.5, 0.0>, // Orange
<1.0, 1.0, 0.0>, // Yellow
<0.0, 1.0, 0.0>, // Green
<0.0, 0.0, 1.0>, // Blue
<0.5, 0.0, 1.0>, // Purple
<1.0, 0.0, 1.0> // Magenta
];
default
{
state_entry()
{
llSay(0, "Touch me to cycle through rainbow colors!");
}
touch_start(integer total_number)
{
// Get the current color from the list
vector currentColor = llList2Vector(colors, colorIndex);
// Apply the color
llSetColor(currentColor, ALL_SIDES);
// Move to next color
colorIndex++;
// Loop back to start if we reach the end
if (colorIndex >= llGetListLength(colors))
{
colorIndex = 0;
}
llSay(0, "Color " + (string)(colorIndex + 1) + " of " +
(string)llGetListLength(colors));
}
}
Make the object greet users by name!
// Personal Greeter Script
// Greets each toucher by name
default
{
touch_start(integer total_number)
{
// Get the key of who touched
key toucherID = llDetectedKey(0);
// Get their username
string toucherName = llKey2Name(toucherID);
// Greet them personally
llSay(0, "Hello, " + toucherName + "! Welcome!");
// Change color to green for friendliness
llSetColor(<0.0, 1.0, 0.0>, ALL_SIDES);
}
}
llDetectedKey(0) - Returns the UUID of the first toucherllDetectedName(0) - Returns display name of toucherllKey2Name(key) - Converts key to legacy name0 parameter means "first toucher" (useful when multiple avatars touch simultaneously)// Interactive Info Display
// Shows status in floating text
integer touchCount = 0;
default
{
state_entry()
{
llSetText("Touch me!\nCount: 0", <1,1,1>, 1.0);
}
touch_start(integer total_number)
{
touchCount++;
string toucherName = llDetectedName(0);
llSetText("Last touched by:\n" + toucherName +
"\nTotal touches: " + (string)touchCount,
<0,1,1>, 1.0);
llSay(0, "Touch #" + (string)touchCount + " by " + toucherName);
}
}
\n for new lines)"" to remove textStates allow objects to behave differently based on their current condition. A light switch has two states: ON and OFF. Each state responds to touches differently.
// Basic state structure
default // First state must always be 'default'
{
state_entry()
{
// Runs when entering this state
}
touch_start(integer num)
{
// Change to another state
state on;
}
}
state on // Custom state
{
state_entry()
{
// Runs when entering 'on' state
}
touch_start(integer num)
{
// Return to default state
state default;
}
}
// Interactive Light Switch
// Touch to toggle between ON and OFF
// OFF State (default)
default
{
state_entry()
{
// Set appearance for OFF state
llSetColor(<0.3, 0.3, 0.3>, ALL_SIDES); // Dark gray
llSetText("LIGHT: OFF\nTouch to turn ON", <1,0,0>, 1.0);
// Turn off any glow/fullbright
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, FALSE,
PRIM_GLOW, ALL_SIDES, 0.0
]);
llSay(0, "Light is OFF");
}
touch_start(integer total_number)
{
llSay(0, "Turning light ON...");
state on; // Switch to ON state
}
}
// ON State
state on
{
state_entry()
{
// Set appearance for ON state
llSetColor(<1.0, 1.0, 0.8>, ALL_SIDES); // Warm white
llSetText("LIGHT: ON\nTouch to turn OFF", <0,1,0>, 1.0);
// Make it glow and bright
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
PRIM_GLOW, ALL_SIDES, 0.3
]);
llSay(0, "Light is ON");
}
touch_start(integer total_number)
{
llSay(0, "Turning light OFF...");
state default; // Switch back to OFF state
}
}
on, off, open, closed)state_entry()default state must always exist// Three-State Dimmable Light
// OFF → DIM → BRIGHT → OFF
default // OFF
{
state_entry()
{
llSetColor(<0.2, 0.2, 0.2>, ALL_SIDES);
llSetText("OFF\n(Touch for Dim)", <0.5,0.5,0.5>, 1.0);
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, FALSE,
PRIM_GLOW, ALL_SIDES, 0.0
]);
}
touch_start(integer num)
{
state dim;
}
}
state dim // DIM
{
state_entry()
{
llSetColor(<1.0, 0.9, 0.7>, ALL_SIDES);
llSetText("DIM\n(Touch for Bright)", <1,1,0>, 1.0);
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
PRIM_GLOW, ALL_SIDES, 0.1
]);
}
touch_start(integer num)
{
state bright;
}
}
state bright // BRIGHT
{
state_entry()
{
llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES);
llSetText("BRIGHT\n(Touch for Off)", <0,1,0>, 1.0);
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
PRIM_GLOW, ALL_SIDES, 0.4
]);
}
touch_start(integer num)
{
state default;
}
}
For simple ON/OFF behavior, you can also use a variable instead of states:
// Simple Toggle Light (Using Variable)
// Simpler than states for basic toggles
integer isOn = FALSE; // Track state with variable
updateLight()
{
if (isOn)
{
// ON appearance
llSetColor(<1.0, 1.0, 0.8>, ALL_SIDES);
llSetText("ON", <0,1,0>, 1.0);
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
PRIM_GLOW, ALL_SIDES, 0.3
]);
}
else
{
// OFF appearance
llSetColor(<0.3, 0.3, 0.3>, ALL_SIDES);
llSetText("OFF", <1,0,0>, 1.0);
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, FALSE,
PRIM_GLOW, ALL_SIDES, 0.0
]);
}
}
default
{
state_entry()
{
updateLight();
}
touch_start(integer num)
{
isOn = !isOn; // Toggle (! means NOT)
updateLight();
llSay(0, "Light " + (string)(isOn ? "ON" : "OFF"));
}
}
Task: Create an object that cycles through primary colors (red, green, blue) on each touch and announces the current color.
Requirements:
Task: Create an object that counts how many times it's been touched and displays the count in floating text.
Requirements:
Task: Create a three-state traffic light (red → yellow → green → red).
Requirements:
Task: Create an object that remembers and greets the object owner specially.
Requirements:
Use: if (llDetectedKey(0) == llGetOwner())
Task: Create a simple door that opens and closes with different appearances.
Requirements:
Use: llSetAlpha(0.3, ALL_SIDES) for transparency
Task: Create an information kiosk that provides different info on each touch.
Requirements:
| Function | Purpose | Example |
|---|---|---|
llSay() |
Speak in chat | llSay(0, "Hello!"); |
llSetColor() |
Change color | llSetColor(<1,0,0>, ALL_SIDES); |
llSetText() |
Floating text | llSetText("Info", <1,1,1>, 1.0); |
llDetectedKey() |
Get toucher UUID | key id = llDetectedKey(0); |
llDetectedName() |
Get toucher name | string name = llDetectedName(0); |
llGetOwner() |
Get owner UUID | key owner = llGetOwner(); |
state_entry() - Runs when entering a statetouch_start(integer num) - Runs when touchedtouch_end(integer num) - Runs when touch released{} are balancedllOwnerSay() for debugging (only you see it)Congratulations on completing Introduction to Scripting!
You've learned the fundamentals of LSL and can now create interactive objects that respond to touches, change appearance, and maintain different states.