acron.fixed_loop¶
Fixed-rate game loop – Godot’s _physics_process cadence on Acron.
Godot runs _physics_process at a constant tick rate (default 60 Hz). Ported
movement code frequently assumes delta == 1/60 (velocity-from-position
tricks, per-frame deltas multiplied by 60), so the loop MUST step at a fixed
rate rather than Bullet’s variable substeps. A wall-clock accumulator with a
spiral-of-death cap drives it.
Ordering per fixed step (avoids one-frame visual “ghosting” – Bullet syncs each
body’s NodePath transform only AFTER do_physics):
call each node’s
_physics_process(dt)(applies forces / velocity)
world.do_physics(dt, 0, dt)(Bullet integrates + syncs)call each node’s
update_visuals()(place visuals vs FINAL xform)
input_map.end_step()(just-pressed flags live one step)
Do not throw away the accumulator remainder: GameLoop.alpha is the
render-interpolation factor. Physics advances at the fixed rate but rendering
runs at the display refresh; a camera/model that snaps to the raw body position
each render frame advances in irregular full-step jumps (“camera jitters as the
player runs”, worse with speed). Consumers record pre-/post-step positions and
render at interpolated(prev, curr, loop.alpha).
Per-frame (variable-dt) work is Godot’s _process, and goes through
GameLoop.process(), which the app calls once per render frame alongside
GameLoop.update_visuals(). Camera smoothing and HUD may equally be
driven straight from the app’s own render task.
Headless testing: offscreen, task_mgr.step() barely advances the global
clock, so an accumulator loop runs ~0 steps and “nothing moves”. Call
GameLoop.step() directly instead – fully deterministic, no clock.
|
Drives fixed-step physics over registered nodes, exposing |
Global Functions