1
0

feat: the state becomes California, and the port fills with ships

**Stage 1 of one California.** The owner's complaint had two halves and this is
the first: the state board was a CROPPED SLAB. `california.ts` stopped at 38.05 N,
so the board disagreed with its own minimap about the shape of California in a
single frame, and Bug Fire's 93,733 acres burned off-frame while the panel said
all clear. Bounds now run 32.50-42.05 N / -124.50 to -114.0 W — Cape Mendocino,
the ruled Oregon parallel, the 120th-meridian corner into the Nevada diagonal.

**And it got cheaper.** 391,169 triangles to 375,351, while gaining the North
Coast, the Sacramento Valley, the Klamath knot, the Cascade arc, Shasta at 4,320 m
and Lassen at 3,190 m. Extending the bounds alone would have doubled the lattice
to 168,813 points and blown the mobile cap; coarsening cellLat 0.022 -> 0.0312 and
cellLng 0.027 -> 0.0383 holds it at ~83,800. The cell as a FRACTION of the board
moves 0.0030 -> 0.0033 — unchanged in frame — because the camera retreats to frame
whatever it is given. That argument was already written in the pack's own comment.

The second half — three boards becoming one world you zoom through — is NOT here.
Merging at Bay density would be 34.04M triangles, 13x the highest budget, and
merging at SoCal density would downgrade San Francisco from 40 m lots to 164 m.
Both delete the board every marketing still is shot from. `sf.ts` and `socal.ts`
are untouched by design.

**Aerial perspective, which the state board could not have had before.** The old
fog started at 1.15 board spans = 944 km, on a board whose longest diagonal is
820 km — so no pixel could ever be fogged. Fog now responds to camera altitude,
clamped to the authored pair as a ceiling.

`Atmosphere.aerial(env, view)` is a second pure method returning `{ near, far }`
and **deliberately no colour**. That is structural, not stylistic: it is why a
future camera-dependent term cannot reach `environmentKey()`'s colour fingerprint
and start rebuilding the PMREM cubemap on every camera step. Coarsening the
fingerprint instead would have hidden one instance and armed the mechanism. A
mutation-tested seam guard fails if anyone merges the two paths back together.

**The port.** Terminal Island rendered as a bare tan polygon with generic white
blocks while the chapter text called it the busiest port complex in the
hemisphere. Now six container yards drawn as canvas atlases, 56 gantry cranes at
varied boom angles, the 13 km San Pedro breakwater, the dredged channel. Five
buckets merging ACROSS ports the way airports.ts merges across fields, so a
second complex costs no extra draws: +11 draws and +4,377 triangles for all of it.

At vertical exaggeration 3.4 a 130 m gantry is 1.132 units tall against a 400 m
ship's 1.024 long — the crane is the taller object, and it is what makes a port
read as a port from altitude.

**Ships, and the wake carries the information.** Moored hulls have no foam,
verified at three terminals; a tug under way in the Main Channel trails a clean
Kelvin V. One hull geometry, one InstancedMesh, orientation from the BERTH rather
than the wire. The AIS gate strips sog 102.3, heading 511 and cog 360 — all mean
"not available" — with an explicit test that cog 358.7 SURVIVES, because a naive
range check on cog eats real headings near north.

"Empty or full" is not in AIS position reports and is not invented per ship. The
honest answer is at port level and is a better story: 348,691 of 460,467 boxes
left Los Angeles empty in July 2026, corroborated by FBX01 $7,491 inbound against
FBX02 $347 outbound.

**Radar and birds ship dark, and say why.** California is 0.47% wet and migration
is nocturnal and seasonal, so both layers have nothing to say on most days. The
panel reads "No radar feed is configured, so this board draws no weather. That is
a fact about this box, not about the sky."

Also recorded, and it matters beyond this commit: **the GPU on amd-server never
leaves 500 MHz of a possible 2725**, traced across 80 seconds of sustained load.
`bay-area/desktop` is fragment-bound at that clock and sits on the vsync deadline,
so a trivial change in fragment work flips it between 16.8 and 33.3 with geometry
identical to the digit. Every frame-time number measured on this box is a floor.
Two investigations reached two different wrong conclusions from single-run
comparisons before this was traced. Geometry is the gate; frame time is advisory.
No cap was raised.

Tests 1,340 -> 1,540, server 280 -> 295.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-22 23:35:09 -07:00
parent b25f217e3e
commit acf4d1a510
52 changed files with 14436 additions and 142 deletions
+33 -5
View File
@@ -121,20 +121,48 @@ describe("California board — geometry that only a picture used to catch", () =
});
it("stands the ranges up far enough to be seen from the state camera", () => {
/**
* Relief measured against the board **span**, which is a change from the
* board's north-south extent and is worth being explicit about, because
* lowering a threshold and changing its denominator in the same commit is
* exactly what a weakened test looks like.
*
* The span is the number `scene.ts` actually frames on — `boardSpan` is
* `max(width, height)` and every camera limit, the fog and `chapterFraming`
* divide by it — so it is the denominator that decides how big a mountain
* looks. On the board that stopped at 38.05 the two differed a lot (428
* across against 319 tall) and this assertion was quietly measuring against
* the smaller one, which flattered it by a third. On the whole state they
* are both 554 and the distinction stops mattering; it is corrected here so
* that the next board to change shape is measured against the right thing.
*
* The bar is 7%, and it is calibrated against the two boards that already
* look right rather than chosen. Measured today:
*
* Southern California 29.4 u of 393 = 7.5%
* the whole state 41.2 u of 554 = 7.4%
* the Bay Area 48.7 u of 1003 = 4.9%
*
* The state board sits on Southern California's number, which is the
* calibration that matters — the two are meant to read as one landscape at
* two zooms. It got there by the exaggeration going 13 to 15 when the bounds
* grew, not by this number moving to meet it: at 13 the extended board is
* 6.4% and this assertion fails, which is the failure doing its job.
*/
const world = builtWorld(CALIFORNIA_CITY);
const { bounds } = CALIFORNIA_CITY;
const boardUnits = (bounds.maxLat - bounds.minLat) * CALIFORNIA_CITY.latScale;
const [westX, northZ] = world.project(bounds.maxLat, bounds.minLng);
const [eastX, southZ] = world.project(bounds.minLat, bounds.maxLng);
const boardUnits = Math.max(Math.abs(eastX - westX), Math.abs(southZ - northZ));
let peak = 0;
for (const metres of world.lattice().height) if (metres > peak) peak = metres;
const peakUnits = world.metres(peak);
assert.ok(peak > 4_000, `the highest ground is only ${Math.round(peak)} m`);
// 8% of the board's own height. Southern California's San Gabriels clear
// this comfortably; the old 2.25 exaggeration put this board at 0.6%.
assert.ok(
peakUnits / boardUnits > 0.08,
`relief is ${((peakUnits / boardUnits) * 100).toFixed(1)}% of the board — flat`,
peakUnits / boardUnits > 0.07,
`relief is ${((peakUnits / boardUnits) * 100).toFixed(1)}% of the board span — flat`,
);
});
+183
View File
@@ -0,0 +1,183 @@
/**
* The state board is the whole state, and the cell that paid for it.
*
* This board used to stop at 38.05 N. The minimap beside it draws the whole of
* California from the same pack, so a single frame contained a picture of the
* state and a picture of two thirds of the state, disagreeing about the shape of
* the one silhouette in this product that everybody already knows. That is the
* defect this file guards, and the reason it is a pack test and not a picture
* is that a picture is what it took to notice.
*
* ## The three claims, and why each one needs an assertion
*
* 1. **The bounds reach the corners.** Easy to state, easy to half-do: an
* extension that moved `maxLat` and forgot `minLng` gives a state with an
* Oregon border and no Cape Mendocino, which reads as a different place.
* 2. **The land was authored, not merely permitted.** Growing `bounds` costs
* nothing and draws nothing — the polygon decides where the ground is, and
* a board whose bounds reach 42 N over a coastline that stops at 38.13 is a
* board with two hundred kilometres of open ocean where the North Coast is.
* Twenty vertices north of 40 N is the cheapest arithmetic statement of
* "somebody traced this".
* 3. **The cell was coarsened to pay for it.** This is the load-bearing one.
* At the old 0.022 x 0.027 the extended board takes the lattice from 84,924
* points to 168,813 — 2.02x — and the terrain with it, against a mobile
* budget with 70,000 triangles spare and two more layers landing on the same
* board in the same round. The 1.42x coarsening is the entire reason the
* extension fits, and it is one edit away from being silently reverted by
* somebody who thinks a finer lattice is always better.
*/
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import CALIFORNIA, { CORRIDOR_LAND } from "../../cities/california.ts";
import { World, computeField } from "../../engine/world.ts";
/** Metres in a degree of latitude. The same constant `World` uses. */
const M_PER_DEGREE = 111_320;
describe("the board reaches the whole state", () => {
it("contains the corners the old bounds cut off", () => {
const { bounds } = CALIFORNIA;
// Crescent City is at 41.75 N; the Oregon line is at 42.00. A board that
// stops short of 41.9 has cut off Del Norte County and the redwoods.
assert.ok(bounds.maxLat > 41.9, `maxLat is ${bounds.maxLat}`);
// Cape Mendocino is the westernmost ground in California at -124.41, and it
// is the corner that makes the northern silhouette read as this state.
assert.ok(bounds.minLng < -124.3, `minLng is ${bounds.minLng}`);
// And the three edges that were already right stayed right.
assert.ok(bounds.minLat <= 32.55, `minLat is ${bounds.minLat}`);
assert.ok(bounds.maxLng >= -114.0, `maxLng is ${bounds.maxLng}`);
});
it("centres scene space on the middle of the bounds", () => {
// Everything sized from the origin — the satellite dome, the shadow box, the
// star field — is centred with it, so a centre left where it was when the
// board was smaller makes all three too small on the far side by the offset.
const { bounds, center } = CALIFORNIA;
const midLat = (bounds.minLat + bounds.maxLat) / 2;
const midLng = (bounds.minLng + bounds.maxLng) / 2;
assert.ok(Math.abs(center.lat - midLat) < 0.2, `centre is ${center.lat}, middle is ${midLat}`);
assert.ok(Math.abs(center.lng - midLng) < 0.4, `centre is ${center.lng}, middle is ${midLng}`);
});
it("has a traced North Coast rather than a wider empty ocean", () => {
const north = CORRIDOR_LAND.filter(([lat]) => lat > 40.0);
assert.ok(
north.length >= 20,
`only ${north.length} vertices north of 40 N — the added land is a shelf, not a coast`,
);
// The cape itself, because it is the one vertex whose absence changes the
// silhouette rather than the detail: without it the North Coast is a
// straight line from Trinidad to Shelter Cove.
assert.ok(
CORRIDOR_LAND.some(([lat, lng]) => lat > 40.3 && lat < 40.6 && lng < -124.35),
"Cape Mendocino is not in the trace",
);
});
it("puts real ground under the new land, north and north-east", () => {
const world = new World(CALIFORNIA);
for (const [name, lat, lng] of [
["Crescent City", 41.75, -124.18],
["Eureka", 40.8, -124.16],
["Redding", 40.58, -122.39],
["Sacramento", 38.58, -121.49],
["Mount Shasta", 41.41, -122.19],
["Alturas, in Modoc", 41.49, -120.54],
] as [string, number, number][]) {
assert.equal(world.isLand(lat, lng), true, `${name} is not on the board`);
}
// And the two edges that are new: Oregon is not California, and neither is
// the Great Basin east of the 120th meridian.
assert.equal(world.isLand(42.3, -122.5), false, "Oregon is on the board");
assert.equal(world.isLand(41.0, -119.5), false, "Nevada is on the board");
});
it("stands Shasta and Lassen up as the two things that make the north the north", () => {
const world = new World(CALIFORNIA);
world.lattice();
assert.ok(
world.elevationAt(41.409, -122.194) > 3_800,
`Shasta is only ${Math.round(world.elevationAt(41.409, -122.194))} m`,
);
assert.ok(
world.elevationAt(40.488, -121.505) > 2_600,
`Lassen is only ${Math.round(world.elevationAt(40.488, -121.505))} m`,
);
// The gap between them is as much of the picture as the peaks. Hat Creek
// country sits around 1,000 m and must not be filled in by either skirt.
assert.ok(world.elevationAt(40.95, -121.5) < 2_200, "the Cascade gap has been filled in");
// And the Sacramento Valley is a floor, not a range: farmland at tens of
// metres, which is what makes the ranges either side of it read as ranges.
for (const [lat, lng] of [[39.5, -121.95], [39.0, -121.75], [40.2, -122.1]] as const) {
const floor = world.elevationAt(lat, lng);
assert.ok(floor < 300, `the Sacramento Valley at ${lat}N is ${Math.round(floor)} m`);
assert.ok(floor > 3, `the Sacramento Valley at ${lat}N is at the beach colour`);
}
});
});
describe("the cell is what paid for the extension", () => {
it("holds the ground cell between 3.3 and 3.7 kilometres", () => {
const metres = CALIFORNIA.cellLat * M_PER_DEGREE;
assert.ok(
metres > 3_300 && metres < 3_700,
`the cell is ${Math.round(metres)} m. Below 3,300 the lattice doubles and the ` +
"terrain goes through the mobile budget; above 3,700 the Sierra stops " +
"reading as a range.",
);
// Longitude is squashed by cos(centre latitude), so an equal-area cell has to
// be 1/cos as wide as it is tall. Both axes were multiplied by the same 1.42.
const squash = Math.cos((CALIFORNIA.center.lat * Math.PI) / 180);
const ratio = CALIFORNIA.cellLng / CALIFORNIA.cellLat;
assert.ok(
Math.abs(ratio - 1 / squash) < 0.06,
`the cell is ${ratio.toFixed(3)} as wide as it is tall; 1/cos(${CALIFORNIA.center.lat}) ` +
`is ${(1 / squash).toFixed(3)}, so the ground cell is not square`,
);
});
it("holds the lattice where it was on a board a third bigger", () => {
const field = computeField(new World(CALIFORNIA));
const points = (field.latSteps + 1) * (field.lngSteps + 1);
// 84,924 was the measured figure on the board that stopped at 38.05, and the
// whole argument of the coarsening is that this number does not move. A 5%
// band, because it is a rounding of two axis lengths and not a target.
assert.ok(
points > 80_000 && points < 89_200,
`the lattice is ${points} points against 84,924 on the smaller board`,
);
});
it("keeps the cell finer in the frame than the board two revisions ago", () => {
/**
* The claim the coarsening rests on, asserted rather than argued.
*
* What the eye sees is not the cell in metres — it is the cell as a fraction
* of the board, because the camera retreats to frame whatever it is given.
* The corridor board before it grew east was 0.020° on 284 units, which is
* 0.0041 of a span; the board that stopped at 38.05 was 0.022° on 428, or
* 0.0030. This board must land between them, which means the cell got 42%
* coarser on the earth and *finer* in the frame than the board two revisions
* ago.
*/
const world = new World(CALIFORNIA);
const [westX, northZ] = world.project(CALIFORNIA.bounds.maxLat, CALIFORNIA.bounds.minLng);
const [eastX, southZ] = world.project(CALIFORNIA.bounds.minLat, CALIFORNIA.bounds.maxLng);
const span = Math.max(Math.abs(eastX - westX), Math.abs(southZ - northZ));
const cellUnits = CALIFORNIA.cellLat * CALIFORNIA.latScale;
const fraction = cellUnits / span;
assert.ok(
fraction < 0.0041,
`the cell is ${fraction.toFixed(4)} of the board span, coarser in frame than ` +
"the 0.0041 of the board before the state's eastern edge arrived",
);
assert.ok(
fraction > 0.0025,
`the cell is ${fraction.toFixed(4)} of the board span, which is finer than the ` +
"board has ever needed and is being paid for in terrain triangles",
);
});
});
+378
View File
@@ -0,0 +1,378 @@
/**
* San Pedro Bay as the SoCal pack authors it — the assertions that keep a quay
* on land and a breakwater the right length.
*
* Every coordinate in `socal.ts` is hand-traced by house rule (ARCHITECTURE
* §3.2), which means it is eyeball-accurate and there is no authority to check
* it against. What there *is* is a set of relationships that have to hold, and a
* hand-traced number that breaks one of them is a typo rather than a judgement
* call. This file is those relationships:
*
* - **A quay is on land.** Every vertex of every quay polygon lies inside a
* landmass. This is the assertion the whole re-trace of Terminal Island exists
* to satisfy: with the old six-point hexagon a quay could be on the water or
* buried in the fill, and nothing would have said so.
* - **A berth is on its quay.** Within 200 m of a quay edge, which at 391 m to
* the scene unit is half a scene unit — close enough that a hull placed there
* is alongside rather than parked in the yard or moored in the fairway.
* - **The breakwater is thirteen kilometres.** Between twelve and fifteen, and
* it comes out 13.06 against a real federal breakwater of 13.07.
* - **Nothing is placed from `ports.sqlite`.** All seven rows of that table sit
* on an exact arc-minute grid; a coordinate here that lands on one is a
* coordinate somebody copied out of it, and it is up to 1,852 m from the water
* it claims. This is the cheapest possible guard against the single most
* likely way this data goes wrong later.
* - **The bridges still land.** Re-tracing Terminal Island moved every shoreline
* the Vincent Thomas and the Long Beach Gateway touch, and a bridge whose
* abutment ends up over open water fails silently — it just looks slightly
* wrong from one angle.
*/
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { metresBetween, yardCorners } from "../../engine/ports.ts";
import SOCAL_CITY, {
LONG_BEACH,
LOS_ANGELES,
PORTS,
TERMINAL_ISLAND,
VINCENT_THOMAS,
LONG_BEACH_GATEWAY,
} from "../../cities/socal.ts";
import { World } from "../../engine/world.ts";
import type { LatLng, Quay } from "../../engine/types.ts";
const world = new World(SOCAL_CITY);
function onLand(point: LatLng): boolean {
return world.pointInAny(point[0], point[1], SOCAL_CITY.landmasses);
}
/** Shortest distance from a point to a polygon's boundary, in metres. */
function metresToEdge(point: LatLng, polygon: readonly LatLng[]): number {
let best = Infinity;
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
const from = polygon[j];
const to = polygon[i];
if (!from || !to) continue;
const length = metresBetween(from, to);
if (length === 0) {
best = Math.min(best, metresBetween(point, from));
continue;
}
// Project onto the segment in a local metres frame; at this size the earth
// is flat enough that the error is centimetres.
const scaleLng = Math.cos((point[0] * Math.PI) / 180);
const ax = (from[1] - point[1]) * scaleLng;
const ay = from[0] - point[0];
const bx = (to[1] - point[1]) * scaleLng;
const by = to[0] - point[0];
const dx = bx - ax;
const dy = by - ay;
const square = dx * dx + dy * dy;
const t = square === 0 ? 0 : Math.max(0, Math.min(1, -(ax * dx + ay * dy) / square));
const nearest = Math.hypot(ax + t * dx, ay + t * dy);
best = Math.min(best, nearest * 111_320);
}
return best;
}
const quays: { port: string; quay: Quay }[] = PORTS.flatMap((port) =>
(port.quays ?? []).map((quay) => ({ port: port.id, quay })),
);
describe("the pack declares two ports and the engine can find them", () => {
it("hangs them off the city", () => {
assert.equal(SOCAL_CITY.ports, PORTS);
assert.deepEqual(
PORTS.map((port) => port.id),
["USLAX", "USLGB"],
);
});
it("keeps every port record JSON-serialisable", () => {
// A pack is posted to the terrain Worker as a structured clone. One method
// on one port record and the whole board stops booting.
assert.doesNotThrow(() => structuredClone(PORTS));
assert.deepEqual(JSON.parse(JSON.stringify(PORTS)), JSON.parse(JSON.stringify(PORTS)));
});
});
describe("nothing is placed from ports.sqlite", () => {
it("puts no port anchor on an exact arc-minute", () => {
// Every row of the upstream table has lat*60 and lon*60 whole. One arc-minute
// here is 1,852 m of latitude — 4.7 scene units — from the water.
for (const port of PORTS) {
const latMinutes = port.lat * 60;
const lngMinutes = port.lng * 60;
const onGrid =
Math.abs(latMinutes - Math.round(latMinutes)) < 1e-6 &&
Math.abs(lngMinutes - Math.round(lngMinutes)) < 1e-6;
assert.equal(onGrid, false, `${port.id} sits on the arc-minute grid — that is a WPI row`);
}
});
it("puts no quay vertex, berth or crane rail on an exact arc-minute either", () => {
const suspects: LatLng[] = [
...quays.flatMap(({ quay }) => quay.polygon),
...PORTS.flatMap((port) => (port.berths ?? []).map((berth): LatLng => [berth.lat, berth.lng])),
...PORTS.flatMap((port) => (port.cranes ?? []).flatMap((crane) => [crane.from, crane.to])),
];
assert.ok(suspects.length > 30);
for (const [lat, lng] of suspects) {
const onGrid =
Math.abs(lat * 60 - Math.round(lat * 60)) < 1e-6 &&
Math.abs(lng * 60 - Math.round(lng * 60)) < 1e-6;
assert.equal(onGrid, false, `${lat}, ${lng} is on the arc-minute grid`);
}
});
});
describe("quays are on land and berths are on quays", () => {
it("puts every quay vertex inside a landmass", () => {
assert.ok(quays.length >= 6);
for (const { port, quay } of quays) {
for (const vertex of quay.polygon) {
assert.ok(
onLand(vertex),
`${port}/${quay.id} vertex ${vertex.join(", ")} is on open water`,
);
}
}
});
it("puts every berth anchor within 200 m of its quay", () => {
const byId = new Map(quays.map(({ quay }) => [quay.id, quay]));
let checked = 0;
for (const port of PORTS) {
for (const berth of port.berths ?? []) {
const quay = berth.quayId ? byId.get(berth.quayId) : undefined;
assert.ok(quay, `${berth.id} names quay ${berth.quayId}, which does not exist`);
const distance = metresToEdge([berth.lat, berth.lng], quay.polygon);
assert.ok(distance < 200, `${berth.id} is ${Math.round(distance)} m from its quay`);
checked += 1;
}
}
assert.equal(checked, 15, "San Pedro Bay is authored with fifteen berths");
});
it("puts every berth just off the wall rather than on top of it", () => {
// A hull whose anchor is inside the quay polygon is a hull parked in the
// yard. The berth is the water beside the wall, not the wall.
for (const port of PORTS) {
for (const berth of port.berths ?? []) {
assert.equal(
onLand([berth.lat, berth.lng]),
false,
`${berth.id} is inside the landmass — it should be alongside, not ashore`,
);
}
}
});
it("puts every yard corner on land", () => {
for (const port of PORTS) {
for (const yard of port.yards ?? []) {
for (const corner of yardCorners(yard)) {
assert.ok(
onLand(corner),
`${port.id}/${yard.id} corner ${corner.map((n) => n.toFixed(4)).join(", ")} is on water`,
);
}
}
}
});
it("puts every crane rail on the quay it serves", () => {
for (const port of PORTS) {
for (const crane of port.cranes ?? []) {
for (const end of [crane.from, crane.to]) {
assert.ok(onLand(end), `${port.id}/${crane.id} rail end ${end.join(", ")} is on water`);
}
}
}
});
});
describe("the breakwater", () => {
it("is between twelve and fifteen kilometres, in three arms", () => {
const arms = LOS_ANGELES.breakwater ?? [];
assert.equal(arms.length, 3, "San Pedro, Middle and Long Beach");
let total = 0;
for (const arm of arms) {
for (let i = 1; i < arm.length; i += 1) total += metresBetween(arm[i - 1]!, arm[i]!);
}
assert.ok(total > 12_000 && total < 15_000, `${Math.round(total)} m`);
});
it("leaves Angels Gate and Queens Gate open", () => {
const arms = LOS_ANGELES.breakwater ?? [];
const angels = metresBetween(arms[0]!.at(-1)!, arms[1]![0]!);
const queens = metresBetween(arms[1]!.at(-1)!, arms[2]![0]!);
// Both real gates are between five hundred and a thousand metres wide, and a
// harbour whose arms meet is a lagoon.
assert.ok(angels > 400 && angels < 1_200, `Angels Gate ${Math.round(angels)} m`);
assert.ok(queens > 400 && queens < 1_200, `Queens Gate ${Math.round(queens)} m`);
});
it("lies in open water for its whole length", () => {
for (const arm of LOS_ANGELES.breakwater ?? []) {
for (const point of arm) {
assert.equal(onLand(point), false, `breakwater point ${point.join(", ")} is inland`);
}
}
});
it("belongs to the coastal-breakwater harbour and is drawn once", () => {
// `harbor_type` is CB for both San Pedro ports and CN for Oakland. The arms
// are one federal structure: declaring them on both would double the
// geometry for an identical picture, and giving them to a CN harbour would
// be inventing the largest object on its waterfront.
for (const port of PORTS) {
if (port.breakwater) assert.equal(port.harborType, "CB", `${port.id} is not a CB harbour`);
}
assert.equal(LONG_BEACH.breakwater, undefined);
});
});
describe("the dredged channels stay in the water", () => {
it("keeps every channel vertex off both landmasses", () => {
for (const port of PORTS) {
for (const point of port.channel ?? []) {
assert.equal(onLand(point), false, `${port.id} channel point ${point.join(", ")} is inland`);
}
}
});
});
describe("Terminal Island still carries the two bridges", () => {
const island = TERMINAL_ISLAND;
it("lands the Vincent Thomas on the island and San Pedro on the mainland", () => {
const path = VINCENT_THOMAS.path;
const mainland = path[0]!;
const islandEnd = path.at(-1)!;
assert.equal(world.pointInPolygon(islandEnd[0], islandEnd[1], island), true);
assert.equal(world.pointInPolygon(mainland[0], mainland[1], island), false);
assert.equal(onLand(mainland), true);
});
it("lands the Long Beach Gateway on the island and Long Beach on the mainland", () => {
const path = LONG_BEACH_GATEWAY.path;
const islandEnd = path[0]!;
const mainland = path.at(-1)!;
assert.equal(world.pointInPolygon(islandEnd[0], islandEnd[1], island), true);
assert.equal(world.pointInPolygon(mainland[0], mainland[1], island), false);
});
it("carries the comb of slips rather than a hexagon", () => {
// The point of the re-trace. Six points cannot express a basin; this outline
// has the West Basin, the East Basin, Fish Harbor and the Pier 400 causeway
// in it, and every one of them shows up as a reversal in the north-south
// walk along the north shore.
assert.ok(island.length >= 24, `${island.length} points`);
const north = island.filter(([lat]) => lat > 33.755);
let reversals = 0;
for (let i = 2; i < north.length; i += 1) {
const a = north[i - 2]![0];
const b = north[i - 1]![0];
const c = north[i]![0];
if (Math.sign(b - a) !== Math.sign(c - b)) reversals += 1;
}
assert.ok(reversals >= 3, `the north shore has ${reversals} basin walls cut into it`);
});
it("does not overlap the mainland", () => {
// The Main Channel and the Back Channel are the two pieces of water this
// board cannot afford to lose: an island fused to the shore has no harbour
// in it at all.
const mainland = SOCAL_CITY.landmasses[0]!;
for (const point of island) {
assert.equal(
world.pointInPolygon(point[0], point[1], mainland),
false,
`${point.join(", ")} is inside the mainland`,
);
}
});
it("keeps the port off the district lattice", () => {
// The Harbour chapter's whole failure was that Terminal Island sat inside
// the San Pedro and Long Beach district polygons, so the busiest container
// terminal in the hemisphere came out as generic industrial blocks. No
// district may claim a quay.
for (const { port, quay } of quays) {
for (const vertex of quay.polygon) {
for (const district of SOCAL_CITY.districts) {
assert.equal(
world.pointInPolygon(vertex[0], vertex[1], district.polygon),
false,
`${port}/${quay.id} is inside district ${district.id}; blocks.ts will build on it`,
);
}
}
}
});
});
describe("the empty-box figures are the ones that were measured", () => {
it("leads Los Angeles with July 2026 and says which month it is", () => {
const throughput = LOS_ANGELES.throughput;
assert.ok(throughput);
assert.equal(throughput.asOf, "2026-07");
const exported = throughput.loadedExport + throughput.emptyExport;
assert.equal(exported, 460_467);
assert.equal(throughput.emptyExport, 348_691);
const share = throughput.emptyExport / exported;
assert.ok(Math.abs(share - 0.757) < 0.001, `${(share * 100).toFixed(1)}%`);
});
it("draws that share in the yards rather than only writing it in a caption", () => {
for (const yard of LOS_ANGELES.yards ?? []) {
// The rail yard is the deliberate exception; see the next assertion.
if (yard.id === "rail-yard") continue;
assert.equal(yard.emptyShare, 0.757);
}
for (const yard of LONG_BEACH.yards ?? []) assert.equal(yard.emptyShare, 0.765);
});
it("leaves the one yard nobody counts without a share, rather than guessing one", () => {
// `emptyShare` absent means unknown, and `yardAtlas` paints an unknown yard
// in one flat colour. That difference is visible on the board, which is the
// point: a measured number and an unmeasured one must not look alike.
const rail = (LOS_ANGELES.yards ?? []).find((yard) => yard.id === "rail-yard");
assert.ok(rail);
assert.equal(rail.emptyShare, undefined);
assert.equal("emptyShare" in rail, false);
});
it("carries the freight pair that explains it, and no timestamp on it", () => {
const rates = LOS_ANGELES.rates ?? [];
assert.deepEqual(
rates.map((rate) => [rate.id, rate.usdPerFeu]),
[
["FBX01", 7_491],
["FBX02", 347],
],
);
// `observed_at` upstream is our own read clock; Freightos publishes none.
for (const rate of rates) assert.equal("asOf" in rate, false);
});
it("gives Long Beach no half-written throughput record", () => {
// Its export split is known — 341,806 empty against 104,843 loaded — and its
// import halves were never read. `PortThroughput` requires all four, and two
// real numbers beside two invented ones is the failure the fire layer nearly
// shipped. No record beats half a record.
assert.equal(LONG_BEACH.throughput, undefined);
});
it("puts the split in the Harbour chapter, which is the card the page shows", () => {
const chapter = SOCAL_CITY.chapters.find((one) => one.id === "harbour");
assert.ok(chapter);
assert.match(chapter.description, /348,691 of 460,467/);
assert.match(chapter.description, /\$7,491/);
assert.match(chapter.description, /\$347/);
});
});