Earlier I’d written a post on Mono and Bytecode Sharing. In that post, I mentioned that there were several ways that a script could be written to take configuration parameters. Being able to configure scripts for multiple purposes has at least two advantages.
- Scripts that don’t need to be compiled to make small parameter changes support bytecode sharing.
- Being able to configure a single script to serve multiple purposes potentially makes the script easier to maintain.
One way to make a script configurable is to put socks in your object. Yeah, yeah, I know that sounds weird. But it is really a pretty easy way to set simple configuration parameters. And if you don’t like socks you could use any clothing object. The LSL functions that deal with clothing can’t actually tell what type of clothing it is.
Basically, what you do is place a clothing item with a particular name in the object. Then have the script read the object inventory looking for clothing items. If it finds an item with a name of a keyword that you’ve chosen, then set a flag, flip a switch or whatever you need to do in your script to make it behave differently.
First you have to create a pair of socks. Don’t worry. This is easy. You don’t have to do anything to them other than name them as their name is all we’re interested in. Open your inventory, select the ‘Clothing’ folder and right click on it. On the menu that opens, select ‘New Clothing’, then ‘New Socks’. If you don’t rename them now, they’ll be called ‘New Socks’. Drag them to the inventory of your object and rename them to whatever you like.
The llGetInventoryName function is the key to socks approach. It will return the n’th item of the indicated type from the inventory. In this case I specified ’0′ for the item number so we get the first item.
socks = llToLower(llGetInventoryName(INVENTORY_CLOTHING, 0));
In the example above, I’m saving the name of the first item of type INVENTORY_CLOTHING in the variable ‘socks’. I also use the llToLower function to make it lower case so I don’t have to worry about what case things are. I’ll do all of my compares in lower case.
For this demonstration, the assumption is that there is only one clothing item in the inventory. If there are others, the one you want might not be the first one and the code would have to loop through and look at all clothing items.
In the sample script below, the code immediately after llGetInventory goes through a sequence of if statements to check for various names and sets a flag as appropriate. In this example, I was setting a debug flag. Of course you could just as easily set a ‘left’ or ‘right’ to tell a script to open a door to the left or right. Or a ‘blue’ or ‘red’ to make a particle script spew blue or red particles. You get the idea.
A few other comments about the sample code.
I use the on_rez event in most of my scripts to cause an automatic reset when the object is rezzed.
Also, in this sample, I used the changed event to detect when the object inventory changes. The result is that if you rename the socks inventory item, or change any inventory item, the script automatically resets.
Then lastly, the touch_start event is just included so you can touch the object and have it report the current setting of the flag.
And now for the sample code. It doesn’t do anything useful. Just demonstrates the approach. And, it works in both SL and OpenSim.
// Config Demo - Socks
//
// Script to demonstrate the use of socks to set config parameters.
//
// The clothing object name in inventory is checked to see if it is
// a particular keyword of 'debug on' or 'debug off'. Set the gDebug
// flag accordingly.
//
// Additional inventory objects could be used to set other flags.
//
// Micheil Merlin/SL - 12/1/2009
integer gDebug = 0; // Debug flag.
default
{
state_entry()
{
string socks; // Name of inventory clothing object.
// Get the name of the first inventory item of type clothing. Any
// clothing type will work. The llGetInventoryName function does
// not look for socks specfically. The llGetInventoryName function
// is called with a '0' to get the first item of type clothing. It
// could be called successively to obtain additional clothing
// items. If it returns an empty string, there is no more
// inventory of that type.
socks = llToLower(llGetInventoryName(INVENTORY_CLOTHING, 0));
// Look for clothing name of 'debug on' in lower case.
if (socks == "debug on")
{
gDebug = 1;
// Look for clothing name of 'debug off' in lower case.
} else if (socks == "debug off")
{
gDebug = 0;
// Check for the existence of the inventory item.
} else if (socks == "")
{
llSay(0, "No inventory of type clothing exists.");
// If the clothing name is neither, then just say it.
} else
{
llSay(0, "Clothing name of '" + socks +
"' found. We weren't expecting this.");
}
llSay(0, "Debug is set to " + (string)gDebug);
//
// The socks processing is complete. Other code could be inserted
// here.
//
}
// This event is triggered when the object is rezzed.
on_rez(integer num)
{
llResetScript(); // Reset script when object rezzed.
}
// This event is triggered when the object has changed.
changed(integer change)
{
// If inventory has changed, assume script reset is needed.
// Adding socks to the inventory or renaming them will cause this
// event to trigger.
if (change == CHANGED_INVENTORY)
{
llResetScript();
}
}
// This event is triggered when the object is touched.
touch_start(integer total_number)
{
llSay(0, "Debug is set to " + (string)gDebug);
}
}









[...] This post was Twitted by iliveisl [...]
Twitted by iliveisl
2 Jan 10 at 3:18 pm
I’m leery of this, as it does not present a 100% secure method of verifying the parameters were supplied by a product’s creator or a malicious user.
Zauber Exonar
2 Jan 10 at 3:46 pm
posted before I finished, lol. By malicious user, I mean a customer who purchased a “standard” version of a product using this method, and then figuring out what to do to change it to a deluxe version.
Zauber Exonar
2 Jan 10 at 3:47 pm
Well, if you are thinking about a commercial product, the creator is in complete control over what they allow to be configured this way. I normally don’t think in terms of commercial products but more along the lines of someone creating things for their own purposes as that’s what I do most.
Micheil Merlin
2 Jan 10 at 4:16 pm
But, for a commercial product where there was a full featured and demo version, I probably would just use two versions of the script. I would likely still use one script with a hardcoded switch inside to make them act differently. That means compiling them twice but still only having to maintain one source.
Micheil Merlin
2 Jan 10 at 4:23 pm
omg, you are talking about real socks! i thought it was just some OOP lingo! lol, this has my attention (that means i will actually read it rather than my spaz speed reading)
thanks on this post (and fitting, i need to put on thicker socks, it’s pretty cold up here in the northland!)
iliveisl
2 Jan 10 at 4:53 pm
Nice socks, Ener. I kinda do something similar, sometimes, in my scripts. I might add an ‘extra’ object (or script) in my main prim’s contents. I have my main script always look for that item (which is set to No Copy) when it resets/runs… if not found, the entire thingie is disabled or “dies.” It’s another way to (try) to protect your content/scripts from copybot and the likes. If you want to be able to update things you previously sold to customers (like Hippo and some other nice creators do), it gets a bit more complicated, of course.
DreamWalker
2 Jan 10 at 9:58 pm
[...] original here: Scripting Tips: Does your script need socks? « By admin | category: scripting | tags: earlier, iliveisl, iliveisl-estate, post-on-mono, [...]
Scripting Tips: Does your script need socks? « Scripts Rss
3 Jan 10 at 11:19 am
[...] original here: Scripting Tips: Does your script need socks? « By admin | category: scripting | tags: earlier, iliveisl, iliveisl-estate, post-on-mono, [...]
Scripting Tips: Does your script need socks? « Scripts Rss
3 Jan 10 at 11:19 am