Understanding events
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-01-2007 02:54
I need to find out how the event system works because of a timing problem.
OK scripts execute in the server and cause events to be raised. For example one script says something on a specific channel. The listen commands are checked to see if one of them is waiting on that channel and if there is, the event is raised.
The listen event handler code in that script is executed when: 1 Immediately? 2 When the running script completes? 3 When the running script asks for another event to be raised (kernel interrupt).?
Now compound the situation with more than one script in running state. Is there an order of events being handled. eg Timer events take priority over listen events over touch_* events etc? or is it just one big queue of events to be handled?
There are many subsidiary questions that this will raise. eg dual processor queues, parallel processing, multiple scripted objects executing....
If there is a reference somewhere to how it is set up please feel free to quote it.
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
07-01-2007 03:25
Probably doesn't fully address the questions, but... AFIK, a single script is single-threaded, and so an event handler within a script runs to completion before the next event is dequeued. I don't believe the order of events presented to a script is defined anywhere, but I would *guess* it's just FIFO across all event types. Of course, multiple scripts represent multiple threads, so there's plenty of opportunity for race conditions and deadlocks in interactions among scripts.
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-01-2007 08:35
Thanks for the reply.
I will need to research the possibilities further before I can come to any conclusions as to what my problem is caused by. Could even be my lousy coding.
Is there anywhere a description of the server environment?
The problem is compunded by many objects competing for server processing time so time slicing or usage based allocation raise their heads.
Is there a timestamp on any events accesible from a script?
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
07-01-2007 09:01
From: someone Is there anywhere a description of the server environment? Nothing detailed that I've seen. There's http://wiki.secondlife.com/wiki/Server_architecture. [EDIT: Actually, the lslwiki's "events" entry has a bit of relevant information: http://www.lslwiki.net/lslwiki/wakka.php?wakka=events]. But perhaps there are other sources; since it's really the VM that's of most interest here, one would expect something like that to have informed earlier discussions about Mono. From: someone Is there a timestamp on any events accesible from a script? I don't think so, other than what you might attach yourself.
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-01-2007 11:45
From: Qie Niangao .... one would expect something like that to have informed earlier discussions about Mono. .... I have seen Mono referred to in other threads but cannot find a reference to it. Have you one?
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
07-01-2007 13:19
From: Gregory McLeod I will need to research the possibilities further before I can come to any conclusions as to what my problem is caused by. Could even be my lousy coding.
Is there anywhere a description of the server environment?
The problem is compunded by many objects competing for server processing time so time slicing or usage based allocation raise their heads.
My gut sense it that you're going about this the wrong way. When dealing with a generic event-driven system at this level, my usual strategy is to assume the order of delivery is never predictable. You need to design your code to avoid synchronization problems assuming no knowledge of the order of events, only which events can possibly be received at any given point in time. It might help if you were to describe your problem in more detail, or show some code.
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
07-01-2007 13:21
From: Gregory McLeod I have seen Mono referred to in other threads but cannot find a reference to it. Have you one? Mono is the project to provide .Net on UNIX/Linux based platforms. See http://www.mono-project.com/.
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
07-01-2007 13:32
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-01-2007 14:41
From: Kidd Krasner It might help if you were to describe your problem in more detail, or show some code. I do not like to expose too much of my coding at this time as it is in a rapid state of change. I am on version 5 of the game coding versions 1 to 4 have been abandoned because of limitations in either LSL code or more generic sim limitations. V1 Abandoned because it took 144 prims to make the board. V2 Abandoned because of memory overflow and a single script could not contain all the code required. V3 Abandoned because I could not rely on link messages being received, initially I thought because they were faulty but latterly because they were being dropped. V4 Abandoned because of Alpha sorting problems which did not show up until the late stages of testing. V5 Nearly got abandoned when the scripts started repeating themselves over and over again. Cured by rebuilding the object from scratch and reloading the scripts from offline source and not copying from previous versions. It is now in testing phase. For code example see my thread /54/86/193233/1.html. The problem lies in knowing when the multiplicity of scripts are in synchronization. I had tried to secure that using the llSetScriptState("Main",FALSE) in a script which rezzed objects who on_rez started a parallel script in the source prim which was running all the time to llSetScriptState("Main",TRUE) thus restarting the Main script where it left off. Then the problem of other scripts raising events to be handled seems to be interfering hence the subject
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
07-01-2007 15:32
From: Gregory McLeod V3 Abandoned because I could not rely on link messages being received, initially I thought because they were faulty but latterly because they were being dropped. Generally, though, link_message() is a very reliable event, as long as the queue doesn't overrun (64 deep, I think); they seem like the natural choice for sync pulses.
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-02-2007 00:31
From: Qie Niangao Generally, though, link_message() is a very reliable event, as long as the queue doesn't overrun (64 deep, I think); they seem like the natural choice for sync pulses. I had the belief that link messages were the correct way to communicate between scripts until my many scripts just stopped receiving them all. As you may have seen from the snippets of code I have posted there are many things going on at apparently the same time within my object. Rezzing pieces and responding to their rezzing event notification caused me considerable heartache. Which rez event was which. I did not know quite as much as I do now and it may be that I need to re-visit the abandon decision I made. Your point about the queue length is aposite I had 121 rezzed objects at one point in the build every one of which was raising its on-rez event and needing to notify the main script. Needless to say that caused problems. Two versions later I have reduced the number of rezzed prims to a maximum of about 70 in a full game. I am still looking for the interrupt stucture of the server and how it affects the individual scripts. An event driven system is fine until you cause multiple evnst to be raised of different kinds.
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
07-02-2007 01:59
This may be irrelevant but... I wonder if things could be simplified at all by breaking up the rezzing loop such that, after the first object is rezzed, subsequent ones are rezzed from the object_rez() event of their immediate predecessor. That would be a little slower, but assuming the rezzing is handled in a single script, it can't be all that fast anyway, since llRezAtRoot() sleeps the script for .1 seconds per call (and llRezObject sleeps some function of the rezzed object's mass, I guess).
A more radical approach might be to start with everything already linked together as one object, then llBreakLink() for any prims that are to be separate stand-alone objects--but that could get pretty messy if the stand-alone gamepieces consist of multiple prims. And would require obtaining PERMISSION_CHANGE_LINKS.
Possibly, depending on the mechanics of game play, it may even be easier to just leave everything linked together unless or until pieces are removed or added to the board (except the half-alpha guys from the other thread, which I gather are kinda transient indicators of possible moves and so probably wouldn't warrant linking and unlinking). Then perhaps llDetectedLink() and all the llSetLink* and llLink* functions might be adequate to operate the game. (Or not, depending on the game.)
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-02-2007 08:18
From: Qie Niangao This may be irrelevant but... I wonder if things could be simplified at all by breaking up the rezzing loop such that, after the first object is rezzed, subsequent ones are rezzed from the object_rez() event of their immediate predecessor. That would be a little slower, but assuming the rezzing is handled in a single script, it can't be all that fast anyway, since llRezAtRoot() sleeps the script for .1 seconds per call (and llRezObject sleeps some function of the rezzed object's mass, I guess).
A more radical approach might be to start with everything already linked together as one object, then llBreakLink() for any prims that are to be separate stand-alone objects--but that could get pretty messy if the stand-alone gamepieces consist of multiple prims. And would require obtaining PERMISSION_CHANGE_LINKS.
Possibly, depending on the mechanics of game play, it may even be easier to just leave everything linked together unless or until pieces are removed or added to the board (except the half-alpha guys from the other thread, which I gather are kinda transient indicators of possible moves and so probably wouldn't warrant linking and unlinking). Then perhaps llDetectedLink() and all the llSetLink* and llLink* functions might be adequate to operate the game. (Or not, depending on the game.) Point 1. At most the startup of the game can require 60 pieces to be rezzed. This was taking far too long one at a time so your point 2 was adopted. Point 2. Puzzled me for a long time until I realised that the 'still linked' group of 60 pieces could be made to request permissions to break links but not unlink before I had saved the group. This meant the group could be rezzed as one and then BreakAllLinks actioned. Point 3. If all the pieces were left on the board there would be 121 of them with consequent difficulty controlling the messaging. You are right the llSetAlpha 0.5 with the appropriate color of the player is to indicate which moves are possible and save having to send repeated messages "You can't move there". I estimate that at most an additonal 10 - 15 pieces need to be rezzed for any one move and then one will be selected and the others removed. The starting position piece is indicated by it flashing until either it is selected to allow another starting choice or it is removed when one of the "Dimmed" pieces is selected. Sorry for the long winded explanation but I am sure you will appreciate it. Communication between the multiple scripts necessary because of the ~16k limit on memory is what causes me the most problems. One script no communication necessary but not possible.
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
07-02-2007 08:27
From: Gregory McLeod I do not like to expose too much of my coding at this time as it is in a rapid state of change. I am on version 5 of the game coding versions 1 to 4 have been abandoned because of limitations in either LSL code or more generic sim limitations.
Ah, yeah, now I remember your problem. Off the top of my head, I can think of the following. Apologies if some of these are things you've already done. 1. Provide at least one resynch state. When any of the subsidiary scripts is in this state, all it does is to wait for a command from the controlling script - and possibly a timer to cause it to shut down and derez, or for debugging purposes. Make sure that one of the events in this state is purely validation that the event is in this state, both to the controller script and to you, for debugging. This will give you a grounding point, a point at which you can be sure all the objects are in the same state and can be transitioned the same way. Also, don't do anything in this state that causes a delay, other than changing states. So no dataserver, IM, etc. 2. Provide a single resynch command that every other state in the subsidiary scripts can handle, and which forces them into the above state. 3. You might also want to provide an 'empty queue' operation, which would cause a script to set a timer and ignore all linked messages until the timer goes off, and then transition to a above resynch state. 4. Get a lot of scrap paper, and draw state transition diagrams, lots of them. Number them so that it's easy to keep them matched with your code. For each state, indicate the possible event sources (listen, linked message, timer, etc) and constraints (who is allowed to send such a command). Periodically review your code so that it matches thoroughly. 5. Make sure all your event handlers validate the events they get, both syntactically and the source (i.e. which other objects or scripts, if any, can trigger the event). 6. Look for loops. In particular, prefer explicit prim numbers when using llMessageLinked to send linked messages. This raises question to which I don't know the answer, namely whether the limit of 64 linked messages applies separately to each prim receiving the message or to the object as a whole.
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
07-02-2007 09:35
From: Kidd Krasner This raises question to which I don't know the answer, namely whether the limit of 64 linked messages applies separately to each prim receiving the message or to the object as a whole. The lslwiki ( http://www.lslwiki.net/lslwiki/wakka.php?wakka=events) suggests that each script gets 64 events of all kinds combined in a single queue. Reading that page again, I'm reminded that "changing state clears the event queue" which might be relevant to #3, the 'empty queue' operation.
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-02-2007 11:30
Good thinking Chaps.
On the subject of state changes I am thinking that a main script could act as a sort of "Queue central". I am accustomed to using queue and wait coding and it saves a lot of hassles. So thinking on my keyboard and not with any preplanning do you think the following worth investigation.
A main script in a linked prim by itself with a link message event handler. It receives requests for queue events which include the response channel and/or prim linknumber the time interval to wait and the number of occurrences. The main script then makes a new entry in a queue which contains a number of counters, one per queue event using the lowest interval required. It multplies the other counts by the new factor if the time interval is shorter than previously set. When the timer event triggers it checks the queues and gives the appropriate message (link or chat) to the originator of the queue request. If the queu entry was a one of and the interval requested was the smallest the llSetTimer is increased and the number of counts remaining divided by the factor difference in time interval. How say you?
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
07-02-2007 15:34
From: Gregory McLeod Point 3. If all the pieces were left on the board there would be 121 of them with consequent difficulty controlling the messaging. Just to clarify, I was actually suggesting that the linked gamepieces would contain no scripts at all, and be "remote controlled" from one or more scripts in the root prim. (There may be good reason why this isn't viable anyway, but the intent was to actually simplify the messaging.) As for "Queue central," dunno if it's quite on-point, but my main scripts often evolve into most-global state-orchestration, with another script handling most of the message-passing among communication media and muxing among slave scripts to get around delays in llInstantMessage(), etc. But the description sounds like quite a lot of infrastructure, and I'm having trouble imagining just what underlies the complexity of events and states that necessitates queues managed by the script itself. (Hmmm... does the game have "turns" between/among players, or can any player make a move at any time? If the latter, things could indeed get pretty complicated.)
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-03-2007 01:03
From: Qie Niangao ... (Hmmm... does the game have "turns" between/among players, or can any player make a move at any time? If the latter, things could indeed get pretty complicated.) It is a conventional game where the game players take turns, so perhaps not as complicated as I think it is. When you get too close to a problem it takes on a life of its own and obscures the real need 'a simple solution'.
|
|
Boss Spectre
Registered User
Join date: 5 Sep 2005
Posts: 229
|
07-03-2007 22:28
Just wondering... I came to this discussion late lol
Have you considered rezzing an item which consists of all of your (unlinked) game pieces taken all at once in Edit? You'd still get lots of object_rez events at once, but I don't know if you had considered rezzing a "multiple" object, to cut down on rez time.
|
|
Gregory McLeod
Registered User
Join date: 21 Oct 2006
Posts: 278
|
07-04-2007 00:57
From: Boss Spectre Just wondering... I came to this discussion late lol
Have you considered rezzing an item which consists of all of your (unlinked) game pieces taken all at once in Edit? You'd still get lots of object_rez events at once, but I don't know if you had considered rezzing a "multiple" object, to cut down on rez time. I have in part used that technique, although I am not sure what you mean by 'unlinked game pieces taken all at once in edit'? The need is to have individually addressable pieces and I have used the link number plus start_param in the on_rez event to specify which chat channel they will respond to. The method I have adopted is split in two. The first part where the initial pieces need to be rezzed altogether before removing the unneeded ones (depends on number of players 2-6). The second to individually rezz the needed pieces as they become required. The starting position for the pieces is fixed (bar removing uneeded) so I linked the complete set of pieces, set the permissions to break links and took it into inventory then put it in the prim with the Setup script. This works fine. I still have a problem which last time I tried did not work which was after rezzing a piece it needs to be 'colored' and 'dimmed' the rez would work but the coloring and dimming would not (reliably). The discussion we are having relates to this fundamental problem of the timing of events, their position in a queue or queues and their priority in being presented to the scripts for action. I have used the llSetScriptState("Main",FALSE) technique with a companion, always running, script to restart Main when it receives a message from the rezzed object's (on_rez event). This is causing timing problems as far as I can detect. Your input is appreciated, thanks.
|