At OSCC I had a booth and (among other things) I had a “poster paper” about making blinking lights for the holidays without bogging down your SIM. Next to that was an example string of 100 lights that blink in patterns controlled by a single low-lag script. And a blinking holiday tree with a similar script for changing texture maps. I'm publishing the scripts here now as a holiday gift to the Open Simulator community in the hopes that it brightens your holiday SIMs!
That booth at OSCC will stay up for a while, so I will leave the lights on for you. And trees there for anyone to grab a full-perm copy for free. Hypergrid to http://cc.opensimulator.org:8002 and find your way to Expo Zone 4. I also have them available for the taking on the Kitely Grid, HG to [url]hop://grid.kitely.com:8002/Panthalassa/129/129/24[/url] . If you can grab copies of these, they have the full perm scripts in them and are made of sculpts designed to work well with the scripts. For the holiday tree, I started with a texture map I bought from Ro!Act Designs on the Kitely Marketplace (http://www.kitely.com/market?store=3080617). I stretched this to fit on the right surfaces of my sculpt and painted lights in different positions on 4 different versions of that texture map. Arianna Monaron gave me permission to give away these copies of this texture. For the lights on the tree I used a glitter brush from Obsidian Dawn (http://www.obbsidiondown.com).
December of 2013 I installed some of my toboggans on a friend's holiday SIM, only to discover that they only worked in spits and starts. I tracked down the problem to a free open source flashing light script. There were strings of holiday lights all over this SIM, with a copy of this script in every bulb. Thousands of copies of this script all running at once. The script had a timer event, but inside this event it was turning the light on, then llSleep'ing for a second, then turning the light off.
There is this dirty little secret of the Open Simulator LSL engine: When you call llSleep(), it stops the “thread” that is running your script for the delay time you asked for. A thread is like a separate processor that can run one script. By default, a SIM has 100 of these threads, so 100 scripts can be running at once. This may not sound like a lot, but most well-written scripts are “event driven”. This means that they spend most of their time doing nothing but waiting for a click, waiting for a timer, waiting for a message, waiting for a collision, etc. But the important thing is that while a script is waiting for an event, it frees up the thread. The threads are only used by scripts that are actually doing something. So thousands and thousands of scripts can all be “running” and ready to work, as long as only 100 or fewer are processing events at any one time.
But llSleep() is not the same thing as waiting for an event. It pauses the thread and HOLDS ONTO IT, preventing ANY OTHER SCRIPTS from using that thread until the delay time is over. So in the case of my friend's holiday SIM, after the first 100 blinking lights called llSleep, all 100 of the threads were paused and unable to work. No other scripts in the SIM were allowed to run, except once in a while when a thread was released for an instant. Nobody noticed that the lights were all blinking slower than they were supposed to. Only when I sat on a toboggan did I discover that something was very, very wrong.
Here is the holiday light script I wrote to solve that and several other problems:
Code: Select all
//holiday lights
//Written by Kayaker Magic and given away as open source with no restrictions.
//I've seen some blinking light scripts that were very hard on the simulator
//this is an attempt at a low-lag blinking light script.
//It is completely event driven, running on a timer
//One script can blink up to 256 lights
//It uses llSetLinkPrimitiveParamsFast to avoid the script thread locking bug
//It blinks the lights in an order that looks like they are shifting sequentially
//You specify the light on/off pattern by putting a string of 1's and 0's
//in the root prim description
//To use this:
//Put this script in one light ONLY IN ONE LIGHT!
//link it to as many lights as you want (well up to 256 lights total)
//Name each of the light prims in an order that sorts in the order you want them to blink
//In the root prim (or the one with the script) change the prim description to
//a string of 1's and 0's to indicate the pattern of lights that are on.
//The default (if no description) is "001" meaning two lights off and one on
//repeats down your string of lights.
//I have single-prim holiday light sculpt that looks like a bulb with a base. That
// works well with this script. I made a black-and-white texture for that bulb so the
// base of the light is black, and the bulb white. You can change the color of the
// bulb and this script changes the brightness and glow. The black base is not
// effected by this and remains dark.
list lites;
string pattern; //will contain the pattern of on/off lites
integer off; //offset to the next character in the pattern
SortLites() //sort the lights into the order they will blink
{
lites=[]; //clear the list
integer i;
for (i=1;i<=llGetNumberOfPrims();i++)
lites += [llGetLinkName(i),i]; //get every prim name and number
lites = llListSort(lites,2,TRUE); //sort them into name order
//also get the light order string from the description
pattern=llGetDescription();
if (llStringLength(pattern)==0)
pattern="001"; //default to two off, one on.
}
default
{
state_entry()
{
SortLites();
llSetTimerEvent(0.5); //start the timer
}
on_rez(integer param)
{
SortLites();
}
changed(integer flags)
{
if (flags&CHANGED_LINK)
{ //if a prim is added or removed,
SortLites(); //better make a new sorted list
}
}
timer()
{
integer i;
for (i=1;i<=llGetNumberOfPrims();i++)
{ //turn this light on if there is a "1" in the description
integer loff=(off+i)%llStringLength(pattern); //advance through the pattern
integer brite = (llGetSubString(pattern,loff,loff)=="1");
llSetLinkPrimitiveParamsFast(llList2Integer(lites,i*2-1),[
PRIM_FULLBRIGHT,ALL_SIDES,brite,
PRIM_GLOW,ALL_SIDES,(float)brite*0.5
]);
}
off = off+1)%llStringLength(pattern); //advance the offset by one light
}
}
Code: Select all
//holiday tree
//Written by Kayaker Magic and given away as open source with no restrictions.
//I've seen some blinking texture scripts that were very hard on the viewers
//this is an attempt at a low-lag blinking texture script.
//It is completely event driven, running on a timer
//This one script can blink up to 256 trees
//It uses llSetLinkPrimitiveParamsFast to avoid the script thread locking bug
//It blinks the textures randomly on each tree
//To use this:
//Put this script in one tree. ONLY IN ONE TREE!
//Put a sequence of textures in the tree with the script. ONLY IN THE ONE TREE!
//link it to as many trees as you want (well up to 256 trees total)
//I have single-prim holiday tree sculpt made from 4 intersecting planes. That
// works well with this script. I added a set of textures for this with lights
// painted in different locations. When the script changes textures, the lights
// appear to blink on and off.
default
{
state_entry()
{
llSetTimerEvent(0.5);
}
timer()
{
integer tree;
for (tree=1;tree<=llGetNumberOfPrims();tree++)
{
llSetLinkPrimitiveParamsFast(tree,[
PRIM_TEXTURE,
ALL_SIDES,
llGetInventoryName(INVENTORY_TEXTURE,
(integer)llFrand(llGetInventoryNumber(INVENTORY_TEXTURE))),
<8,1,0>,
<0.5,0,0>,
0.0
]);
}
}
}