Continuing on a theme beginning with “Mono Bytecode Sharing“, followed by “Does your script need socks“, this is another post describing another method to pass configuration options to scripts. I really struggled with the title of this one and just couldn’t come up with anything near as cute as “Does your script need socks“. Oh well…
To summarize the theme again, 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 a script easier to maintain.
In the last post I described a way to configure scripts by placing clothing items with special names inside the object. Another way to set configuration parameters is to read them from the object description.
The object description is a string of up to 127 characters that can be both read and written from the script. Prior to January, 2008, the string used to be at least twice as long. But in order to address a couple of other bugs, LL changed the maximum length to 127. This in turn caused much disturbance within the community. Go take a look at SVC-1394 and related issues for more information.
The llGetObjectDesc function is what is used to read the description of the object the script is in. Actually, if the script is in a prim linked to other prims, it will only read the description from the prim containing the script.
objdesc = llToLower(llStringTrim(llGetObjectDesc(), STRING_TRIM));
In the example above, I’m saving the object description string in a variable called ‘objdesc’. I also use the llToLower function to make the string lower case so I don’t have to worry about what case things are in. All compares I do will be in lower case. And, I use the llStringTrim function to remove any leading and trailing blanks. It’s easy to put a blank somewhere you didn’t intend, so removing any leading and trailing blanks helps somewhat.
Following the llGetObjectDesc code, the script goes through a series of if and else if statements comparing the string to my special selected settings. In this case, ‘debug on’ and ‘debug off’. Finding either of those, the script turns a debug flag on or off. You can get as complex as you want here as long as you don’t go past the 127 character limit. The object description could hold several keywords to be used to set several options within your script.
Some peculiarities about the object description.
- If the description is null and if the object has been saved and taken from inventory, the function will return ‘(no description)’ instead of null or a blank string. So, your script needs to allow for this if it is important to know if the description is null.
- If the description is null and if the object has not been saved and taken from inventory, the function will return a null string.
- If you’ve ever typed anything in the description and then tried to remove it, the description may now have spaces. You may need to be aware of this. If you use the llStringTrim function as I have, the string appear as null and you don’t have to worry about how many spaces might be there.
- If you try to remove the description by deleting characters in the edit gui, it will look like it is gone but is not actually saved as a null when you get out of edit. The string will still be there when you look again. There are a few JIRAs open on this. You can set the description back to null by using the llSetObjectDesc(“”) function.
A few other notes about the sample script.
In the “Does your script need socks” sample, I used the changed event to detect the change of inventory and trigger the reprocessing of the options automatically. There is no way to automatically detect the change of the description so you’ll have to have a way to tell the script to reread the description if you change it or just manually reset the script to make it read the description again.
In this sample, I put all of the option processing in the readdesc() subroutine and then used the touch_start event to trigger the readdesc() subroutine. Again, this is some sample code to demonstrate the approach and you may not want this to happen when the object is touched. I also have the readdesc() in the state_entry and that may be the only place you want it in your script.
In some ways, this approach to configuration may be simpler than the socks approach. I’ve seen many examples of this object description approach in use within SL. However, it is easy to type the wrong thing or otherwise mess up the object description so you’ll have to decide how much error checking for typos you need to have in your script.
And now for the sample code. This sample has been tested in both SL and OpenSim.
// Config Demo - Read Object Desc
//
// Script to demonstrate the use of the object description to supply
// parameters.
//
// The object description is checked to see if it says either 'debug on'
// or 'debug off'. Set the gDebug flag accordingly.
//
// Micheil Merlin/SL - 1/1/2010
integer gDebug = 0; // Debug flag.
readdesc()
{
string objdesc; // Object description.
// Read the description field for the object.
// Translate to lower case and trim blanks from the end.
objdesc = llToLower(llStringTrim(llGetObjectDesc(), STRING_TRIM));
// Look for an object description of 'debug on' in lower case.
if (objdesc == "debug on")
{
gDebug = 1;
// Look for an object description of 'debug off' in lower case.
} else if (objdesc == "debug off")
{
gDebug = 0;
// Check for an empty object description.
// Empty object descriptions could either be blanks or the string
// '(no description)'. Earlier, we trimmed blanks from the string
// so if it was blanks, it is now a null string.
} else if (objdesc == "" || objdesc == "(no description)")
{
llSay(0, "No object description exists.");
// If the object description is not one of our choices or empty, then
// say the string.
} else
{
llSay(0, "Object Description of '" + objdesc +
"' found. We weren't expecting this.");
}
llSay(0, "Debug is set to " + (string)gDebug);
//
// The object description processing is complete. Other code could be
// inserted here.
//
}
default
{
state_entry()
{
readdesc(); // Process object description.
}
// 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 is touched.
touch_start(integer total_number)
{
readdesc(); // Go check the object description.
}
}









I’ve used object descriptions as well. A bug used to exist that allowed you to store a massive amount of data in object descriptions, but the Lindens have since fixed this. You can also save configuration information within a note card. I made a video tutorial that shows how to read values from a note card.
Dedric Mauriac
29 Jan 10 at 10:36 am
Ah, I forgot the link. Here it is – http://dedricmauriac.wordpress.com/2008/05/03/configuration-reading-tutorial/
Dedric Mauriac
29 Jan 10 at 10:36 am
Yes about the notecard. I was saving it for last as it requires a little more effort than the other couple of methods but provides much more potential.
I use the notecard configuration method most often unless I just have one or two things to set. That usually doesn’t seem to be the case though…lol. But when I have just one or two things, I’ll use the ‘socks’ method.
Micheil Merlin
30 Jan 10 at 7:23 pm
You might be interested to see how I tackled this in RealXtend using familiar .ini notation in the extended object description field. See http://peterquirk.wordpress.com/2008/12/31/tutorial-realxtends-powerful-configuration-management-for-models-without-notecards/#more-289.
Peter Quirk
30 Jan 10 at 11:17 pm
Now that’s a really nice feature Peter. More elegant than plain old notecards. It would nice if SL had something like that.
Micheil Merlin
31 Jan 10 at 11:56 am