feat: the crane grows a mast, the harbour works a shift, and the site is re-shot
**The Asset Factory verdict, and it mostly went against the vote.** Nine candidates were thumbed up. One was taken. TOOK the STS crane. Rebuilt in `ports.ts` from 5 unit boxes to 11 — an A-frame mast and apex cap, a forestay to the boom, a backstay to the tail, a sill, the truck-lane portal beam, a machinery house — still exactly ONE InstancedMesh. What was missing is the thing that makes a gantry a gantry: on a real STS the tallest part of a WORKING crane is the A-frame apex, not the boom, and a parked raised boom clears its own apex by only 15-25%. Before, 56 gantries read from altitude as 56 crosses — two coincident verticals with one bar through them and nothing above it — so a berth flattened into a picket fence. Proportions came from both upvoted candidates agreeing independently (hinge ~58 m under an apex at 99-104 m), taken conservatively because Tera's packs already author an 82 m hinge against a real 55-60. The apex beacon came across as EMISSION: `craneLights()` returns bare positions, `nightlights.ts` turns them into one additive Points cloud, 56 points, one draw call, night only, no THREE.Light anywhere. 0.09 units was invisible against the port's own cream emissive; 0.17 — half a bridge head light — is right, and the screenshot at 0.09 is what condemned it. REJECTED all three bridges, city-lights and both aircraft: the incumbents won on the picture, decisively for the bridge. TWO PARTS WERE BUILT FROM THE APPROVED CANDIDATES, PHOTOGRAPHED, AND CUT. Four legs: 14 m of quay spacing is 0.036 units at 391 m/unit against a 0.032 member floor, so 90% overlap. A portal X-brace: the bay is 0.115 wide by 0.38 tall, so both diagonals come out near-vertical and add a lump at mid-leg. Both are among the best things about the factory cranes AT THE FACTORY'S FRAMING. Neither survives at board scale. That gap is the whole reason a factory asset is reference geometry and not a drop-in. Fixed a defect the rebuild exposed: the backreach started a full rail-gauge behind the hinge, leaving a gap over the portal with the beam floating below it. One unbroken girder now. And every inclined member goes through a `strut()` that takes two points in the (distance-along-boom, height) plane, so the vertical-exaggeration bug the module header warns about is no longer reachable — it needs a length and an angle, and there is now no way to start from those. **The harbour works a shift.** It was a frozen tableau: 19 hulls placed from the pack's berths that never changed. Vessels now arrive through the channel, are met by a tug, berth, work and depart — seeded, so two people see the same harbour and a capture script shoots the same frame twice. A ship loses its wake when it ties up, because the wake is the information. **Every still and film re-shot.** The site was showing a Tera that no longer existed — SHOTS_COMMITb7f5c41, FILMS_COMMIT2aa4049, against an engine that has since gained fires, the whole state, ports, ships and night infrastructure. Two frames were bad and are fixed by moving the hour, not by retouching: `bay-relief-day` and `peninsula-day` were white lids of marine layer. Four captions described a Tera that no longer existed and are rewritten to the delivered frame. `california-relief-night` is measurably brighter than the frame it replaces (canvas mean 7.91 -> 10.57) despite the state being 30% larger. Ten budget cells pass, run twice. socal 1,422,025 -> 1,429,993 triangles against 1,700,000, 218 draws against 320. The measured delta is double the geometry because the crane mesh casts shadow, so renderer.info counts it in both passes — worth knowing before anyone reads that number as geometry. Tests 1,540 -> 1,570, server 295. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,13 +8,11 @@ in an issue, not here.
|
||||
`src/cities/california.ts` now runs 32.50–42.05 N and -124.50 to -114.0 W. Four
|
||||
things fall out of it that somebody has to pick up.
|
||||
|
||||
- **The marketing stills are frames of a board that no longer exists.** Every
|
||||
`city: "california"` shot in `scripts/brand-assets/shots.mjs` was photographed
|
||||
at 428 units across with a ruled crop along 38.05 N. Re-shoot with
|
||||
`npm run refresh`. The `chapter` indices are all still correct — the north
|
||||
chapter was added at the **end**, index 5, precisely so nothing re-points — but
|
||||
`california-relief`'s caption says "428 units across at 1,919 metres to the
|
||||
unit" and that number is now 554. The caption is the only edit needed.
|
||||
- ~~**The marketing stills are frames of a board that no longer exists.**~~
|
||||
**Done 2026-08-23.** All 21 shots and all four films were re-shot at `e7a8aa0`
|
||||
plus this round's uncommitted work; `california-relief`'s caption now says 554
|
||||
units and names the north. See "The imagery was re-shot" below for what that
|
||||
run found, and for the two manifests that are still waiting on a clean sha.
|
||||
- **`scripts/performance-budget.mjs`'s header comment is now stale in one row.**
|
||||
It records `california/mobile` at 389,843 triangles; the extended board
|
||||
measures 373,825. The caps in `performance-budgets.json` were rewritten
|
||||
@@ -277,55 +275,194 @@ on a bridge frame.** On the deck the lamp run, both tower silhouettes and the re
|
||||
light over each tower head all read clearly at 21:35, where at 20:50 there was no
|
||||
light on the structure anywhere.
|
||||
|
||||
## Re-shoot the time-lapse films
|
||||
## The imagery was re-shot on 2026-08-23 — what that run found
|
||||
|
||||
All 38 product stills were re-shot on 2026-08-22 against the night-infrastructure
|
||||
work, so the manifest records `SHOTS_COMMIT b7f5c41` with **`SHOTS_DIRTY true`** —
|
||||
that tree was not committed when the shutter opened, and the manifest says so
|
||||
rather than naming a commit that would render something else. Re-run
|
||||
`shots.mjs --manifest-only` once it is committed. The two **share cards** were not
|
||||
re-shot and did not need to be: `capture.mjs` shoots both at 11:20 and 17:30, so
|
||||
nothing that changed after dark is in them. **The films were not** — they were
|
||||
last shot on 2026-08-07 at `9c9e78f`. `films.ts` in lumbridge-v4 records the tera
|
||||
commit each reel was shot at, so a stale reel is visually stale and no caption edit
|
||||
fixes it — check that commit against tera HEAD before assuming a reel is current.
|
||||
`npm run refresh` at `e7a8aa0` + this round's uncommitted work: **21 shots x 2
|
||||
frames**, both share cards, all four films, both manifests. Every run printed
|
||||
`ANGLE (AMD, Vulkan … Radeon RX 6700 XT (RADV NAVI22))` and not SwiftShader; no
|
||||
chapter guard and no `play` guard fired. Timings on this box, for budgeting:
|
||||
build 7 s, stills 545 s, cards 26 s, films 416 s.
|
||||
|
||||
What the reels predate: ACES tone mapping and the runtime PMREM environment rig; a
|
||||
sea that reflects, with a swell normal map, Fresnel and sun glitter, in place of a
|
||||
flat `MeshLambertMaterial` that had no specular term at all; a world-space sky dome
|
||||
replacing the screen-space gradient, which at dusk painted the sunset band along the
|
||||
*bottom* of the picture, under the board; terrain that casts shadows; a California
|
||||
board with the Basin and Range, Death Valley, the Salton Sea and San Diego on it;
|
||||
SFO, LAX, both bridges and a freeway that reads as a road; aircraft that move,
|
||||
carrying registration and type; a rebuilt LA studio; the studio device hardware; and
|
||||
a new UI chrome with a first-run flow.
|
||||
**Both manifests are dirty and that is the one thing still owed.**
|
||||
`SHOTS_COMMIT` and `FILMS_COMMIT` are `e7a8aa0` with `SHOTS_DIRTY` /
|
||||
`FILMS_DIRTY` **true**, because the tree was not committed when the shutter
|
||||
opened — the port, vessel and night-light work of this round is in every frame
|
||||
and in no commit. That is the manifests being honest rather than naming a sha
|
||||
that would render something else. Once tera is committed:
|
||||
|
||||
```sh
|
||||
npm run refresh -- --films-only --rough # rough cut first: ~20 s a reel, and it is
|
||||
# the cheapest way to find out a camera is
|
||||
# pointed at the wrong thing
|
||||
npm run refresh -- --films-only # ~90 s per 180-frame film on the Radeon
|
||||
node scripts/brand-assets/shots.mjs --manifest-only # no browser, no render
|
||||
node scripts/brand-assets/films.mjs --manifest-only
|
||||
```
|
||||
|
||||
Worth knowing before starting (the rest is in `~/.claude/skills/tera-capture`):
|
||||
then commit lumbridge-v4 and deploy it.
|
||||
|
||||
- Check the run prints the Radeon and not SwiftShader. The software path is ~15x
|
||||
slower — 22 minutes a film rather than 90 seconds — and it reports success.
|
||||
- `hero-soma` is a different animal: `chrome: "bare"`, midnight to midnight, and a
|
||||
two-stage encode (a CRF 18 master, then 1440w CRF 28 and 960w CRF 30 delivered).
|
||||
- **The hero camera is worth reconsidering.** Whole-board was tried and rejected
|
||||
because the edge of the terrain plate showed against the sky. That seam no longer
|
||||
exists: the sea now runs eighteen board spans and ends past the fog's far plane.
|
||||
- After tuning the hero, run `npm run check:hero` in lumbridge-v4.
|
||||
- `#onboarding-host` is in `FURNITURE.CLUTTER` now, and `#mode-dock` and
|
||||
`#play-hud` are in `FURNITURE.BARE`. Every *new* overlay has to be added to one
|
||||
of those two lists on the day it lands, because a frame with a stray card in it
|
||||
still renders and still looks deliberate. The mode dock proved it: it shipped
|
||||
inside the tera share card for a fortnight and nobody noticed.
|
||||
- **The two capture scripts both serve on port 5210.** Two of them at once is
|
||||
`EADDRINUSE` a minute into a run, so do not start a film while a stills pass is
|
||||
going — or give one of them `--site`-style isolation first.
|
||||
- Commit tera first, then re-run, so the manifest records a clean sha.
|
||||
### Two new shots, and one of them needs a page
|
||||
|
||||
- **`harbour`** — socal chapter 5, aimed at 33.7405/-118.2565 broadside across
|
||||
Terminal Island. Four crane rails at four bearings, the container yards, hulls
|
||||
alongside and one under way, the Vincent Thomas across the Main Channel, and at
|
||||
night a red obstruction light on every gantry apex.
|
||||
- **`california-fire`** — the state board with the fire feed behind it. See the
|
||||
section below; it is the only frame here that is not the keyless experience.
|
||||
|
||||
Both are in `shots.ts` and both are delivered as WebP. **Neither is on a page.**
|
||||
Every one of the other nineteen ids is named explicitly by something in
|
||||
`lumbridge-v4/apps/web/src`, so a new shot appears in the manifest and nowhere
|
||||
else until somebody places it. That is a handoff, not a defect.
|
||||
|
||||
### The fire feed is photographable now, from a fixture
|
||||
|
||||
`drawsFire()` gates the whole layer on `access.feeds?.fires === true`, which
|
||||
comes from `/health`. A keyless capture — which is every other frame here — can
|
||||
therefore not photograph fire at all, while `tera.lumbridgecorp.com` answers
|
||||
`"fires":"cloud1"` and every anonymous visitor to the deployed site does get it.
|
||||
The site was about to ship an imagery set in which the most visible thing the
|
||||
engine gained this round did not exist.
|
||||
|
||||
`shots.mjs` now has `serveFeed()` and a per-shot `feed` field. It fulfils exactly
|
||||
two routes and 404s the rest of `/api/v1`, and the body is
|
||||
`scripts/brand-assets/fires-2026-08-23.json` — the verbatim response from the
|
||||
live feed on 23 August 2026, kept whole. **Do not trim that file.** `promote()`
|
||||
counts the rows it refuses and the panel prints that number, so a fixture with
|
||||
the refused rows deleted would draw the same eight fires under a sentence
|
||||
claiming a gate that never ran.
|
||||
|
||||
Three consequences worth knowing before extending this:
|
||||
|
||||
- the synthetic `/health` says `auth.mode: "none"`, which resolves the visitor to
|
||||
`member` and keeps **`#tier-adds`** out of the frame. That card is the sign-in
|
||||
offer, it is shown only to `anon`, and it is **not** in `FURNITURE.CLUTTER` —
|
||||
so the day this pipeline meets a real API it will arrive in the art silently,
|
||||
exactly the way `#mode-dock` did;
|
||||
- `california-fire` is the only shot clocked to **2026-08-23** rather than
|
||||
2026-08-06, because the panel prints the body's own `fetchedAt` and how long
|
||||
ago that was. A fixture from the 23rd photographed on the 6th reads "fetched
|
||||
2026-08-23 · just now";
|
||||
- the hot-pixel layer draws every FIRMS detection inside `bounds`, and `bounds`
|
||||
is a lat/lng **rectangle**. On the state board that puts a handful of cyan
|
||||
points over open water and over Baja in the night frame. They are real
|
||||
detections and the rectangle is the honest gate the layer has; it is worth
|
||||
deciding whether a board wants a land test before the count in the panel is
|
||||
ever quoted as a California number.
|
||||
|
||||
### The marine layer decided two of the day frames, and it should decide any more
|
||||
|
||||
`atmosphere.ts` models the Pacific marine layer on **apparent solar** time, and
|
||||
the curve is 0.95 before dawn, 0.6 at nine, 0.2 at eleven, 0.4 again by four. Two
|
||||
shots were on 09:10 and 09:20 — a little after eight solar, where the layer is at
|
||||
about three quarters — and at a whole-board or 32 km standoff that is not weather
|
||||
in the picture, it is a white lid over the entire subject. `bay-relief`'s caption
|
||||
is about eighty-three named hills and four octaves of value noise, none of which
|
||||
was visible; `peninsula`'s is about twenty miles of city, likewise.
|
||||
|
||||
Both moved to the late afternoon (17:00 and 17:10) and both frames are now
|
||||
legible. The compromise is forced: the layer is thinnest at solar 11-14, which is
|
||||
**12:07-15:07 on a wristwatch here** — the exact hours a heightfield has no
|
||||
shadow. Around five is thin enough to see the ground and low enough that the
|
||||
ranges still throw.
|
||||
|
||||
**Any future wide day frame on the Bay board has this constraint.** Close and low
|
||||
poses do not — `fidi` at 10:10 and `crow-nav` at 09:20 are both clear, because
|
||||
the camera is under the deck.
|
||||
|
||||
⚠️ **A 1x `--preview` does not predict the cloud in the 2x delivery.** The deck
|
||||
animates on elapsed time and the two runs have different settles (3000 ms against
|
||||
6000), so the puffs land somewhere else. Framing, pose and light all preview
|
||||
faithfully; cloud does not. Judge cloud on the delivered frame, which is how
|
||||
`peninsula`'s note lost a sentence about SFO that was true of the preview and not
|
||||
of the render.
|
||||
|
||||
### Four captions had been falsified by engine changes, and nothing catches that
|
||||
|
||||
A caption is prose next to a camera pose. When the engine moves under it, the
|
||||
frame still renders, still looks deliberate, and still ships. All four of these
|
||||
were found by opening the delivered frame and reading its own note back:
|
||||
|
||||
- **`california-flight` day** ended "and the Pacific past the wingtip". Aerial
|
||||
perspective now follows camera altitude, so at 1,413 m the ocean is inside the
|
||||
haze rather than beyond it and there is no sea in the frame at all.
|
||||
- **`california-flight` night** promised "the basin's lit ground in the corner"
|
||||
and "the moon's path broken across the water". The frame is over dark coastal
|
||||
mountains: no basin, no water. What actually carries it is the aircraft's own
|
||||
navigation lights and the corridor's road markings.
|
||||
- **`lax` day** said "the traffic overhead is the real traffic: registration and
|
||||
type come off the same feed". **It cannot be.** Every frame but
|
||||
`california-fire` is shot keyless, so `TrafficSource` is the bundled simulator
|
||||
and not ADS-B. A caption may not borrow a fact from a deployment the shutter
|
||||
never opened on — and this is the failure mode to watch for now that one shot
|
||||
*does* have a server.
|
||||
- **`golden-gate` day** said the towers "throw along the deck". They throw across
|
||||
the water beside it, which is checkable and was checked.
|
||||
|
||||
### `fidi-day`'s day poster had drifted onto the wrong renderer
|
||||
|
||||
`poster: 0.86` was chosen as "a few minutes before sunset: the last of the low
|
||||
sun down the length of Montgomery". On ACES with the world-space sky dome, 0.86
|
||||
is 20:09 with the sun at **+0.4°** and the towers are unlit silhouettes — the
|
||||
frame measured mean luminance **33** out of 255 against the night poster's 21.
|
||||
That is not a pair, and it matters more than a poster usually would: `Film` ships
|
||||
`preload="none"`, so the poster is what most readers see for most of the time the
|
||||
film is on their screen. Now `0.76` — twenty past six, sun twenty degrees up,
|
||||
towers lit and throwing, mean **87**.
|
||||
|
||||
The other three films' posters were checked the same way and are fine
|
||||
(147/24, 106/21, 155/46 day against night). **Check a poster pair by measuring
|
||||
both, not by reading the clock**: the fractions were all chosen on an older
|
||||
renderer and this is the one that had moved.
|
||||
|
||||
### Smaller things the re-shoot turned up and did not fix
|
||||
|
||||
- **`freeway` and `drive-101` are nearly the same photograph.** Both are the
|
||||
chase camera on the 101 chapter at 09:00; the only difference is where on the
|
||||
leg they land — 47% against 57%. `freeway` gets there with `settle: 3000`,
|
||||
which is the duration-not-position trap `drive-101` exists to document. It has
|
||||
landed on 47% on two consecutive runs, so it is reproducible in practice on
|
||||
this box, but it is a duration and it is measured from boot. It cannot simply
|
||||
be given a `play` block: the 101 chapter is *already* in drive mode, and
|
||||
`enterPlay` clicks the dock button, which would toggle it off.
|
||||
- **`office-desks` slices the hardware card.** The panel is taller than the
|
||||
viewport, so `Desk speaker`'s controls are below the fold and its header sits
|
||||
on the frame edge. That is the exact condition `shot.hide` was invented for,
|
||||
and it cannot be used here because the hardware *is* the subject.
|
||||
- **`#sky-section` stays in the product stills, deliberately.** It prints "No
|
||||
radar feed is configured … that is a fact about this box, not about the sky"
|
||||
twice, which reads like a hole — but `tera.lumbridgecorp.com` answers
|
||||
`"radar":"none"` and `"birds":"none"` today, so a real visitor sees the same two
|
||||
sentences. It is not the `#tier` case (local disagreeing with deployed); it is
|
||||
the product's own voice. **If either feed is ever wired, this decision has to be
|
||||
taken again**, because then the local frame and the site would disagree.
|
||||
- **`#sea-section` stays too**, and it is the one that earns it: the harbour is
|
||||
modelled identically here and on the deployed site, and its sentence is what
|
||||
keeps a frame full of ships honest about their being modelled rather than
|
||||
observed.
|
||||
- **`PROVENANCE.json`'s two card records now name a date they were not made on.**
|
||||
`refresh.mjs` re-stamps the share cards narrowly — it substitutes the `sha256`
|
||||
in the text and nothing else, which is what keeps that diff two lines instead
|
||||
of a reflow — so `intakeDate` still reads `2026-08-22` for files written on the
|
||||
23rd. `check-provenance` only validates the format, so nothing catches it. It
|
||||
is one line in the one document whose entire job is accuracy.
|
||||
|
||||
## The vessel layer has two gaps that belong to other files
|
||||
|
||||
Both stated in code comments already; recorded here so they are not only there.
|
||||
|
||||
- **Pier 300 and the East Basin take no port calls.** The straight run from the
|
||||
nearest point on `Port.channel` to those berths is 1.9 km and 2.9 km and
|
||||
crosses Terminal Island, so `BERTH_APPROACH_REACH_METRES` (1100) gates them out
|
||||
and they keep a static hull alongside rather than driving a container ship over
|
||||
a container yard. The proper fix is an optional per-berth approach path on
|
||||
`Berth` — `approach?: LatLng[]`, water-side first — which `socal.ts` could then
|
||||
author for Pier 300 as the real route out through Angels Gate and north-east
|
||||
across the outer harbour. `harbourCalls` would prefer it to the nearest-point
|
||||
projection; about ten lines once the field exists. The field is on
|
||||
`src/engine/types.ts`, which the vessel work did not own.
|
||||
- **The tug's own solid is correct, cheap, and sub-pixel at every SoCal pose we
|
||||
ship.** Its payoff is banked for the Bay board and for closer poses rather than
|
||||
realised today.
|
||||
- `engine/nightlights.ts` now imports `craneLights` from `engine/ports.ts`. No
|
||||
cycle — `ports.ts` imports only three, terrain, types and world — but the two
|
||||
files are coupled and want moving, and re-photographing, together.
|
||||
|
||||
## The GPU on this box never leaves 500 MHz, and every frame-time number here is a floor
|
||||
|
||||
|
||||
Reference in New Issue
Block a user