Linden Scripting Language
The state- and event-driven scripting language, with C-like syntax, that residents use to give objects behavior inside the Second Life virtual world.
Created by Linden Lab
Overview
Linden Scripting Language, almost always shortened to LSL, is the language residents write 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 truest sense: rather than running on your own computer through a compiler or interpreter you install, LSL executes inside the simulation itself. A script is placed into the inventory of an in-world object — a primitive, or “prim” — and from then on that object reacts to its surroundings: to being clicked, bumped into, spoken to on a chat channel, or pinged over HTTP.
That model is what makes LSL feel different from a conventional language. Its syntax is borrowed from C, so braces, semicolons, and if/while look familiar, but the way a program is organized — around named states and the events that fire within them — has more in common with programming a reactive embedded device than with writing a command-line tool.
History and Origins
LSL debuted with the public launch of Second Life in 2003 (reportedly June 23). Linden Lab, the San Francisco company founded by Philip Rosedale, conceived Second Life as a world built by its users, and an in-world scripting language was central to that goal: instead of shipping a fixed menu of object behaviors, the platform would let residents program their own. Cory Ondrejka, an early Linden Lab engineer who would become the company’s chief technology officer, is widely credited with driving the design of the scripting system, though the language is most accurately attributed to Linden Lab as a whole.
An earlier, BASIC-flavored language sometimes referred to as LSL1 existed during Second Life’s alpha period but saw little public use; the C-styled language that residents actually adopted — and that the name “LSL” now denotes — superseded it before the public launch. From the start, scripts were compiled to a compact bytecode and run by the simulator (“sim”) process that hosts each region of the world. Because a single 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 or not the script needed it.
The Mono Transition
The largest technical shift in LSL’s history came 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; the language residents write stayed the same.
Rollout was deliberately staged: Mono first appeared on the Beta Grid around January 29, 2008 for compatibility testing against the enormous body of existing scripts, and the production grid was fully able to run Mono by 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 in advance, as the legacy engine had. Identical compiled scripts can also share bytecode, reducing total memory pressure on a busy region.
- Speed. Linden Lab reported that, on compute-heavy benchmark scripts — workloads such as recursion, Mandelbrot-set generation, and similar number-crunching tests — Mono ran up to roughly 220 times faster than the legacy LSL engine. 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 attached rather than as a blanket claim about all scripts.
In principle Mono also made it possible for other languages to target the same bytecode, but in practice LSL has remained the language Second Life residents write.
Design Philosophy
Nearly every distinctive trait of LSL traces back to the environment it lives in — a shared, persistent, massively concurrent 3D simulation:
- Event-first execution. A script does not run start-to-finish and then 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 touch the host filesystem or run native code. They affect the world only through a large library of built-in functions, which protects the simulator and other residents from untrusted, user-written code.
- Familiar on the surface. The C-like syntax was chosen so newcomers could get started quickly, while the language underneath remains a real one, with variables, user 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");
}
}
Frequently 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 instance, is told how many simultaneous touches occurred.
Data types
LSL offers 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 that identifies 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 3D orientation. |
list | An ordered, mixed-type collection of the other types; lists cannot be nested within 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, in effect, 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 functions (around 2013) made structured data exchange with web services much simpler, and the Experience tools framework (around 2015) allowed a set of scripts and objects to share permissions and persistent key-value storage under a single named Experience. These dates mark the general period of each feature; because LSL ships as part of Second Life’s server software, it has 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 itself continues to operate and receive updates. For creators, LSL is simply how things are 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 though 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, but it is a separate ecosystem with its own runtime.
Why It Matters
Linden Scripting Language is a compelling 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 executing 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 just inhabiting it — a notion 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 rely 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.