Jump to content

Closing listens...


Life Camino
 Share

You are about to reply to a thread that has been inactive for 4562 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I was just wondering what the considerations are regarding open listens and when they should be closed?

I'm working on a little space shuttle that can be operated by a HUD, including starting, stopping, cloaking,  color and texture changes, etc.  so I feel like I need my listens open all the time in the ship script so it can hear commands from the HUD.  Is this a problem?  Or, is there a good way to manage the listens properly while meeting the requirement that the ship always hear commands from the HUD?

And, can leaving listens open cause any kind of problems either in the script they are in, other scripts in the object, or for the client?

Thanks, for any insight you can offer on this subject. 

Link to comment
Share on other sites

The channel is important, listening for everything on channel 0 will not make you many friends.

According to the wiki, llRegionSay is the most efficient chat use:

http://wiki.secondlife.com/wiki/LlListen

llRegionSayTo might be useful for you, both of these of course only communicate within the same region.

http://wiki.secondlife.com/wiki/LlRegionSayTo

Link to comment
Share on other sites

main considerations for open listens:

  • Avoid them when it's possible (Often not for command menus from huds)
  • Never use PUBLIC_CHANNEL (zero), or DEBUG_CHANNEL (21474836487)
  • Always filter as tightly as possible, in the llListen call if you can, or in the listen event for things you can't
  • Try to pick an unused channel, using a mostly unique one based on the Object or Owner key may prevent collisions (may not be possible for commands that need to be enterable from user chat as well)

you can filter to only the owner AND owners objects inside the listen event if you check the object owners key against the owners key with
if (llGetOwnersKey( source_key ) == llGetOwner(){
this works because avatars own themselves

there is some debate as to whether llRegionSay is more efficient, in some cases it may be in other it may not, but llRegionSayTo is definitely more efficient, but requires the target key and only works within the same region. an easy way to get that key is to have the hud listen for a static one word message from the item, check that it belongs to the same owner and store the key of that item.

Link to comment
Share on other sites

You should always leave an open listener if you want to control your object with a HUD. But make sure not to use the public channel 0 as the others mentioned. Because the listener will check every chat on its'  targetchannel.

 

I use to generate the listener channels from the object owner key. 

 

Add integer channel; to your script header.

Then in your state_entry()- event add this:

channel=-(integer)("0x"+llGetSubString((string)llGetOwner(),0,7));

 

Make sure to reset the script either on owner changes or better on rez or it will always use the old channel for every owner.

 

Link to comment
Share on other sites

1. you mentioned "listens" that means many, in terms of lag, i suggest to try and stick to one, and different messages.

2. use a negative channel of course.

3. on listen event, check :  if(llGetOwnerKey(id) == llGetOwner())

only than you are sure that its your HUD posting the message.

4. dont forget to use llRegionSay on the hud, because you want to be able to control it from far.

 

 

Link to comment
Share on other sites


Eve Neutron wrote:

2. use a negative channel of course.

[...]

4. dont forget to use llRegionSay on the hud, because you want to be able to control it from far.

@ #2, this advice isn't nearly as useful as it used to be... this used to be to avoid avatars chatting one the same channels, but now avatars can (via llTextBox), it's also bad if you want the hud to be optional

@ #4 as noted above "region say" is limited to the source region, and controlling an item from afar is not always a desirable goal (for instance, attachments and vehicles)

Link to comment
Share on other sites

I remember someone asking a couple of years ago about whether it's wiser to open and close new listeners as you need them or to open a single listener and then switch it on or off with llListenControl, but I don't recall the consensus in this group.  I rarely use llListenControl, but now that the OP has raised the question here, I wonder if I should.  Would it make a difference, or is it a wash?

Link to comment
Share on other sites

personally I never use the function... the code tends to be a bit clunky with it, especially if you have need for more than one. When I do close listens I use a state change, even if all that state does is jump back to the previous state (sometimes a script reset, but that's kind clunky too)

as to which to aim for ::shrugs:: depends on what you are doing... if it has to accept commands frequently or on demand from something other than an av you're pretty much stuck with an open listen. there are a few hack around to avoid it, but some of those (like polling properties) are uglier than just leaving it open and filtering tightly. I do recommend one over many though

Link to comment
Share on other sites

Thanks, Void. That's about what I figured, which is why I haven't used llListenControl much either.  When it makes sense, I too prefer to let a state change close any listeners that might be open.  When an extra state isn't worth the hassle, I often open a llListen and trigger a timer at the same point, and then close the listen with llListenRemove either at the start of a listen event or in the timer event.  I've never been able to see any reason for using llListenControl instead, so I'm glad to hear that you don't either.

Link to comment
Share on other sites

Ok I have a question about using state changes to remove a listener... What happens if you get an event when you are in the second state? 

 

As an example, say you are in state1 with some listeners and a timer running, then jump to state2 to close them. In the instant before you jump  back, the timer runs out and sends the script a timer event...  What if something crazier happened and you got several events... the timer fired and someone touched it, and a collision occurred?

 

Stuff like that keeps me up at night. :P

 

 

Link to comment
Share on other sites

I agree with Void.  While llListenControl or turning listens on and off specifically might reduce overhead a little, if you use listens reasonably following the advice above you should be OK.

When considering performance and the effect on a sim, the question to ask is HOW MANY.  At the bottom, you want to get to how many times your listen handler is invoked and the code inside it runs and does something.  The "innermost loop" as it's sometimes called, somewhat incorrectly.

The thing that many people forget to consider is that a big factor in answering this is a number of other "how many"s.  For example:

1) how many of these scripts will be rezzed within "earshot"?  (using llRegionSay, the region.  Using llWisper, 10M.) In most cases, like the case here, there's just one.  In many other cases, considerably more, so more caution is required, such as poseballs.  For an extreme obsurd example, consider a horridly coded resizer script in a popular brand of 200-prim hair.  (Not that I know of such a case, where resizers use listens in each prim, but you get the idea.)  I did have a friend who was proud of his building skills but wondered why his sims always lagged, and the reason was he left the alignment scripts (skidz or whatever) in all his prims after he was done!  Nearly every prim in the region ran a script with a listen!)

2) how many chats match the llListen filters.  Void made a point of this above, and correctly so.  The most important one here is usually the channel, picking a good unique channel filters out nearly all "crosstalk" -- objects hearing messages meant for other objects.  Any other filters you can apply such as, for a HUD, the owner, also help and should be used.

3) how many chats matching the filters are actually intended -- again as Void pointed out, a few quick sanity checks can avoid "crosstalk" quickly.  Ideally there should be nearly none of these.

The worst case is listen for any text from anyone on channel 0.  This wil fire the scripts Listen event handler for everything anyone in hearing range says.  If there's only one script like this nearby, even then it's usually not a problem.  But we've been burned by sloppy coders of popular objects like poseballs, and so in a hangout spot we might have dozens of scripts processing everything said by anyone -- this is the total fail case that caused people to be concerned about this subject in the first place.  It should be avoided in almost all cases, with the exceptions being either very important functions that can't operate any other way (translators), or novelties that we pull out for a laugh, use for a little while, then put away (possibly forever).

In LSL, anything that only happens say once per second in a region is insignificant in terms of the region's performance.  But if we have thousands of scripts running, and a big chunk of them are doing something once a second, we start to see slow script performance ("script lag", where it takes a while to say, open a door, but the sim works fine otherwise).

Note that bad scripting with listens generally only causes script lag, and does not cause anyone's frame rate to go down, or rubber-banding when you try to move, etc.  The exception to this is when too many scripts use too much memory causing the sim to thrash, which REALLY socks it.  So, in most cases, "lag" isn't caused by bad scripts.

Link to comment
Share on other sites


Lycia Undercroft wrote:

Ok I have a question about using state changes to remove a listener... What happens if you get an event when you are in the second state? 

It depends on the design of your state machine and the overall logic of what you're making.

UNFORTUNATELY (and I'd like to crucify whoever made this decision), all queued events are deleted on a state change.  This means it's actually impossible to build a classical state machine using LSL states (lol).

As Void says, in most cases, our devices aren't too susceptible to loss of a single event.  Most times, it's a click, and the users provide the fault tolerance by clicking again.  The only time you need to worry about this side effect of state changes is when you design a fairly sophisticated system where multiple scripts are communicating, and losing one message would cause a failure.  In this case, don't change states, or build fault-tolerance into the communications architecture (e.g., with acnowledgments and retries).  (gak)

  • Like 1
Link to comment
Share on other sites

Lear beat me to it, but this is how I design all of my scripts that require listens:

 

  • I always like to have my script doing nothing when idle, including removing unnecessary listens.
  • If I require a perpetual listen, I only use one listen and use the simplest method to verify if the messages are meant for my script--checking for a key, value or string within the received data before processing anything.  By design, I try not to have perpetual listens, but sometimes it's unavoidable.
  • Listens that don't need to be perpetual have timeouts (dialog menus, for instance) after x seconds, thus removing the listen.  This keeps listens to a minimum.  The general rule is to keep the script idle until interacted with by an avatar.
  • If any listens need to be turned on/off repeatedly using the same channel, I use llListenControl.
  • I hardly ever use states.  I find I can achieve the same result (i.e. a switch) with boolean integers and much less code.
  • Keep chat messages to a minimum by combining data into as few messages as possible.  One message per interaction is what I always strive for.
  • Multiplicity.  As was stated earlier, you have to conceptualize how your script will be used and how many will be used in a sim.  One script may not cause much of a dip in sim performance, but if you multiply that by 10, 20, 50, 100 what would the performance be?
  • I always try to keep my functionality within one script rather than compartmentalizing in multiple scripts.  Most of the time it's unnecessary to have multiple scripts.  The memory usage will be slightly higher with multiple scripts.
  • More often than not, if I have multiple objects that need to interact with each other, the client/server or one-to-many/many-to-one relationship seems to be the most efficient.  Instead of having 20 clients listening, have one server listening; set the clients on timers for communication to the server.

If I can close a listen that I don't need, or find a different way, I will.  You just have to be creative.  Writing efficient scripts isn't hard.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4562 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...