LSL
The Linden Scripting Language, an event-driven, state-machine language created by Cory Ondrejka to give objects behavior inside the Second Life virtual world.
Created by Cory Ondrejka (Cory Linden)
LSL — the Linden Scripting Language — is the programming language residents use to give behavior to objects inside Second Life, the persistent 3D virtual world operated by Linden Lab. It is a small, purpose-built language whose entire reason for existing is to let a piece of in-world content do something: a door that opens when touched, a vehicle that drives, a vendor that takes payment and delivers an item, a HUD that tracks a game’s score. Rather than being a general-purpose language that happens to be embedded in a game, LSL was designed from the start around the realities of a shared, always-on, multi-user world — and that shaped almost every decision in its design.
History and Origins
LSL was created by Cory Ondrejka, who joined Linden Lab around 2000 as one of its earliest employees and later served as the company’s chief technology officer. Working alongside founder Philip Rosedale on the architecture of what would become Second Life, Ondrejka was responsible both for designing the scripting language and for writing the engine that executed it.
There were effectively two languages. The first, retrospectively called LSL1, was based on BASIC and was used during the alpha phase of LindenWorld, the prototype that grew into Second Life. It never saw much public use. Ondrejka then wrote the language that residents actually came to know — sometimes called LSL2, but universally referred to today as just “LSL” — a C/Java-flavored, state- and event-driven language. He famously characterized the effort by saying the language “got written in a week, like all scripting languages,” having concluded that he knew more about building a scripting language from scratch than about bending an existing one like Java to the task.
When Second Life launched publicly on June 23, 2003, LSL was the language residents used to script the world. Because the world is user-built, LSL was not an afterthought — it was the mechanism through which the platform’s content came alive.
Design Philosophy
LSL’s design follows directly from the constraints of running untrusted, user-written code inside a live, shared simulation:
- Familiar, C-like surface. LSL borrows its curly-brace syntax, control structures, and overall feel from C (with some resemblance to Java), so newcomers with any C-family background can read and write it quickly. Functions,
if/else,for,while, and typed variables all look as you would expect. - States and events as the core model. Instead of a single
main(), an LSL script is organized as one or more named states, and within each state the script declares event handlers that the server calls when something happens — a touch, a chat message, a timer, a collision. This finite-state-machine model maps naturally onto the behavior of physical objects in a world. - Server-side and sandboxed. Scripts execute on Linden Lab’s servers, not on the viewer, and run under tight memory and execution limits so that one buggy or malicious script cannot destabilize the region everyone shares.
- Small but world-aware. The language deliberately keeps a small core, but exposes a very large library of built-in functions (conventionally prefixed
ll, for Linden Library) that reach into the simulator: moving and rotating objects, applying physics, playing sounds, sending chat, handling money, requesting web pages, and far more.
It is worth noting what LSL is not: despite occasional descriptions to the contrary, LSL is not an object-oriented language. It has no user-defined classes, inheritance, or methods. Its power comes from its event/state model and its rich built-in API, not from an object system.
Key Features
States and events
The defining feature of LSL is its state machine. A script begins in the mandatory default state and can transition to other states. Each state reacts to events:
default
{
state_entry()
{
llSay(0, "Touch me!");
}
touch_start(integer total_number)
{
llSay(0, "Thanks for the touch.");
}
}
Here state_entry runs once when the state is entered, and touch_start runs whenever an avatar clicks the object. Other common events include listen (incoming chat), timer, collision_start, money (payment received), and http_response.
Data types
LSL provides seven types, including three that are unusually high-level for such a small language:
| Type | Purpose |
|---|---|
integer | Whole number |
float | Floating-point number |
string | Text |
key | A UUID identifying an avatar, object, texture, sound, etc. |
vector | Three floats <x, y, z> — used for positions, sizes, and RGB colors |
rotation | A quaternion of four floats <x, y, z, s> for 3D orientation |
list | An ordered, heterogeneous collection that can mix the other types |
The vector and rotation types — with full operator support for 3D math — reflect LSL’s nature as a language for manipulating things in a 3D space. The key type encodes the world’s reliance on UUIDs to refer to every avatar and asset.
The Linden library
Almost everything useful in LSL happens through built-in functions. llSay and llRegionSay send chat; llSetPos and llSetRot move objects; llApplyImpulse drives physics; llGiveMoney and the money event handle the in-world currency; llHTTPRequest and llRequestURL connect a script to outside web services. This large, simulator-aware API is where LSL’s real capability lives.
Evolution
For its first several years, LSL scripts were compiled to a custom bytecode (often called LSO) and run by an interpreter built into the simulator. In 2008, Linden Lab introduced a second execution engine based on Mono, the open-source implementation of the .NET Common Language Runtime. Scripts could now be compiled to CLR bytecode and JIT-executed. The deployment was staged: a beta-grid rollout on January 29, 2008 for compatibility testing, followed by enablement across the production grid on August 29, 2008.
Crucially, the LSL language did not change — the same source code ran on either engine. The benefit was performance. Linden Lab reported that compute-intensive scripts could run dramatically faster on Mono — by figures cited as high as roughly 220× for certain tightly looping benchmarks compared to the older LSO interpreter. That headline number applied to the most favorable, computation-heavy cases; typical event-driven scripts that spend most of their time waiting for events saw far more modest gains, and the practical improvement varied widely by workload. Mono also opened the theoretical door to other CLR-targeting languages, though in practice LSL remained the language residents wrote.
The most significant recent evolution is the arrival of a different language rather than a new version of LSL. In 2025, Linden Lab announced SLua, a scripting option built on Luau (the typed, performance-oriented Lua dialect originally developed by Roblox), extended with Second Life’s function set. SLua entered open beta on parts of the production grid in December 2025, offering cleaner syntax, coroutines, and tables, with reports of roughly 50% lower memory use than LSL on Mono. SLua is positioned as a modern alternative; existing LSL scripts continue to run unchanged everywhere.
Current Relevance
LSL remains the workhorse scripting language of Second Life more than two decades after the platform’s launch. The enormous library of existing content, tutorials, marketplace products, and community knowledge built around it means LSL is not going away even as SLua matures — the two are expected to coexist, with LSL scripts running grid-wide while SLua is rolled out region by region. Beyond Second Life itself, the OpenSimulator project keeps an LSL-compatible dialect alive on self-hosted virtual worlds, so the skills and scripts transfer beyond Linden Lab’s grid.
Why It Matters
LSL is one of the most widely used domain-specific languages ever embedded in a virtual world, and it pioneered a model that later platforms would echo: give ordinary users a safe, sandboxed, event-driven language and let them build the world’s behavior themselves. Its state-machine structure, its 3D-native vector and rotation types, and its huge simulator-facing API made it possible for hundreds of thousands of non-professional creators to script everything from games to vehicles to a real economy of paid content. In doing so, LSL helped demonstrate that user-generated, scripted interactivity — not just user-generated geometry — could be the foundation of a persistent online world.
Timeline
Notable Uses & Legacy
Second Life
Every interactive object in Linden Lab's virtual world — doors, vehicles, vendors, attachable HUDs, gesture systems, scripted clothing and animations — is driven by LSL running on Linden Lab's servers, making it the language behind a large part of the resident-built world.
Second Life creator economy
Independent content creators script products such as furniture with sit animations, weapons and games, rezzers, and vending systems, then sell them on the Second Life Marketplace and in-world stores — LSL skills underpin a substantial part of the platform's user economy.
OpenSimulator
The open-source OpenSimulator virtual-world server implements an LSL-compatible scripting system (and extends it with additional OSSL functions), letting content and skills carry over from Second Life to self-hosted grids.
Education and training in virtual worlds
During Second Life's peak adoption, universities and organizations built scripted classrooms, simulations, and interactive exhibits in-world; LSL provided the interactivity (quizzes, controls, presentations) for these teaching spaces.
Interactive art and immersive builds
Artists and builders use LSL to create reactive installations and immersive environments — particle effects, sound, lighting, and objects that respond to visitors — that would otherwise be static geometry.