Skip to content

Open-world browser game, 2026

KL Rush

An open-world Kuala Lumpur you can drive, ride and walk through, in a browser tab or on a phone.

Overview

KL Rush is a free open-world game of Kuala Lumpur that runs in a browser, with 22 story missions, traffic, police chases, trains, side jobs, day and night, and tropical rain. It also ships as a desktop app for Windows, macOS and Linux. The game source is private; the preview repo holds the release notes and feedback.

Engineering approach

  • Rules and state machines live in pure modules with no DOM and no Three.js, so plain Node tests can run them.
  • Optional features load through dynamic imports behind flags, and each import has a reviewed size cap in CI.
  • Performance work starts with frame-by-frame traces in WebKit at iPhone size, because that is the engine players on iPhone run.

How a change reaches players

  1. Specification
  2. Pure logic and tests
  3. Size budgets
  4. Smoke test in a real browser
  5. Automatic deploy
  6. Error reports

Stack

Three.js, WebGPU with WebGL2 fallback, JavaScript modules, checked by TypeScript, Jolt physics in WebAssembly, Vite, Electron, Vercel, Sentry, Blender

Technical challenges

Stutter that averages could not see

Problem
Play felt rough on iPhone, but load times and average frame rate showed nothing.
Solution
Per-frame tracing in WebKit tied each slow frame to its cause: every car was building its own shader graph. Vehicles now share one graph, and compiled programs are kept alive between uses.

Keeping iPhones on the fast renderer

Problem
iPhones run far better on WebGPU than on WebGL2, and one lost GPU device used to move a phone to WebGL2 for good.
Solution
Safari can drop the GPU device under memory pressure, and one such loss should not cost a player that speed. Now only a repeated visible loss switches renderer.

A whole city in a small download

Problem
A browser game loses players while it loads, and every new feature adds code.
Solution
CI fails the build when a chunk passes its gzip cap, so a feature has to earn its size. Content lives in a cache that survives deploys, with retries for bad connections.

Deciding what not to build

Problem
World streaming and occlusion culling are the textbook answers for an open world.
Solution
Profiling rejected both: geometry was a small part of peak load memory, and city areas are too large to hide. Instead the whole city stays loaded and each area is culled by distance. GPS uses a small custom A* on a road graph, with no routing library.

Gallery

Two police cars chasing a red car through a KL junction under a passing monorail
A police chase under the monorail.
Jalan Alor at dusk under rows of red lanterns, with hawker stalls and folding tables along the street
Jalan Alor at dusk.
KLIA Terminal 1 departure hall with white tree columns under a wooden shell roof
The KLIA departure hall.
The SMART Tunnel closed for flooding, with its gates shut and lane signals red
The SMART Tunnel closes in heavy rain.
Merdeka 118 at dusk, its faceted tower and spire outlined in white light above the lit city
Merdeka 118 at dusk, rebuilt from photos.

Outcome and status

Public and playable, with regular releases. It runs on desktop browsers, phones and tablets, and as a desktop app.

Known limits

  • The Windows and Linux desktop apps have not yet been tried on real machines.
  • The apps are not signed by Apple or Microsoft.