Experimental/ModuleScripts/FixedStepScheduler.lua

58 lines
1.7 KiB
Lua
Raw Permalink Normal View History

--!strict
-- A simple fixed step system scheduler
-- Fixed updates can happen multiple times per frame
-- Variable updates will happen after all fixed updates complete
local FIXED_DELTA = (1 / 60)
local MAXIMUM_DELTA = (1 / 5)
export type System = {
--> variable delta_time update, used for rendering
--> blend used for interpolation of simulation state
update: ((delta_time: number, blend: number) -> ())?,
--> fixed delta_time update, used for simulation
fixed_update: ((delta_time: number, frame: number) -> ())?,
}
local function create(systems: {System}): (number) -> ()
local frame = 0
local accumulator = 0
return function(delta_time: number)
delta_time = math.min(delta_time, MAXIMUM_DELTA)
accumulator += delta_time
local steps = 0
local previous_frame = frame
if (accumulator > 0) then
--> typically done with a while accumulator >= fixed_rate but this way is 35x faster
steps = accumulator // FIXED_DELTA
frame += steps
accumulator -= (steps * FIXED_DELTA)
end
for step = 1, steps do
local step_frame = previous_frame + step
for _, system in systems do
if system.fixed_update == nil then
continue
end
system.fixed_update(FIXED_DELTA, step_frame)
end
end
local blend = accumulator / FIXED_DELTA
for _, system in systems do
if system.update == nil then
continue
end
system.update(delta_time, blend)
end
end
end
return create