Updated Wind Sculpt

I’ve been fiddling around with Linden Scripting Language for over nine years now.  It’s an interesting, quirky language, with a huge number of functions in its library (nearly 500).  While I think I know it pretty well, language and library features can always surprise even the most experienced coder.

A week or so ago, I found myself in the position of wanting to be able to rez and derez 64 linked objects.  Previously, I’ve done this by putting a script in the objects to be deleted that listened to the master script and then deleted themselves when told. But…

64 scripts, even though they were very small (about 5 lines of code and less than 6K of memory each), nearly doubled the land impact of my 65 piece object!  There had to be a better way.  And there is.

There are two functions called llSetRemoteScriptAccessPin() and llRemoteLoadScriptPin() that will allow you to load a script to an object on demand and set it to running.  I won’t give you an example here, you can see some at the links to the functions.  All this is leading up to the fact that I have an existing product on MP that also does rez and derez of multiple linked objects, and uses the old method.  Can we use these functions to drop its land impact?  No prize for a correct guess!

This is the BF Wind Sculpt, a kinetic wind sculpture based on Anthony Howe’s Di-Octo.  It rezzes and derezzes its vanes on demand.  With the old system with a script in each vane listening to the support to say “delete yourself”, the object weighs in at 13 LI.  Using the new method, it comes in at 10.  Yay!  If you own a copy, you should now have version V1.3.


Instantly improve your avatar as a newcomer

Oh my, why oh why do I see three year old and older avatars that still look like they created their account yesterday?  I know it must be laziness or perhaps lack of computer skills, but getting a good looking avatar is pretty simple!

Here, I’ll not only give you a step by step, I’ll assume you’re running Firestorm and give you a step by step to switch off things and switch on things that will instantly improve your look.

Let’s start with that.

Firestorm settings

Head follows mouse

  1. Open Preferences via the main “Avatar” menu, or hit Ctrl-P.
  2. Go to the “Firestorm” tab.
  3. Select the “Avatar” tab.
  4. Set the two sliders at the top to zero by dragging them all the way to the left.  They are labeled “Vertical/Horizontal range that avatar’s head follows mouse”.

Selection Beam

This stops your arm waving wildly around when you select something.

  1. Open Preferences via the main “Avatar” menu, or hit Ctrl-P.
  2. Go to the “Firestorm” tab.
  3. Select the “Avatar” tab.
  4. Untick the “Enable selection beam” checkbox.

Animation Overrider (AO)

This is a bit complex, but follow along step by step if you don’t have an AO.  Although there are a lot of steps, the procedure is straightforward, and uses computer skills and SL skills that you should already by familiar with.

  1. Find a FREE AO on marketplace, we’ll use the Basically Girl AO as an example, and buy it for L$0.
  2. Go to a sandbox, for example, Skybeam, or somewhere you have rez rights.
  3. Open your inventory (Ctrl-I) and locate the object “AX-001 Basically Girl AO”, either via the “Recent” tab if you just bought it, or using the search bar at the top of your inventory window.
  4. Left click on the object in your inventory, and while holding the left mouse button, drag it onto the ground.
  5. Right click the object on the ground and “Open” it, and click the “Copy to inventory” button in the “Object Contents” window that opens.
  6. Close the “Object Contents” window.
  7. Delete the object on the ground with right click and “Delete” (or if you’re using pie menus, right click, “More >”, “Delete”).
  8. You should now have a folder in your inventory called “AX-001 Basically Girl AO” containing an object called “AX-001 Basically Girl AO (Oracul Animations HUD)”.
  9. Left click this object in your inventory, and while holding the left mouse button, drag it to the ground (be careful, the object is small).
  10. Right click the object on the ground and open it, and click the “Copy to inventory” button.
  11. Close the “Object Contents” window.
  12. Delete the object on the ground.
  13. You now should have a folder in your inventory called “AX-001 Basically Girl AO (Oracul Animations HUD)” containing lots of animations and three notecards called “SET01-” followed by a height in centimeters.
  14. If you don’t have a toolbar button labeled “AO” in your toolbar, create it by selecting “Toolbar Buttons” from the main “Avatar” menu, locating the “AO Animation Overrider” button, and dragging it to your toolbar.
  15. Click the AO button on your toolbar to open the “Animation Overrider” window.
  16. Choose one of the notecards, for example, “SET01-155cm” that is closest to your height.  If you don’t know your height, right click your avatar and select “Edit shape”.  The shape editor window will open and your height is in the top right corner.  You may have to click “Metres” to see the metric height.
  17. Left click your chosen notecard and holding the left mouse button down, drag it into the “Animation Overrider” window.
  18. Close the “Animation Overrider” window (and your inventory, you’re done with it) and tick the checkbox in the AO button on the toolbar.
  19. Congratulations!  You now have an AO.  You can disable or enable it with the checkbox on the toolbar button.
  20. You can find other AOs and repeat this procedure to create multiple AO sets in Firestorm.

There’s addition information about the in-built Firestorm AO on the wiki, including links to tutorial videos on how to set it up and customize it.

Fix Bento Idle Animation

Bento is cool, it allows us to move our fingers, and do a lot more facial expressions than before.  But if you don’t have something to play an animation on your Bento bones, some of the default positions can look… weird.  The most common newcomer look is splayed hands.  Do this to ensure that if you have no Bento animations playing, your hands (and face, etc) will run a low priority animation that will fix the weirdness.

  1. Open Preferences via the main “Avatar” menu, or hit Ctrl-P.
  2. Go to the “Firestorm” tab.
  3. Select the “Extras” tab.
  4. Tick the box labeled “Fix Bento Idle Animation”

Typing animation and sound

This should probably be the first thing on the list 🙂

  1. Open Preferences via the main “Avatar” menu, or hit Ctrl-P.
  2. Go to the “Chat” tab.
  3. Select the “Typing” tab.
  4. Untick the box labeled “Play typing animation when chatting”.
  5. Untick the box labeled “Hear typing sound when people type in nearby chat”.
  6. On the left hand panel, select “Sound & Media”.
  7. Select the “UI Sounds 2” tab.
  8. Untick the “Play this sound” checkbox next to “Typing a message”

Appearance

There are certain things, mostly very old objects, available at various freebie places around the grid.  Because they’re free, newcomers tend to snap them up, but to anyone with any time in SL, all they do is mark you as completely inexperienced (and oblivious to appearance).  Once you know what these things are, you can avoid them, or modify them to improve the look of your avatar.

Bling

Bling, which is a particle effect meant to represent sparkly things like jewelry (hence the name), was apparently huge… in 2007.  Today, most people avoid it.  My advice is to chuck things with bling.  If you really like the piece and want to keep it, and it has modify permissions, you can potentially get rid of the bling effect, but to do so requires some basic scripting knowledge.

For help, try going to somewhere like Builder’s Brewery and politely asking an experienced person to help you.  Just remember, the people that you ask may not know how, or may not have time to help.  Thank them and politely ask someone else.  Just don’t be a nuisance to people as they are trying to build.  If you can’t find someone to help you, stash the thing back in your inventory and try another day.

Full bright

Full bright is a texture property.  It’s like switching a backlight on behind a picture.  This is great for lighted signs and stuff, but it looks horrible in hair.  Before mesh hair came along, prim hair was all that was available.  To make it look “better”, some creators allow you to switch full bright on and off by clicking your hair.  If you have “glow in the dark” hair, look for this option, else look for another hairstyle.

There are tons of good mesh hairstyles available for FREE if you take the time to look around.

Avatar expression

Specifically, the HUD that makes you smile every couple of seconds.  I remember finding this as a newcomer and thinking, “Great, my expression won’t be static any more!”.  But, strangely, smiling every couple of seconds comes across to me now as… creepy.  If you must use an expression HUD, try AnyPose Expression HUD, which you can get for FREE.  You can trigger an expression manually, rather than smiling creepily every few seconds.  As a bonus, you get eye position control with this, which is a boon for posed photography.

Mesh eyes

Get some for FREE at Mayfly Mesh Eyes, you’ll be impressed by the difference they make.  Using them requires basic editing skills.

Eyelashes

If your avatar doesn’t have eyelashes, get some prim ones for FREE, for example, these free eyelashes.  Using them requires basic editing skills.

Nails

Back in the day, prim nails were the way to go until you could afford SLink hands, which were the hand replacement of choice until mesh bodies came along with in-built hands.  I still love my SLink hands and wear them every day although I have a Maitreya mesh body.

As the new default avatars still aren’t Bento enabled, you should still be able to find some on marketplace.  And yes, Bows and Butterflies have a number of prim nail sets available for L$1 each.  Again, using them requires basic editing skills.

Makeup

It’s easy to be a blonde in RL and a redhead in SL.  And it’s easy to use your normal makeup tones from RL and look dumb 🙂  If you’re a blonde in RL, and you decide to be a redhead in SL, take the time to research makeup tones that suit redheads, just like you would if you dyed your hair in RL.  For heaven’s sake, try not to wear bright red lipstick with ginger hair, OK?!

Shape

We tend to exaggerate body shapes in SL.  Everyone can be the perfect supermodel, or you can go the other way and exaggerate… other attributes.  You can see what I look like on every other post on this blog.  I’m not a total glamor, and I’m not totally exaggerated either.  Both extremes mark you either as someone in the fashion industry, or a total newcomer.   To look good, I highly recommend you go for a “girl next door” look, with nothing totally over the top (pardon the pun).  You can create your own shape, but you can also find good starter shapes on marketplace for little or no cost.

Before fitted mesh, we had standard sizing.  It’s still a good idea to stick close to one of the standard sizes, as you do tend to come across good clothing for those sizes occasionally.  So, a good starter shape is this one for FREE.  It’s modify so of course you can tweak the sliders to make it your own.

Physics

This is a system attachment that makes your breasts and butt react to gravity in appropriate ways.  Get the Firestorm Team’s Physics pack for free on the marketplace and play around with settings until you get something you like.  To do this, wear a physics attachment from the pack, and right click it in your inventory and edit it.  Then you can adjust the sliders to your liking.  Settings can differ markedly for system bodies and mesh bodies, and you should think about what you’re wearing too.  You don’t want bouncing boobies while you’re wearing a corset, for example, so you should create a few physics objects and wear the appropriate one for the occasion.

Skin

Try lots of demos (in private) while you save up your L$ to buy the best skin you can that has both system layers and at a minimum, Omega appliers for both body and head.  Seriously.

You may be really lucky and find one that has system layers and appliers for free, but it’s really rare.  I think I’ve found one in six years.

Mesh body

For FREE.  Yes, really!  You can get all the details over at Ryan’s blog post.  And now FabFree are maintaining a page listing the current free body and head giveaways around the grid.  So there’s no reason not to have a mesh body!

Clothing

Of course, there is a ton of free clothing available via various means on SL and the marketplace as this blog proves every day.  I’ve written an entire article about how to find free clothing before.  And while this blog today is mostly focused on fitted mesh clothing for the major bodies (because that’s what creators generally put out as group gifts), you can still find standard sizes as I mentioned.  Also, with the introduction of BoM, a lot of system layers have been resurrected, and lots of nice things can be found for FREE to improve your appearance.

Thanks

If you got this far, thanks for reading.  I really enjoyed writing this as it bought back fond memories of when I was first starting out, and the steps I took to gradually improve.  Here’s six years difference (note that full bright hair on the 2014 shot eeps!):

Blue – 2014 vs 2020


Getting started

Do you know we have an article to help newcomers get started in Second Life?  Well, we do!  It was this blog’s first published post.  Even though that’s quite some time ago, we still try and keep the article updated when things change.   To that end, I’ve just reviewed and made some minor revisions to it.

If you run into me in-world, I also have a version of the article as a notecard, so feel free to ask me for it.

Check out the article, and please pass it on to new people that could benefit from it.


Script memory

Thinking about script memory in LSL is very important.  In Mono, which is the modern script engine, each script gets 64K of memory allocated by default.  This is true even if the script uses only a few kilobytes of memory.

With thousands of scripts in a region, this can easily consume all the memory allocated to the region, and cause the region to start swapping memory out to disk (this all happens at the Linden Lab server running the region).  Swapping is a Bad Thing™ and will drastically slow down the sim, which you’ll see as lag.

So, what as script creators can we do?  If you have a script that takes no external input, you can limit the amount of memory your script will be allocated with a llSetMemoryLimit () function call.

Firstly, what do I mean by “takes no external input”?  An example of something that takes external input is something like a picture frame that displays the owner’s selection of textures.  The owner can drag textures into the frame and display them.  Typically to do this, the script will load the names of the textures into a list, and therefore the amount of memory used by the list is out of the control of the script creator.  It depends on how many textures the owner loads into the frame’s contents, and not how the script creator codes the script.

So, if you have something that doesn’t allocate memory out of your control, how do you know what upper limit to set with your call to llSetMemoryLimit ()?  There’s a set of memory profiling calls that will tell you.  And, as you may have guessed, this post was prompted by someone triggering the swapping problem on my home sim, which made me see if I could drop the memory that my scripts allocate.

To make things easy, I created an include file for my scripts.  Let me show you an example of how I use it.  You can access the included files by following the link in the comments next to them.

#define DEBUG
#include "debug.lsl"      // See the source of debug.lsl

#define MEMLIMIT 8000
#define PROFILE
#include "profile.lsl"    // See the source of profile.lsl

#define BLUE "c3623b1f-db83-4003-bb6d-d0d60d32c621"

phantom (integer p) {
    llSetLinkPrimitiveParamsFast (LINK_THIS, [PRIM_PHANTOM, p]);
}

default {
    state_entry () {
        init_profile ();
        llCollisionFilter ("", BLUE, TRUE);
        phantom (FALSE);
    }

    collision_start (integer n) {
        phantom (TRUE);
        llSetTimerEvent (2.0);
    }
    
    timer () {
        llSetTimerEvent (0.0);
        phantom (FALSE);
        show_profile ("timer");
    }
}

This is a simple script that goes in an invisible barrier.  It lets me walk through it by turning the barrier phantom when I collide with it, but for everyone else, it does nothing.  It takes no external input, all the memory it will use is its code, it doesn’t even use any variables!  So this is a perfect candidate for limiting script memory allocation.

The code at the top includes my standard debugging code, and the

#define MEMLIMIT 8000
#define PROFILE
#include "profile.lsl"

defines an initial memory limit of 8000 bytes, tells profile.lsl to enable profiling, and includes the profiling code.

Now notice the calls to init_profile () and show_profile ().  The init_profile () call sets the script’s memory limit based on the MEMLIMIT definition, and starts memory profiling if PROFILE is defined (and, just a warning here, memory profiling can drastically slow down your script so make sure you turn it off when done!)

The show_profile () call displays the current maximum amount of memory the script has used.  It can be tricky to figure out where to put this call, but in this case, it’s easy, as the script flow first sets everything up and then waits for a collision by me, followed by the timer firing.  So the logical place to put the show_profile () call is at the end of the timer.  All the code has run by this stage.

When you save this, and collide with it (if you’re trying this, don’t forget to replace my UUID with yours!), you’ll see something similar to the following…

Barrier: Memory profile init: 0
Barrier: Memory profile show (timer): 7598

This tells us that at the end of the timer event, the most memory the script has ever used is 7598 bytes, so our starting figure of 8000 was close.  If you see

Barrier: MEMLIMIT = 8000 too small

increase the size of MEMLIMIT until this message goes away.

I will leave a little buffer between the size reported and the limit, just in case 🙂  So in my example, I left MEMLIMIT at 8000.  Doing this simple exercise saved over 56K!  That may not sound like a lot, but don’t forget there can be thousands of scripts running in a region, so it adds up.

Once you’ve figured out a good number for MEMLIMIT, don’t forget to turn off debugging and profiling by changing the #define DEBUG and #define PROFILE to #undef DEBUG and #undef PROFILE, and leave the init_profile () and show_profile () calls in place.  The init_profile () call just sets the memory limit when PROFILE is undefined (and the show_profile () call is replaced by a blank line of code).

If every script creator did this, we’d be living much less laggy second lives!


Basic animation chooser

Sometimes, you just need something simple to pick an animation to play.  Here’s a script to do just that.  Rez a prim, drop this script in it, and a bunch of animations, then take and wear it as a HUD.

When you touch it, it will offer you a dialog where you can play any of the animations, or stop the one currently playing.

Note the links to the included scripts.  If you don’t use the Firestorm preprocessor, you can get the source for the #included bits by following the link in the comment next to the #include.  Just cut and paste the code into the top of this script, replacing the #include.

#include "dialog_plus.lsl"  // see the source of dialog_plus.lsl
#include "privchan.lsl"     // see the source of privchan.lsl

integer g_have_perms;
string g_current;
list g_animations;
key g_owner;
integer g_channel;
integer g_listen_handle;
string g_msg = "Select";

default {
    
    attach (key id) {
        if (id != NULL_KEY) {
            llResetScript ();
        } else {
            if (g_have_perms && g_current != "") {
                llStopAnimation (g_current);
            }
        }
    }

    state_entry () {
        integer n = llGetInventoryNumber (INVENTORY_ANIMATION);
        integer i;
        string name;
        g_current = "";
        g_animations = ["Stop"];
        g_have_perms = FALSE;
        g_owner = llGetOwner ();
        g_channel = privchan ();
        for (i = 0; i < n; i++) { 
            name = llGetInventoryName (INVENTORY_ANIMATION, i);
            if (llStringLength (name) > 24) {
                llOwnerSay ("Animation \"" + name + "\" longer than 24 chars, not loaded");
            } else {
                g_animations += name;
            }
        }
        llRequestPermissions (g_owner, PERMISSION_TRIGGER_ANIMATION);
    }
            
    run_time_permissions (integer p) {
        if (p & PERMISSION_TRIGGER_ANIMATION) {
            g_have_perms = TRUE;
        }
    }
    
    touch_start(integer total_number) {
        llListenRemove (g_listen_handle);
        g_listen_handle = llListen (g_channel, "", g_owner, "");
        DialogPlus (g_owner, g_msg, g_animations, g_channel, g_menu_idx = 0);
    }

    listen (integer chan, string name, key id, string data) {
        if (chan == g_channel) {
            if (data == "Back") {
                DialogPlus (g_owner, g_msg, g_animations, g_channel, --g_menu_idx);
            } else if (data == "Next") {
                DialogPlus (g_owner, g_msg, g_animations, g_channel, ++g_menu_idx);
            } else if (data == "Stop") {
                if (g_current != "" && g_have_perms) {
                    llListenRemove (g_listen_handle);
                    llStopAnimation (g_current);
                    g_current = "";
                }
            } else {
                if (g_have_perms) {
                    llListenRemove (g_listen_handle);
                    if (g_current != "") {
                        llStopAnimation (g_current);
                    }
                    g_current = data;
                    llStartAnimation (g_current);
                }
            }
        }
    }
}

Physics lesson

Warning, topless shots below the fold.

Let’s talk boobs.  I see a lot of female avatars getting it sooo wrong in SL.  In RL, we don’t have to worry, we have built-in shapes and physics, and our cleavage is controlled by the clothes we wear, not a texture, so we don’t usually have to think about it (with the exception of picking out that awesome pushup bra for a hot date lol)

In SL, none of this works automatically without some input from us.  We have shapes, physics layers, and skin options to worry about.

A decent quality skin is one of the things you should definitely splash out some money for.  You can get a reasonable skin for a couple hundred Linden Dollars, but a good one will probably set you back over L$800.  Believe me, it’s worth the time and money to find one that you like, as, along with your eyes, it’s the one thing you’ll wear all the time.

When it comes to selecting a skin, pick one with multiple cleavage options.  You want at least small for when you’re bare breasted, medium for when you’re wearing a bra or a bikini top, and “lots” for corsets and some formal gowns.  There’s nothing funnier than seeing an otherwise naked girl wearing a skin with lots of cleavage.  I keep having to ask myself “did she stick them together with superglue, or what?”  lol

Do NOT look like this, there’s someone on that beach (like me) quietly laughing at you!

Much more natural looking 🙂

With Lara by Maitreya, there’s a great option in the HUD to store skins in save slots under the “Skins & Options” tab.  My skin (Adore Peach by Lumae) has four cleavage options, and all of those are stored in the HUD in Firestorm’s “Favorite Wearables” for easy switching without having to dig through my inventory.

Now, you all know we need support, and when that support is taken away, things tend to sag, much as we wish they didn’t 🙂  Before fitmesh clothing, we had standard sizes, and to fit them, many of us saved off a modified shape along with the clothes, and the most modified sliders, at least for me, were breast size and gravity.

Using the same principle, you should have at least a few variations on your base shape for the bare/bra/corset thing with various levels of gravity applied.

And also, when that support is taken away, things tend to jiggle.  This is where physics comes in.  Physics is a system layer that you wear.  Not only can it control breast physics, but also stomach and butt as well.  Basically, the settings tell the viewer how much things should jiggle and which way they should jiggle when you move.

Again, you want at least the three options for bare/bra/corset, with plenty of bounce with little damping for bare breasted, and basically no bounce and high damping for corsets.

You can buy physics packages on the marketplace, but they’re pretty easy to set up yourself.  There’s a page on the Firestorm website with instructions on creating physics layers, so I won’t repeat all the “how-to” here, you can hop over there and read it if you need help.  The Firestorm team also have a free physics collection available on the marketplace which is a great starting point to experiment with all this.

I strongly believe it’s worth the time to set up your avatar so it looks as natural as possible.


Land settings

Woohoo!  You’ve bought yourself some land, or rented a nice parcel with full control on a private sim!  These are the minimal settings I’d recommend you tweak so you get the best experience on your new living or working quarters.

In Firestorm, you can just click the little “Land” button in the top navigation bar to pull up the land settings window while you are standing on your land.  Else you can right click on the land and select “About Land” to do the same thing.

Firstly, just the ascetics bits.  You want people to see a nice name and description for the place, not something like “Parcel #59, 1024sqm, 512 prims” or something that the landlord has set to advertise the parcel.  So change your parcel’s name and description in the General tab.

I recommend that you set your land to group owned too.  This will allow you much finer control on what you and friends can do on your land, and what others can’t.  Even for a privately owned parcels like Aeon and I have here, it’s worth the L$100 group setup fee to do it.  To do this, click on the “Set” button next to “Group”, select the group you want to own the land, and hit the “Deed” button.  There is a full article about group owned land in the knowledge base that you should read before you do this.  And of course having said that, I now probably have to write a post about group roles and permissions 🙂

Next up, and most important, is what people can do on your land.  In the “Options” tab, you should untick “Build” and “Object Entry” for everyone.  If you don’t do this, you’re just leaving yourself at the mercy of griefers.  And unless you’re a combat sim, I’d also suggest you tick “Safe (no damage)” and “No Pushing” too.  Also, that “Use with caution!” line next to “Edit Terrain”?  It’s not a joke.  Make sure it’s unticked unless you are oh, let’s see, a sandbox who wants to teach people about terrain editing? 🙂

Do you want privacy?  In residential areas, mostly you do.  So make sure “Avatars on other parcels can see and chat with avatars on this parcel” is unchecked.

And lastly, everyone needs to get along with their neighbors.  The most irritating thing you can do in my opinion to upset your neighbors is let sounds, be they from gestures, radio, media like TVs playing youtube videos, or voice, bleed into surrounding parcels.

Tick “Restrict gesture and object sounds to this parcel”.  And if you enable voice, “Restrict Voice to this parcel”.  Please, please, please do this, your neighbors will thank you!

This post sprang from a friend of ours who devastatingly had her land reclaimed, was lucky enough to get it back before the landlord returned her objects, and wanted my help to set up again.


Detecting RLV

As you may know, I love scripting.  Last Halloween, I made up some RLV traps to scatter around the build for the unwary.  One was a giant skeletal hand that popped out of the ground and grabbed the unsuspecting victim hehehe.

I though you might be interested to see how the basis of RLV scripting works.  Feel free to skip this article if you have zero script interest 😉

To be affected by these type of scripts, avatars must wear an RLV relay and be using an RLV capable viewer, for example, Firestorm.  The relay acts as a bridge between the scripted object and the avatar’s viewer, receiving commands and then those commands are intercepted by the viewer.  This is how RLV can control your viewer.

The RLV relay listens on a specific channel (you can find heaps of detail about all this in the RLV Relay Protocol document).  The first thing you generally do is find a list of avatars wearing an active relay so you can perform some action on them.  That’s what this example script does, find a list of RLV enabled avatars.

#define DEBUG
#include "debug.lsl"        // See the source of debug.lsl
#define TIMEOUT 1.0         // #define is part of the Firestorm preprocessor
#define CHAN 12345          // You can just define these as normal variables
#define RLVCHAN -1812221819 // if you're not using Firestorm

list g_avis;
key g_target;
integer g_idx;
integer g_handle;
string g_command;

default {
    state_entry () {
        debug ("state default");        
    }

    touch_end (integer n) {
        llOwnerSay ("Checking for active RLVs...");
        g_avis = llGetAgentList (AGENT_LIST_PARCEL, []);
        state rlv;
    }
}

state rlv {
    
    state_entry () {
        if (llGetListLength (g_avis) > 0) {
            g_target = llList2Key (g_avis, 0);
            llListenRemove (g_handle);
            g_handle = llListen (CHAN, "", "", "");
            g_command = "testing";
            llRegionSayTo (g_target, RLVCHAN, 
                           g_command + "," + (string)g_target + ",@versionnum=" +
                           (string)CHAN);
            llSetTimerEvent(TIMEOUT);
        } else {
            llOwnerSay ("--");
            state default;
        }
    }
    
    listen(integer channel, string name, key id, string message) {
        if (llGetOwnerKey (id) != g_target) {
            return;
        }
        if (g_command == "testing") {
            llSetTimerEvent (0.0);
            llListenRemove (g_handle);
            llOwnerSay (llGetDisplayName (g_target));
            g_avis = llDeleteSubList (g_avis, 0, 0);
            state redo_rlv;
        }
    }
    
    timer() {
        llSetTimerEvent (0.0);
        llListenRemove (g_handle);
        g_avis = llDeleteSubList (g_avis, 0, 0);
        state redo_rlv;
    }    
}

state redo_rlv {
    state_entry () {
        state rlv;
    }
}

The basis of this script is the llRegionSayTo () function, the listen, and the timer in the rlv state.  Saying a string to an avatar formatted correctly (in this case, we are asking for the avatar to tell us the version of RLV they are running) will cause the avatar to send us a string back with the information, which is received by the listen.  In the event the avatar does not have a relay on, they won’t respond with anything, so eventually, we remove the listen with a timer.


Script preprocessing

As you may know if you’ve read my “About Blue” page, I love writing scripts to get objects to do things in-world.  It’s one of the reasons I joined SL, to discover what I could do with a new and interesting programming language.  So, you get the occasional technical article on the blog.  Feel free to skip this if you have no interesting in scripting 🙂

LSL is limited is a number of ways.  One of them that it lacks a preprocessor.  Preprocessors allow you to do things like:


#define CONSTANT value

and wherever the word CONSTANT appears in the script, the preprocessor will substitute value before it compiles the resulting code.  This is great for things like debugging scripts, and many other uses.

If you are using Firestorm however, you can switch on a preprocessor for LSL built into the viewer!

Other than doing substitutions such as the example above, there are a number of things you can use defined constants for, such as conditional compilation. Also, the preprocessor implements a number of other functions such as code inclusion.

The feature I want to talk about though is the switch statement.  LSL lacks this common feature of other C and Java-like languages.  So the Firestorm developers included a way to have the preprocessor do it.

In their basic form, switch statements look like:


switch (expression) {
    case value1: {
        do something;
    }
    case value2: {
        do something else;
    }
}

And here is the point.  We know that expression is something that can return an integer.  The first time I used a switch statement in LSL, I coded what any C or Java programmer would and said:


switch (llListFindList (list1, list2)) {

knowing that llListFindList () would return an integer result.  But on looking at the resultant code (you can see this in the preprocessor window in Firestorm after your code is preprocessed), I noted that the switch statement is translated into multiple if statements with jumps, but the preprocessor is not smart enough to evaluate the expression once and use the result!  So if you have 40 case statements, the resulting code will have 40 calls to llListFindList () !  This is terrible for performance!

If you are using switch statements in your LSL, please evaluate your expression before handing it to the preprocessor.  For example:


integer result = llListFindList (list1, list2);
switch (result) {

This will ensure expression is only evaluated once.

You can read more about the Firestorm preprocessor here.


Jennifer

Or “How I got my shape right for my new Bento head” 🙂

I’ve been watching the revolution in Bento with keen interest.  Slink and Maitreya Bento enabled hands are fantastic (I have both), and some of the wings available?  Oh my!

Ever since Bento was released and offered us the opportunity to shape a mesh face how we wanted it, I’ve been keen to get one (to be honest, mainly so my eyelashes look right! lol)  Over the last few months, I must have tried twenty different demos from creators such as Catwa, Laq, AK, and GA.EG, but I couldn’t find one that I could shape so I would still look like myself.  My biggest problem was I couldn’t get my eyes right.

However, two weeks ago, GA.EG released a new model called Jennifer, and Aeon pointed it out to me as she has Barbara from the same creator, and saw the announcement.  Within 20 minutes of working with the demo, I had a very good feeling that this was going to be the one for me!

Working with the demos, most creators recommend you start with the included shape, so the first thing I did was copy their demo shape, and set every slider except the ones to do with the face to my measurements.

Then I created this evil looking device…

This is actually a pose stand (the base is out of the picture below).  While I posed on it in my normal system shape, I adjusted all the little cones so they would touch strategic parts of my face.  Then I changed to the mesh face and shape, and started playing.

Here’s a picture so you get the idea…

This turned out to be a huge time saver as I could look at a demo, pose on this, adjust some sliders, and know nearly instantly if the demo had any hope at all of matching my system face.  Not only that, it got me close enough to where I wanted things to be that I could then take a photo on a normal pose stand and without moving the camera, change to the demo. take another photo, and then do a comparison in Gimp.  I did comparison photos from both the front and the side.  Hundreds of them 🙂

While I’m still playing around a tiny bit, especially with the eyes and eyebrows, I got close enough with Jennifer that I pulled the trigger and bought it.  Here’s a before and after picture.  How do you think I did?

  • Bento Head: Jennifer by GA.EG
  • Shape: Blue’s Fantasy