[Minor Feature] Expose the simulation clock to Python — getSimulationTime() is C++-only, metrics runtime is wall clock #396
Labels
No labels
Alpha Release Requirement
Bugfix
Demo Target
Documentation
Major Feature
Minor Feature
priority:tier1-active
priority:tier2-foundation
priority:tier3-future
priority:tier4-deferred
Refactoring & Cleanup
system:animation
system:documentation
system:grid
system:input
system:performance
system:procgen
system:python-binding
system:rendering
system:ui-hierarchy
Tiny Feature
workflow:blocked
workflow:needs-benchmark
workflow:needs-documentation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
john/McRogueFace#396
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The engine keeps a millisecond simulation counter for headless mode at
src/GameEngine.h:229(
int simulation_time), readable in C++ viagetSimulationTime()(src/GameEngine.h:334). Neitheris reachable from Python.
The only clock Python can currently see is
runtimein the metrics dict(
src/McRFPy_API.cpp:1925), which is wall clock. For any use that needs replayable timing —headless test harnesses, deterministic benchmarks, agent/simulation environments (#55, #154, #156) —
wall clock is the wrong clock, and every timing number collected through it is unreplayable.
Two parts
1. Expose the counter. Python-reachable access to the simulation millisecond counter and to
current_frame. Additive only — do not changeruntime's existing meaning, other code depends on it.2. Per-interval timer semantics on advance.
GameEngine::testTimersfires each elapsed timeronce per step, regardless of how many intervals actually elapsed. So advancing 10 seconds in one
wide step fires a 1-second repeating timer once, not ten times.
This is the subtle half. The resulting trace is not corrupt — it is sparse, which is far harder to
notice than a crash and easy to mistake for a real result. A caller needs to be able to advance by
N ms and have every repeating timer fire once per elapsed interval.
Acceptance criterion: a 1-second repeating timer fires exactly 10 times across 10 seconds of
advance.
3. Rendering must cost zero simulated time.
renderScene()must not advancesimulation_time, soa screenshot is free with respect to the clock. Currently believed true; needs a test asserting it.
Notes
mcrfpy.lock()coverage), #55 / #154 / #156 (agent-simulation use cases that need a replayable clock).
last_ran = nowdiscards skipped intervals AND the residual #397