maniator / maniator/verticopolis

[Feature]: [P3] session_fps samples idle (speed 0) and modal-frozen frames, diluting the fps signal on big towers

Open
#603 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

perf review-deferral
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 noteFrame on SPEEDS[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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.