Summary: Inside Playdate documents the result of playdate.getElapsedTime()
as being "a floating-point number with microsecond accuracy." The Simulator works as expected with a precision to about 3 microseconds. On my physical Playdate, playdate.getElapsedTime()
only ever returns values precise to milliseconds. That seems less precise than the documention suggests.
This may be the same bug reported for the C API: [C SDK] High resolution timer has only millisecond precision - #2 by fum1h1ro
I have a simple program (below). On start it repeatedly runs a spinloop waiting for playdate.getElapsedTime()
to return a different result. It prints to screen how many loops were needed for each. Then, after 1 second, it collects playdate.getElapsedTime()
for 9 frames and displays that when done.
In the simulator (1.11.1 for Linux under Ubuntu 20.04.4), I get plausible looking results. It appears to be precise to about 3 ms. A transcription is below.
On a physical Playdate (running Playdate OS 1.11.1), it only appears to be precise to 1000 microseconds. A transcription is below.
To reproduce:
- Create project using the source code below.
- Compile to pdx
- Load onto phsyical Playdate
- Run on Playdate
Expected Behavior: No more than the last 2 digits for each time value are identical across all samples (which would indicate sub-millisecond precision)
Observed Behavior: Last 3 digits for each time value are 000
, suggesting only millisecond precision.
The code I'm using:
import "CoreLibs/object"
local gfx = playdate.graphics
log = ""
function addlog(msg)
local stamp = string.format("%.6f", playdate.getElapsedTime())
log = log .. stamp .. " " .. msg .. "\n"
end
local msg = ""
playdate.resetElapsedTime()
for i = 1,10 do
local start = playdate.getElapsedTime()
local done = false
local count = 0
while not done do
local now = playdate.getElapsedTime()
if now ~= start then
done = true
end
count = count + 1
end
addlog(tostring(count))
end
local msg = "spinloop count\n"..log
gfx.drawText(msg, 2, 2)
log = ""
local frame = 0
playdate.resetElapsedTime()
function playdate.update()
frame = frame + 1
if frame > 30 and frame < 40 then
addlog(tostring(frame))
elseif frame == 61 then
local msg = "frames\n"..log
gfx.drawText(msg, 200, 2)
end
--gfx.sprite.update()
--playdate.resetElapsedTime()
end
Results from PlaydateSimulator, manually transcribed, may have typos:
Elapsed Loops
0.000008 1
0.000018 2
0.000022 1
0.000026 2
0.000029 1
0.000033 3
0.000037 2
0.000041 2
0.000044 1
0.000048 2
Elapsed Frames
1.321656 31
1.354444 32
1.387243 33
1.453728 34
1.458024 35
1.490204 36
1.522406 37
1.555363 38
1.588089 39
Results from physical Playdate, also manually transcribed, may have typos:
Elapsed Loops
0.001000 132
0.002000 120
0.003000 93
0.004000 116
0.005000 124
0.006000 127
0.007000 125
0.008000 128
0.009000 125
0.010000 117
Elapsed Frames
0.991000 31
1.023000 32
1.056000 33
1.089000 34
1.122000 35
1.156000 36
1.188000 37
1.221000 38
1.254000 39
(All numbers are being formatted with string.format("%.6f", time)
. If you add more digits, the physical device reports numbers within 3 microseconds. I believe it's likely an artifact of what the float can store.)