Don't click here unless you want to be banned.

LSL Wiki : Hacks

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are


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

With sensor, collision, and touch events, the object type being dealt with can be detected with llDetectedType. This is not so with listen events. To determine whether the key returned by a listen is an agent or not, you can check the agent's size. Objects return ZERO_VECTOR, agents return their size.

integer isAgent(key id)
    return (llGetAgentSize(id) != ZERO_VECTOR);


    listen(integer channel, string name, key id, string msg)
            llSetColor(<0,1,0>,ALL_SIDES); //Prim turns green if an Agent speaks
        } else
            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). -BW

Short-Distance (In-Sim) faked "Teleportation"

If using a large offset vector with llSitTarget, 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, integers, rotations, or vectors, 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.

integer num = 1;
string str = "hello";
string str2 = "goodbye";

llMessageLinked(LINK_SET, num, str, (key)str2);

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 (using llSetObjectName/llGetObjectName) and description (llSetObjectDesc/llGetObjectDesc) 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, alpha, scale, 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.

llSetTexture 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 conditional statement's brackets.

    state foo; 
// Doesn't compile.

    if(1 == 1)
        state foo;
// Compiles.

See this page for more details.

llSetPos > 10m per call

llSetPrimitiveParams executes its rules as it comes across them, so if a list has multiple PRIM_POSITIONs in it, each one will be executed. This allows the 10m limit on llSetPos to be avoided.

See WarpPos 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). -Christophe003Carter

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)

integer idGrid()
    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
    touch_start(integer total_number)
        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

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 in world.

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:

Making 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:[LSL_STRING]

You can change it back any time by repeating steps 1-3, and selecting "Reset to default"

str_replace Workaround

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:
string str_replace(string search, string replace, string subject)
    return llDumpList2String(llParseStringKeepNulls(subject,[search],[]),replace);

str_replace("@","_","Hello@world! The@method@is@working@properly.");
// 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:

llSetVehicleType(VEHICLE_TYPE_AIRPLANE); // Works with any other vehicle type if you are using this for an LSL vehicle.

LSL Style Guide | Lag
Comments [Hide comments/form]
Key instead of inventory name has always been, and will always be acceptable in LSL. There was a bit of a heated discussion about its proposed exclusion in v1.2 (or was it 1.1?) and LL decided it was best to keep the functionality.
-- ChristopherOmega (2004-04-01 15:17:30)
the "consequences" link in the "Change state within a function" section is broken since the forum change. What are the consequences of this piece of code?
-- NeoRebus (2004-07-05 15:44:40)
It fucks up the stack. You should never use it. It's a bug and it will hopefully be fixed soon.
-- EzharFairlight (2004-07-05 17:50:17)
You just have to be very careful about using it. It basicly clears the stack out completely, from any depth within the stack (it doesnt even finish the current running event). That might cause some internal problems (memory leaks?), but I didnt see any with my tests on it. You can blame the dead link on LL, who recently fucked up the forums. Dont use the state-change hack on functions that are supposed to return a value, since when you are trying to return a string or list, and change state within the function, the VM throws a Runtime Bounds Error.
-- ChristopherOmega (2004-07-05 18:36:07)
It seems that the three above comments are now outdated, Ive created a new page with updated information on the state change function hack here: FunctionStateChangeHack
-- ChristopherOmega (2005-02-21 22:14:43)
EzharFairlight, this is a PG wiki. Do not use the F word. If you need to use it, mask it like this: fk.
There are Teen Grid residents here too! (like me)
-- Flarn2006 (2006-07-11 14:39:49)
Whoops! I mean like this: F asterisk asterisk K
-- Flarn2006 (2006-07-11 14:41:35)
Closing bold tags.
-- CatherineOmega (2006-07-11 18:48:16)
You may want to look at the wiki formating syntax Flarn2006
-- BlindWanderer (2006-07-12 03:06:50)
This doesn't quite make sense to me: "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."

What are they trying to say?
-- SuezanneCBaskerville (2006-10-21 11:06:24)
I think it is relating to the set/get texture rotation/alpha/color etc. Because it cannot be stored as an integer (unless your using 1 and 0 only).
-- ZeeraXi (2006-10-22 12:54:39)
I hope everyone doesn't mind but I removed the profanity from this page. It's unprofessional to have this in developer documentation (and, as mentioned above, inappropriate since this is a PG wiki).

Second Life is beginning to be seen more seriously by businesses and having profanity hurts things in the long run.
-- (2007-05-07 09:53:43)
As of version 1.18.5(3) The limits on string length stored in a prim's Name and Description fields are 255 characters for Name, and 127 characters for Description. If a script attempts to store longer strings in these fields you can get strange results. (When I tried longer strings it seemed to work, but when I took the object into inventory it then refused to rez again.)
-- (2007-12-04 12:17:24)
Attach a comment to this page: