mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
92 lines
3.2 KiB
Lua
92 lines
3.2 KiB
Lua
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
love = love or require("tests.love_stub")
|
|
|
|
local FixedStep = require("src.core.FixedStep")
|
|
local GameSpeed = require("src.core.GameSpeed")
|
|
local STEP = FixedStep.STEP
|
|
|
|
local function run(speed, fps, frames, clock, period)
|
|
local now = 0
|
|
local steps, maxPerFrame, maxAccum = 0, 0, 0
|
|
FixedStep.refreshPeriod = period
|
|
FixedStep:init(function()
|
|
steps = steps + 1
|
|
if clock == "ms" then now = now + 0.001 end
|
|
end)
|
|
FixedStep.clock = function() return now end
|
|
local dt = 1 / fps
|
|
for _ = 1, frames do
|
|
local before = steps
|
|
FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt)
|
|
FixedStep:update(dt, speed)
|
|
if clock == "ms" then now = now + 0.004 end
|
|
if steps - before > maxPerFrame then maxPerFrame = steps - before end
|
|
if FixedStep.accum > maxAccum then maxAccum = FixedStep.accum end
|
|
end
|
|
FixedStep.clock = nil
|
|
FixedStep.refreshPeriod = nil
|
|
return steps, maxPerFrame, maxAccum
|
|
end
|
|
|
|
for _, speed in ipairs(GameSpeed.LEVELS) do
|
|
local steps = run(speed, 60, 60, "frozen")
|
|
check(math.abs(steps - 60 * speed) <= 1,
|
|
("%dX at 60fps: %d logic steps a second (want %d)"):format(speed, steps, 60 * speed))
|
|
local slow = run(speed, 30, 30, "frozen")
|
|
check(math.abs(slow - 60 * speed) <= 1,
|
|
("%dX at 30fps: %d logic steps a second (want %d)"):format(speed, slow, 60 * speed))
|
|
local mid = run(speed, 45, 45, "frozen")
|
|
check(math.abs(mid - 60 * speed) <= 1,
|
|
("%dX at 45fps: %d logic steps a second (want %d)"):format(speed, mid, 60 * speed))
|
|
end
|
|
|
|
local fast = run(200, 60, 60, "frozen")
|
|
local ten = run(10, 60, 60, "frozen")
|
|
check(fast >= ten * 15,
|
|
("200X runs far more logic than 10X on a fast frame (%d vs %d)"):format(fast, ten))
|
|
|
|
local steps, perFrame, carried = run(200, 60, 60, "ms", 1 / 60)
|
|
check(perFrame >= 11 and perFrame <= 14,
|
|
("200X on a slow device stops at the frame budget (%d steps a frame)"):format(perFrame))
|
|
check(carried < STEP,
|
|
("the unpaid debt is dropped, not carried (max accum %.4f)"):format(carried))
|
|
check(steps >= 60 * 11,
|
|
("and still runs as fast as the device allows (%d steps)"):format(steps))
|
|
|
|
local oneX = run(1, 60, 60, "ms", 1 / 60)
|
|
eq(oneX, 60, "1X ignores the work budget")
|
|
|
|
local function hitchBurst(speed, hitch)
|
|
local n = 0
|
|
FixedStep.refreshPeriod = nil
|
|
FixedStep.clock = function() return 0 end
|
|
FixedStep:init(function() n = n + 1 end)
|
|
for _ = 1, 30 do
|
|
FixedStep.maxAccum = FixedStep.catchupLimit(speed, 1 / 60)
|
|
FixedStep:update(1 / 60, speed)
|
|
end
|
|
n = 0
|
|
FixedStep.maxAccum = FixedStep.catchupLimit(speed, hitch)
|
|
FixedStep:update(hitch, speed)
|
|
FixedStep.clock = nil
|
|
return n
|
|
end
|
|
|
|
for _, speed in ipairs({ 1, 2, 4, 10 }) do
|
|
local cap = math.max(2, math.floor(speed * 1.5 + 1e-9))
|
|
for _, hitch in ipairs({ 0.05, 0.1, 0.25, 1.0 }) do
|
|
local n = hitchBurst(speed, hitch)
|
|
check(n <= cap,
|
|
("%dX: a %.0fms hitch is not repaid as a burst (%d steps, max %d)"):format(speed, hitch * 1000, n, cap))
|
|
end
|
|
end
|
|
eq(hitchBurst(1, 0.25), 2, "1X after a 250ms hitch runs 2 steps, like before the budget")
|
|
|
|
FixedStep:init(function() end)
|
|
FixedStep.maxAccum = FixedStep.MAX_ACCUM
|
|
|
|
T.finish("fast forward rate bug 2471")
|