Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Moving a large number of child prims?

Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
01-19-2008 15:44
In the past, I've handled this by having a script in each child prim, and sending broadcast link messages from the root. Is there a better way to do it? I'm experimenting with llSetLinkPrimitiveParams, but the built-in delay makes the movement very 'sequential'. I can hide all the prims, move them, then reveal them, but that puts a delay of several seconds while everything's transparent. Remote script loading will be worse, since that would need to iterate through prim UUID's with a 3 second delay.

Anything else I didn't think of? There's no way to broadcast-set-script-state on all child prims, is there.

This is for a HUD with multiple buttons and open vs. closed positions (hence the movement), in case that helps.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-19-2008 16:35
You could take care of the script delay by putting a bunch of scripts in the root prim that use llSetLinkPrimitiveParams(). That way you can also disable the helper scripts with llSetScriptState() when they aren't doing their job.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
01-19-2008 17:22
Ah, llSetScriptState doesn't have a delay. OK then, that's the solution. Still needs a truckload of scripts, but at least they're turned off most of the time.

Thanks :)
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
01-19-2008 18:52
Hmm, I guess this is just how the scheduler works? In the main script:

for (i = 0; i < n; i++)
{
llSetScriptState("Some Prefix " + (string)i, TRUE);
}

llMessageLinked(LINK_THIS, 9999, "", NULL_KEY);

The child scripts set their state to FALSE in state_entry. The first time after a reset, this function in the main script always fails, i.e. nothing happens. The next time, it works. I haven't tried enough attempts to see if it randomly fails later or not.

But if I add a 0.1s sleep before sending the link message, then it works. So... I'm guessing the other scripts get put in some kind of a "ready to be woken" state, but they're not yet awake and their event queues aren't yet active? So making the main script sleep for a bit gives the system time to prepare the other scripts?

I don't think I've ever encountered something like this before, where the asynchronous event system needs an llSleep 'nudge' to get it working :) But I haven't worked with turning scripts on and off like this too much.

Anyway... this may be common knowledge, but it had me stumped for a few minutes, so I thought I'd share.

Edit: Nope, it still fails sometimes. So either it needs a longer delay, or it's something else. Back to debugging.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
01-19-2008 19:33
having played with sleeping scripts before I noticed a delay between starting them and the server picking them up (triggering events) and had to script in a reset and a wakeup message w/ comfirmation

if you can you might want to place all the subs in one prim, perhaps with a single running script that makes use of the description field, have the subs read from that on wakeup, then execute their instructions and perhaps auto shutdown
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
01-19-2008 19:35
This was in the comments section of the wiki. Author unknown:

"this function seems to be buggy if you switch 2 scripts on/off dependend which linkedmessage it receives. condition call within link_message-event seems so that it doen´t stop on next condition. it runs through next condition although it doesn´t get a linkedmessage which met the condition. seems to me that it searches 1st condition met and runs all code behind that condition. quite annoying...:("

Don't know if that helps....................................
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
01-20-2008 08:49
Thanks, I'll try those suggestions. The slave scripts are all in the root prim now.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
01-20-2008 13:30
"New Script"

default
{
state_entry()
{
llSay(0, "Hello, Avatar!";);
llSetScriptState(llGetScriptName(), FALSE);
}
}

"New Script 1"

default
{
touch_start(integer total_number)
{
llResetOtherScript("New Script";);
llSetScriptState("New Script", TRUE);
}
}

This fails every other time. Reverse the sequence (i.e. set it to running, then reset it), and it appears to work every time.

So... if a script shuts itself off, then you reset it, and turn it on, it won't always execute state_entry. This is different from how it works through the UI, where if I click Reset and then click the 'running' checkbox, it appears to always execute state_entry.

Anyway... I'll proceed with the "turn on, then reset" approach, move the code from link_message to state_entry, and see if that works reliably.

Once again, thanks for the help.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-20-2008 13:39
I wouldn't count on anything affecting the other script (including resets, communication, etc.) to work until that script has been woken. So the order in which I would always do it is wake all the scripts you want to behave themselves, sleep for a fraction of a second to let the system process it, then do all the stuff that depends on their behavior.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
01-20-2008 15:01
From: someone
So the order in which I would always do it is wake all the scripts you want to behave themselves, sleep for a fraction of a second to let the system process it, then do all the stuff that depends on their behavior.


That's what I had earlier, and it didn't work, at least with sleeping 0.2s and then sending out a broadcast link message - the scripts should have been awake, but they didn't process it. Now I'm waking them and then resetting them, and that seems to be more reliable.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-20-2008 15:26
Bah. Well, worst case you can just not pause them. Sometimes that's what you get for trying to be nice. Heh heh.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
01-20-2008 15:37
Dumb thought #2190238:

What about doing a reset on the other script before it is turned off? Then even if the "turn off" command is processed 1st, maybe, just maybe the reset will be waiting in que????
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-20-2008 16:02
Is there a reason resets need to be used at all? Why not just link messages and global variables and/or states? Most of my work with llSetScriptState() has been turning on/off one other script at a time, but also I tend to make script resets pretty rare occurances. Not sure which is the key to mine working smoothly, but they have so far either way.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
01-20-2008 16:11
In case you EDIT: "do" want to stick with the reset then what I suggested is working:

CODE

integer reset = -1;
default {
touch_start(integer total_number) {
if(reset == 1){
llResetOtherScript("New Script");
llSetScriptState("New Script", FALSE);
llOwnerSay("other script off");
}
else{
llSetScriptState("New Script", TRUE);
llOwnerSay("other script on");
}
reset *= -1;
}
}

used with:
CODE

default
{
state_entry()
{
llSay(0, "I am reset & running");
}
}

"[16:06] Object: other script off
[16:09] Object: other script on
[16:09] Object: I am reset & running"
The reset isn't being processed until the other script is turned back on.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
01-20-2008 18:48
From: someone
Is there a reason resets need to be used at all?


No. The only reason I'm using it is because the following isn't working:

* Wake up other scripts
* Wait a bit
* Send them a link message saying "go"

That seems to be the logical way to handle a scenario like this, but it does not appear to be working.

From: someone
Why not just link messages and global variables and/or states?


In the master or the slave? Using states/globals in the slave means leaving it running, and then I can just use link messages. I'm trying to avoid having a bunch of active scripts that don't do anything 99% of the time.

From: someone
In case you EDIT: "do" want to stick with the reset then what I suggested is working:


I don't actually have a trigger to turn the other script off from the main script, nor do I need one. The slave scripts need to be woken up on a trigger. When they're awake, they each know exactly what to do, after which they can go back to sleep. So, I'd have to roll those two cases into one block, I think, and I'll probably end up in some other weird timing problem :)

So, since link messages don't seem to work reliably, I've put the "know what to do" part inside state_entry, and am using the script reset to be the 'reliable' trigger for when the other script runs. The "wake, then reset" sequence seems to work so far, at least a lot better than "wake, then send message".
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
01-20-2008 23:55
wonder if this might work...

CODE

default{
state_entry(){
//-- do stuff
llSetScriptState( llGetScriptName(), FALSE );
llResetScript();
}
}
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
01-21-2008 09:34
How do I trigger that? Oh, set that script to running from the outside? Hmm... might be worth experimenting with. It still calls wake/sleep/reset, just in different places. And according to the Wiki, sometimes a script will execute the next instruction or two before it actually gets turned off. So if it resets and starts on the state_entry code, that wouldn't work for me. Interesting idea though.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
01-21-2008 09:45
you could always add some do nothing code between setting it to false, and the reset, maybe even that sleep you had trouble with in the waking script... but I'm guessing even in a fast sim it won't get through a reset before it shuts down.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -