1
0

Real weather, real aircraft, a heightfield off the main thread, and instruments

Three things that were built and never connected, connected.

**The weather was already there.** `observe()` has always taken a
`WeatherObservation` and `main.ts` has always passed null, so the cloud,
precipitation, visibility and marine-layer paths in atmosphere.ts had never run
outside a test. The server already shipped NWS, met.no and Open-Meteo, all
configured off. What was actually missing was that a single TERA_ORIGIN_LAT/LNG
served one metro and lied to the other — so weather and traffic are per-region
now, derived from the city's own bounds, and the Bay Area gets its fog while
Long Beach gets its own sky. The route takes ?city= or a validated ?lat=&lng=
and refuses to become an open geocoding proxy for the planet.

**The heightfield moved to a Worker.** 2.3 s of blocked main thread at boot, and
another ~950 ms of point-in-polygon on top of it: the park mask is filled in the
worker now, and block placement samples four corners and only runs the exact
test on a cell that straddles an edge — 8 buildings differ out of 185,036.
createScene is async and takes a Stage as a consequence, and there is a
main-thread fallback because "clone it and it works" has no exception clause.

**Spaces is a chunk you fetch when you reach for the door**, not one everybody
downloads. Same for the godmode tools. The entry chunk is 722 kB rather than
772; three.js is most of what is left and splitting it is a different job.

**Godmode is an instrument panel now** rather than one slider: the date and the
season, not just the hour, so the Meeus moon and the sun's seasonal arc become
visible instead of merely correct; a weather override that says on screen when
it is lying; a frame-time and draw-call readout; and a pose editor that emits a
paste-ready Chapter block, which is the thing that makes adding New York cheap.

Two blockers the review caught:

  - Every city switch leaked 8 GPU textures — one of them a 2048x2048 shadow map
    — and ~10.5 shader programs, and deleteTexture had never been called once in
    the app's lifetime. The renderer was being built per scene; it belongs to the
    canvas, for the life of the page.
  - An upstream fetch that threw rather than returning null skipped the cache
    stamp, so the TTL — the only rate limit on outbound calls — collapsed to one
    upstream request per inbound request, and the caller got a 500.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-06 03:25:31 -07:00
parent a6f6a91813
commit e41c90fe8d
39 changed files with 8482 additions and 503 deletions
+107 -17
View File
@@ -11,11 +11,12 @@
*
* ### Where the coordinates came from
*
* The three Bay Area airport positions are published FAA airport reference
* points, typed in by hand. They are US government facts in the public domain,
* and — as with every other coordinate in this repo — emphatically not derived
* from OpenStreetMap. Everything else here is a waypoint someone made up so the
* legs go the right way. See ARCHITECTURE.md §3.2 and CONTRACT.md §8.
* The seven airport positions — SFO, OAK and SJC in the north, LAX, BUR, LGB and
* SNA in the south — are published FAA airport reference points, typed in by
* hand. They are US government facts in the public domain, and — as with every
* other coordinate in this repo — emphatically not derived from OpenStreetMap.
* Everything else here is a waypoint someone made up so the legs go the right
* way. See ARCHITECTURE.md §3.2 and CONTRACT.md §8.
*
* The callsigns are invented, with operator prefixes that belong to nobody. A
* repo that refuses to ship other people's logos should not ship their flight
@@ -95,17 +96,100 @@ const BAY_AREA: WireSimRoute[] = [
},
];
/** Degrees, roughly the distance from downtown SF to the far end of the bay. */
const BAY_AREA_RADIUS = 0.75;
const LAX: [number, number] = [33.9425, -118.4081];
const BUR: [number, number] = [34.2007, -118.3585];
const LGB: [number, number] = [33.8177, -118.1516];
const SNA: [number, number] = [33.6757, -117.8682];
/**
* The Southland, which is a different shape of airspace and not a translated
* copy of the Bay Area.
*
* Almost everything here runs eastwest, because the terrain does: the basin is
* walled by the San Gabriels to the north, so departures go out over the water
* and turn, and arrivals come down the length of the valley. Four fields instead
* of three, and the two small ones matter more than they do in the north — a
* board four times the area at a third of the scale reads as empty very fast if
* everything is at cruise.
*/
const SOCAL: WireSimRoute[] = [
// Departures — the standard west-over-the-ocean climb, the north-east haul
// over the Cajon Pass, and the two valley fields going their own way.
{ callsign: "LMB604", from: LAX, to: [33.6, -119.3], fromAlt: 20, toAlt: 10500, duration: 440 },
{ callsign: "PAC712", from: LAX, to: [34.6, -117.1], fromAlt: 20, toAlt: 11500, duration: 520 },
{ callsign: "SIE288", from: BUR, to: [34.9, -118.9], fromAlt: 20, toAlt: 9800, duration: 460 },
{ callsign: "BAY1516", from: SNA, to: [33.1, -118.6], fromAlt: 20, toAlt: 9600, duration: 420 },
{ callsign: "GLD843", from: LGB, to: [34.5, -116.9], fromAlt: 20, toAlt: 10200, duration: 500 },
// Arrivals — the long straight-in from the east, the coastal descent from the
// north-west, and one down the back of the mountains into Burbank.
{ callsign: "LMB1170", from: [34.1, -116.8], to: LAX, fromAlt: 6200, toAlt: 20, duration: 560 },
{ callsign: "RDW425", from: [34.7, -119.4], to: LAX, fromAlt: 6800, toAlt: 20, duration: 600 },
{ callsign: "PAC96", from: [34.8, -117.6], to: BUR, fromAlt: 5400, toAlt: 20, duration: 480 },
{ callsign: "SIE1901", from: [33.2, -117.2], to: SNA, fromAlt: 5000, toAlt: 20, duration: 450 },
// Overflights, level the whole way: the coastal corridor and the desert one.
{
callsign: "GLD1330",
from: [34.9, -119.2],
to: [32.9, -117.0],
fromAlt: 11200,
toAlt: 11200,
duration: 690,
},
{
callsign: "RDW78",
from: [33.0, -119.1],
to: [34.9, -116.8],
fromAlt: 10600,
toAlt: 10600,
duration: 720,
},
// Low across the basin. General aviation is most of what anybody standing in
// Culver City actually sees, and it is the only traffic that reads as *near*.
{
callsign: "BAY3312",
from: [33.78, -118.42],
to: [34.16, -117.75],
fromAlt: 850,
toAlt: 850,
duration: 540,
},
{
callsign: "LMB2044",
from: [34.22, -118.72],
to: [33.72, -117.98],
fromAlt: 1300,
toAlt: 1300,
duration: 570,
},
];
/**
* The airspaces this file has actually laid out, and how close a region's centre
* has to be to get one.
*
* Degrees rather than kilometres because the comparison is a box, not a circle,
* and the radii are generous: the Bay Area's is roughly downtown to the far end
* of the bay, and the Southland's spans a basin that runs from Ventura to
* Riverside. A region centre that lands inside one of these is close enough that
* the real airports are the right answer; anything else gets spokes.
*/
const AIRSPACES: { centre: [number, number]; radius: number; routes: WireSimRoute[] }[] = [
{ centre: [37.7749, -122.4194], radius: 0.75, routes: BAY_AREA },
{ centre: [33.82, -118.05], radius: 1.0, routes: SOCAL },
];
/**
* A plan for a city this file has never heard of.
*
* A self-hoster pointing `TERA_ORIGIN_LAT/LNG` at somewhere that is not San
* Francisco should get moving aircraft rather than an empty sky, so eight legs
* are laid out on evenly-spaced bearings through their origin. It is not their
* city's real airspace and does not pretend to be — it is motion in the right
* kind of place, which is all the map ever wanted from this.
* A self-hoster pointing `TERA_REGIONS` (or `TERA_ORIGIN_LAT/LNG`) at somewhere
* that is neither of the two boards should get moving aircraft rather than an
* empty sky, so eight legs are laid out on evenly-spaced bearings through the
* region centre. It is not their city's real airspace and does not pretend to be
* — it is motion in the right kind of place, which is all the map ever wanted
* from this.
*/
function genericPlan(lat: number, lng: number): WireSimRoute[] {
const routes: WireSimRoute[] = [];
@@ -127,9 +211,15 @@ function genericPlan(lat: number, lng: number): WireSimRoute[] {
return routes;
}
export function planFor(origin: { lat: number; lng: number }): WireSimRoute[] {
const nearSf =
Math.abs(origin.lat - 37.7749) < BAY_AREA_RADIUS &&
Math.abs(origin.lng + 122.4194) < BAY_AREA_RADIUS;
return nearSf ? BAY_AREA : genericPlan(origin.lat, origin.lng);
export function planFor(centre: { lat: number; lng: number }): WireSimRoute[] {
for (const airspace of AIRSPACES) {
const [lat, lng] = airspace.centre;
if (
Math.abs(centre.lat - lat) < airspace.radius &&
Math.abs(centre.lng - lng) < airspace.radius
) {
return airspace.routes;
}
}
return genericPlan(centre.lat, centre.lng);
}