From 7373a28c99c8d2e03b592c580c4a0135dec3e90f Mon Sep 17 00:00:00 2001 From: scamiv <6170744+scamiv@users.noreply.github.com> Date: Mon, 17 Nov 2025 04:10:20 +0100 Subject: [PATCH] Feature/frame profiler (#2467) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description: Adds a reusable FrameProfiler utility, and a way to export profiling data for offline analysis. ### What this PR changes in the existing performance monitor This PR enhances the performance monitor by: - **Introducing a reusable `FrameProfiler` utility** - New `FrameProfiler` singleton in `src/client/graphics/FrameProfiler.ts`. - Profiling is only active when the performance overlay is visible (toggled via user settings), to avoid unnecessary overhead. - **Per-layer and span-level timing integration** - `GameRenderer.renderGame` now: - Clears the profiler at the start of each frame. - Wraps each `layer.renderLayer?.(this.context)` call with `FrameProfiler.start()/end()`, keyed by the layer’s constructor name. - Consumes the recorded timings at the end of the frame and passes them into `PerformanceOverlay.updateFrameMetrics(frameDuration, layerDurations)`. - `TerritoryLayer` instruments key operations: - `renderTerritory` - `putImageData` - Drawing the main canvas - Drawing the highlight canvas during spawn - These show up in the performance overlay as additional entries (e.g. `TerritoryLayer:renderTerritory`). - **JSON export of performance snapshots** - `PerformanceOverlay` can now build a full performance snapshot (`buildPerformanceSnapshot`) containing: - FPS and frame time stats (current, 60s average, 60s history). - Tick metrics (avg/max execution and delay, plus raw samples). - Layer breakdown (EMA-smoothed avg, max, total time per layer/span). - A new “Copy JSON” button: - Uses `navigator.clipboard.writeText` when available and falls back to a hidden `