maniator / maniator/verticopolis
[Feature]: [P3] session_fps samples idle (speed 0) and modal-frozen frames, diluting the fps signal on big towers
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 5
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
Deferred from the S5 gds-code-review (session_fps, #538). Edge Case Hunter, minor.
GameplaySession.noteFrame (src/analytics.ts) samples every foreground rendered frame, including frames where the sim is not advancing: game speed 0 (paused) and while a blocking modal freezes time. runFrame calls noteFrame as its first line, before the modal-freeze early return, and speed 0 still fires rAF -> tick -> render.
Why it matters: at speed 0 (or behind a modal) the per-frame CPU sim cost is skipped, so on a large tower, where the sim tick is the dominant per-frame cost, those idle frames run at a higher fps than active play. A player who parks at speed 0 or sits on a modal banks easy high-fps samples that pull p50/low toward the vsync ceiling and dilute the busy-simulation frames the metric exists to characterize. Big-tower sessions are exactly the Pixel 8a freeze scenario #538 targets, so the dilution is worst where the signal matters most.
Not fixed in the S5 PR because the clean fix couples the sampler to frame-loop state (game speed and modal-open), and gating sampling on "actively simulating" needs anchor-reset handling on every active<->idle transition (the wall-clock sampler must not charge the idle gap as one slow frame when active play resumes). That is more machinery than a minor bias warrants inline.
Options when picked up:
- Gate
noteFrameonSPEEDS[app.speed] > 0(and optionally modal-open), resetting the frame anchor whenever sampling pauses, so the reservoir reflects active render load only. - Or keep sampling all foreground frames and document the metric as "all rendered frames, idle included" so the dilution is a known, accepted property.
Context: the S5 PR already fixed the larger correctness bug in the same area (the engine's 200ms frame-delta spike-clamp was inverting the worst-frame low signal); this deferral is the remaining measurement-validity refinement.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/analytics.ts with GameplaySession.noteFrame and runFrame, then trace app.speed, SPEEDS, modal state, and the frame-anchor handling. Decide whether idle and modal-frozen frames should be excluded or documented as included; done means the chosen behavior preserves valid active-play frame timing without charging idle gaps after sampling resumes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- analytics, performance
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100