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

LSL Wiki : llListen

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org
integer llListen(integer channel, string name, key id, string msg)

Sets a filter for listening to the specified chat channel while the current state persists. If a message is heard that meets the specified criteria, the object's listen() event handler is invoked.

Messages are heard from the root prim of a link-set, not the scripted prim, making this command awkward for use in large builds. To avoid this causing a problem, keep root prims towards the center, or most used part, of your builds.

The name, id, and msg arguments specify the filtering criteria. You can pass the empty string (or NULL_KEY for id) for these to set a completely open filter; this causes the listen() event handler to be invoked for all chat on the channel. To listen only for chat spoken by a specific object or avatar, specify the name and/or id arguments. To listen only for a specific command, specify the (case-sensitive) msg argument. You can also use all the arguments to establish the most restrictive filtering criteria.

Caution: The id is the key of the originator of the chat. In the case of an agentandavatar it will coorespond with llGetOwner. In the case of an object the key of the root prim (which changes on rez) is returned not the key of the owner of the prim. To verify that a chat message emitted by an object is owned by a particular agentandavatar (as is often the case with HUDs) use llGetOwnerKey and compare that with the value returned by llGetOwner inside the listen event.

This function returns a handle that can be used to deactivate or remove the specific channel filter using llListenControl and llListenRemove. An object should remove any filters it has established when it no longer needs them. Listen filters DO NOT persist and are automatically removed on state changes. The returned handles start at 1, so you can set your handle variable to 0 (zero) when you deactivate a channel and test for that elsewhere when you need to know if it's active or not.

Using many instances of llListen can have a visible effect on sim performance and cause lag. If there is a viable alternative communication method such as llMessageLinked, consider using that instead. Especially avoid listening on channel 0 whenever possible. If you must listen to regular chat conversation, use a filter if possible.

If a script with an llListen "hears" a string longer than the script's amount of available free memory, it will halt with a "stack/heap collision" error before your code in the listen() event handler has a chance to begin executing. As of SL v1.13, a single chat string on any channel can be up to 1023 bytes in length.

Examples

Establishes a completely open filter for avatar chat:
integer handle  = llListen( 0, "", NULL_KEY, "" );

Sets a filter that listens only for chat spoken by the object's owner:
integer handle = llListen( 0, "", llGetOwner(), "" );

Sets a filter that listens on channel 96 for objects named "button":
integer handle = llListen( 96, "button", NULL_KEY, "" );

This could be used, for example, in an elevator that responds to button objects on different floors of a building. Each button object would have the same name, but could identify its floor through the specific message it sends.

To set up to 65 filters on different channels, call llListen repeatedly with different criteria. All messages found by any filter are passed to the same listen event handler. If llListen is called again with the identical criteria, the same listener handle is returned, and the listen() event will only be called once.

If a script goes over its limit of 65, it crashes with a run-time "Too Many Listens" error.

As of SL 1.5.4, the following does work correctly:
llListen(0, "Froggy", "", "");
llListen(0, "", llGetOwner(), "");

To listen on a single channel, for both chat from the owner and from an object with a certain name, (or any other combination of logic) the best option is to use a single llListen function and an if-else in the listen event.

Selling scripts which contain listeners can be problematic if the id parameter is set to llGetOwner. Be sure to update listen filters or use llResetScript when it changes owners if a script's listeners are set to only listen to their owner.

Example

default
{
    state_entry()
    {
        // listen on channel zero for any chat spoken by the object owner.
        llListen(0,"",llGetOwner(),"");
    }
    
    listen(integer channel, string name, key id, string message)
    {
        // check if the message corresponds to a predefined string.
        // llToLower converts the message to lowercase.
        // This way, "HELLO", "Hello" or "HeLLo" will all work the same way.
        if (llToLower(message) == "hello")
        {
            // if the message from the owner is "hello", respond with "Hello.".
            llSay(0,"Hello.");
        }
    }
}


Potential Issues

Crosstalk

One common problem that is easy to forget about when creating a fancy new scripted widget is crosstalk. This occurs when objects get confused about whose messages are whose. This can be two identical objects which mistake each other's messages or other people's objects which happen to use the same channel and may send problematic (partially compatible and invalid) messages.

There are a number of ways to deal with this problem. A few are listed here:


This is a common issue and the solution can vary widely based on the requirements of a particular problem.

I know that it is listed that 64 listens per script is the limit but i was able to put in 65. Now 64 may be a suggested limit for memory useage reasons or something but I fit 65 listen functions into 1 script all in 1 state and 1 event and the script had no errors and works fine.
- BlablablakGumbo
It is not a memory constraint it is a specific run-time error, the wiki is simply wrong the number is 65 not 64, add one more listen to your script and it will fail with two errors


FAQ


Q: I can see how the millions of scripts out there listening to channel 0 would collectively create lots of lag. But, with the callback mechanism and a listener on a private channel, it seems like the only time resources would be used is when an actual message is present. Is this the case?
A: Well, the real server-side problem is the filter. When a script listens on channel 0, it calls the filtering methods every time it hears something. This doesn't create a lot of lag, but tons of these without good use of callback can create some effect on server resources.

Q: Can a wildcard be used for the msg argument? I only want to monitor text that begins with "ls" but can be anything after it ("on", "off", "silence", etc).
A: Wildcards are not supported. You'll want to use llGetSubString or llSubStringIndex in your listen() event.

Q: How close to my listener do I have to be for it to hear me?
A: When saying chat, under 20m. When shouting, 100m. See chat for specifics with dealing with the other chat functions.
A2: Also, more recently, llRegionSay has been implemented, which allows communication throughout an entire sim. Though it cannot chat on channel 0.'



This article wasn't helpful for you? Maybe the related article at the LSL Portal is able to bring enlightenment.

Functions | Events | Chat | Communications
There are 15 comments on this page. [Display comments/form]