Ayumi Faith Posted September 14, 2015 Share Posted September 14, 2015 I am trying to get a object to say a random line from a notecard every 1 min or so. But I can only get it to work when you touch it. I don't want it to work when touched.here is what I got so far.string card = "Announcement"; key linecountid; key lineid; integer linemax; integer random_integer( integer min, integer max ) { return min + (integer)( llFrand( max - min + 1 ) ); } default { state_entry() { linecountid = llGetNumberOfNotecardLines(card); llSleep(10.0); llPlaySound("953d8b35-cdae-f316-92f6-92bf3c2264e1",0.02); llSleep(2.0); //############################################################# // lineid = llGetNotecardLine(card, random_integer(0, linemax)); llSay(0, llGetNotecardLine(card, random_integer(0, linemax)));//I can't get it to read a random line from notecard. //llSay(0, dataserver(data)); // linemax; //############################################################## llSleep(0.1); llResetScript(); } dataserver(key id, string data) { if (id == linecountid) { linemax = (integer)data - 1; } else if (id == lineid) { llSay(0, data); } } } This line works when I use it in a touch_start(integer total_number)lineid = llGetNotecardLine(card, random_integer(0, linemax)); I have no clue what to do to get it to work right. Can someone tell me what I need to do to get it right. Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted September 14, 2015 Share Posted September 14, 2015 Create a timer event, and put the line inside it that you have previously got working in a touch event. Comment out the llResetScript line, and put a line llSetTimerEvent(60.0); Every 60 seconds, the timer event will occur, and it should fetch a random line from the card for you just as it had from the touch. You probably also want to add a changed event, test for CHANGED_INVENTORY, and reset the script if true. Link to comment Share on other sites More sharing options...
Ayumi Faith Posted September 14, 2015 Author Share Posted September 14, 2015 Thank you so much this worked. string card = "Announcement";key linecountid;key lineid;integer linemax;integer random_integer( integer min, integer max ){ return min + (integer)( llFrand( max - min + 1 ) );}default{ state_entry() { linecountid = llGetNumberOfNotecardLines(card); llSetTimerEvent(10.0); } timer() { llPlaySound("UUID",0.1); llSleep(2.0); lineid = llGetNotecardLine(card, random_integer(0, linemax)); } dataserver(key id, string data) { if (id == linecountid) { linemax = (integer)data - 1; } else if (id == lineid) { llSay(0, data); } }} Link to comment Share on other sites More sharing options...
Miranda Umino Posted September 14, 2015 Share Posted September 14, 2015 In this case , it s maybe preferable to use a sensorrepeat . Because your script ( if you use a timer ) will try to speak even when there is nobody at the range and so triggers some events for nothing. For instance if you have the script inside a skybox , and people are in other skybox or at the ground , using a timer will continue to run when it s not expected. If you use a sensorrepeat , some events will be triggered only if there are some people , and every 60 seconds . It s when the sensor is triggered , there is the request of a new line : It s when the datserver is triggered , there is the display of message . string card = "";key linecountid;key lineid;integer linemax;integer random_integer( integer min, integer max ){ return min + (integer)( llFrand( max - min + 1 ) );}float timePeriod = 60.0;default{ state_entry() { card = llGetInventoryName(INVENTORY_NOTECARD, 0); if ( card != "" ) { linecountid = llGetNumberOfNotecardLines(card); } else { llOwnerSay("No notecards in the inventory"); } llPlaySound("953d8b35-cdae-f316-92f6-92bf3c2264e1",0.02); llSleep(2.0); } sensor(integer n) { lineid = llGetNotecardLine(card, random_integer(0, linemax)); } dataserver(key id, string data) { if (id == linecountid) { linemax = (integer)data - 1; if ( linemax > 0 ) { llSensorRepeat("", NULL_KEY, AGENT, 20, PI, timePeriod); } else { llOwnerSay("Notecard ["+ card +"] is empty , or has no rights , or contains embedded datas ( textures, LM etc )\nReplace it "); } } else if (id == lineid) { llSay( 0, data ); } } changed(integer c) { if ( c & CHANGED_INVENTORY ) { llSensorRemove(); card = llGetInventoryName(INVENTORY_NOTECARD, 0); if ( card != "" ) { linecountid = llGetNumberOfNotecardLines(card); } else { llOwnerSay("No notecards in the inventory"); } } }} Link to comment Share on other sites More sharing options...
Estelle Pienaar Posted September 14, 2015 Share Posted September 14, 2015 Wait! Your sensor also triggers every 60 seconds, even if nobody is there. A sensor event might very well take more resources than a timer and a short dataserver event. I am not a specialist in the impact of different events on sim resources but lets say that I am sceptical. A sensor is one of the most resource heavy LSL function calls/events out there! Link to comment Share on other sites More sharing options...
Miranda Umino Posted September 14, 2015 Share Posted September 14, 2015 No , my sensor doesn t trigger every 60 seconds .. You make a mess between the 1 ) test of the simulator to know which event should be trigerred ( some code written by Linden in C++ and who runs fast ) 2 ) and the execution of the trigerred event ., ( the code written by yourself in LSL who runs slow ) + the execution to "load" the event ( written by Linden ) If you set a timer of 60 seconds : the first part is always executed :: the simulator needs to make a test if 60 seconds are elapsed when 60 seconds are elapsed , the second part ( the code written by yourself ) is always executed If you set a llsensorrepeat of 60 seconds : the first part is always executed :: the simulator needs to make a test if 60 seconds are elapsed , and needs to detect if an avatar is in range when 60 seconds are elapsed , the second part ( the code written by yourself ) is not always executed Of course the first part of the llsensorrepeat consumes more CPU than the the first part of the timer. But the second part of the llesensorrepeat will consume less CPU than the second part of the timer . And the second part will be considerably slower than the difference of time in the first part between sensorrepeat and ttimer Indeed , there is probably a save of states of variables ( on the disk ) , there is the load in memory of the script ( may cause too a disk operation ) ., the resume of o thread paused , the compilation JIT of the methode/event if it s the first time it runs , the cleanup of the memory with garbage collector and a lot of other stuff and finally your code . Link to comment Share on other sites More sharing options...
Estelle Pienaar Posted September 14, 2015 Share Posted September 14, 2015 With all due respect, I don't make a mess of anything. I am making the assumption that triggering a timer event and a very short dataserver event every 60 seconds uses less scripting time than one sensor event every 60 seconds. This might be right or wrong. I am curious for the opinion of other scripters on the subject. From "Scripting your World" book: llSensorRepeat() is a very costly LSL activity, in terms of server effort, and also has problems if there's a lot of lag." To come back to the original discussion, one way to make the the timer event script more efficient could be to use an llGetAgentList call and only run the dataserver event when no "zero vector" is returned. Link to comment Share on other sites More sharing options...
irihapeti Posted September 15, 2015 Share Posted September 15, 2015 Estelle Pienaar wrote: To come back to the original discussion, one way to make the the timer event script more efficient could be to use an llGetAgentList call and only run the dataserver event when no "zero vector" is returned. yes. agree you got it right in the timer event do that. get the list of agents, check if any in chat range and are on the parcel. then do the data server + just add making sure that the avatar is on the parcel is something that gets missed sometimes. Can drive our near neighbours who on their own parcel bananas if we dont mind out for them, with these kinda things Link to comment Share on other sites More sharing options...
Miranda Umino Posted September 15, 2015 Share Posted September 15, 2015 Your book has been written several years ago , at time when llgetagegentlist didn t exeist . at time too when some functions to monitor and mesaure teh scripts didn t exist neither at time too when the compiler mono was not well established... So it can t be a reference for performances To add, i have nor readen it , but i am sure that this book talks about timers ,and it didn t told that the timers were free-lag. And last point : has it talked about sensors when it detects some objects ( so max15000 present in the sim , and so an high probability to be triggered ) or when it detects avatars ( so max 100 in the sim, 40 max in the mainland , and a few probability to be triggered in comparing ) ?? The probability is totally different JUST USE YOUR LOGIC !!! When you code some stuff who will be executed 100 times in one script , and exactly the same stuff who will be executed 50 times in one another script , which one is the laggest ??? This is exacly what you do ith a timer in the case of the OP ( of this thread ) : The code you have written inside the timer will run every 60 seconds , without condition , when the code code you have written inside the sensor won t run every 60 seconds : if there is nobody in range , the sensor is not triggered and doesn t run .. Point ! Nobody is always connected to SL : with a timer your script will run 24hours/24hours , 7 days/ 7days , even if there is nobody at the chat range , even when there is nobody in the same parcel , and even when there is nobody in the sim . With a sensor it will run only when there are people nearby Of course , if your script codes at the same time sensor() ( triggered only when someone is nearby ) and no_sensor() ( triggered only when nobody is nearby ), your events will be always triggered , as a timer , and you may replace it with a timer . But it s not the case of the OP . He needs only one type of event . It s worst to use llgetagentlist in this case : what does the OP : he wants to chat in a range of 20 meters with llsay .. Why should he grab the keys of avatars ? If he did this , he did useless and consuming work . Why should he detect the avatars who are outside of the 20 meters range .. In the case of OP , the OP doesn t care about the informations about avatars : the ony thing interesting for his script is "is there someone nearby" , because it s useless and consuming work to send messages , even when there are nobody to receive the messages You increase the work of the script in doing this . Your version with llgetagentlist will be totally innefficient in comparing. Link to comment Share on other sites More sharing options...
Qie Niangao Posted September 15, 2015 Share Posted September 15, 2015 Oy. Firstly, the differences in execution time among all the approaches under consideration are barely measurable, so barely worth mentioning. Nonetheless, as long as we're this deep into it already... I do think llGetAgentList() costs more than the sensor in this case. (I'd measure it, except I don't have high confidence that all the entailed execution time is fully apportioned to per-script measures, particularly for sensors.) I think, however, it's an unwarranted leap of faith that there's a win to be had in testing for any agents in range, no matter how that test is done. For one thing, we don't know if there is ever a time when there won't be at least one agent within 20m of the scripted object. If this is in the landing zone a busy commercial sim, any such test is wasting time. And note how much more we care about wasted time when there are actually agents in range than when, in contrast, there's nobody on the sim at all. So even if this isn't the busiest sim on the grid, I think it's a few orders of magnitude more important to avoid unnecessary computation when there's somebody around than when there's not. From which I conclude: don't spend time testing whether there's somebody in range to save time only when nobody is around. I'd also observe that, compared to the old days, Mono dramatically reduces the overhead of in-script calculations. It's still a win to get stuff done by built-in functions, but it's much a different trade-off now than before. (Again, though, it can be really tricky to get comparable measurements.) Finally, specifically to this case, if the notecard isn't that huge, by far the greatest efficiency win would be to read the whole thing into one long list of strings, once, so the script never needs to see a dataserver event until reset by the CHANGED_INVENTORY of a new notecard. The approach does use some memory, but it's been years now since memory has been a common problem in even the busiest sims. Link to comment Share on other sites More sharing options...
irihapeti Posted September 16, 2015 Share Posted September 16, 2015 i am biased in my approach (how I think about things) toward small parcel coding where dif owners are in close proximity. bc is my main experience. small parcel ownership what sensor dont do is restrict to only finding on own parcel. So the sensor will return agents who arent on our parcel in a small parcel environment. So we have to check whether they are by loop thru the count examples sensor(integer d){ // here we only got 1 choice // if we dont want to spam the neighbours while (~(--d)) { // find the 1st agent who is on the parcel if any if (llAgentOverLand(llDetectedKey(d)) { Say(); return; } }}timer(){ list a = llGetAgentList(AGENT_LIST_PARCEL, []); integer d = llGetListLength(a); // here we got 2 choices // 1. can Say() when anyone is on our parcel, or // 2. can loop thru and only Say() when find the 1st agent in range } in the sensor() way there is two loops performed necessarily 1. the server loops to build a list of agents in range2. our code loops again to check for on parcel in the timer() way there is one loop performed necessarily 1. the server loops to build a list of agents on parcel the 2nd loop is discretionary/optional for us to do or not + another issue with sensor() in small parcel environment is: there is a sensor limit to how many agents are found. In small parcel environment then if the neighbour has lots of agents on it, then is quite often that any agents on our parcel are missed in the sensor scan when loop thru checking for agentOverLand then they not in the list at all. So they never get the Say() we want to direct at them Link to comment Share on other sites More sharing options...
Miranda Umino Posted September 16, 2015 Share Posted September 16, 2015 Your object is at < 128, 128, 30> and there is an avatar who is at <128, 128, 4000> : - the avatar is on your parcel . - but he is totally outside of the range of the llSay . The volume in range llWhisper = 4/3 * Pi * r*r*r = 4 189 meters cube llSay = 4/3 * Pi * r*r*r = 33 3510 meters cube llgetangentlist for a parcel of 32*32meters footprint = 32* 32 * 4096 = 4 194 304 meters cube . It s not the worst case for timer/llgetagentlist : your parcel could be non-squared and give worst results So , no : in the case of OP who needs to talk only in a chat range , and not to everybody in the parcel , timer + lllGetAgentList is a VERY worst solution than llSensor A small parcel , is small only in surface , not in volume . ========================================== For the call to dataserver Qie wrote :Finally, specifically to this case, if the notecard isn't that huge, by far the greatest efficiency win would be to read the whole thing into one long list of strings, once, so the script never needs to see a dataserver event until reset by the CHANGED_INVENTORY of a new notecard. The approach does use some memory, but it's been years now since memory has been a common problem in even the busiest sims.totally agree with this point . Link to comment Share on other sites More sharing options...
Ayumi Faith Posted September 16, 2015 Author Share Posted September 16, 2015 I don't want to bug my neighbours with this. Just to shine some light on what am doing I got this from the market place LINK and it was shouting the announcement. So I want to make my own. This is what my script looks like as of now. string card = "Announcement";key linecountid;key lineid;integer linemax;integer random_integer( integer min, integer max ){ return min + (integer)( llFrand( max - min + 1 ) );}default{ state_entry() { llSetPrimitiveParams([ PRIM_TEXTURE, ALL_SIDES, "f75823f3-f2df-bcde-c398-09724eafaef4", <1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>, 0.0 ]); llSetObjectName("GLaDOS"); linecountid = llGetNumberOfNotecardLines(card); llSetTimerEvent(300.0); //1800sec = 30mins | 600 = 10min | 300 = 5min } changed(integer change) { if (change & CHANGED_INVENTORY) //note that it's & and not &&... it's bitwise! { llOwnerSay("I feel like I have gained more knowledge."); llPlaySound("038483a4-6b7d-5f14-d782-2b7a656041ae",0.5); llSleep(0.1); llResetScript(); } } timer() { llPlaySound("59411461-3f3c-dc31-106f-a31827865c3f",0.5); llSetPrimitiveParams ([PRIM_POINT_LIGHT, TRUE, <1.0, 0.0, 0.0>, 1.00, 2.0, 0.75]); llSetPrimitiveParams( [ PRIM_GLOW, ALL_SIDES, 0.05 ] ) ; llSetPrimitiveParams( [ PRIM_FULLBRIGHT, ALL_SIDES, TRUE]); llSetPrimitiveParams( [ PRIM_COLOR, ALL_SIDES, <1.0, 0.0, 0.0> ,1.0]); llSleep(2.5); lineid = llGetNotecardLine(card, random_integer(0, linemax)); llSleep(0.5); llSetPrimitiveParams ([PRIM_POINT_LIGHT, FALSE, <0.0, 0.0, 0.0>, 1.00, 2.0, 0.75]); llSetPrimitiveParams( [ PRIM_GLOW, ALL_SIDES, 0.0 ] ); llSetPrimitiveParams( [ PRIM_FULLBRIGHT, ALL_SIDES, FALSE]); llSetPrimitiveParams( [ PRIM_COLOR, ALL_SIDES, <0.000, 0.122, 0.247> ,1.0]); } dataserver(key id, string data) { if (id == linecountid) { linemax = (integer)data - 1; } else if (id == lineid) { llSay(0, data); } }} Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted September 16, 2015 Share Posted September 16, 2015 On a long timer event such as you are now using a lot of the earlier discussion points become academic, I don't see any real problems with what you are doing. So long as the object is positioned more than 20 metres from the nearest that a person in an adjoining parcel cen get to it, there souldn't be any issue with unwanted chat. You could always change the llSay to an llWhisper if necessary to further drop the range. In similar instances in my island I have experimented with long-interval timers starting a single sensor scan looking for anybody inside a certain range, and an alternative with a sensorRepeat, and although the differences in script time are small enough to be not worth worrying about, I find the timer followed by a sensor works best for me. The point about reading a notecard into a list of strings and accessing them that way is worth you looking at for a next development. Link to comment Share on other sites More sharing options...
irihapeti Posted September 16, 2015 Share Posted September 16, 2015 i can only repeat what I said before if you run the script on a small parcel (a standard 512m for example) and you dont mind that if the neighbours parcels are busy so that a agent on your parcel who you do want to get the Say() doesnt actual get it then use a sensor If speed of microseconds is more important than the agent on your parcel actual getting it then go with a sensor Link to comment Share on other sites More sharing options...
Miranda Umino Posted September 16, 2015 Share Posted September 16, 2015 Your logic is wrong : because if a scripter may change the range of the sensor to avoid detecting people outside of the parcel , the scripter couldn t change the range of llsay or llwhisper . So even with a timer + llgeteangentlist , people outside of your parcel will hear your chat you have a pacel of 4*4 .. easy to make a sensor of 2 meters range centered in the parcel who detects only objects inside the parcel : it detects not the whole parcel but it doesn overlap the neighbours client . But your llsay ( or even your llwhisper ) will be heard in a spherus of 40 meter of diameter independtly if you have chosen sensor or timer The volume where llsay will be heard is unchanged by the position of rhe detected item/avatar. So with llgetenaglist , it s worst : because you detect an avatar for instance at high altitudes when your script is in the ground , it will talk to the neighbours of your region a message who won t interest them Definitevly no . timer + llgetagentlist is not an option for the case of the OP If you want to avoid to talk to eighbours , the only solution is to avoid that your objet is too close of the border , or worst at the corner ) of your parcel N To add , testing if an avatar is in your parcel gives often wrong positives : Let s see for instance this sim : http://maps.secondlife.com/secondlife/Rossa/137/177/53 This picture represent the different parcels of the sim : each color represent one parcel . You see that majority of parcels are rectangles and not squares . And you have even some parcels who are not regular shapes : Look for instance the parcel in the shape of F in red . Or more common the parcel in a shape of stairs in drak green , or in yello , or in blue at the bottom right It s not an adition of my part , it s like this the parcel has been built . When you know that the range chat is a sphere ( or its projection on a surface is a circle ) , you see you will get always wrong positives in checking if one avatar is in the parcel An another instance of sim Link to comment Share on other sites More sharing options...
irihapeti Posted September 18, 2015 Share Posted September 18, 2015 Miranda I dont disagree with you about the problems that sensor has in the pcode I showed. We have the option to loop thru the list of agents and check if they are in range of the object before we say or whisper what we do know with getagentlist is: 1) they are on the parcel 2) we dont risk missing them when the area within the sensor scan is busy + i just add another what else situation. Where using get agents list on parcel can give you a no miss result everytime, and avoid the misses (and multiple retrys sometimes) that sensor can introduce you at a club. Is busy as. heaps of avatars you want to invite your friend to come on your dance HUD They standing right next to you click. Sensor scans. The sensor dont find them. bc heaps avatars click. scan. nope move. click. scan. nope and repeat until ah! ha! got you. blinking SL !!! not only does the jaded SL user go: blinking SL !!! in these situations, but so does the scripter who made this dance HUD + alternative click. get list of agents on parcel. got you eta; tpyos Link to comment Share on other sites More sharing options...
Miranda Umino Posted September 19, 2015 Share Posted September 19, 2015 No , there is no problem with sensor . Why do you read me badly ? It s your timer who has sevral problems you can t fix . You offer the solution of clipping . Firstly you may add a clipping test inside the sensor event and not in the timer event . And it will be better than your timer because your timer runs every time without condition . With your timer you will do continuously and permenently some clipping tests . With a sensor , it will do only to prevent wrong positives, so not every time. If there are only negatives , it won t run . Less events triggered , less clipping tests done , so less load . Secondly : you clip by llovermyland . but llovermyland is a costly function : you may do better when you know than you can grab the border/limits of the parcel at the state_entry once and only once . Finally your clipping in the sensor will be the same that clipping something inside a cuboid , so very fast without calls to some LSL functions Thirdly , why to do a clipping test : i repeat : may you do a clipping chat ? Not by llSay neither llWhisper . Your local chat will have always the shape of sphere and not a cuboid . In fact there is no reason to clip inside the timer because there is no clipping chat possible Thats why i have posted the pictures of the shape of parcels , because , by evidence , it s absurd to make some tests based on the shape of the parcel when you know that the chat shape is a sphere ( or its projection on the ground plane a circle ) And It s because to show you , that even with llgetagentlist , you will talk to neighbours , whatever your code , because your chat shape is a sphere , not the shape of the parcel . So it s an useless test Your instance of club has no link with the topic : In your club you want to detect every avatar .And it will fail to detect more than 16 avatarsI If there are 2avatars it will work , if there are 23 avatars it will fail . And giving anaimations to your neighbours avatars can be done outside the chat range . It s a different job of the script in this thread : the OP wants to detect zero avatar or more than 0 . No matter if there are 23 avatars or 2 avatars , because the script should chat in the two cases Link to comment Share on other sites More sharing options...
irihapeti Posted September 20, 2015 Share Posted September 20, 2015 with sensor the best we can do on a standard 512m (16m x 32m) without going over the boundary is 8m. When do this then we cover less than half our parcel to cover our whole 512m at ground level then put sensor on ground at centre of parcel and set sensor range to: 17.93m 17.93m is the length of the diagonal from the centre of parcel to the top corner of the cube (8m * 16m * 1.2m). 1.2m is a bit over half the max. agent bounding box. So to cap any agents on the ground, on the parcel . If we just set to the diagonal of the plane then the sensor will miss the agent in the corner bc our sensor range is over the boundaries on all 4 sides and also a bit over the diagonal parcels as well, then filter out any agents not on the parcel, and stop when find the first on parcel + if we do this, the question then is how to best do the filtering? Link to comment Share on other sites More sharing options...
Miranda Umino Posted September 20, 2015 Share Posted September 20, 2015 For a parcel of 16m*32 meters : * your chat range is a circle of 20*2 = 40 meters of diameter : your chat is over the boundaries of the parcel * even with llwhisper , you will be over the boundaries of the parcel So your problem is your chat , not your sensor To add, it s not realistic than every objects ( who needs to chat ) will be at the center of your parcel Link to comment Share on other sites More sharing options...
irihapeti Posted September 21, 2015 Share Posted September 21, 2015 we do want to chat to a avatar on our parcel. Whether there is a avatar on the next parcel or not. So am not sure what is your point about that + a avatar on the next parcel (our neighbour) will accept hearing the chat message when they can see that there is a avatar on our parcel to who the chat is directed what the avatar on the next parcel (our neighbour) wont accept is that when our parcel is empty, a chat message is directed at them due to them (the neighbour) being on their own parcel, and not on ours if we sensor then when the sensor picks them up on their parcel, we have to filter them out so we dont direct our chat at them [when there is no one on our parcel] if we use agentlist on parcel then we will never direct a chat at them. When our agentlist on parcel is empty then no chat. Not ever. No filtering needed either. No matter how many avatars are on the neighbours parcels + i just add a general for anyone who might read this for years LL was asked to provide a reliable no-miss alternative to sensor. for years and years. And eventual they did: llGetAgentList. Is reliable and it dont miss eta: [ ] just to make more clear what I am saying Link to comment Share on other sites More sharing options...
Recommended Posts
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