

Because it is sync'ed to the wall clock, several objects will act in unison, give or take a couple hundreths of a second.
CODE
// Regular clock ticker.
// Set interval to some number of seconds
//
// Put a call to perfomr some actions in action().
//
// Object will perform action() every interval seconds. If there are more than
// one, they will work in synch.
//
// Lee Ponzu, no rights reserved
float interval = 3.0; //seconds between actions
float inv;
float acc = .01;
action()
{
// put the action that should be performed here
llSetRot( llGetRot()*llEuler2Rot(<0,0,PI_BY_TWO>) );
}
// Gets the number of milliseconds since midnight UTC.
// GetGMTmsclock() is by ...damn, can't find it. Thanks though.
integer GetGMTmsclock()
{
string stamp = llGetTimestamp();
return
(integer) llGetSubString(stamp, 11, 12) * 3600000 +
(integer) llGetSubString(stamp, 14, 15) * 60000 +
llRound((float) llGetSubString(stamp, 17, -2) * 1000.0);
}
float GetTime()
{
return GetGMTmsclock()*.001;
}
default
{
state_entry()
{
llOwnerSay( "entering default state");
llSetTimerEvent(interval);
inv=1.0/interval;
}
on_rez(integer n)
{
llOwnerSay("rezzing");
//tick = llGetTime();
}
touch_start(integer total_number)
{
llSay(0, "Touched.");
llSleep(10);
}
timer()
{
float now = GetTime();
float count = now*inv;
// invariant is for count to be close to an integer, and
// delta to be zero
float delta = interval*(count - llRound(count));
if(llFabs(delta) > acc)
llSetTimerEvent( interval-delta );
// this is where the action would go...
action();
}
}