Jump to content

Bleuhazenfurfle

Resident
  • Posts

    108
  • Joined

  • Last visited

Everything posted by Bleuhazenfurfle

  1. We have a space for this feature ready and waiting for it to be implemented: llRequestInventoryData Having access to the description would be a good fallback in the event the DB simply doesn't have that information presently, but I'd prefer to see the description working as an actual description. But if they really don't want to add a separate field for this, then shoving aspect ratio at the start of the description field, and letting us access it, would indeed be a reasonable fallback. Just off the top of my head, I see two problems here; 1) I suspect there arises a problem of privacy with giving us access to the description field, since you need to be able to look up an images size/aspect by UUID alone, and we can't know if/what else that description could contain — especially if we're ever allowed to actually use it for its intended purpose. So to make this work, they need to at least come up with a scheme to distinguish it from description text, so they're only giving us the aspect part. And at that point, it'd be easier to just add a new field and do it right. 2) The killer issue, though… I don't think the texture HAS a description field. (At least, not one we'd be allowed to poke at.) Pretty sure the description field is only on the inventory item, which is only available if the texture is there in the prims own inventory, and can be different for each and every instance of that texture. This would still be fine for a large number of use cases, however, so a reasonable interim fallback, given just the scripts ability to read inventory descriptions. (And having it in inventory also removes the privacy consideration above.) But in those same cases, we already have it's name, and can just put it in there instead.. So I think llGetInventoryDescription is still a reasonable thing to keep pushing for in it's own right (feels weird we don't already have it… unless LL are themselves using the description field of some items for something, and don't want us to find out — maybe that's where they hide their friday night pub limericks or something), and I am VERY certain I've seen Jira's requesting access to inventory description, but I guess another one won't hurt — let them know we still want it! But asking specifically for image aspect ratio by that means, I strongly expect would be DOA. And probably not much better for asking for an inventory field for it (plus I don't think that's really want you want, either). llRequestInventoryData is the right place for this, since the sim almost certainly never actually needs this information itself, and because we really want it to work on textures by UUID which the sim quite likely has no reason to have any knowledge of at all. So on the topic of llRequestInventoryData specifically… (Which last time I checked, returns zip for textures presently.) There's at least one already; my Jira: https://jira.secondlife.com/browse/BUG-232877 Some similar discussion around the topic just recently: https://jira.secondlife.com/browse/BUG-234448 In that case, no new commands are needed or anything, and as I suggest in at least one of those, if they stick to a float aspect ratio as the response, they could return a flat "1" for images that are lacking the original size information. A "1" like that would both be interpreted as the most useful value in a float cast (the same value we currently assume for all textures), and also be trivially distinct from a proper stored "1.000000" aspect ratio.
  2. Fear not, the joke was well received — such hallucinations are one of ChatGPT's more "delightful" features, which I myself have pointed out to many an enamoured fan. It's an interesting point, though, that in certain fairly specific areas (and the name of an existing corporate entity being one such particularly likely case — ie. something that shows up nice and cleanly in it's training data), it tends to be pedantically correct, where as was also pointed out a lot of real people (including myself quite often) call them "Linden Labs" (plural), mostly because it just sounds better. And I just checked — it does, in fact, get it right (and pedantic), for LL; The correct name of the company behind Second Life is "Linden Lab," not "Linden Labs." It's a common mistake, but the company name is singular, not plural. So, it's "Linden Lab." Of course, in the very next digital breath, it'll also invent an entirely new corporate entity besides. It's getting things "mostly" and "plausibly" right, that is always the biggest problem. And why even when it seems to be neigh infallible for your specific use case, you still can't actually rely on it without it coming around to bite you — as at least one lawyer has discovered the hard way…
  3. It's not…? You mean they're all crammed into the one single room? Well damn. That's gotta suck. (That is humour, by the way — I know some people on here have difficulty with the concept.) But in all seriousness, I had actually forgotten that it's not plural — just sounds weird, being singular. Mostly because when I refer to LL, I typically write it as LL's or thereabouts, because I'm referring to the people that make up LL, rather than the corporate entity itself. So combined with my wonderful memory, I tend to forget the exact entity name. On those grounds, I would posit that reality is the other way around; only the bots actually get it right.
  4. I believe that is why Bing put a limit on the number of interactions you can have before it resets the conversation. Otherwise, they tend to progressively drift off into their own little fantasy land, and occasionally turn evil (they have no actual comprehension of what they're saying, let alone any kind of morals, after all).
  5. Playing "spot the ChatGPT script" was a fun side activity in most of the scripting groups for a time. Seems to have settled down now.
  6. No doubt you'll have a whole bunch of people telling you how easy that is very soon. (Because it is.) You do realise though (not everyone does), doors can be skipped by various methods, like just sitting on something on the other side. And you need the door to clearly indicate whether it's open or not, or people are inclined to just assume it's broken, and bypass it. Or have an LM on the inside. Or assume that every door is annoying — because most of them are — and just generally not bother with them anyhow. Personally, I find it's better just to leave the door open, and put up a sign instead. It'll probably work better. Also, you can't have a "group only visible countdown". If it's on the door, it's either visible to everyone, or not. There is no group only. That'd require something like a HUD, or spamming group members with messages (not going to be appreciated). Better would probably be a single message if the door is clicked on out of hours, or something. If you still want to go with the door idea, might help to also describe how you imagine setting the lock/unlock and timer configuration.
  7. That was one of the first things I experimented with when I first learnt about llGetNotecardLine … and pretty much never bothered with it since. The added complexity just wasn't worth the effort. That said, when (if) that change to nuke the delay goes through, this question might be worth revisiting. In the meantime, all that happens is you get a sliding window of already fulfilled requests sitting in your event queue. I'm inclined to go with the term sequential, also. Synchronicity usually relates to predictability in time (in LSL terms, immediate response, vs. "some time in the very near future, hopefully" response). Two events can be synchronous, even if they happen otherwise at random. What you're describing there, is exactly sequential behaviour — ordered, ie. following a sequence, but possibly unpredictable in time. Also, your script can do plenty of other things while it waits for the "real data" to be returned, which wouldn't be possible if it was synchronous. It is of course also a question of what layer you're looking at, though; If you take a step up the ladder, it's all synchronous because your script runs it's higher level process one step at a time regardless. If you take a step down, then it's all asynchronous because the focus shifts to considering the script overrunning it's time slice, the whole scheduling thing, etc… But from a normal scripters point of view (ie. what we have control of, vs. what we don't), llGetNotecardLine definitely feels asynchronous, with your script process being sequential, and this seems to be the terminology adopted by the LL's also.
  8. Are you sure it's actually necessary? Usually if you care about detatch, it's because you've been interacting with the object and have already authenticated it in some way — and are probably checking on it every now and again in case they skip the sim before detaching it. That usually implies you already know it's key, and a simple check of the UUID will do. Maybe not in this case, just thought it was worth mentioning in case you're over-thinking it all.
  9. That "don't hold your breath" response is indeed most frustrating. But even when they DO accept one, the very next week two Lindens are talking about that very topic and getting the very same ideas handed to them in the meeting (in one case, an idea that had been specifically pointed out as sub-optimal in the *accepted* Jira), like it's an entirely new concept. Gah.
  10. That's not a way of looking at it, it's actually how it's defined. The comma — when not consumed as a syntactic element — is an actual operator. I ran into it a bunch of years back, and have lamented in the groups on a number of occasions since that I wish they made the comma operator a proper thing in LSL, too… It's much nicer than that (listVar=[])+listVar construct… Especially since we're fairly sure LSL isn't smart enough to optimise out that addition. The comma-operator version is much the same, but makes what you're doing a whole lot more obvious, and there's no point adding an empty list to your actual list; hopefully, the addition operator at least short-circuits when it notices the LHS is empty — though that's something that can only be done because of immutability, so, not counting on it. If it isn't short-circuiting the addition (and simply returning the RHS untouched), then it'll be effectively just making a copy of the RHS, and there seems to be a window during which that can blow your script heap (though I have a suspicion that might actually be a different issue lots of people seem to not quite understand, because I haven't seemed to run into it, myself). I'm rather famous for jumping in on that discussion whenever it comes up. Pretty sure I've got at least two posts on this forum along those lines. It's not even a very smart optimisation — for simple values like an integer, most compilers pretty much do it by accident during register selection. Personally, I don't care what someone does in their own code. I'll explain the issue if it comes up, though… What I do care about, is people in a position to teach coding (or writing wiki examples, or helping others on forums), blindly following the bad habits they themselves were taught because they've never stopped to actually think it through (or worse, don't understand what they're teaching well enough to even realise the issue exists) — it can and has bitten people hard, when they move on to real programming languages out in the real world. And it's a simple enough thing — just fix it. Use the pre form unless you specifically need the post form. Make doing it the better way the new habit, especially when you're teaching others, even if you can't be bothered for your own stuff. Otherwise, for me, it's just one of several red flags telling me they don't truly know what they're doing. The prime motivation for just plain "learning it right", that I often mention, was (a year or three ago now, so no, I don't have a link to the post) a company made a seemingly small change in an unrelated part of their code, that took a worrying slice off their performance, but it was new code, hadn't been optimised yet, so they kept going, and they had a schedule to keep and all that. But the servers just kept getting slower, even while they were optimising other stuff trying to make up the time elsewhere, something they couldn't identify kept eating it right back up and more, especially when it actually went live and had to deal with real life customers. Eventually they hired a consultant to just target that specific performance problem, and he tracked it down to this very issue — people using var++ instead of ++var in their for() loops (this is optimised C++, not LSL, so it shouldn't matter, right? That's why none of their employees ever thought to check. Everyone just does it that way! Heck, some companies even recommend it in their coding style guides "for familiarity, because it doesn't actually matter"). All up, between the extra employee time spent hunting it down, and optimising other things that didn't actually need optimising yet, then the consultants time, plus the extra servers they needed to spin up to handle the regular load (they were expecting a little of that, like getting a little slower until they had time to properly profile and characterise to figure out where best to put in the optimisation effort, but not THAT much), this tiny little thing cost them quite a few millions of real life US dollars. Still think it's not worth caring about?
  11. Think I'd prefer it if they dropped the "Stop Moving:" prefix… you can add that yourself if you want it (as you did there), but you can't readily get rid of it if you don't. That could be particularly annoying if you want to show the controls for an aircraft or something, with more appropriate terms like roll instead of turn, or strafe instead of slide, etc. I guess that could be there to match with the official key binding name… but still.
  12. Ooooh, didn't know you could have a negative balance. I would so try to keep mine at a nice round -1, just to be annoying. It could also be that the two flags DID at one time actually mean what they say, but the LL's had the same feeling of "information residents shouldn't know" we have, and semi-nuked one of them. But those bits are now forever ingrained into LSL's history… Would be nice to have an official statement of what they do/don't mean, though… Could also sometimes be a reflection of how your payment information was removed from your file. I get the impression support don't always do things the same way as the automated systems, which could lead to minor differences.
  13. there's also llRequestUsername / llRequestDisplayName… it's be a dataserver request in either case, if they're not present on the sim. llRequestUsername will give you cannonical name (lower-case with a dot, and no "resident"), while DATA_NAME gives you legacy name (proper cased with a space, with "Resident"). Keeping both in mind lets you select which form you want. Both use a dataserver response.
  14. By "when I teleport", you mean at the arriving end, right? Getting it to trigger where you just left is a touch trickier. And the change needed would be: ... the other stuff stays the same ... default { state_entry() { keystate = 0; } changed(integer change) { if ( change & CHANGED_TELEPORT ) { updateParticles(); } } }
  15. Yeah, I mentioned the gift giving in my previous comment (I know, there was that big amusing story in the top half, no one bothers to read past that, I guess, prolly should have moved it to the bottom, at least); that and bulk transfers from my money bags account are exactly how I set up this one, and the one immediately before it — no payment info on file or used ever, yet both have been kitted out with outfits and what-not. I keep a couple 10's of L$k's in each account at any given time for spot purchases (L$40k on this one at the moment) and transfer a chunk more over to top it up when needed, or just plain gift stuff to it. It's much easier to just keep all my accounts main funds in the one place, let alone having to update credit card info on them all every time it expires, etc. Plus, it's my builder account that gets all the revenue from marketplace sales, and the premium stipend, anyhow. So this one simply doesn't need any payment info, and the less payment info in any online sites records, the better — they ALL get hacked, eventually. I didn't actually know you could remove your payment info, though I'd have assumed you'd have to be able to. (Probably just a sign of how infrequently I bother to look.) It is good to know that flag does actually do something. And that would be why I made a point of mentioning that the Wiki is actually reasonably consistent in it's use of hex values so far as I recall seeing — when you see the 0x, you generally know it's a bit field, let alone the fact all the values are single 1's, 2's, 4's, or 8's, along with a bunch of 0's (admittedly, not so relevant in this specific case). And personally, I don't see how some might be "led slightly astray", the wiki page in question even straight up calls it a Flag, vs. a Value. It's not going out of it's way to be subtle about it, or anything, it's simply something people need to learn, and making it any more obvious would be down right annoying to everyone else. I'm sorry, but people only get a pass on this one once. It's really a very basic and important concept anyone planning on coding to any degree simply needs to get. That said, it may be worth adding a bit fields primer page to the wiki (if there isn't one already), and a link to it on relevant pages, I guess.
  16. Errr… It's a bit field. It's not complicated. If the info had 8 bit flags, would you expect them to add constants for the other 248 combinations as well? The bigger problem with all this, is that the only people you'll end up blocking with those rules, are legitimate users who're trying to set up their new account. The actual miscreants spin up a batch of accounts a couple months before they'll need to use them, or straight up just use stolen accounts that are typically years old, and usually with someone else's payment info on file.
  17. Yays, I'm actually younger than someone here…! I don't feel like the oldest person in the room any more. (I didn't even exist in '68…) 10 is most definitely in the wiki, it's literally PAYMENT_INFO_USED… (3 is left as an exercise for the reader, I guess.) But you can generally tell bit fields in the wiki right off — they're the ones written in hex. As soon as you see "0x", it's generally a bit field, and if it's not a bit field, it's generally represented in decimal. Seems to be one of the few things the wiki actually does consistently. On that note, 0, 1 and 3 make complete sense, but I was wondering about 2 myself, recently, actually… Could that be, payment info expired, perhaps? (Apparently not, actually.) Or perhaps it relates to one-time purchase of L$, vs. ongoing subscription? Am kinda curious, though to be honest, it kinda feels like information we shouldn't have. "payment info currently on file" is kind of a useful "adult test" signal, but I question the other. Does anyone actually use this info for anything? Because as for being a reliable signal of anything, only two of my accounts have ever had any payment info on file (I thought it was only one, both show "Payment Info Used", and respond with a 3, so I don't personally have any 1's or 2's — would have expected that old account might have been a 2); I always put payments in through one specific account, and then transfer it as needed (or just buy the thing directly as a gift to my other account, in the case of marketplace). I've still been playing this coding game too long, though — I see the binary and decimal (also hex, and octal) representations totally interchangeable (would no doubt be same for b64 if I could ever remember the alphabet well enough — I visualise it in my head the same way), and it took me a moment to remember others may not. I do remember back in early highschool, I was clearly not paying attention to the teacher, so the teacher had me "tell the class how many of <thing> there is", or something (did I mention I wasn't paying attention?), and being bored and feeling a little churlish that day, I started counting them off on my fingers out loud… """ 1, thing , 2 another thing, 3, (etc.) 4… 5… 6… 7… 8… 9… A… B… oh… *embarrased* I mean, 10, 11… 12… """ There were thirteen or fourteen total, from memory, a little shy of there being F of them, much to my still mildly juvenile brains dismay — it was an honest mistake though (I'd been doing some hex math instead of paying attention) — but I realised pretty much then just how readily my head accepts differing number systems. (It was a little worse, too, because next weeks class was on hexadecimal, so I got an extra large glare from the teacher who'd just realised I was going to be ignoring him for those classes, too.) I don't even remember learning that stuff, which typically means it was back in primate school (long before school taught it), and that it just seemed "obvious and natural" at the time… I guess I must have learnt it during my time with AppleSoft BASIC, or more so CALLing machine code held in DATA statements… ahhh… memories… And fuzzy screens… anyways…
  18. When you use the variable name, presumably. Because dynamic strings can change in size, they're not "in" the variable. The variable is a pointer to the actual string contents which is stored somewhere else (typically the heap, but for string literals, that may be the bytecode/executable). So a NULL (basically, 0) is a very very different thing compared to an empty string — the string isn't empty, it fundamentally doesn't exist. If you try to read it anyhow, C won't throw any errors (not counting any linting done by the IDE or compiler, C also doesn't have exceptions) unless it explicitly checks first, most often the program just crashes with a page fault when it tries to read the start of memory (which it's not allowed to do), unless it's in DOS (or similar non-protected environment) in which case it just reads whatever garbage happens to be there (neither case is terribly good). Basically, in Mono (in which LSL runs), the variable is pre-filled with 0's making it NULL, and then explicitly checked to make sure it's not still NULL when you go to use it (that's where the exception usually comes from — the fact they don't just swap it out for an empty value, probably means the check is being done by either the VM, or it's standard library). They could basically have just done the equivalent of: myVar ??= ""; (what I often do in TypeScript) but here we are…
  19. Damn. Oh wells. Would have been funnier if it was. heh Also also also, if that was LSL, you'd have just done the "initialise a variable two (or three) times" thing I'd mentioned.
  20. Yup, it is the C way. And lols… You must have been doing that test, while I was doing the exact same one in LSL.
  21. Also, also… That inspired me to do a little test… Looks like the variable is likely function-hoisted, not scope-hoisted. default { state_entry() { integer n; for ( ; n < 2 ; ++n ) { llOwnerSay("N = " + (string)n); { llOwnerSay("Inner"); if ( n ) jump skipInit; // change the above to !n, and watch it burn string foo = (string)n; @skipInit; llOwnerSay("foo = " + foo); } llOwnerSay("Outer"); { llOwnerSay("Inner 2"); if ( n ) jump skipInit2; string bar = "cows"; @skipInit2; llOwnerSay("bar = " + bar); } } } } Which is mostly what I'd have expected. All local variables are likely pre-allocated at function entry. Though with how little memory we get, scope-hoisting would have been nicer. Easiest example of this, is in Python, when you inspect a function it has a "varnames" array containing the names of all your function parameters, and then all your local variables. There's a corresponding array of values created at function call (pretty sure Python just does a bulk zero-fill too, probably as simple as a call to calloc), and then the supplied parameter arguments are simply plugged into the appropriate spots before the function is started — all local variables your function will define already exist in the array by that point. And within the bytecode, variables and function parameters are simply referred to by their index into that array, rather than their names (the names are kept around for introspection purposes, but never used by the bytecode itself). Python does it this way because it doesn't use the system stack for function calls (makes generators trivial, and Python loves generators). Also because everything in Python is an object (much like Java), all variables just happen to take up the exact same amount of space, too — a pointer to the actual value somewhere on the heap. Of course, Python also doesn't have block scoping, but the same thing happens in languages that do. Whatever the specifics, in compiled languages (C in particular) the local variables are generally "allocated" by simply adding (technically subtracting, since stacks generally grow downwards) their total size to the stack pointer, and expecting the programmer to initialise them appropriately (this is the C way, before linting comes into play). Anyhow… Dunno whether LSL (Mono) does arguments in Python or C style (I think I saw something in this forum a bit back, suggesting Mono uses a system stack), but I'd be quite surprised if one way or another, your Mono locals weren't just sitting in a chunk of bulk zero-filled memory — hence the NULL exception error if you skip the formal initialisation.
  22. Also, annoyingly, they say they review past bugs periodically and stuff… But I had a Jira accepted, and then like the very next meeting a week later, the lindens present were talking about it like it was a completely new idea, and accepting suggestions, most of which I'd already covered in my Jira issue (because I tend to be rather on the verbose side). So we do clearly need to remind them of these things from time to time… But the topic did come up again just recently, so it's at least on their radar. Though probably infrequent enough that they've just labelled it as "too hard" for now.
  23. 2016…? At least. More likely right from day 1… I've known about it over a decade now… (And also forgotten about it, and re-discovered it again in between… *mutters* ) Well, actually, C defines variables as uninitialised. So in C's case, you'll get whatever was in memory already. That's not to say modern IDE's and compilers haven't added warnings, they've added a whole bunch of linting stuff these days — stuff that was left out originally because systems were much smaller. But you can turn those off, and you'll get C's default behaviour of "whatever was in memory" (whjch is particularly fun for stack allocated variables). And ideas about wasting memory have changed, too, so global/static variables are often allocated in zero-filled memory (ie, they'll read as NULLs). Pretty sure most loaders have the option to zero-fill sections (the executable just says, "give me X bytes of zero-filled memory), but even still, you can see huge swaths of 0's just sitting in many executables because it gets initialised at compile time, and then the whole chunk is just slapped into memory by the loader (and the compiler couldn't be bothered splitting that space into zero'd and initialised loader sections). You see this up close and personal if you've ever done any assembler, where you actually define the loader sections yourself. Pretty sure Java is different, because everything is an object, therefore everything has an initialiser, and because it's a VM not "bare metal" code — also, does it even actually have statically initialised variables (not the same as static variables, I'm talking about the space the object will occupy having been pre-initialised by the compiler)? I rather suspect every Java program starts with a flurry of object creation, where each and every variable/object initialises itself. Jave is also just plain newer, and the newer languages are burning not-so-precious-any-more memory and processor time with trivial niceties like initialising variables for you. Mono is doing the same for LSL, by the way, also being VM-based (after all, it is literally "Microsoft's answer to Java")… Just, it's initialising your variable to NULL, rather than "", which LSL isn't happy about. Basically, the variable definition is almost certainly "hoisted" (to use a JavaScript term) to the top of the scope (maybe even the function as a whole), but then an assignment is placed at the spot where it's defined — since it may be initialised to a value other than "", and if that value is computed, then it doesn't actually exist yet. So instead of trying to figure that out, or potentially wasting time initialising all your variables twice (three times if it's a for loop variable — how many of us are guilty of setting an already 0 variable to 0 at the front of our for loops?), it just puts an assignment at the definition spot and expects you not to do dumb things.
  24. As long as you provide additional syntax to ignore a returned value when you want to, it's probably actually a good thing. Which is usually where this kind of thing is picked up — the compilers themselves generally don't care (except as noted, in the case of C/++ which has compiler flags for pretty much everything ever conceived of) — it's often only the linter (usually in an IDE) that is at all worried by it. And even then, it's not generally an error, you can usually simply ignore such warnings at will (though they also generally have an option to MAKE it an error). Same in my dooberwatsit too (it's only a warning), where I provide a special LSL-safe syntax to ignore a returned value. But not just functions, either — any expression who's result isn't used (as in, "Expression Statements"). Having an internal void type makes this easy; all functions return exactly one value, and all unused expression results must be void. (It works syntactically, because you can't actually use void in an expression, or as an argument to anything.) Both C/++ and D have the ability to mark a return value as important (and corresponding syntax to ignore it again). But it's opt-in, and of the dozen or so languages I've used seriously (seriously!), those are the only two I can think of that even have it as part of the language (I think I remember that Rust does, too…? I'm sure it does, but I wouldn't count Rust as a language I've used seriously enough to remember reliably). It's definitely an unusual feature for languages to care about (and that's even considering they generally DO need to actively deal with it). The only case I can think of where it may have been an actual error, was a once-popular functional language I learnt in Uni, but have long since forgotten. However, it doesn't like your thingo does linting too, so, it would fit. In LSL in particular, this occurs quite frequently with pretty much all asset server functions, in simpler scripts. Like the aforementioned notecard reading; you know which line you requested, notecard lines are the only dataserver thing you are requesting, and if there's no other scripts in your object that use that event, then if the event fires, you know what it is, and keeping the key around is just going to be a waste of memory anyhow. I've had that same situation come up with llHTTPRequest, too (probably more often than for notecards, actually), and several of the new LSD functions (how many people actually check that every single LSD write succeeded, and how often do you actually care if an LSD delete failed? — even in fairly complex scripts). And, of course, there's llListen. Of the lot of them, llListen is probably the one I (and likely most people) intentionally ignore the returned value of most often, and it would be more annoying than useful to not have an easy way to ignore the handle.
  25. Another option is https://wiki.secondlife.com/wiki/LlStringToBase64 — the output is unreadable, but it'll be smaller for just about anything other than alphanumerics.
×
×
  • Create New...