Linden Scripting Language (LSL)
The event-driven, state-based scripting language with C-like syntax that residents use to give behavior to objects inside the Second Life virtual world.
Created by Linden Lab (notably Cory Ondrejka)
Overview
Linden Scripting Language, almost always written LSL, is the language residents use to give behavior to objects inside Second Life, the long-running virtual world operated by Linden Lab. It is a domain-specific language in the strictest sense: you do not install a compiler or interpreter and run programs on your own machine. Instead, a script is dropped into the inventory of an in-world object — a primitive, or “prim” — and from that moment the object reacts to its surroundings, responding when it is clicked, collided with, spoken to on a chat channel, or contacted over HTTP.
Its surface syntax is borrowed from C — braces, semicolons, and familiar if/while constructs — but the way a program is organized sets LSL apart. Code is structured around named states and the events that fire within them, a model that has more in common with programming a reactive embedded device than with writing a command-line tool. The result is a language whose every quirk can be traced back to one fact: it runs inside a shared, persistent, massively concurrent 3D simulation.
History and Origins
LSL debuted with the public launch of Second Life on June 23, 2003. Linden Lab, the San Francisco company founded by Philip Rosedale, set out to build a world made by its users, and an in-world scripting language was essential to that vision: rather than ship a fixed menu of object behaviors, the platform would let residents program their own. Cory Ondrejka, an early Linden Lab engineer who later became the company’s chief technology officer, was chiefly responsible for the scripting system, though the language is most accurately attributed to Linden Lab as a whole.
An earlier, BASIC-flavored language sometimes called LSL1 existed during Second Life’s alpha period but saw little public use. The C-styled language residents actually adopted — known internally as LSL2, and what the name “LSL” now denotes — superseded it before the public launch. From the beginning, scripts were compiled to a compact bytecode and executed by the simulator (“sim”) process that hosts each region of the world. Because one region can run thousands of scripts at once, the original virtual machine enforced strict limits — most famously a flat 16 KB of memory per script, reserved whether the script used it or not.
The Mono Transition
The single largest technical shift in LSL’s history arrived in 2008 with the Mono scripting engine. Mono is an open-source implementation of the Common Language Infrastructure (the runtime that underpins .NET), and Linden Lab adopted it as a faster execution backend. Under Mono, LSL source is compiled to Mono bytecode that the simulator then runs — but the language residents write was left unchanged.
Rollout was deliberately staged. Mono first appeared on a beta grid in early 2008 for compatibility testing against the enormous existing body of scripts, and reached the production grid as Second Life Server 1.24 on August 29, 2008. Two improvements mattered most to scripters:
- Memory. The per-script ceiling doubled from 16 KB to 64 KB, and Mono allocates only the memory a script actually uses rather than reserving the full block up front, as the legacy engine did. Identical compiled scripts can also share bytecode, easing total memory pressure on a busy region.
- Speed. Linden Lab reported that on compute-heavy benchmark scripts — number-crunching workloads such as recursion and tight mathematical loops — Mono ran up to roughly 220 times faster than the legacy LSL2 engine, according to the company’s own benchmark figures. That figure is a best case for math-intensive code; typical event-driven scripts, which spend most of their time idle waiting for events, see far smaller gains. The “220x” number should always be read with that benchmark context rather than as a blanket claim about every script.
In principle Mono also opened the door to other languages targeting the same bytecode, but in practice LSL has remained the language Second Life residents write.
Design Philosophy
Nearly every distinctive trait of LSL follows from the environment it lives in — a shared, persistent, real-time 3D world running untrusted, user-written code at scale:
- Event-first execution. A script does not run start-to-finish and exit. It stays dormant until the world raises an event, runs a short handler, and goes back to sleep. This keeps the cost of hosting thousands of scripts manageable.
- States as structure. Each script is divided into named states, and every state holds its own event handlers. Changing state (
state running;) swaps which behaviors are active — a clean model for objects with distinct modes, like a door that is open versus closed. - Sandboxing for safety. Scripts cannot reach the host filesystem or run native code. They affect the world only through a large library of built-in functions, protecting the simulator and other residents from arbitrary user code.
- Familiar on the surface. The C-like syntax was chosen so newcomers could start quickly, while the language underneath remains a real one — with variables, user-defined functions, and ordinary control flow.
Key Features
States and events
Every script must define a default state, where execution begins. Behavior is expressed as event handlers placed inside a state:
default
{
state_entry()
{
llSay(0, "Click me to begin.");
}
touch_start(integer num_detected)
{
llSay(0, "Switching on.");
state running;
}
}
state running
{
state_entry()
{
llSetTimerEvent(1.0);
}
timer()
{
llSay(0, "tick");
}
}
Commonly used events include state_entry (a state is entered), touch_start (an avatar clicks the object), listen (chat is heard on a channel), collision_start, timer, and http_response. Handlers receive parameters describing what happened — touch_start, for example, is told how many simultaneous touches occurred.
Data types
LSL provides seven built-in types:
| Type | Description |
|---|---|
integer | A 32-bit signed whole number. |
float | A single-precision decimal number. |
string | A run of characters in double quotes. |
key | A UUID identifying an avatar, object, texture, sound, or other asset. |
vector | Three floats in angle brackets, used for positions, RGB colors, and velocities, e.g. <1.0, 0.0, 0.5>. |
rotation | A quaternion of four floats (x, y, z, s) describing a 3D orientation. |
list | An ordered, mixed-type collection of the other types; lists cannot be nested inside lists. |
The presence of vector and rotation as first-class types reflects exactly what LSL is for: scripting objects that move and turn through 3D space, where quaternion math is part of everyday work.
The ll function library
Almost everything a script does to the world flows through built-in functions whose names begin with ll (for Linden Lab): llSay and llOwnerSay for chat, llSetPos and llSetRot for movement and orientation, llListen for hearing chat, llHTTPRequest for web calls, llGiveInventory for handing items to avatars, and hundreds more. Because all interaction with the world is mediated by these calls, the function library is effectively the Second Life platform API.
Evolution
After the Mono switch, LSL grew mainly by adding functions and capabilities rather than by reworking its core syntax. Networking expanded through HTTP — outbound requests with llHTTPRequest and an inbound HTTP-in server that lets external systems drive in-world scripts. Native JSON helpers (around 2013) made structured data exchange with web services far simpler, and the Experience tools framework (around 2015) let a set of scripts and objects share permissions and persistent key-value storage under one named Experience. These dates mark the general period of each feature; because LSL ships as part of Second Life’s server software, it carries no conventional version numbers and evolves through incremental, server-side updates.
Current Relevance
More than two decades after launch, LSL is still the native language of Second Life, and the platform continues to operate and receive updates. For creators, LSL is simply how things get built: anyone who wants a HUD, a scripted outfit, an in-world game, or an interactive venue writes LSL. That keeps a steady ecosystem of scripters, tutorials, open-source snippet collections, and marketplace products active around the language, even as it sees essentially no use outside its home world.
By design, LSL is tightly bound to Second Life. It is not a general-purpose language you install and run locally, which is why no standalone Docker image or local toolchain is listed here. The OpenSimulator project — an independent, open-source virtual-world server — implements a largely compatible scripting dialect (often extended through OSSL functions), but it is a separate ecosystem with its own runtime.
Why It Matters
Linden Scripting Language is a striking example of a language shaped almost entirely by its runtime environment. Its event-and-state architecture, its sandboxed ll function library, its quaternion-aware type system, and even its original 16 KB memory budget all follow directly from the demands of running untrusted, user-written code inside a shared, real-time 3D world. LSL helped make Second Life one of the first mainstream spaces where ordinary people programmed a persistent virtual world rather than simply inhabiting it — an idea that echoes through later user-scripted worlds and the broader “metaverse” conversation. As a domain-specific language, it stands as one of the most widely used and longest-lived scripting languages ever created for a virtual world.
Timeline
Notable Uses & Legacy
Second Life marketplace creators
Independent residents script furniture, vehicles, weapons, games, and gadgets for sale on the in-world and web marketplaces, sustaining a long-running, user-driven virtual economy.
Avatar customization and fashion
Designers depend on LSL for animation overrides (AOs), resizer and texture-change menus, and HUDs (heads-up displays) that let wearers tune clothing, accessories, and mesh bodies.
Education and training environments
Universities and institutions have built interactive classrooms, role-play exercises, and data visualizations in Second Life, using LSL to make objects respond to learners.
Roleplay and combat communities
Combat meters, quest systems, and inventory mechanics across roleplay regions are implemented in LSL, with scripts handling damage, state, and region-wide messaging.
Interactive art and live venues
Builders script reactive installations, particle shows, and venue automation — lighting, seating, and tip jars — that respond to nearby avatars through LSL events.