Jump to content

Frionil Fang

Resident
  • Posts

    409
  • Joined

Everything posted by Frionil Fang

  1. Texture thrashing is caused by running of out video memory so it (probably) won't affect everyone playing the game, depending on hardware. By keeping a single 1024x1024 texture in memory (or trying to) you are keeping all its unused parts loaded as well; multiple smaller textures will certainly save video memory if the whole area of the texture is never needed at the same time, but then you're making more asset calls to the servers, causing more overhead and chances to get stuck blurry so it's a tradeoff. If the individual faces were changing what they're displaying often, I'd probably stick with the single large texture method for a more seamless experience -- even if the smaller textures were already cached, changing the whole texture instead of just offset/repeats will cause more of a disruption. Optimizing other textures in the scene, if possible, might be a better target for reducing memory usage.
  2. And to change the GeForce Experience shortcut to something else, open it with alt-Z, click the cog icon below the gallery button and go to "keyboard shortcuts". You can also disable them entirely (press delete or backspace as the new shortcut key).
  3. I for one would love to see some old last names become available again. I've long wanted to change my username but none of the ones offered since it became possible have sparked any joy with me: I want a normal but cool lastname, not a thematic or funny one. All the ones fitting my vibe have already been used and can't be suggested, not like the "suggest a last name" form appears to do anything anyway. 😛
  4. Notecards are read asynchronously, that is, you can't get the notecard contents immediately after calling the notecard reading and have to handle it in the dataserver() event. There's really no particular magic to reading multiple notecards, even simultaneously: calling llGetNotecardLine returns a key which can be used to identify which request the event was a response to. Assuming you strictly have that single line in a notecard, as in your example: key nc_handle; // identifies the request default { touch_start(integer _) { // use the touched prim's name as the notecard name string notecard_name = llGetLinkName(llDetectedLinkNumber(0)); nc_handle = llGetNotecardLine(notecard_name, 0); // get the first line (0) of the notecard } dataserver(key id, string data) { // handle only the notecard read that was requested last if(id == nc_handle) { // data is the constant EOF when the notecard is finished if(data != EOF) { // parse the notecard line into variables list params = llCSV2List(data); vector color = (vector)llList2String(params, 0); // must use (vector)list2string instead of list2vector string message = llList2String(params, 1); integer face = llList2Integer(params, 2); llSetColor(color, face); llOwnerSay(message); } } } } Of course, you can't use human-readable color names like "red" and "blue" as colors in LSL directly, you need to use color vectors in the format <R, G, B> or write a function to do that yourself. The example code assumes you use a vector.
  5. Another vote for the built-in editor, guess my projects have never approached the complexity to require a separate program. The only thing I miss sometimes is regex search/replace, but that's what I have notepad++ for, a little select all+copy+paste isn't that much of an inconvenience.
  6. I get that, I guess I have to admit being very used to the Firestorm style after 13 years (Emerald and Phoenix before it). I like tooltips for condensing UIs but it does add hassle when getting "started".
  7. There should be tooltips for nearly everything I can see in Firestorm though. After mousing over my standard view, the only icons that remained unexplained were the parcel properties icons -- things like script and rez permissions, that is (which I'm not sure if they're even shown by default). Then I spent a while mousing over everything in the other programs I had open and it works just the same everywhere, nearly every program I use will set up tooltips. I don't think it's a particularly obscure UI feature.
  8. No modify blocks everything except moving and rotating, can't make things invisible or remove particles. And yeah, I'd be bound to agree it's not worth worrying about someone who's willing to get illegal or suffer a hassle just to get something cheap for free... they probably were not going to pay in the first place.
  9. Yes, combining non-rigged and rigged makes it so that the rigged parts will snap to where they should be, but non-rigged parts are positioned in relation to the attachment point and can be moved, even while no-modify. To avoid just hiding the demo sign, it needs rigging too; I'm not good with rigging even if I know the theory somewhat, so I think the correct solution would be to rig every vertex of the demo sign identically to the pelvis bone (or a head bone, etc., depending on where you want it to follow), so the rigged thing just stays put in relation to the bone but doesn't deform and can't be shoved under the ground.
  10. Otherwise -mod is kind of meh (depends on circumstances, prefer +mod) but for demos it seems like the right way to go. I think the classic big "DEMO" lettering above the head is pretty functional... at least, as long as the person trying it on isn't so big that the text ends up disrupting the product. Of course if the demo sign isn't rigged but the clothing itself is, you *can* still move no-mod objects so the sign could be moved into an invisible position - would need to rig the demo sign too to prevent that. One design for a demo sign could also be an inverted one-sided sphere - it can't get in front of the camera, but is "discouraging" enough to have a bubble spelling out "DEMO" behind you at all times. Also needs to be rigged instead of just using a sphere prim to prevent moving, though.
  11. Anyone who's willing to go through the effort of stealing something isn't going to be going after a demo (they could just steal the full version from someone else, if they have the tools to save meshes and textures they're not allowed to, who's wearing them isn't going to matter), so IMO the only factor is "is this convenient for a legit customer". I think unsightly prims that don't actually cover important areas is the best way to go, just don't forget to make it -mod. Makes it silly to try to wear instead of the full product, but doesn't actually ruin the textures so you can get a better idea of what it really looks like. The "automatically detaches and/or self destructs" is just frustrating to no end like you said and makes me *less* likely to buy the full product since it went out its way to annoy me while trying to test it, and again won't deter a sneaky person. The only way to ensure no one pirates a thing is to not upload it or use it anywhere, otherwise it's best to just think about honest people and what's easiest for them.
  12. You probably would need to work with ANS (Store setup->Automatic notifications in your marketplace merchant menu). This is the documentation about it that I can find: https://wiki.secondlife.com/wiki/Direct_Delivery_and_Automatic_Notification_System There seem to be a couple examples available. Since ANS requires a static URL it sends the notifications to, trying to accomplish that with inworld scripts alone is not very feasible, you'd need at least some kind of a middleman handling the changing URLs.
  13. Now that I'm no longer just trying to type single-handed during a phone call downtime: yeah, the llSensor is a request for "I'd like to receive a sensor/no_sensor event at a later date", it will never be fulfilled at the time the llSensor call finishes but only when the event queue can resume processing, i.e. after the listen event has finished. How to fix it: you'd have to move any handling into the sensor/no sensor events completely, and the listen event only has the single llSensor call. Also not related to this issue, your loop in the sensor event starts at the wrong index. DetectedNNN functions index starting from 0, not 1, so you're skipping the first result (and probably the only result, considering what it's trying to do) every time.
  14. llSensor does not call the sensor event: it happens at a later time once the current event (listen, in your case) is complete.The code hasn't had a chance to run when you try to debug the value.
  15. MoveToTarget is a physics engine function and those are inherently imprecise, I wouldn't use those for an elevator. The tau parameter is more of a request to reach the destination in tau seconds and depending on distances and other physics conditions might happen early or not at all (resulting in vibration). For a simple elevator that's not running all the time I'd just skip the physics engine and do SetRegionPos movement in steps, it might not be as elegant as a single call but it's not far. Keyframed motion would be most elegant, but it's annoying to set up. default { touch_start(integer _) { vector here = llGetPos(); // assign random location within a 1m cube as destination vector there = here + <llFrand(2), llFrand(2), llFrand(2)> - <1, 1, 1>; integer step; // granularity of movement integer max_steps = 10; // delay = travel time/max steps float delay = 1.0/max_steps; float interpolation; for(step = 0; step <= max_steps; ++step) { interpolation = (float)step/max_steps; // lerp between locations llSetRegionPos((1-interpolation)*here+interpolation*there); llSleep(delay); } } } You could of course move the loop into a timer to allow other events to happen during movement and optimize away many of the variables. Edited to amend: I didn't really consider fully that it's an *elevator* , position warping doesn't really move any unseated avatars on the object and relies on bounding boxes to make sure no one clips into the elevator floor while moving up and everyone will constantly fall a little while moving down, so it's not the cleanest looking... might want to do the llTarget+events approach as suggested by Qie after all.
  16. You're dividing 2 integers, which means the result will be an integer. (4388 / 65536)*100 = 0*100 = 0. If you changed the order of operations to 100*4388/65536, the answer would be 6 (integer division rounds towards 0). To use float division, you must cast to float (float percent = ((float)used/65536)*100), or, in this case since you're hardcoding the values and I won't question that, you can use a float literal (float percent = (4388.0/65536)*100).
  17. A very simple way to preserve multiple objects' relative positioning is to select all of them (hold shift+click with build tool open, or drag a frame around them with build tool) and then just pick them up. They become a "coalesced object" asset in your inventory: coalesced objects can't be attached but when rezzed they contain all the individual objects just the way you picked them up. This won't of course help you getting them in the exact original position, but moving a bundle that's already relatively correct to each other is a bit easier.
  18. llShout is not region wide, the range is 100 meters, including the third dimension. You can use https://wiki.secondlife.com/wiki/LlRegionSay instead which is region wide.
  19. The midway point of your alpha mask reads as about 176 for me, so very much not 127. If use my image editor's levels tool to apply a gamma of 1.8 to your gradient, it becomes roughly linear with 127 around the middle. I'd imagine the issue is color profiles: Photoshop is applying some kind of gamma correction to your alpha mask gradient instead of treating it linearly. As for how to make it not do that, no idea, it's been decades since I used Photoshop, sorry. Color profiles can be damaging to image data that's not meant to be interpreted as colors, though, such as alpha channels and normal maps, so there has to be some kind of a feature to work in a linear space.
  20. Not the most clean, but something like: integer temp = coins; integer platinum = temp/1000000; temp -= platinum*1000000; integer gold = temp/10000; temp -= gold*10000; integer silver = temp/100; temp -= silver*100; integer copper = temp; Basically, split off coins of certain value subdivision from the total, update the value, repeat until only lowest subdivision remains.
  21. The same method works almost everywhere in the viewer: [<url> title], for example [http://google.com my webzone] would get you a clickable "my webzone" link to Google. You can't see it as clickable yourself, though, since you have to be able to edit it.
  22. Additionally, if having empty parameters is useful (I don't know about your case), you can use llParseStringKeepNulls. Works identically to llParseString2List but, like the name suggests, it keeps empty pieces between 2 separators or spacers. E.g. llParseString2List("7::31", [":"], []) would return the list ["7", "31"], but llParseStringKeepNulls("7::31", [":"], []) would get you ["7", "", "31"], the "" indicating an empty string that was between the two :s.
  23. It's pretty easy to see there's some shallow copying and referencing going on, generate a 256-length list by duplicating a seed list: default { state_entry() { integer i; list a = [0]; for(i = 0; i < 8; ++i) a += a; llSleep(0.01); // ensure memory count is accurate llOwnerSay((string)llGetListLength(a)); // =256 llOwnerSay((string)llGetUsedMemory()); // =5044 } } As opposed to generating a 256-length list by adding individual values: default { state_entry() { integer i; list a; for(i = 0; i < 256; ++i) a += 0; llSleep(0.01); // ensure memory count is accurate llOwnerSay((string)llGetListLength(a)); // =256 llOwnerSay((string)llGetUsedMemory()); // =8100 } } I prefer to use the latter to be certain the reported memory use is reliable and stays static after rewriting pieces of the list, even if the initialization takes longer. Also you can use the former to see yourself going above 64k script memory used, at least briefly: default { state_entry() { integer i; list a = [0]; for(i = 0; i < 14; ++i) a += a; llSleep(0.01); // ensure memory count is accurate llOwnerSay((string)llGetListLength(a)); // =16384 llOwnerSay((string)llGetUsedMemory()); // =69556 llOwnerSay("how is this still running"); // might crash, might not, depends on if the engine catches on to being over limit on this execution frame } }
  24. The params in the call will get set just as fast. E.g. set 20 params with a single call and there is no difference in how the results appear, regardless of which SPP/SLPP/SLPPF you use.
×
×
  • Create New...