The following formulas should be used instead of the current assumption of reasonable tick separation values.
ceil(duration/tick_separation) //the number of ticks
duration / ticks //the actual separation between ticks
start_time + n/ticks * duration //the actual time that tick n should fire.
next_tick - world.time //the actual sleeping time for the current tick.
Provided next_tick-world.time is less than 1 world tick, multiple ticks will actually fire in a single frame, because sleep() rounds down to the nearest multiple of world.tick_lag.
Ticker effects should also save their calculated next_tick value, thus making their ticks more reliable when they are restored from a savefile, or backdated.
This also means that ticker effects should not rely on the end_time, but rather the tick counter for terminating the timer loop, unlike timer effects.