Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

How do I detect the number of responses in a listen()?

Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
01-15-2009 06:22
I'm putting the finishing touches to something that needs to communicate with another object on the same sim using llRegionSay. Since I can't guarantee that there won't be more than one receiver object belonging to the same person rezzed on a sim, and since I certainly can't guarantee that people will RTFM, I need to check that, if my object receives more than one response when it pings receivers on rez, I'm talking to the nearest receiver.

I think the way to do it is to grab the uuid of any responses I get, use that to get each respondant's location using llGetObjectDetails, subtract my location from this, and then sort the results in an ascending list.

This seems to be working well in tests, but I'm a bit worried about giving all potential respondants time to reply to the ping before I sort my list. Using a timer event to sort the list after 5 seconds or so appears to work but doesn't seem amazingly scientific. Has anyone got any suggestions?
Yingzi Xue
Registered User
Join date: 11 Jun 2008
Posts: 144
01-15-2009 09:23
I did the exact same thing for a gift card system. It works fine. I used the object UUID to isolate messages from each object and also used the timeout of 5 seconds. It works fine so far. The only time I can see it not working is if the sim is having poor performance, but if you set your master object to poll the receivers every once in awhile they should be updated anyway.
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
01-15-2009 09:40
In general, there is no guaranteed way. A timeout is probably the best compromise.

If a timeout isn't feasible (i.e., you need to respond quickly, and missing one of the responders isn't easily recoverable), you could use a sensor to count them before asking.

That works best there are 16 or fewer and they're all named the same, which should be the case here. It also doesn't work well if the responders can come and go, because a responder could appear or disappear between checking and sending the message -- you'd still need a timeout (and even then you'd miss a spanking new responder, but that's usually not a problem).

Usually, the first item returned by the scan (llDetectedXxxx(0)) is the closest -- but not always. I don't remember the cases where it's not.
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
01-15-2009 22:04
Thanks, guys. I now feel greatly reassured, particularly to know that Yingzi has used this method successfully. I would, I think, be happier using a sensor, since there's less to go wrong, but I can't rely on things being in range. Nothing to stop me taking a belt and braces approach and using both, I suppose.

Probably tempting fate here, but I guess that, combined with a message to the owner that "I think the nearest object I should be talking to is at .... If that's not where you think it is, we've got problems" is about as close to coving it as I can get.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-16-2009 00:19
I think you've got the basic idea. However, if all you need is the closest responder for each owner, I wouldn't store a list of all that owner's responders. I would just remember the closest, and replace it if I hear from one closer. No REAL sorting required.
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
01-16-2009 06:48
I would encourage you not to use the belt and braces method. It complicates things considerably, increasing the likelihood of bugs, without really increasing reliability. Also, it adds overhead -- especially important if this exchange happens very frequently.

I would use the sensor ONLY if it's important to respond quickly, if a 5 second timeout would cause observably sluggish behavior. (And, first I'd see if I could find an architecture to avoid that even without using a sensor. For example, providing a "connect" button rather than finding the responder each time the object is used.)

Keep it simple, and it'll be far more robust.

Hewee's right, of course: no need to remember all the responses, just the closest one.

I have a product that has to handle only one helper object, when there may be multiple. It simply says "Multiple helpers found, using closest one", and nobody has ever complained or questioned that. In use, I occasionally found myself surprised to learn I'd left another "helper" object nearby, and in my case it's quickly obvious whether it got the right one.

This is in a freebie "product", with rather wide usage (sit target positioner). Of course, you have to figure out whether this applies to your situation.
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
01-16-2009 07:44
My problem's this.

I need to put scripts into rezzed objects. When these scripts run for the first time, they have to locate another object, of a different type, on the sim to exchange information and record their position relative to this object.

It's very important indeed that, if there's more than one object they could chose to exhange information with, they choose the nearest one. Things go spectacularly wrong if they don't.

Because of the distances potentially involved I have to use llRegionSay and, while I do generate a new channel when I've established initial contact between scripts and objects and store that for all subsequent use other than the initial "where are you?", for operational reasons I need to use a preset channel -- a very long negative number -- to establish contact in the first place.

I've discovered in testing that I can't rely on the first answer I receive being from the nearest object if there are more than one.

I found this out the hard way when, in testing, things started to go strangely wrong and I eventually discovered that I was getting interference from an object I'd rezzed on the other side of the sim and forgotten about. Things worked fine after I turned off the hitherto forgotten object, and continued to work after I put something in my scripts to check for the nearest object and then tested with several potential sources of confusion rezzed at various places.

The rationale for my considering a belt and braces approach was that I only really need to use llRegionSay to fix my initial relative positions if I'm out of sensor range, which shouldn't be normally be the case but it may be. So first I would check using llSensor -- which seems to me the simpler option if it's available -- and only call llRegionSay as a fall-back in the no_sensor event.
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
01-16-2009 12:09
It'll be simpler, and I believe more efficient, to just use llRegionSay().
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-16-2009 21:55
Yeah, I'd just use llRegionSay(). It almost always seems simpler when you have control of the other end too, so the scripts can cooperate. Why bother with a sensor if you don't have to? Sensors not only have a reasonably high overhead, but are also imprecise (filter by name and hope nothing else has been given an unfortunate name that collides with your solution, or simply let the script logic take care of it by letting the other end know it needs to reply?).

It's true that nearer objects won't always reply first; you shouldn't assume anything about the order or replies, in fact. The most likely approach I'd use is to send out a query, wait a reasonable period for replies, and use llGetObjectDetails() to test for proximity. You could have the replies include the position of the responder to eliminate the llGetObjectDetails() step if you like, but I generally don't; easy enough to simplify the chat protocol and eliminate a few characters over the wire by using this great new function.