PURPOSE

Resolves runtime performance toggles and the device-adaptive pixel budget at module load. Reads URL query parameters and localStorage, combines them with mobile detection, and exports a frozen-in-practice PERF_FLAGS object plus a PERF_VERSION_TAG string that fingerprints the active toggles alongside BUILD_VERSION.

OWNS

  • PERF_FLAGS — single object holding every runtime perf toggle, the resolved dprOverride, the lowPerf mode resolution, and the devScenario selector.
  • PERF_VERSION_TAGBUILD_VERSION suffixed with the hyphen-joined names of every flag whose value is the boolean true.
  • The pixel-budget heuristic: MAX_PIXELS = 1_500_000 total canvas pixels per frame, floored at DPR 1.0, ceilinged at DPR 2.0.
  • The three-source lowPerf resolution order: ?lowPerf query param, then localStorage.lowPerf === '1', then mobile fallback.

READS FROM

  • ./_version for BUILD_VERSION.
  • ./_gameplay for _IS_MOBILE.
  • window.location.search via URLSearchParams (guarded by typeof window !== 'undefined').
  • window.localStorage for sticky lowPerf preference (try/catch guarded for privacy-mode throws).
  • window.devicePixelRatio, window.innerWidth, window.innerHeight for the pixel-budget computation.

PUSHES TO

Nothing. Module-level export only — consumers import PERF_FLAGS and PERF_VERSION_TAG directly. No side effects beyond reading the URL/localStorage/window at module load.

DOES NOT

  • Does not mutate PERF_FLAGS after module load — values are resolved once.
  • Does not write to localStorage; only reads the sticky lowPerf preference.
  • Does not apply the DPR cap to a canvas — only computes the override value; canvas wiring lives elsewhere.
  • Does not throw on missing window — every browser API access is guarded for SSR / non-browser contexts.
  • Does not validate query-param values beyond a parseFloat for dpr and a !== '0' check for lowPerf.

Signals

  • noStickers, noTerrain, noNebula, noWorldObj, noBullets, noPostFx, noParticles, noEffects, noBackground — disable individual render layers when the matching query param is present.
  • autoplay — present-only flag for kiosk / soak modes.
  • webglBatch — inverted: defaults true, set false only when ?noWebgl is present.
  • perftest — present-only flag for the perf-test harness.
  • lowPerf — boolean resolved from query → localStorage → mobile fallback. Boss data files read this via isLowPerfMode() to skip ambient VFX layers (dustMotes, floorGlowStripes, per-swarm corePulse, refractionSweep).
  • devScenario — string from ?dev=, empty string when absent.
  • dprOverridenumber | null. null means use the native DPR; a number means cap to that value. Returns Math.max(1, sqrt(MAX_PIXELS / (w*h))) when desired pixels exceed the budget, 2 when native DPR > 2, otherwise null.
  • isMobile — mirror of _IS_MOBILE for callers that already have PERF_FLAGS in scope.

Entry points

  • import { PERF_FLAGS } from '.../config/_perf-flags' — runtime toggles, mobile flag, DPR override, lowPerf resolution, dev scenario string.
  • import { PERF_VERSION_TAG } from '.../config/_perf-flags' — version string with active-flag suffix, used for telemetry / cache busting.

Pattern notes

  • Module-load resolution: every value is computed inside an IIFE or expression at import time. No lazy getters, no recomputation, no reactive updates if the URL changes after load.
  • Pixel-budget over DPR-ratio: history note in source records v5.122.0 capped phones at DPR 1.0 (caused grainy sprites on 3× retina via browser upsampling); v5.123.3 switched to capping total pixels rendered so each device gets the highest crisp DPR under a fixed budget.
  • DPR floor at 1.0 prevents desktop monitors at native DPR=1 from rendering a sub-CSS-pixel buffer that the browser then upscales — that CSS upscale was the source of soft desktop sprites.
  • DPR ceiling at 2.0 is a perception-based cap: beyond 2× the eye can’t resolve more detail at phone viewing distance.
  • PERF_VERSION_TAG filters by strict === true, so non-boolean values (dprOverride number, devScenario string, lowPerf when sourced from localStorage) only contribute to the tag when they happen to be the boolean true. The webglBatch default of true means it appears in the tag unless ?noWebgl is set.
  • try/catch around localStorage reads exists because privacy modes throw on access — failure path silently falls through to the mobile heuristic.