ItHadToComeToThis Posted February 14 Share Posted February 14 (edited) Hey, so, I have a system setup where if you enter the region a hud auto attaches to the avatar. The way it currently works is. Box A scans the sim and adds all avatars into a "inSim" list. Box A then works through the list, first setting the avatars key as the description of Box A. Box A then rez's Box B. Box B, using llGetObjectDetails, gets the description of Box A, aka avatar in sims key, and then sends a message to that avatar asking them if they already have the system attached. If Box B gets a response, Box B deletes itself. If Box B doesn't get a response after 10 seconds, Box B requests experience permissions and then rez's the system, which uses the same method but grabs the key from Box B description, and then auto attaches to the avatar. The reason Box B asks if you are wearing the HUD first is, this system is working across multiple regions joined together. The reason for so many boxes is....once Box B is Rez and has the key, that frees up Box A to continue working through the inSim list. The issues im getting are as follows... 1. Occasionally when I cross from one sim into another, the system will detach itself, as if it's trying to attach another version. Which it shouldn't as it's supposed to answer Box B's question of is the hud on. And then delete Box B if it is. 2. The HUD / Box B is occasionally throwing an error about not being able to find an avatar to request the experience from. It should be getting the avatars key from the previous rez description. 3. Is there a better way to do this? The method im using seems like it would be the most sensible but is there a better and more efficient way? You can ignore the dialog stuff, its just the experience attach and sim scan stuff that im having these issues with. Box A Code - Keys for dev, admin, channel numbers and encryption stuff was removed for privacy reasons list inSim=[]; //In sim already list grab=[]; //Temporarily grab all to be sorted list aMenu=[ //Admin menu "Update", "DetachAll" ]; list nMenu=[ //Normal menu "AttachHUD" ]; list admins=[ ]; key admin; //Channels integer sChan; integer sList; integer mChan; integer mList; integer mInd; //Keys key target; key dev=""; key player; //Encryption password string password=""; //Encrypt string encrypt(string msg){ return msg; } //Decrypt string decrypt(string msg){ return msg; } grabPlayers(){ //Scan players grab=llGetAgentList(AGENT_LIST_REGION,[]); integer i=-1; integer inCheck; //Determine if in the sim already or need to check exp while(++i<llGetListLength(grab)){ if(~inCheck=llListFindList(inSim,[llList2Key(grab,i)])){ //Already in sim //llOwnerSay(llKey2Name(llList2Key(grab,i))+" is already in the sim"); }else{ //Not in the sim //llOwnerSay(llKey2Name(llList2Key(grab,i))+" is not in the sim"); inSim+=[llList2Key(grab,i)]; target=llList2Key(grab,i); llSetObjectDesc((string)target); //if(target==admin)llRezAtRoot("SystemExpCheck",llGetPos()+<0.0,0.0,2.0>,ZERO_VECTOR,ZERO_ROTATION,1); llRezAtRoot("SystemExpCheck",llGetPos()+<0.0,0.0,2.0>,ZERO_VECTOR,ZERO_ROTATION,1); llSleep(2.0); //Check experience } } //Now check inSim list to make sure no one has left if(llGetListLength(inSim)>0){ list temp=inSim; i=-1; while(++i<llGetListLength(temp)){ if(~inCheck=llListFindList(grab,[llList2Key(temp,i)])){ //llOwnerSay(llKey2Name(llList2Key(temp,i))+" is already in sim"); }else{ inSim=llDeleteSubList(inSim,i,i); //llOwnerSay("Removed "+llList2String(temp,i)+" from list"); } } } } detachAll(){ integer i=-1; while(++i<llGetListLength(inSim)){ llRegionSayTo(llList2Key(inSim,i),sChan,encrypt(llList2String(inSim,i)+",detachHUD")); llRegionSayTo(llList2Key(inSim,i),sChan,encrypt(llList2String(inSim,i)+",detachMeter")); } } default{ state_entry(){ llListenRemove(sList); sList=llListen(sChan,"",NULL_KEY,""); llSetTimerEvent(5.0); } on_rez(integer param){ llResetScript(); } touch_start(integer x){ key admin=llDetectedKey(0); if(~llListFindList(admins,[(string)admin])){ mInd=1; llListenRemove(mList); mChan=11111+(integer)llFrand(99999); if(llDetectedKey(0)==admin){ player=admin; mList=llListen(mChan,"",player,""); llDialog(player,"\nHUD",aMenu,mChan); } }else{ llRegionSayTo(admin,0,"You do not have permission to use this item."); } } listen(integer channel, string name, key id, string message){ if(channel==mChan){ if(id==dev){ //Admin options if(mInd==1){ if(message=="Update"){ inSim=[]; detachAll(); grabPlayers(); }else if(message=="Notice"){ return; //mInd=2; //llTextBox(admin,"System Notice",mChan); }else if(message=="DetachAll"){ detachAll(); }else if(message=="AttachHUD"){ return; //llSetObjectDesc((string)dev); //llRezAtRoot("SystemExpCheck",llGetPos()+<0.0,0.0,2.0>,ZERO_VECTOR,ZERO_ROTATION,1); } }else if(mInd==2){ integer i=-1; while(++i<llGetListLength(inSim)){ llRegionSayTo(llList2Key(inSim,i),sChan,encrypt(llList2String(inSim,i)+",hudNotice,"+message)); } } }else{ //Normal if(message=="AttachHUD"){ llSetObjectDesc((string)id); llRezAtRoot("SystemExpCheck",llGetPos()+<0.0,0.0,2.0>,ZERO_VECTOR,ZERO_ROTATION,1); } } }else if(channel==sChan){ return; list pStr=llCSV2List(decrypt(message)); if(llList2String(pStr,0)=="attachHUD"){ llSetObjectDesc(llList2String(pStr,1)); llRezAtRoot("SystemExpCheck",llGetPos()+<0.0,0.0,2.0>,ZERO_VECTOR,ZERO_ROTATION,1); llSleep(2.0); } } } timer(){ grabPlayers(); } } Box B Code - Keys, Channels etc removed for same reasons as above //Channels integer sysChan; integer sysList; //Encryption string password=""; //Other key expCheck; key av; integer rezCheck=0; //Encrypt string encrypt(string msg){ return msg; } //Decrypt string decrypt(string msg){ return msg; } default{ on_rez(integer param){ key rez=llList2Key(llGetObjectDetails(llGetKey(),[OBJECT_REZZER_KEY]),0); av=llList2Key(llGetObjectDetails(rez,[OBJECT_DESC]),0); //llOwnerSay("Av is: "+(string)av); llSetObjectDesc((string)av); llListenRemove(sysList); sysList=llListen(sysChan,"",NULL_KEY,""); llRegionSayTo(av,sysChan,encrypt((string)av+",isHudOn,"+(string)llGetKey())); llSetTimerEvent(5.0); } experience_permissions(key id){ if(id){ llRezObject("HUD",llGetPos()+<0.0,0.0,2.0>,ZERO_VECTOR,ZERO_ROTATION,1); } } listen(integer channel, string name, key id, string message){ if(channel==sysChan){ //System chan list pStr=llCSV2List(decrypt(message)); if(llList2Key(pStr,0)==av){ if(llList2String(pStr,1)=="hudIsOn"){ //llOwnerSay("is on"); llDie(); } } } } timer(){ if(!rezCheck){ llRequestExperiencePermissions(av,""); rezCheck=1; llSetTimerEvent(0.0); llSetTimerEvent(20.0); }else{ llDie(); } } } Code inside the system that attaches to the avatar. integer rez=0; default{ on_rez(integer param){ //Param code check if(rez==0){ rez=1; key rez=llList2Key(llGetObjectDetails(llGetKey(),[OBJECT_REZZER_KEY]),0); key target=llList2Key(llGetObjectDetails(rez,[OBJECT_DESC]),0); llRequestExperiencePermissions(target,""); llSetTimerEvent(5.0); } } experience_permissions(key id){ if(id){ if(rez){ rez=0; llAttachToAvatarTemp(ATTACH_HUD_CENTER_1); } } } timer(){ if(rez){ llDie(); } llSetTimerEvent(0.0); } } Edited February 14 by ItHadToComeToThis 1 Link to comment Share on other sites More sharing options...
Qie Niangao Posted February 15 Share Posted February 15 15 hours ago, ItHadToComeToThis said: Is there a better way to do this? There's a bunch of this I don't understand, but I can't imagine using object descriptions to communicate between objects. It appears that Box A sets its description, rezzes Box B, and llSleep()s for two seconds in hopes Box B will finish rezzing and reading the description before Box A wakes up and rezzes the next Box B. That'll probably work almost all the time, but it's sure not to work some of the time, and there are multiple widely-used approaches for communicating between a rezzer and its rezzed children. See the object_rez wiki page for a couple cookbook examples, or try something else, perhaps communicating via the Experience's KVP persistent store (since all the scripts can be compiled to that experience), but whatever the medium, the logic mustn't assume the rezzed object is ready to do anything until it says it's ready. This section, I'm sure, explains why there needs to be a separate Box B instead of just rezzing the HUD directly, but I've reread it a dozen times and can't understand: 15 hours ago, ItHadToComeToThis said: The reason for so many boxes is....once Box B is Rez and has the key, that frees up Box A to continue working through the inSim list. It's not obvious to me why a freshly rez'd HUD can't just do everything Box B is doing and then decide whether to attach to the target avatar. If at all possible, I'd remove Box B from the architecture, removing a whole raft of potential failure modes with it. With the llSleeps between rezzes, it's not surprising that some avatars will escape the region before anything asks whether they have a HUD attached, requests Experience permissions, or tries to attach, but if it remains unexplained after tightening up the delays you could log those attempts (to Experience KVP if nowhere else) to gather more info about which avatars are falling through the cracks, and maybe why. Maybe somebody who deals with temp-attached objects across region borders will know if they just fall off sometimes, even if both regions have the Experience enabled. It wouldn't seem too surprising, considering that regular attachments fall off occasionally on teleport. Link to comment Share on other sites More sharing options...
ItHadToComeToThis Posted February 15 Author Share Posted February 15 5 hours ago, Qie Niangao said: There's a bunch of this I don't understand, but I can't imagine using object descriptions to communicate between objects. It appears that Box A sets its description, rezzes Box B, and llSleep()s for two seconds in hopes Box B will finish rezzing and reading the description before Box A wakes up and rezzes the next Box B. That'll probably work almost all the time, but it's sure not to work some of the time, and there are multiple widely-used approaches for communicating between a rezzer and its rezzed children. See the object_rez wiki page for a couple cookbook examples, or try something else, perhaps communicating via the Experience's KVP persistent store (since all the scripts can be compiled to that experience), but whatever the medium, the logic mustn't assume the rezzed object is ready to do anything until it says it's ready. This section, I'm sure, explains why there needs to be a separate Box B instead of just rezzing the HUD directly, but I've reread it a dozen times and can't understand: It's not obvious to me why a freshly rez'd HUD can't just do everything Box B is doing and then decide whether to attach to the target avatar. If at all possible, I'd remove Box B from the architecture, removing a whole raft of potential failure modes with it. With the llSleeps between rezzes, it's not surprising that some avatars will escape the region before anything asks whether they have a HUD attached, requests Experience permissions, or tries to attach, but if it remains unexplained after tightening up the delays you could log those attempts (to Experience KVP if nowhere else) to gather more info about which avatars are falling through the cracks, and maybe why. Maybe somebody who deals with temp-attached objects across region borders will know if they just fall off sometimes, even if both regions have the Experience enabled. It wouldn't seem too surprising, considering that regular attachments fall off occasionally on teleport. Sorry, I thought I had explained clearly enough but I can see how it might be confusing. So, the reason for Box B is because of Box B asking the question of "is the hud on", and I wanted to be able to Rez multiple Box B's and leave Box A looping through the people on sim. Then I found out that Box B wasn't grabbing the UUID quick enough so had to start adding delays to allow it to do so. However, I figured out a better method than asking "is the hud on" and that's checking the avatars attachments for the overhead meter. If the meter is attached, then Box B doesn't Rez and simply dies. The HUD has stopped occasionally detaching when you cross regions now which im happy with, but if theres a better method to be used here then Im happy to explore it. I will play around with the object_rez method , I had forgotten that event existed to be honest. Link to comment Share on other sites More sharing options...
Qie Niangao Posted February 15 Share Posted February 15 1 hour ago, ItHadToComeToThis said: So, the reason for Box B is because of Box B asking the question of "is the hud on", and I wanted to be able to Rez multiple Box B's and leave Box A looping through the people on sim. Yeah, but… I understand that Box A needs to rez something quickly so it can get through potentially multiple avatars in a loop, but what I'm being dense about is why it needs to rez another level of rezzer rather than directly rezzing the HUD and have it determine for itself if it should attach (make sure there's not a HUD attached already) and either llDie or try to temp-attach. 1 hour ago, ItHadToComeToThis said: However, I figured out a better method than asking "is the hud on" and that's checking the avatars attachments for the overhead meter. So… the overhead meter (which would be in llGetAttachedList) will always be attached iff the HUD is? 1 Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 15 Share Posted February 15 2 minutes ago, Qie Niangao said: Yeah, but… I understand that Box A needs to rez something quickly so it can get through potentially multiple avatars in a loop, but what I'm being dense about is why it needs to rez another level of rezzer rather than directly rezzing the HUD and have it determine for itself if it should attach (make sure there's not a HUD attached already) and either llDie or try to temp-attach. Peeve: A box can't rez copies of itself from its own inventory! Link to comment Share on other sites More sharing options...
elleevelyn Posted February 15 Share Posted February 15 1 hour ago, Love Zhaoying said: Peeve: A box can't rez copies of itself from its own inventory! it can when use a self-replicator. Which goes: 1) Make a box. Put a copy of the box and a giver script in the box 2) On_rez copy of box from contents. Give the copy of box the contents of the rezzer box is useful for things like sit teleporters and vehicles which are available for anyone to drive. Saves having to provide a rezzer post. Person sits on the vehicle. On_sit the vehicle rezzes a copy of itself, person drives away leaving a new vehicle behind in its place for the next person Link to comment Share on other sites More sharing options...
ItHadToComeToThis Posted February 15 Author Share Posted February 15 2 hours ago, Qie Niangao said: Yeah, but… I understand that Box A needs to rez something quickly so it can get through potentially multiple avatars in a loop, but what I'm being dense about is why it needs to rez another level of rezzer rather than directly rezzing the HUD and have it determine for itself if it should attach (make sure there's not a HUD attached already) and either llDie or try to temp-attach. So… the overhead meter (which would be in llGetAttachedList) will always be attached iff the HUD is? Yeah, the meter and the hud coexist, if you detach one it detaches the other. You have to be wearing both or none at all. I guess i could just Rez the hud directly. It would technically just do the same as Box B I guess. I think I was over thinking that bit. 1 Link to comment Share on other sites More sharing options...
elleevelyn Posted February 15 Share Posted February 15 (edited) On 2/15/2024 at 9:25 AM, ItHadToComeToThis said: The method im using seems like it would be the most sensible but is there a better and more efficient way? a alternative approach can be multiple scripts in the region monitor. Something like: 1) Scanner script: - timer scan for agents on region llGetAgentList(...REGION...) - loop thru - if (agent no longer on region - llGetAgentSize)) then tag agent KVP Active = False (or remove from KVP) and done - if (agent not in experience) then - if (agent tagged in KVP as OOC after X invites) then skip/ignore else hand off agent key + delegated Ping script id (link_message) to Invite script else if (agent in experience) then hand off agent key + KVP Active status (link_message) to available Ping script 2) Invite script: - receive agent key + delegated ping script id (link_message) - if (agent no longer on region - llGetAgentSize) then tag agent KVP Active = False (or remove from KVP) and done - invite agent to experience - if (agent accepts invite) then hand off agent key + KVP Active status = False to delegated Ping script else if (agent refuses/ignores invite after X scanner-prompted invites) then tag them in KVP as OOC 3) Ping script: - receive agent key + KVP Active status (link_message) - if (agent no longer on region - llGetAgentSize) then tag agent KVP Active = False (or remove from KVP) and done - if (agent no longer in experience) (people can leave an experience at any time) then tag agent KVP Active = False and done (inviting them again on next scan) - if (agent KVP Active status = False is new entrant) then attach HUD and tag KVP Active = True else ping the agent's HUD - if (ping response) then done else if (after X time) attach HUD - on_attach HUD (HUD checks for presence of existing HUD) - if (existing HUD) then remove/delete the newly attached HUD 4) HUD monitors for presence of companion Meter. Check on HUD attached, Meter detached, and on changed region. Attaching new when Meter not found. When HUD detached then HUD detaches Meter 5) KVP Writer script: Any script can read the KVP for info. In the multiple script scenario tho is often better for scripts to pass a Write link_message to a dedicated KVP Writer script to do this work in this approach there are as many Invite and Ping scripts as needed to better handle the volume of agents present at any one time. The scanner script farming (handing off) the work to the Invite and Ping scripts the objective with this approach is to only rez things when they are needed and to have the scanner script do the least amount of work as possible Edited February 15 by elleevelyn 1 Link to comment Share on other sites More sharing options...
ItHadToComeToThis Posted February 19 Author Share Posted February 19 On 2/15/2024 at 11:46 PM, elleevelyn said: That was really helpful advice, thank you. Am I right in thinking that when you cross into a region, the attachments you have on, for a brief second, aren't attached to you while they load into that region? It seems adding a short delay to the meter check, fixed an issue where the HUD would sometimes attach when you enter a new region, as if it couldn't find the meter you were wearing? Link to comment Share on other sites More sharing options...
Quistess Alpha Posted February 19 Share Posted February 19 12 hours ago, ItHadToComeToThis said: Am I right in thinking that when you cross into a region, the attachments you have on, for a brief second, aren't attached to you while they load into that region? Basically, yes. You could also think about it as the new region taking non-zero time to learn about your attachments from the old region. Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 19 Share Posted February 19 2 minutes ago, Quistess Alpha said: 12 hours ago, ItHadToComeToThis said: Am I right in thinking that when you cross into a region, the attachments you have on, for a brief second, aren't attached to you while they load into that region? Basically, yes. You could also think about it as the new region taking non-zero time to learn about your attachments from the old region. That sounds similar / the same has how vehicles are treated when you cross regions. In case I missed it, can "temp attachments" cross regions, or always bonked / borked? Link to comment Share on other sites More sharing options...
Quistess Alpha Posted February 19 Share Posted February 19 1 hour ago, Love Zhaoying said: In case I missed it, can "temp attachments" cross regions, or always bonked / borked? AFAIK the "correct" behavior is that temp attachments only detach when done explicitly (logout/user detach/llDetachFromAvatar) or when entering a parcel/region that doesn't have the experience that requested the permission to attach. A quick test shows that non-experience temp-attachments survive region-changes non-borked. 1 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