City detail
Automatic, Light, Balanced or Detailed. This changes population, nearby detail and shadows—the CPU-heavy work.
PERFORMANCE & SOUND · SEPTEMBER 2026
Jalan KL now opens its playable centre first, streams packed city life and sound, keeps the game HUD out of the view, and lets each player balance speed, clarity and atmosphere.
01
The old gate waited for residents, vehicles, trees, food stalls, navigation, parking, history, golf, ambience and a whole-scene shader pass. The new critical path contains only the city metadata, centre district, roads and walkable terrain, collision data, courier and delivery state.
Background downloads are limited to two, Draco decoding to one worker, and mounting work yields between frame-budgeted slices of at most 4 ms. Shared models and low vegetation use content-hashed gzip transports; their lookup is compiled into the game, so core startup never waits for the runtime manifest. Authored GLBs remain a compatibility fallback.
Only the playable core receives bounded, cancellable shader preparation before Start. Optional roots warm incrementally after entry. Audio metadata is read lazily, and optional failure, cancellation or disposal never restarts the playable centre.
Runtime preparation compares generated bytes before writing and removes only stale files it owns. An unchanged build therefore leaves timestamps alone instead of reloading an open Vite session. Unit tests create their manifest fixture in an operating-system temporary directory and clean it afterward.
02
The normal city view no longer asks the browser for default-framebuffer MSAA. Automatic and Performance render to an unsigned-byte scene target and use the low-cost RenderPass → OutputPass → FXAAPass chain. Matrix and Doodle retain their own post-processing without stacking normal-view effects.
Automatic, Light, Balanced or Detailed. This changes population, nearby detail and shadows—the CPU-heavy work.
Automatic, Performance, Balanced or Sharp. Scene budgets are 1.2 M, 1.8 M and 2.7 M pixels; output is capped at 2.1 M except Sharp at 2.7 M.
Automatic begins at Light + Performance. CPU pressure lowers city detail; slow frames with CPU headroom lower resolution. Six seconds of sustained headroom raises resolution before population or shadows.
03
The gear opens one keyboard-accessible dialog before or after Start, with Graphics, Audio, Controls, Accessibility and System tabs. It pauses movement and simulation while open, restores the control that opened it, fits a 320 px viewport, and is also available from the compact menu. Choices apply immediately and stay only in this browser under the validated jalan-kl-settings-v1 record.
| Preset | City / image | AA / screen AO | Shadows / reflections | Frame cap |
|---|---|---|---|---|
| Automatic | Adaptive / adaptive | FXAA / off | Adaptive / adaptive | Display |
| Performance | Light / Performance | FXAA / off | Off / off | 60 |
| Balanced | Balanced / Balanced | FXAA / off | Low / off | 60 |
| Quality | Detailed / Sharp | SMAA / high GTAO | High / on | Display |
Advanced controls add a 75–100% within-tier render scale, AA Off/FXAA/SMAA, screen-space AO Off/Low/High, shadow and reflection controls, and 30/60/display frame caps. Automatic, fresh installs and Reset All use Display refresh, which follows browser requestAnimationFrame; Performance and Balanced remain capped at 60 FPS, and a saved explicit Custom cap is preserved. Adaptive graphics can still lower rendering cost without changing that browser cadence. Changing an advanced control makes the preset Custom. An explicit Quality choice is never silently rewritten: it carries a high-GPU-cost warning, while a WebGL recovery can temporarily render with Performance-safe effects and keep the saved preference intact.
Settings, Matrix colour and the history filter progressively enhance their canonical native selects into branded listboxes. Rounded surfaces, a selected check, 44 px options and constrained viewport placement support pointer, touch, typeahead, Arrow/Home/End, Enter/Space, Escape and Tab. Programmatic native changes remain synchronized, only one menu opens at once, and unsupported browsers retain the native control. Settings panels, tabs and menus also use brand-tinted, rounded scrollbars with high-contrast fallbacks.
Low AO is a half-resolution, 16-sample SSAOPass. High AO is a 0.75-resolution, 16-sample GTAOPass with denoising. Quality changes AA to SMAAPass. The combined module is requested only when one of those effects is selected; Automatic and Performance do not download it. If GTAO cannot start, the effective setting falls back to Low SSAO and then Off; SMAA falls back to FXAA. The System tab reports preferred and effective effects, pass order, effect buffers and the reason for any fallback.
There is deliberately no DLSS-labelled option. NVIDIA Streamline integrates DLSS with a native DirectX or Vulkan renderer and engine-provided resources such as motion vectors. A browser WebGL game cannot expose that integration. Jalan KL's honest browser-native alternatives are adaptive resolution, manual render scale, FXAA and SMAA.
Audio controls adjust master, ambience, effects and UI buses while the header mute button remains synchronized. Controls cover look sensitivity, vertical-look inversion, left/right joystick placement and Hold/Toggle keyboard running. Accessibility can follow the system or force Reduced/Full motion, enlarge interface text and increase UI contrast. System offers live renderer diagnostics, copy-to-clipboard and a complete local reset.
04
Sound is on by default and unlocks from the Start gesture. One lazy Web Audio graph provides master, ambience, effects and UI buses with an eight-voice cap, short gain ramps, mute persistence and hidden-tab suspension. Footsteps vary by distance travelled; deliveries, controls, traffic, the park, fountain and passing train have their own cues. A failed request or decode never delays entry.
Each logical sound is fetched once through a content-hashed base64 JSON text envelope, then restored to its exact OGG bytes in memory. Chrome's native decoder gets two serialized attempts using those same bytes. Only if both fail does the game load one reusable Web Worker/WASM Vorbis decoder, copy the resulting PCM into an AudioBuffer, and keep using the same Web Audio buses. A sound that also fails there is remembered as unavailable until reload instead of being requested again.
All bundled sounds use Creative Commons CC0 1.0. Checksums and exact encoded byte sizes are committed with the source.
05
On desktop, the minimap and delivery mission form one right-side rail, with the narrower map aligned above the mission. At 768 px and wider the history preview uses the top-left space beneath navigation; through 767 px it becomes a compact sheet, the mission stays near the top, and a visible safe-area-aware joystick stays at lower-left. Middle-width layouts keep the mission clear of that control.
When a nearby history card is visible, a pointer-transparent SVG leader projects an anchor derived from the loaded landmark's real mesh bounds into the current canvas viewport. The gold dot sits 0.35 world units above the geometry's highest radial extent; until geometry is ready, the line stays hidden instead of guessing inside the building. Its four-point route uses two 90-degree bends and joins the exact vertical midpoint of the card's landmark-facing left or right edge. It hides and clears both paths and its endpoint when the point is occluded, off-screen, behind the globe, covered by the card, or when gameplay is paused, driving, in overview or showing a modal. Compact layouts keep the history sheet without the line.
The original stale-line bug came from assigning an expando hidden property to an SVG element instead of creating the real attribute used by CSS. The portrait-stretch bug came from startup writing fixed inline canvas dimensions. The callout now toggles a real attribute and clears geometry, while startup and gameplay resize only render buffers and leave the CSS box synchronized with the viewport.
The live minimap no longer waits for a 12-frame counter, which made walking appear to update at roughly 5 Hz on a 60 Hz game. Roads and feature bounds are prepared once, off-neighbourhood geometry is culled before projection, projection storage is reused, and identical player/camera/destination/district states skip painting. A moving view is capped at 60 Hz and is painted after the current camera update; teleport, destination, resize, loading and map-mode changes request an immediate repaint. The expanded atlas remains a separate renderer, and unchanged district/distance labels are not rewritten.
The canvas still receives programmatic focus for movement, but its accidental full-screen blue outline is gone. Keyboard entry or focus shows a compact Controls active badge beside the control guide; pointer or touch input hides it without breaking WASD, driving, dialog focus restoration, the left-hand joystick or two-thumb look and walk.
06
The previous September audit supplies the historical before/after baseline. It used a shared Mac and Android emulation, so it is useful history rather than proof for a Windows GPU. The new run used headed Chrome 153 at 1920×1080 and recorded the driver-visible renderer, AA mode, scene/output buffers, transfer and traces for three sequential cold/warm pairs.
| Profile | Ready cold | Transfer cold | Average FPS cold | p95 frame |
|---|---|---|---|---|
| Mac desktop | 7.33 → 9.30 s | 9.97 → 5.88 MB | 54.8 → 55.0 | 33.3 → 33.3 ms |
| Android emulation | 41.10 → 15.75 s | 9.64 → 5.88 MB | 22.9 → 18.2 | 83.3 → 133.4 ms |
| GPU / mode | Average FPS range | p95 frame range | Ready median cold / warm | Transfer at ready | Result |
|---|---|---|---|---|---|
| Radeon 680M Light + Performance | 31.9–41.6 | 42.8–60.6 ms | 3.357 / 3.510 s | 2.38 MiB cold 7–8 KiB warm | Not accepted: warm-ready, p95, sustained floor and one worst-frame/long-task run failed |
| RTX 3050 Ti Balanced + Balanced | 24.4–27.3 | 54.6–66.9 ms | 4.667 / 4.759 s | 2.38–2.42 MiB cold 7 KiB warm | Not accepted: ready, FPS, p95, worst-frame and long-task targets failed |
Both renderer checks passed: Radeon used ANGLE D3D11 with AMD driver 32.0.11038.9002; the RTX used ANGLE D3D11 with NVIDIA driver 32.0.15.7628. Both reported FXAA, context antialias off and zero default-framebuffer samples. Start-to-walking and entry transfer passed in all twelve runs.
These measurements exercised a dirty implementation tree based on 969ded6; raw traces/screenshots remain local. A prior headless AMD stall remains diagnostic evidence only. The table reports failures as failures—there is no Windows performance-success claim or deployment from this work.
07
Case study · 15 September 2026. Cursor, Chrome and Edge are separate executables with separate GPU processes. Assigning cursor.exe to the NVIDIA processor therefore fixed Cursor's embedded browser but did not configure chrome.exe or msedge.exe.
The supplied Chrome 153 report's current feature status was software-only: WebGL, OpenGL and WebGPU were disabled, GL_VENDOR and GL_RENDERER were Disabled, and the log contained ten GPU-process crashes, repeated RESULT_CODE_HUNG exits and shared-context failures. The same report still discovered both a Radeon 680M and RTX 3050 Ti, and a later hardware probe successfully created AMD ANGLE/D3D11. A capable GPU being listed is not proof that the browser's current GPU process is healthy.
Routing Chrome and then fully restarting it recovered WebGL2 on this machine. On modern Windows, the operating system's per-app graphics preference takes priority when one exists, as explained by NVIDIA's preferred-processor guidance. Configure every browser executable separately through Windows Settings → System → Display → Graphics, ensure the browser's graphics acceleration setting is enabled, completely exit every browser process, restart, then check the top/current feature status and renderer at chrome://gpu or edge://gpu.
WebGL Developer Extensions and WebGL Draft Extensions are extension-testing switches, not WebGL enable switches. Leave them at Default/Disabled. Google describes flags as temporary experimental controls; reset altered flags while diagnosing. Do not disable the GPU sandbox or integrated GPU, override the browser blocklist, or force experimental flags as a production fix.
A discrete GPU is not required. Supported integrated graphics automatically use Light + Performance. If the browser and driver cannot provide any functioning WebGL2 implementation, JavaScript cannot manufacture one; Jalan KL then shows its existing non-3D fallback instead of entering the city.
This is a recovery record for one hybrid-GPU Windows laptop, not a new FPS result. The historical Radeon and RTX tables above remain the latest controlled measurements.
08
This was request churn, not a DDoS or security attack. The old native-decode failure path created a fresh HTML media element for every footstep. Chrome then made media Range requests that returned 206 Partial Content, and Internet Download Manager correctly recognized each exposed .ogg URL as downloadable media.
The comparison screenshot did not show a game with no requests: Messenger had 110 requests in the Network panel, while the active dd text filter matched zero of them. Normal one-time GLB, encoded-audio, JavaScript, CSS and manifest transfers must appear in DevTools because the browser needs those bytes. A CDN or bundler can cache and compress them; it cannot make required network traffic invisible.
On the affected Chrome profile, direct Fetch requests for both .ogg and generic .bin versions of the same sound were intercepted and replaced with empty synthetic 204 responses. The runtime now transports each logical OGG in a static, content-hashed JSON text envelope, restores its bytes in memory, then follows fetch once → native or WASM decode → AudioBuffer. It never gives an OGG URL to an HTML media element, sends no audio Range header, and caches terminal failures for the session.
.mjs means a JavaScript ECMAScript module; it is not itself a download command. Some project .mjs scripts launch Playwright. Previously, the unconditional pretest generator also deleted and recreated directories watched by an already-open Vite session, which made that page reload and fetch its assets again. Routine tests now use an OS-temporary manifest fixture, content-aware generation, bundled headless Chromium with extensions disabled, and a download guard that cancels and fails on any Playwright download event. Installed Chrome, Edge, channels and executable paths are rejected unless the operator explicitly sets JALAN_ALLOW_SYSTEM_BROWSER=1, so normal tests never enter an IDM-enabled browser profile. No IDM setting change is required. IDM's file-type and browser-integration options remain optional background for users who want to understand its interception rules.
09
The existing Cloudflare Workers Static Assets setup remains the only delivery layer. Content-hashed audio envelopes, packed model transports, JavaScript and CSS receive one-year immutable caching. HTML, runtime manifests and mutable JSON revalidate. The generated manifest keeps the public shape {version, assets: {logicalId: {url, bytes, sha256}}} for audio, districts and packed shared models, while compiled model lookup avoids an extra core-startup request.
There is no R2 bucket, separate CDN, server API, database, Supabase project or user authentication in this change. No production setting or deployment was changed for this review candidate.