Here, my timer code. If it can help you:
//----------------------------------------------------
//BOSS TIMER
//----------------------------------------------------
task TBossTimer {
let timer = -1;
let time01_path = GetCurrentScriptDirectory() ~ "se/se_timeout.wav";
let time02_path = GetCurrentScriptDirectory() ~ "se/se_timeout2.wav";
let timer_end = false;
let f = 0;
let count = 5;
let num_id = [ObjText_Create,ObjText_Create,ObjText_Create,ObjText_Create,ObjText_Create,ObjText_Create];
let sep = "";
let sep_space = 6;
let size_min = -6;
let pulse = 0;
let r = 0;
let listNum = DigitToArray(timer, 5);
let objScene = ID_INVALID;
let taskOn = true;
ascent(iObj in 0 .. 5) {
if((4-iObj) == 2) {
sep_space = 0;
size_min = 0;
}
if((4-iObj) == 3) {
sep_space = 0;
}
let num = listNum[4-iObj];
Text(num_id[4-iObj], "",196-iObj*12+sep_space, 14-0.75*size_min, 18+size_min, 255, 255-r, 255-r, 255, 255-r, 255-r, 8+r, 8, 8, 0.70);
}
while(taskOn == true) {
objScene = GetEnemyBossSceneObjectID();
if(objScene == ID_INVALID) {
ascent(iObj in 0 .. 5) {
let num = listNum[4-iObj];
if((4-iObj) == 3) {
if((iObj) < count) {
sep = ",";
} else if((iObj) == count) {
sep = " ";
}
} else {
sep = "";
}
ObjText_SetText(num_id[4-iObj], "");
}
} else if(objScene != ID_INVALID) {
if(timer == -1) {timer = 100*ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER);}
if(timer < 100*ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER)) {timer = 100*ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER);}
f += 1/0.6;
timer -= 1/0.6;
if(timer < 0) {timer = 0;}
if(timer > 1000) {r = 0;}
if(timer <= 1000) {r = 80;}
if(timer <= 500) {r = 120;}
if(timer <= 1000 && timer > 997) {
SE(time01_path);
timer_end = false;
}
if(timer <= 900 && timer > 897) {SE(time01_path);}
if(timer <= 800 && timer > 797) {SE(time01_path);}
if(timer <= 700 && timer > 697) {SE(time01_path);}
if(timer <= 600 && timer > 597) {SE(time01_path);}
if(timer <= 500 && timer > 495) {SE(time02_path);}
if(timer <= 400 && timer > 395) {SE(time02_path);}
if(timer <= 300 && timer > 295) {SE(time02_path);}
if(timer <= 200 && timer > 195) {SE(time02_path);}
if(timer <= 100 && timer > 95) {SE(time02_path);}
if(timer <= 0 && timer_end == false) {
SE(time02_path);
timer_end = true;
}
count = truncate(log10(1+timer));
if(count < 3) {count = 3;}
let listNum = DigitToArray(timer, 5);
ascent(iObj in 0 .. 5) {
let num = listNum[4-iObj];
if((4-iObj) == 3) {
if((iObj) < count) {
sep = ",";
} else if((iObj) == count) {
sep = " ";
}
} else {
sep = "";
}
if((iObj) > count) {
ObjText_SetText(num_id[4-iObj], "");
} else {
ObjText_SetText(num_id[4-iObj], sep ~IntToString(num));
}
ObjText_SetFontColorTop(num_id[4-iObj], 255, 255-r, 255-r);
ObjText_SetFontColorBottom(num_id[4-iObj], 255, 255-r, 255-r);
ObjText_SetFontBorderColor(num_id[4-iObj],8+r, 8, 8);
}
}
yield;
}
}
(don't mind about while(taskOn == true), I don't know loop{stuff} works when I wrote this).
If I remember correctly, when there is no boss, the timer is still here but invisible with space instead of numbers. And when there is a boss, it take the value of the actual boss timer.
I don't know if it's the best way to do but it works fine.