Hacks are usually undocumented features, surprising unexpected consequences, or unintended uses of features of LSL
and Second Life
. Given the crazy-glue-and-duct-tape nature of hacks, there is no guarantee that a hack that works today will work tomorrow, or will work in exactly the same way.
This page is not a guide to hacking the client
, an act which is against the TOS.
Agent Key Determination
, and touch events
, the object
type being dealt with can be detected with llDetectedType
. This is not so with listen event
s. To determine whether the key return
ed by a listen is an agent
or not, you can check the agent's size. Objects return ZERO_VECTOR, agents return their size.
listen(integer channel, string name, key id, string msg)
llSetColor(<0,1,0>,ALL_SIDES); //Prim turns green if an Agent speaks
llSetColor(<1,0,0>,ALL_SIDES); //Prim turns red if a scripted object speaks
Very useful in an intercom system, so you don't relay spammy vendor ads too!
Note: this will not work across sim borders as llGetAgentSize only works on keys of agents in the current sim. Using llGetOwnerKey on a key not in the simulator will return the key passed to it. If you use it to check if a key is an agent it will falsely identify invalid keys (if using it on a key returned from a listen and the chat originated from a neighboring sim, the key will be invalid).
Short-Distance (In-Sim) faked "Teleportation"
If using a large offset vector
, and then llUnSit
when detecting the changed
event, an effective short-range (up to 300m as of 1.3.0) teleporter
can be made that works when a resident
chooses to "Sit
" on the object. (Note that this is not the same as actually teleporting
; it just looks that way to the user.)
2-String Linked Message Transmission
Because a key is really just a fancy string
, a second string can be substituted instead of the key and llMessageLinked
can send it without typecasting
However, because there's no limit to the length a string can be, it's primarily useful as a way to organize data by reducing the amount of work the recieving script must do to parse input. Also, having two strings already seperated is marginally more efficient then having one string and later parsing it into two.
Note: as keys cannot be directly typecast to or from floats
s, or vector
s, if the intended second message is one of these types, first cast
it to a string, then to the type of choice. The inverse is true when recieving the message.
Permanent Small-Memory Information Storage
Besides using a script's memory
as permanent storage (and just never resetting
it), a script can store short strings in the object name
) and description (llSetObjectDesc
) of each prim. If the object is not going to change it's name, use child prims
in a link
set for that. Floats can also be stored in other object properties such as texture rotation, offset
, etc. Basically anything that has a get/set combination. To store integers, you can simply convert them to floats and back by scaling them down to fit into the usual 0 - 1.0 range.
can also store strings using the typecast (but the object will always have to have full permissions
to read back the data), as well as llSetAlpha
for floats, llSetColor
for vectors. Combined, a lot of information can be stored permanently.
Note: The llSetTexture
hack no longer works attempting to specify a texture that is not a valid texture key or not the name of a texture in the objects inventory will return an error "Couldn't find texture (your string)"
In-Function State Change
Usually, the compiler
gives an error
when the state
tries to change from within a function. There is a workaround to this though: put the state change within a condition
al statement's bracket
// Doesn't compile.
if(1 == 1)
See this page
for more details.
llSetPos > 10m per call
executes its rules as it comes across them, so if a list
has multiple PRIM_POSITION
s in it, each one will be executed. This allows the 10m limit on llSetPos
to be avoided.
for more details and code
Please note WarpPos no longer appears to work in havok4 sims. (In havok4 sims you see the seperate jumps, but less delay then llSetPos).
Detect Which Grid Script is running on
If you use an external system to keep track of sales on your vendor, you don't want People on Beta Grid messing up your tidy book keeping, by simply buying something from you. Here is a simple but slow routine to identify which Grid a script is running on (if you know a faster way than llGetSimulatorHostname, please correct me)
list Grids = ["agni","teen","dmz","colo","siva","durga","aditi"];
string server = llGetSimulatorHostname();
list serverParsed = llParseString2List(server,["."],);
string grid = llList2String(serverParsed, llGetListLength(serverParsed) - 3);
return llListFindList(Grids, [grid]);
//Update by Bobbyb30 Zohari to llOwnerSay v. llSay
integer grid = idGrid();
if(grid == 0)
llOwnerSay("You are on the Main Grid.");
else if(grid == 1)
llOwnerSay("You are on the Teen Grid.");
else if(grid == 2)
llOwnerSay("You are on the Linden Only Grid.");
else if(grid >= 3)
llOwnerSay("You are on the Beta Grid.");
llOwnerSay("I don't recognize this grid!");
Local Application Launching via llLoadURL
functionality can be altered to allow for user initiated interactions between the SecondLife
Client and applications running on the same computer workstation.
On Windows machines, the HKEY_CLASSES_ROOT\HTTP\shell\open\command can be modified to a batch or command line processing application, resulting in llLoadURL
calls executing the specified application. This has the unfortunate side effect of breaking any other standard uses of llLoadURL
Alternatively, changes could be made to a machines host file or the machine's local IP address could be specified in a URL and a webserver run on the local machine.
Discussion of usage: http://forums.secondlife.com/showthread.php?t=110251
Making lslwiki.net the default WikiHelp in the SL LSL Editor
If you prefer to use this
wiki as your reference when writing LSL script inworld, you can change the SL client's LSL Wiki Help
menu option (on the Help menu in the LSL Editor) to link here instead of the default LSL Portal:
1) If you cannot see the "Advanced" menu option (or "Client" and "Server" for older versions) on the Menu Bar of your SL client program, you need to turn on DEBUG mode:
Press: CTRL-ALT-D (or CTRL-ALT-SHIFT-D on some systems)
This will toggle these hidden menu options on and off.
2) From the Advanced (or Client) menu, select "Debug Settings"
3) A small window will open, use the dropdown menu, or type it in, to find the key: LSLHelpURL
4) Change the value to: http://www.lslwiki.net/lslwiki/wakka.php?wakka=[LSL_STRING]
You can change it back any time by repeating steps 1-3, and selecting "Reset to default"
Since there's no nifty way to simply have all instances of a substring replaced at once, you can use llParseStringKeepNulls
(to avoid losing replaced character on the end of a string) and llDumpList2String
to do it for you. The method looks like this:
// Returns: Hello_world! The_method_is_working_properly.
Rotating an object you're sat on without affecting Mouselook
A very useful trick if you are trying to make a sittable object which rotates according to the user's Mouselook camera rotation; this works both for physical and non-physical objects. Put those 2 calls in the state_entry
of a script within the object that is sat upon:
LSL Style Guide