Разделить частоту обновления часов и расчёта симуляции

Счётчик времени UI обновляется до 10 Гц по запрошенному времени, а тяжёлые циклы по-прежнему запускаются с адаптивным интервалом и обрабатывают весь накопленный промежуток. Обновить тесты и описание модели.
This commit is contained in:
Kirill
2026-10-17 23:41:18 +03:00
parent 00b6192d19
commit 273093bd9e
14 changed files with 853 additions and 10 deletions
+3 -1
View File
@@ -69,7 +69,9 @@ func coarsen_cycle_stars(target: Dictionary, id: String) -> void:
func temporal_resolution(target: Dictionary) -> Variant:
var speed: int = int(target.get("speed", 1))
if speed < 4: return 0
var width: Variant = E.divide(E.power(10, speed - 1), 10)
# Keep the existing 0.1-second resolution at the default 5 Hz cadence,
# and scale temporal grouping with the adaptive cycle interval.
var width: Variant = E.multiply(E.power(10, speed - 1), world.frame_step_seconds / 2.0)
return E.multiply(width, E.power(2, world.adaptive_quality))
func window_duration(target: Dictionary, lifespan: Variant) -> Variant:
+24 -1
View File
@@ -23,6 +23,12 @@ var adaptive_quality: int = 0
var adaptive_cycle_ema_ms: float = 0.0
var adaptive_recovery_cycles: int = 0
var adaptive_generation_phase: int = 0
## Runtime-only cadence: 5, 4, 3, or 2 full simulation cycles per second.
var adaptive_cadence: bool = true
var cadence_level: int = 0
var cadence_recovery_cycles: int = 0
const CADENCE_STEPS: Array[float] = [0.2, 0.25, 1.0 / 3.0, 0.5]
var frame_step_seconds: float = 0.2
func update_adaptive_quality(cycle_usec: int) -> void:
var cycle_ms: float = float(cycle_usec) / 1000.0
@@ -46,6 +52,20 @@ func update_adaptive_quality(cycle_usec: int) -> void:
adaptive_recovery_cycles = 0
else:
adaptive_recovery_cycles = 0
if adaptive_cadence:
var step: float = CADENCE_STEPS[cadence_level]
if adaptive_cycle_ema_ms > step * 900.0 and cadence_level < CADENCE_STEPS.size() - 1:
cadence_level += 1
frame_step_seconds = CADENCE_STEPS[cadence_level]
cadence_recovery_cycles = 0
elif adaptive_cycle_ema_ms < step * 650.0 and cadence_level > 0:
cadence_recovery_cycles += 1
if cadence_recovery_cycles >= 30:
cadence_level -= 1
frame_step_seconds = CADENCE_STEPS[cadence_level]
cadence_recovery_cycles = 0
else:
cadence_recovery_cycles = 0
if adaptive_quality >= 3:
adaptive_generation_phase = 1 - adaptive_generation_phase
@@ -103,9 +123,12 @@ var _production_queue_cancelled: bool = false
var frame_active_clock: Dictionary = {}
var _resume_clock: Dictionary = {}
var frame_elapsed_seconds: float = 0.0
const frame_step_seconds: float = 0.2
const production_slice_usec: int = 4000
## The HUD follows requested time; world state remains at the last committed cycle.
func display_clock() -> Dictionary:
return frame_clock if not frame_clock.is_empty() else state.time
## Keep the requested clock advancing while a transaction spans render frames.
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