Refactor simulation timing and frame processing logic for improved accuracy and performance

This commit is contained in:
Kirill
2026-10-08 00:15:23 +03:00
parent 3fcc7211ce
commit 413f2be904
4 changed files with 29 additions and 22 deletions
+10 -4
View File
@@ -66,6 +66,7 @@ var _requested_speed: int = 0
var _queued_productions: Array = []
var frame_active_clock: Dictionary = {}
var _resume_clock: Dictionary = {}
var frame_elapsed_seconds: float = 0.0
const frame_step_seconds: float = 0.2
## Keep the requested clock advancing while a transaction spans render frames.
@@ -73,12 +74,14 @@ func evolute_frame(delta: float, tree: SceneTree) -> void:
if not is_finite(delta) or delta < 0.0 or not is_finite(delta * pow(10.0, speed - 1)): return
if frame_clock.is_empty(): frame_clock = state.time.duplicate()
frame_clock = SimulationTime.advance(frame_clock, delta, speed)
frame_elapsed_seconds += delta
if frame_busy: return
var next_clock: Dictionary = _resume_clock
if next_clock.is_empty():
next_clock = SimulationTime.advance(state.time, frame_step_seconds, speed)
# Start only after a full 0.2 seconds of simulation time is requested.
if E.gt(next_clock.datetime, frame_clock.datetime): return
# Cadence limits starts; each transaction consumes the whole pending interval.
if frame_elapsed_seconds + 1e-12 < frame_step_seconds: return
next_clock = frame_clock.duplicate()
frame_elapsed_seconds = 0.0
frame_busy = true
frame_budget = preload("res://world/owniverse/frame_budget.gd").new(tree)
frame_active_clock = next_clock
@@ -95,11 +98,14 @@ func request_production(id: String, amount: Variant, resource: bool = false) ->
## Persist work requests, never the partially calculated transaction.
func frame_checkpoint() -> Dictionary:
return {"requested_clock": frame_clock, "active_clock": frame_active_clock if frame_busy else {}, "speed": speed, "productions": _queued_productions}
return {"requested_clock": frame_clock, "active_clock": frame_active_clock if frame_busy else {}, "speed": speed, "productions": _queued_productions, "elapsed_seconds": frame_elapsed_seconds}
func restore_frame_checkpoint(checkpoint: Dictionary) -> void:
frame_clock = checkpoint.get("requested_clock", {})
_resume_clock = checkpoint.get("active_clock", {})
var reserved_clock: Dictionary = _resume_clock if not _resume_clock.is_empty() else state.time
var pending_years: Variant = E.maximum(0, E.subtract(frame_clock.get("datetime", reserved_clock.datetime), reserved_clock.datetime))
frame_elapsed_seconds = float(checkpoint.get("elapsed_seconds", E.approx(pending_years) / pow(10.0, int(checkpoint.get("speed", state.speed)) - 1)))
_queued_productions = checkpoint.get("productions", [])
if _resume_clock.is_empty():
speed = checkpoint.get("speed", state.speed)