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
There are 13 comments on this page. [Display comments/form]