LSL is an event-driven language. Literally, scripts are divided into blocks of code that are triggered when a certain event happens. Scripts can provide event handlers, like moving_end or touch_start. If a script provides an event handler, and an event of this type occurs, thesimulator will add this event to the script’s event queue.

The script’s event handlers will then be called in the order the events are queued in (FIFO). According to Cory Linden, the event queue can hold up to 64 events. If the event queue is filled, it will silently drop any new events. Remember: LSL is not multi-threaded. Only one event will be run at a time; events cannot interupt each other. There is no way to interact with the event queue directly.

Changing states clears the event queue. Different states can have different event handlers. Be wary of bugs though. For instance, when an event handler is called, all of the arguments for that event handler are passed by value, and thus placed on the script’s stack. If a script has insufficient memory to hold all of the arguments, the script is halted with a “stack/heap collision” error and no code in the event handler will run.

Unlike functions, it’s not possible for scripters to create our own custom event handlers. If you need to check whether or not something has occurred, and it’s not covered by an existing event handler, you’ll need to use the timer() event.

The function llMinEventDelay may be of some use in coordinating events.

Event Triggered
at_rot_target when a rotational target set with llRotTarget is reached
at_target when a target set with llTarget is reached
attach when an object attaches or detaches from agent
changed when certain aspects of the object are changed (inventory, color, shape, scale, texture, link, ownership)
collision while task is colliding with another task
collision_end when task stops colliding with another task, or stops being penetrated while llVolumeDetect is set
collision_start when task starts colliding with another task, or starts being penetrated while llVolumeDetect is set
control when one of the controls taken with llTakeControls is pressed/held/released
dataserver when task receives asynchronous data
email when task receives email
http_response when task receives response to request made with llHTTPRequest
http_request when task receives response to request made with an external HTTP Request
land_collision while task is colliding with land
land_collision_end when task stops colliding with land
land_collision_start when task starts colliding with land
link_message when task receives a link message sent via llMessageLinked
listen when task is within hearing range of chat matching the critera set in llListen
money when money is given to task
moving_end when task stops moving or when task exits a sim.
moving_start when task begins moving or when task enters a sim.
no_sensor when a call to llSensor or llSensorRepeat results in no targets sensed
not_at_rot_target when a rotational target set with llRotTarget is not yet reached
not_at_target when a target set with llTarget is not yet reached
object_rez when task rezzes another task using llRezObject
on_rez when task is rezzed (from inventory or another task, includes attaching directly from inventory)
remote_data any kind of XML-RPC communication
run_time_permissions when an agent grants run-time permissions to task that were requested via llRequestPermissions
sensor Result of llSensor or llSensorRepeat functions
state_entry on any transition into the state and on startup
state_exit on any state transition out of the state
timer in intervals set by llSetTimerEvent
touch while agent clicks on task
touch_start when agent starts clicking on task
touch_end when agent stops clicking on task
transaction_result fired by llTransferLindenDollars

Events FAQ:

Q:  Wait, what’s a “task”?

A:  In LSL parlance, a task is an avatar/agent or an object. Both can collide with an object, though only objects can contain scripts. In the above list, you can generally take “task” to mean “the object containing the script.”


Q:  How do I get input from one event and act on that in another?

A:  Use a global variable to store and recall the data. Global variables can be accessed and redefined from any event or state.


Q:  How do I know which event is going to be triggered, and in what order? This is complicated!

A:  It is, but you can get the hang of it pretty quickly. Say you have state_entry, on_rez and attach events in a script, and you attach the object from inventory. What’s going to happen? Well, state_entry will already have triggered when the script first ran, so it’s not that. on_rez always executes first, even if you attach it, so that’s what will happen first. attach will happen afterwards, unless on_rez contains a state change, or something else to interrupt the state, such as llResetScript or llDie. See: Example Event Order.


Q:  Okay, but what about other events? How do I know when they’ll be triggered?

A:  As soon as something happens to trigger them, in the order that the event occurs in. So if you click on an object, you’ll see touch_start, touch and touch_end, in that order. If the listen event is triggered while you’re still touching the object, you’ll get that after touch. It can be difficult to structure a script, if you need some input from a listen event, and some from touch_start, but you can use global variables to hold data between events.


Q:  What’s the different between an “event” and an “event handler”? I’ve seen both terms used, but they seem to both apply to the same thing.

A:  Properly, an “event” is the thing that happens and an “event handler” is the thing that handles it. In practice, most scripters use the terms interchangably, or favour “event” over “event handler”. This is technically incorrect, but is very common usage.


Q:  Can events interrupt each other?

A:  No, events are run to their completion, in the order that they were received. For example, if you have a while(TRUE); statement (a statement that never finishes executing) in your state_entry event, and someone touches the object (triggering a touch_start event) the touch_start event will never run, because the state_entry event never finishes.


Credit to: (not working) with changes made for brevity and clarity.