diff --git a/CALIFORNIA.md b/CALIFORNIA.md new file mode 100644 index 0000000..63098a5 --- /dev/null +++ b/CALIFORNIA.md @@ -0,0 +1,184 @@ +# Building out one California + +What the merged board is missing, sized so it can be worked in parallel. + +This is a **content** programme. It is deliberately separate from `TODO.md`, +which tracks engine work that is decided but not done: nothing below needs a new +mechanism, and every item is a data file somebody can write against a pack format +that already exists. The two do meet in one place, and the meeting is stated up +front so nobody starts at the wrong end — see "What has to come first". + +--- + +## The scale is already right. The density is not. + +Worth settling before anything else, because "make the map bigger" and "make the +map denser" are different jobs and only one of them is open. + +The board runs **32.50–42.05 N and −124.50 to −114.00 W** — the whole state, at +its true shape, on real latitude and longitude. `World.project` is a linear map +from degrees to scene units at 1,919 m to the unit, and every hill, district, +landmark, bridge, airport and port in every pack is placed by its real +coordinate. Nothing is schematic and nothing is squashed to fit. A board 554 +units across is 1,063 km across, and that is a fact rather than a framing. + +So the state is not too small. **It is empty above 38 N**, and this is the +measurement that says so — every district on the board, by the latitude of its +centre: + +| band | districts | +| --- | --- | +| 32 N | 1 | +| 33 N | 23 | +| 34 N | 26 | +| 35 N | 1 | +| 36 N | 2 | +| 37 N | 54 | +| **38–42 N** | **0** | + +107 districts, and 103 of them are in two clusters four hundred kilometres +apart. The northern **four hundred and fifty kilometres of California has not one +building on it**, and the Central Valley between the clusters has three. The +state capital is absent. So is San Diego, Fresno, Bakersfield, Stockton, Redding +and Santa Rosa. + +The same is true of everything else the board carries: + +- **Airports — 8, all of them Bay or Los Angeles.** KSFO, KSJC, KLAX, KBUR, + KVNY, KLGB, KSNA, KONT. No Sacramento, no San Diego, no Oakland, no Fresno, no + Santa Barbara, no Palm Springs. +- **Ports — 2, both in San Pedro Bay.** USLAX and USLGB. No Oakland, no + Richmond, no San Diego, no Stockton, no Humboldt Bay, no Hueneme. +- **Freeways — 2 roads of 12 vertices each.** US-101 and I-5, as twelve-point + polylines across a thousand kilometres of state. That is roughly one bend + every ninety kilometres, which is why they read as a diagram rather than as + roads, and it is before the separate problem that the engine draws them 1,919 m + wide on purpose. + +--- + +## What has to come first + +**Two engine items gate the value of most of this, and both are measured and +written up in `TODO.md`.** Content added before them will be authored against +ground that is about to change and a budget that is about to stop being the +binding constraint. + +1. **The relief ramp is landed (`d6dc307`) but unjudged.** Vertical exaggeration + now falls from 15x to 5.78x as the camera descends. Every judgement about how + a hill or a skyline reads is a judgement about relief, so wait until this has + been looked at before tuning heights. +2. **Cost does not track the view.** Measured with `scripts/cost-at.mjs`: the + merged board draws 355,759 triangles at 400 km and 329,392 at 2.5 km — flat, + because `createTerrain` is one mesh and the anonymous city is one + `InstancedMesh`, and `three` culls per object. Until the terrain and the lots + are chunked, **every district added anywhere is paid for everywhere**, and the + 400,000 cap is reached by content that is nowhere near the camera. After it, + the cap stops being the reason a city cannot be dense. + +The honest order is therefore: judge the ramp → chunk the terrain → chunk the +lots → then add the cities below at a lot size that is finally worth choosing. +**Coastline, hydrography, airports, ports and the freeway geometry are exempt** — +they are cheap, they are not lot-limited, and they can be authored in parallel +starting now. + +--- + +## The work, in parcels + +Each parcel is one pack-format contribution, sized to be reviewable on its own. +`src/tools/poseEditor.ts` (godmode, `G`) emits paste-ready `Chapter` blocks, +which is what makes adding a place cheap; `src/cities/socal.ts` is the reference +for a multi-city region and `src/cities/sf.ts` for a dense one. + +**Everything is traced by hand.** ARCHITECTURE.md §3.2 is the constraint and it +has not moved: OpenStreetMap is ODbL, ODbL is share-alike, and a share-alike +obligation cannot live in an Apache-2.0 repo — nor be discharged by serving it +from an API instead. Original expression, or a US-Government public-domain source +named in `NOTICE`. `scripts/check-no-binaries.mjs` enforces the other half. + +### A. The Central Valley — the corridor the board already drives + +The two freeway chapters run through it and there is nothing to see. Highest +value per district in the programme, because a visitor is already sent here. + +- **Sacramento** — the capital, and the most visible single absence. A downtown + district, the Capitol as a landmark, the river confluence, Old Sacramento. +- **Stockton and Modesto** — Delta port town and valley grid. +- **Fresno** and **Bakersfield** — the two big valley cities, low and wide. +- The **agricultural fabric** between them: the valley is not empty ground, it is + a grid, and a very low-coverage district with a near-zero tower chance reads as + farmland where bare terrain reads as desert. + +### B. The north — four hundred and fifty kilometres with nothing on it + +`TODO.md` already records that the Klamath knot reads as four chains at four +bearings and that the Cascade corner reads as Basin and Range. Both are relief +notes; these are settlement. + +- **Redding** and **Chico**, the two northern valley towns. +- **Santa Rosa** and the Sonoma/Napa corridor — the nearest real settlement to + the Bay's northern edge and currently a hard stop at the pack boundary. +- **Eureka and Humboldt Bay** — the only harbour on four hundred kilometres of + North Coast, and the one place up there with a port. +- **Tahoe**: the lake exists as inland water; the basin has no settlement. + +### C. San Diego — the missing corner + +The board runs to 32.50 N and the southernmost district centre is at 32.75. +San Diego is a metro the size of the ones already modelled and it is absent: +downtown, Coronado, the bay, North Island, the mesa canyons that shape it, and +**the port**, which is one of the two things the board's vessel layer could +already use. + +### D. The freeway network — the roads, as roads + +Twelve vertices is a diagram. Two roads is not a network. + +- **Retrace US-101 and I-5** at a vertex density that survives being looked at + from ten kilometres rather than from a thousand. The `Road` type already + carries `widthM` alongside `width`, and `cities/reconcile.ts` already reads it. +- **Add the ones a Californian would notice missing**: I-80 over Donner, I-15 to + the Mojave, I-10 east from Los Angeles, I-405, I-880/I-680 around the Bay, + CA-99 up the valley, CA-1 down the coast. +- **The width question is engine work, not content.** `createFreewayWorld` draws + a 4.7 km-wide atlas glyph because DRIVE mode has to drive down it on a board + where a real freeway is a fifth of a pixel, and `23e4bb8` withdraws that glyph + close in rather than fixing it — so today a city has no roads on it at all. + The true-width corridor needs the roadside props to be re-scaled with it + (`structures.ts` sets their setback from the slab, so a 44 m ribbon with + today's props puts 600 m oaks beside a two-lane road) and drive mode's near + plane is 0.1 units, which is 192 m on this board, against a car 2.6 mm long. + **File this as engine work in `TODO.md`, not as a tracing job.** + +### E. Airports and ports — the assets + +Both types are plain data with an existing renderer, so these are the cheapest +items here and they are not gated on anything in "What has to come first". + +- **Airports**: KSMF (Sacramento), KSAN (San Diego), KOAK, KFAT (Fresno), + KSBA (Santa Barbara), KPSP (Palm Springs), KRDD (Redding), KMRY (Monterey). +- **Ports**: Oakland, Richmond, San Diego, Stockton, Humboldt Bay, Port Hueneme. + Oakland is the one to do first — it is across the water from a board the + product already photographs, and the vessel layer is already wired. + +### F. Landmarks the eye goes looking for + +58 today, all Bay and LA. The state Capitol, the Coronado bridge, Shasta Dam, +the Golden Gate's northern approach, the Carquinez bridges, Vandenberg, +the Salton Sea's shoreline works. + +--- + +## Two things to check before opening a parcel + +- **The block cap.** `src/test/packs/californiaBoard.test.ts` holds the state + pack's block count under 9,200 and it currently reads 8,881. Several parcels + above will cross it. The cap is a real budget on a real board and the right + move is to measure and move it deliberately, in the same commit, with the + number recorded — not to raise it quietly to make a test pass. +- **Draw calls, not triangles.** `TODO.md` records that adding Sacramento is + "a district and about 300 lots; the budget that has to be checked first is + draw calls on the california mobile cell, not triangles." That board reads 411 + draws of a 460 cap. Draw calls are the scarce resource on this board, and they + are what a new airport, port or landmark group spends. diff --git a/TODO.md b/TODO.md index 77f3e69..51001bb 100644 --- a/TODO.md +++ b/TODO.md @@ -851,3 +851,30 @@ Two pieces, in this order: **Do not do either before the relief ramp is judged**, since both are tuned against how the ground looks and the ramp changes that. It landed at `d6dc307`. + +## One California is the default now — two consumers that follow it + +Landed 2026-08-24. A bare `tera.lumbridgecorp.com` is the merged board; +`?city=sf` and `?city=socal` still get the dedicated boards unchanged, because +twenty-nine capture guards and two budget cells assert the `data-board` they land +on and a metro id that silently fell back to the merged board would make them +measure something else. `?one=0` forces the old three-board arrangement. + +Both `california` budget cells were pinned to `?one=0` in the same change: their +caps are the plain state board's 440,000, and left alone they would have measured +the merged board — passing, while `california-one` measured the same board and +nobody watched the other. + +**The marketing imagery has not followed, and it should.** `shots.mjs` and +`films.mjs` build `?city=${shot.city ?? "california"}&handover=0`, so every shot +that does not name a city now photographs the merged board rather than the plain +state tier. That is the right picture of the product and the wrong thing to have +happen silently — the captions were written against a board with no cities on it, +and `scripts/check-chapter-identity.mjs` does not check prose. Re-shoot with +`npm run refresh`, then read the captions against what came back; `TODO.md` +already records that four captions were falsified by engine changes once before +and that nothing catches it. + +The content programme this opens up — what a single cohesive California is still +missing, and in what order — is **`CALIFORNIA.md`**, kept separate because none +of it needs a new mechanism and all of it can be worked in parallel. diff --git a/scripts/performance-budget.mjs b/scripts/performance-budget.mjs index dc286bc..7d88af2 100755 --- a/scripts/performance-budget.mjs +++ b/scripts/performance-budget.mjs @@ -54,13 +54,23 @@ const SCENES = { // `california-overview` chapter never becomes ready — but a harness that // depends on an app default is a harness that reports someone else's change // as its own flake. - query: "?city=california&handover=0", + // `one=0` on purpose: both California cells' caps were measured against the + // **plain** state board, which is now what `?one=0` means and no longer what + // a bare `?city=california` gives. Without it these measure the merged + // board — which passes, and which `california-one` already covers, so the + // failure is two cells measuring one board and nobody watching the other. + query: "?city=california&one=0&handover=0", signature: "california-overview", ready: () => document.getElementById("boot")?.hidden === true && document.querySelector("#chapters .chapter[data-view='california-overview']") !== null, }, "california-drive": { host: "tera.lumbridgecorp.com", - query: "?city=california&handover=0", + // `one=0` on purpose: both California cells' caps were measured against the + // **plain** state board, which is now what `?one=0` means and no longer what + // a bare `?city=california` gives. Without it these measure the merged + // board — which passes, and which `california-one` already covers, so the + // failure is two cells measuring one board and nobody watching the other. + query: "?city=california&one=0&handover=0", signature: "california-overview", ready: () => document.getElementById("boot")?.hidden === true && document.querySelector("#chapters .chapter[data-view='california-overview']") !== null && document.querySelector("#chapters .chapter[data-view='la-sf-us-101']") !== null, activate: () => { diff --git a/src/main.ts b/src/main.ts index 01d8808..3be1fd2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -227,7 +227,7 @@ import type { import type { PresenceIndicator } from "./realtime/presenceIndicator.ts"; /** - * One full California, as **one pack**, behind `?one=1`. + * One full California, as **one pack** — and now the default. * * The first attempt at this nested each metro's built scene inside the state * board's under a similarity transform. The transform was right and the result @@ -236,8 +236,41 @@ import type { PresenceIndicator } from "./realtime/presenceIndicator.ts"; * one `City` carrying the state's landform and both metros' detail, so the * engine builds one world, one lattice and one terrain mesh. See that file for * the measured lattice cost and for the two merges that are not a union. + * + * ## Why it is no longer behind a flag + * + * Because a flag is a second product, and the whole point was to stop having + * three. Shipped behind `?one=1` the merged board was something a visitor could + * not find and did not get: `tera.lumbridgecorp.com` still landed on the Bay + * Area, the left column still offered two other boards, and clicking one still + * tore the board down and built another. The board existed and the product did + * not change. + * + * ## The three ways this resolves, and why the escape hatches are shaped so + * + * Default — no `?city=`, or `?city=california` — is **one California**. + * + * `?city=sf` and `?city=socal` still get the dedicated boards, unchanged. That + * is deliberate and it is not hedging: twenty-nine capture guards in + * `scripts/brand-assets` and the `bay-area` and `socal` cells of + * `scripts/performance-budget.mjs` aim at those boards by name and assert the + * `data-board` they land on. Making a metro id fall back to the merged board + * would not degrade those, it would make them silently measure and photograph + * something else — which is the exact failure the budget harness's own comment + * says the `data-board` assertion exists to catch. A named board stays a named + * board. + * + * `?one=0` forces the three-board product whatever the city is. One consumer + * needs it — the `california` budget cell, which is written against the *plain* + * state board's 440,000 cap and would otherwise measure the merged board that + * `california-one` already covers — and it is the honest way to say "the old + * arrangement" without spelling a board id. */ -const ONE_CALIFORNIA = new URLSearchParams(location.search).get("one") === "1"; +const ONE_PARAM = new URLSearchParams(location.search).get("one"); +const CITY_PARAM = new URLSearchParams(location.search).get("city"); +const ONE_CALIFORNIA = + ONE_PARAM === "1" || + (ONE_PARAM !== "0" && CITY_PARAM !== "sf" && CITY_PARAM !== "socal"); /** * The boards on offer — three, or **one**.