1
0

feat: SFO, LAX, both bridges, a road that reads as a road, and aeroplanes that move

**The aeroplanes were stuck because the wire could not describe motion.**
`WireAircraft` carried position, altitude and heading and nothing else, so the
client could only interpolate between the last two observations: every aircraft
replayed a segment it had already flown, arrived at the newest known point, and
sat still until the next poll landed five to fifteen seconds later. The feed had
the missing numbers the whole time and the server threw them away. Sampled live
from `api.adsb.lol/v2/point` while writing this — `gs` ground speed, `track`,
`baro_rate`, plus `r` registration and `t` type designator. They are on the wire
now in SI, aircraft dead-reckon along their own track and correct toward the
truth when a fix lands, and the click card an anonymous visitor gets says
"B739 · N68834". That last part is the enrichment FR24 was wanted for, obtained
from an ODbL feed we may actually republish.

**SFO and LAX exist.** A new `engine/airports.ts` composes an airport from
runways, taxiways, aprons and terminal masses, with markings drawn on a canvas
rather than modelled; the pattern of the runways is what the eye recognises from
altitude, long before any building does. SFO is the two crossing pairs on the bay
fill; LAX is the four parallels either side of the terminal horseshoe, plus the
Southland fields under the traffic that actually flies there.

**The Golden Gate and the Bay Bridge are those bridges.** One kit in
`engine/bridges.ts`, because a suspension bridge is a repeated tower, a catenary
main cable, a series of hangers and a deck — so both are configurations rather
than two private implementations. The Bay Bridge carries the real 2013 topology:
two suspension towers west of Yerba Buena, one east, then the piered causeway.
The freeway stopped being a wireframe overlay and became a road, with shoulders,
a median, and lane markings as texture.

**And the board got faster while all of that landed.** California went from
728,744 triangles and 562 draw calls to 391,169 and 371 — headroom from 2.8% to
47.8%. The Bay Area board is 506,550 triangles lighter than before this work.
Two things paid for it:

- `transmission: 0.08` on the aircraft cockpit glass. three.js runs a full
  transmission backdrop pass whenever any rendered material has transmission
  above zero, re-drawing the entire opaque scene into a second target every
  frame — so the city was rendering terrain, every block and every freeway piece
  TWICE. Measured by patching only that number in a copy of the built bundle:
  703,267 tris / 562 draws with it, 398,608 / 371 without. The material was
  already `transparent: true, opacity: 0.86`, so it was buying nothing.
- Flatness-adaptive terrain LOD, which collapses runs of lattice cells wherever
  the height and colour agree with the quad replacing them. The coastline is
  provably untouched — a patch collapses only when every point is on land and
  agrees about `park` — and a test asserts the drawn footprint matches the
  cell-by-cell area to 1e-6. `createTerrain` got *faster*: the vertices it stops
  emitting cost more than the flatness scan costs to run.

**The budget now watches the boards this was built on.** There was no `bay-area`
or `socal` cell — so SFO, LAX and both bridges all landed in frames nothing
measured, which is how a cap you do not have looks from the inside. Both are in
the matrix now with caps set from measurement, and the rationale lives in the
harness because JSON cannot hold a comment.

Two known defects ship with this, both recorded in TODO.md rather than hidden:

- `bay-area.desktop` drops about one frame in twenty (p50 16.7, p95 33.3). It is
  desktop-only and not fill rate — mobile runs the same 2.26 M triangles at a
  comparable pixel count and holds 16.7 flat — which points at the 2048 shadow
  map desktop uses against handheld's 1024. Measured at the commit before this
  work with the same harness: identical p95 33.3. Pre-existing, and invisible
  until the cell existed.
- The aeroplane glyph is still about 1.5x the Golden Gate's main span at chapter
  zoom, down from 2.5x. `GLYPH_MAX_SCALE` is 52 because the raw scale at the far
  end of the California orbit is 51.0 at a 60-degree field of view, and 26 —
  tried first — put the glyph at 0.0123 of the frame against the 0.012 where the
  wings stop resolving. The real fix is to clamp against the camera's focus
  distance rather than the aircraft's, which is a signature change.

Tests 1020 -> 1137. Typecheck, build, eight budget cells, no-binaries,
provenance, zero-config boot, dependency licences, arena source hashes and the
UI smoke across two viewports and two access tiers all pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-22 05:06:12 -07:00
parent d9f8baf171
commit f81d5218d4
29 changed files with 7056 additions and 288 deletions
+73 -1
View File
@@ -25,6 +25,33 @@ const SCENES = {
active: () => document.querySelector("[data-control-mode='drive']")?.getAttribute("aria-pressed") === "true" && document.getElementById("play-hud")?.hidden === false,
},
office: { host: "office.lumbridgecorp.com", ready: () => document.getElementById("boot")?.hidden === true && document.getElementById("enter")?.textContent?.includes("Back to the city") === true },
/*
* The two metro boards, added after they became the boards with the most on
* them and were still the boards nothing measured.
*
* For a long time the matrix was california, california-drive and office. That
* was defensible while the metro boards were terrain and buildings, and stopped
* being defensible the moment SFO, LAX, the Golden Gate, the Bay Bridge and a
* surfaced freeway all landed on them — every one of those is city-frame
* geometry, and every one of them arrived in a frame with no budget watching
* it. A cap you do not measure is a cap you do not have.
*
* Their own numbers rather than California's: `sf` carries the densest built
* ground in the product and `socal` the widest basin, and holding either to a
* board tuned for a whole state would be arbitrary in both directions. These
* are set from the first measured run with headroom deliberately left, in the
* same spirit as the others.
*/
"bay-area": {
host: "tera.lumbridgecorp.com",
query: "?city=sf",
ready: () => document.getElementById("boot")?.hidden === true && document.querySelectorAll("#chapters .chapter").length > 0,
},
socal: {
host: "tera.lumbridgecorp.com",
query: "?city=socal",
ready: () => document.getElementById("boot")?.hidden === true && document.querySelectorAll("#chapters .chapter").length > 0,
},
};
const args = process.argv.slice(2);
@@ -37,6 +64,51 @@ function positive(name, fallback) {
if (!Number.isFinite(value) || value <= 0) throw new Error(`--${name} must be a positive number`);
return value;
}
/*
* WHY THE TWO METRO BOARDS CARRY CAPS THREE TIMES CALIFORNIA'S.
*
* Measured on the first run that included them: bay-area 2,265,056 triangles and
* socal 1,417,648, against california's 391,169. That is not a regression and it
* is not slack — it is what those boards are. California is one state at a
* standoff where a building is a speck; the Bay Area is the densest built ground
* in the product with every lot, the freeway network, both bridges and SFO in
* frame at once, and the Southland is the widest basin with LAX and five more
* fields on it. Holding either to a cap tuned for a whole state would be
* arbitrary in both directions.
*
* Both render at 60 fps (p95 16.7-16.8 ms) on the box that measured them, which
* has a Radeon RX 6700 XT. That is the honest limit of what these numbers prove.
*
* TWO THINGS A READER SHOULD KNOW BEFORE TREATING THESE AS COMFORTABLE:
*
* - The mobile cell measures the SAME geometry as desktop — 2,263,784 against
* 2,265,056 — because the handheld path reduces the pixel ratio and the
* shadow map and does not reduce the scene. A phone draws every triangle a
* desktop does. The mobile budget here is therefore a frame-time gate and not
* a geometry one, and it is the number most likely to be wrong on real
* hardware nobody in this repo has tested on.
* - These cells did not exist until the round that put SFO, LAX, the Golden
* Gate, the Bay Bridge and a surfaced freeway on them. Every one of those is
* city-frame geometry and every one arrived in a frame with no budget
* watching it. A cap you do not measure is a cap you do not have.
*
* `bay-area.desktop.p95FrameIntervalMs` IS 33.4 AND THAT IS A RECORDED DEFECT,
* NOT A TARGET. The board renders a median frame in 16.7 ms and drops roughly
* one frame in twenty: p50 16.7, p95 33.3, and 443-456 frame samples in a window
* where every other cell returns 480. It is desktop-only, and it is not fill
* rate — the mobile cell runs the SAME 2.26 M triangles at a comparable pixel
* count (1.32 MP against 1.30) and holds 16.7 ms flat. The obvious suspect is
* the shadow map, which `stage.ts` sizes 2048 on desktop and 1024 on handheld,
* over what is now the heaviest shadow-casting scene in the product.
*
* Measured at the commit BEFORE the airports and bridges landed, with this same
* harness: p95 33.3, p50 16.7, 443 samples, 2,771,606 triangles. So the stutter
* predates that work, and that work left the board 506,550 triangles LIGHTER
* while adding SFO, two bridges and a surfaced freeway. The allowance exists so
* this cell still guards the numbers that are healthy — triangles, draw calls,
* and the mobile frame time — instead of being permanently red and therefore
* permanently ignored. Fix the stutter and put it back to 16.7; see TODO.md.
*/
function sceneBudget(value, label) {
if (!value || typeof value !== "object") throw new Error(`missing budget for ${label}`);
for (const key of ["p95FrameIntervalMs", "maxDrawCalls", "maxTriangles"]) {
@@ -202,7 +274,7 @@ async function measure(browser, port, sceneName, viewportName, budget, requestLo
const before = requestLog.length;
await page.addInitScript(instrumentation);
const scene = SCENES[sceneName];
const url = `http://${scene.host}:${port}/`;
const url = `http://${scene.host}:${port}/${scene.query ?? ""}`;
try {
await page.goto(url, { waitUntil: "networkidle", timeout: readyTimeoutMs });
try {