Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Synchronizing scripts

Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
05-13-2007 02:25
I have a prim which contains more than one script. One is for rezzing objects and a second for receiving the object_rez event. I need for a timing reason to synchronize these scripts. I am used to the queue and wait technology but cannot see how to implement that in LSL.
Has anyone any suggestions?
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
05-13-2007 09:46
This sounds like a linked message problem. Simplest, least accurate solution might be for one script to send a message that says NOW, waits a tiny bit, and then does the action, assuming the other script will do it at as soon as it hears the message.

more accuracy could be obtained by multi-phase protocol, or by including time information in the NOW message.

There are probably technically correct solutions to this, but alas I have not references to offer you.

You might also be able to use the Regular Timer script...search the script forums.
AnnMarie Otoole
Addicted scripter
Join date: 6 Jan 2007
Posts: 162
05-13-2007 09:48
From: Gregory McLeod
I have a prim which contains more than one script. One is for rezzing objects and a second for receiving the object_rez event. I need for a timing reason to synchronize these scripts. I am used to the queue and wait technology but cannot see how to implement that in LSL.
Has anyone any suggestions?

Have one sit "listening" for a message sent as an llSay() by the other item. The delay is minimal and should synchronize for you. Use a Channel number other than zero so the message is not being broadcast to everyone in the vicinity.

But if you are synchronizing something like sound, it will not work very well since loading times and lag are unpredictable.
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
05-13-2007 10:45
From: Lee Ponzu
This sounds like a linked message problem. Simplest, least accurate solution might be for one script to send a message that says NOW, waits a tiny bit, and then does the action, assuming the other script will do it at as soon as it hears the message.

more accuracy could be obtained by multi-phase protocol, or by including time information in the NOW message.

There are probably technically correct solutions to this, but alas I have not references to offer you.

You might also be able to use the Regular Timer script...search the script forums.
I am trying to avoid the use of linked messages as I have found them to be unreliable, they get dropped if there are too many, and these complicated scripts are using them for other things.
From: AnnMarie Otoole
Have one sit "listening" for a message sent as an llSay() by the other item. The delay is minimal and should synchronize for you. Use a Channel number other than zero so the message is not being broadcast to everyone in the vicinity.

But if you are synchronizing something like sound, it will not work very well since loading times and lag are unpredictable.
No sounds are involved so that might be a workable solution. The exact problem concerns the retrieval of Prim data from rezzed prims while in the middle of rezzing many of them. I am not using linked prims because to do so exceeds the number of prims allowable in some locations and for the reason that delays might occur in the transmitting of the llSay's from the prims with data to be used in the original script. I have tried using a timer event to set up a queue and wait system which I think might work but you can't have more than one timer event in a script. (I think).
Unless you know differently?
Kenn Nilsson
AeonVox
Join date: 24 May 2005
Posts: 897
05-13-2007 12:19
You can only have one timer in a script.

I would say that if you're not keen on the link_messages, an llWhisper() or llSay() is the best way to go in this situation.
_____________________
--AeonVox--

Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms chasing ghosts, eating magic pills, and listening to repetitive, addictive, electronic music.
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
05-13-2007 12:20
From: Gregory McLeod
I am trying to avoid the use of linked messages as I have found them to be unreliable, they get dropped if there are too many, and these complicated scripts are using them for other things.


chat will get dropped too if theres too many, infact anything will

maby you need to rethink your flow control, do a send-do-next-send-do-next and control whats happening vs just overloading the script and hoping they all go tru in order
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
05-13-2007 14:24
From: Osgeld Barmy
chat will get dropped too if theres too many, infact anything will

maby you need to rethink your flow control, do a send-do-next-send-do-next and control whats happening vs just overloading the script and hoping they all go tru in order
That's what worries me, if there is no guarantee that they will get through then the system is broken bigtime. You cant even wait on an event since the events may never happen.
I wonder how anything works that is more than just a single script. My game needs about 15k alone to hold the compressed pattern of positional information. So I chose to split the scripts up, maybe I was wrong in thinking that SL is a workable system, except for buildings.
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
05-13-2007 17:17
(parent script) hey script bob here is some data
(script bob) ok
(script bob) im done
(parent script) super heres some more tasks
(parent script) um bob my TTL just went off whats up
(script bob) what?? i didnt get that command
(parent script) no biggie ill just resend it to you

TTL= time to live

which is only one scereno
RJ Source
Green Sky Labs
Join date: 10 Jan 2007
Posts: 272
05-13-2007 20:06
I've had some good luck with syncing things by using llGetUnixTime() in a master script, adding some wait time, and using that future point for the sync time. Then send that sync time to the other script(s). Once all scripts have the sync time, they each again get the current time, and set a timer event to the difference.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
05-14-2007 00:54
I tend to take Osgeld's approach using linked messages in a request -> responce -> verify sequence (although I usually call my scripts fred)
_____________________
I'm back......
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
05-14-2007 01:11
From: Osgeld Barmy
(parent script) hey script bob here is some data
(script bob) ok
(script bob) im done
(parent script) super heres some more tasks
(parent script) um bob my TTL just went off whats up
(script bob) what?? i didnt get that command
(parent script) no biggie ill just resend it to you

TTL= time to live

which is only one scereno
That looks like a very good approach but I want to complicate the thought process:
Scenario: Two main scripts one to set up a playing board and another to operate it. A third script is in one of many almost identical in prims rezzed by the setup script. The problem comes when after rezzing the prim both the prim's on_rez event fires and the setup prim's rez_object fire. No way to synchronize them and the data sent from the rezzed prim cannot include data it hasn't been sent yet; name, colour, alpha etc.
Add to this the need to rez up to 60 prims from the setup script. I cannot rely on the rez-object events being in the same sequence as the prim rezzing if one or more are missed. This means that data intended for a sepcific third script will not be received correctly (lack of identification of the third script or prim). I suppose I could include the handshaking you propose into all three. The only disadvantage I can see is the long time to wait for the three to agree that they have all the data before allowing the rezzing of the next prim.
From: RJ Source
I've had some good luck with syncing things by using llGetUnixTime() in a master script, adding some wait time, and using that future point for the sync time. Then send that sync time to the other script(s). Once all scripts have the sync time, they each again get the current time, and set a timer event to the difference.
A fair point but the exact time will vary depending on the load on the Sim and thus cannot be used to sequence the scripts. There is no need actually to synchronize them in time just guarantee the sequence see post above.
Alderic LeShelle
Registered User
Join date: 28 Dec 2006
Posts: 104
05-14-2007 02:04
I faced a similar problem, but even on a more complicated base, it concerned scripts situated in three prims, linked into an object.

One of the scripts sending single llMessageLinked() whenever actions are required and both of the 'slave' scripts listening and taking the necessary action proved quite sufficient - though it helps much to have the slave script's code to be highly optimized.

Another approach may be using llSetScriptState() - have the slave scripts stopping themselves at a dedicated point and the master script restarting them as needed. Never did an indepth testing, but it may work.

A third method may work if some latency between the execution command and the scripts actually running is acceptable. Have the execution command send with a timestamp and the slave scripts calculate the needed delay for the timer events by themselves - that would counter delays in message transit - only problem would be the precision of the timer event itself.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
05-14-2007 02:58
What about having the rezer handle the rez_object call and then send the rezzed object's key to the setup script via linked message and wait for a setup complete responce before stepping on to the next object?
_____________________
I'm back......
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
05-14-2007 03:15
From: Alderic LeShelle
I faced a similar problem, but even on a more complicated base, it concerned scripts situated in three prims, linked into an object.

One of the scripts sending single llMessageLinked() whenever actions are required and both of the 'slave' scripts listening and taking the necessary action proved quite sufficient - though it helps much to have the slave script's code to be highly optimized.

Another approach may be using llSetScriptState() - have the slave scripts stopping themselves at a dedicated point and the master script restarting them as needed. Never did an indepth testing, but it may work.

A third method may work if some latency between the execution command and the scripts actually running is acceptable. Have the execution command send with a timestamp and the slave scripts calculate the needed delay for the timer events by themselves - that would counter delays in message transit - only problem would be the precision of the timer event itself.
Now, that IS three new ideas! I will have to examine more closely. Thanks.
From: Newgate Ludd
What about having the rezer handle the rez_object call and then send the rezzed object's key to the setup script via linked message and wait for a setup complete responce before stepping on to the next object?
And yet another new idea. I knew this forum's members would come to my rescue. I may take me some time to test out these methods. Again Thanks.
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
You can use this if you think it might help
05-17-2007 17:32
CODE
integer ch = -5191928;
integer repeat = 2;

// send a message to all the others on the channel
sending()
{
vector color = <llFrand(1), llFrand(1), llFrand(1)>;
integer r = repeat;

// if you want to be sure, send the message more than once.
while( r > 0 ) {
llShout(ch, (string) color );
--r;
}

acting( color );
}

// Do whatever the action is.
acting( vector c )
{
llSetColor( c, ALL_SIDES );
}


default
{
state_entry()
{
//llSay(0, "Hello, Avatar!");
ch = (integer) llGetObjectDesc();
llListen( ch, "", "", "" );
}

listen(integer c, string n, key k, string m)
{
acting( (vector) m );
}

timer()
{
//action();
}

touch_start(integer total_number)
{
llSay(0, "Sending...");
sending();
}
}
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
05-18-2007 14:19
From: Lee Ponzu
CODE
integer ch = -5191928;
integer repeat = 2;

// send a message to all the others on the channel
sending()
{
vector color = <llFrand(1), llFrand(1), llFrand(1)>;
integer r = repeat;

// if you want to be sure, send the message more than once.
while( r > 0 ) {
llShout(ch, (string) color );
--r;
}

acting( color );
}

// Do whatever the action is.
acting( vector c )
{
llSetColor( c, ALL_SIDES );
}


default
{
state_entry()
{
//llSay(0, "Hello, Avatar!");
ch = (integer) llGetObjectDesc();
llListen( ch, "", "", "" );
}

listen(integer c, string n, key k, string m)
{
acting( (vector) m );
}

timer()
{
//action();
}

touch_start(integer total_number)
{
llSay(0, "Sending...");
sending();
}
}
Thanks for the interest and the code sample. I am not sure if I have understood the code properly and will need some time to check it out.
i am deeply into the method outlined above; llSetScriptState. This appears to be working well in the synchronizing of the scripts but needed a llSleep(0.1) to work reliably in a high activity region. I will refrain from passing judgement on whether it all works as well until I have reassembled all the components and scripts changed to use llSay comms. Thanks.
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
05-18-2007 18:14
From: Alderic LeShelle


A third method may work if some latency between the execution command and the scripts actually running is acceptable. Have the execution command send with a timestamp and the slave scripts calculate the needed delay for the timer events by themselves - that would counter delays in message transit - only problem would be the precision of the timer event itself.

Use a timer event to get close, and then a short llSleep() for that last few fractions of a second.
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
05-19-2007 00:45
From: Lee Ponzu
Use a timer event to get close, and then a short llSleep() for that last few fractions of a second.
We seem to be drifting off topic from my original question so I will retire from this thread and leave you to it.