Corona SDK Pro Tip of the Day #33
Timer precision

For timer.performWithDelay() function, the delay time is not exact, it's affected by your app's FPS.

If you pass a delay value lower than FPS tick time, the timer listener will be invoked on the next frame.

For 60 FPS, tick time is 16.6ms, for 30 FPS - 33.3ms. If you rely on times lower than these values - it won't work.

I usually use 1 when I need something to be invoked on the next frame. For example in a collision listener.

timer.performWithDelay(1, function()  

Another problem is a total time of a timer with count more than one.

-- less precise
timer.performWithDelay(1000, function(event)  
    if event.count == 60 then
        print('One minute has passed, I think?')
end, 60)

-- more precise
timer.performWithDelay(60000, function()  
    print('One minute has passed! Or a bit more.')

When count is high, a bigger error accumulates over time. The second timer will be closer to exactly one minute than the first one.

From my test first timer had 480ms error, and the second one only 16ms.

If you need both higher precision and invoking something each second or so (maybe you have a clock animation), you need to use enterFrame listener and check each time system.getTimer() value.

local startTime = system.getTimer()  
local seconds = 0

local function enterFrame()  
    local diff = system.getTimer() - startTime
    local currentSecond = math.floor(diff / 1000)
    if currentSecond > seconds then
        print('A seccond has passed!', currentSecond)
        seconds = currentSecond
    if currentSecond == 60 then
        print('A minute has passed!')
        Runtime:removeEventListener('enterFrame', enterFrame)

Runtime:addEventListener('enterFrame', enterFrame)  

Indie Game Developer