44c5a79424
Six agents in parallel, and the two city packs independently reported the same blocker: `focusRegions` and `coarseFactor` existed on the `City` type and nothing implemented them. Uniform lattices would have been 2.9M points for Southern California and 3.7M for the expanded bay. Both packs were unloadable as written. `buildAxis` is the answer, and it is honest about its limits: refinement is per axis, not per rectangle, so a focus region sharpens its whole row *and* its whole column. Two regions at opposite corners refine nearly everything between them. Measured, not guessed — the bay went 0.53M points with one region and 1.64M with three, for detail nobody is looking at from a board this wide. One region each, coarse factor ten, and the builds land at 3.8 s and 2.3 s. Then three things that were only ever right because San Francisco was the only city. `maxDistance: 340` and a 170-unit shadow box were constants tuned for a 230-unit board; the bay is 1003 units across and the camera physically could not retreat far enough to frame it. Fog distances were scene units pinned to the same assumption. And `minVisibilityM` defaulted to 4.5 km of honest weather, which over ninety-four kilometres of bay correctly hides three quarters of it — the night view was a black rectangle for a completely reasonable reason. All three now derive from the board. The moon is a real ephemeris and its light is a deliberate lie: 1.15, against a physical ratio of one to four hundred thousand. What is being reproduced is what a moonlit night looks like on a screen in a lit room. The CI gate caught itself, which is the part worth keeping. Port 8431 was already held by a server from an earlier session, so the boot check polled a healthy stranger while the process it started died on EADDRINUSE. It now refuses to run rather than pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
78 lines
4.1 KiB
HTML
78 lines
4.1 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Lumbridge Simulate — San Francisco</title>
|
|
<style>
|
|
* { box-sizing: border-box; }
|
|
html, body { margin: 0; height: 100%; background: #d9e6ee; overflow: hidden;
|
|
font-family: ui-monospace, "SF Mono", Menlo, monospace; }
|
|
#scene { display: block; width: 100vw; height: 100vh; }
|
|
#panel { position: fixed; top: 0; left: 0; padding: 1rem; width: 19rem;
|
|
display: flex; flex-direction: column; gap: 0.25rem; pointer-events: none; }
|
|
#panel > * { pointer-events: auto; }
|
|
.card { background: rgba(8,12,16,0.55); backdrop-filter: blur(6px);
|
|
border-radius: 6px; padding: 0.75rem; color: rgba(255,255,255,0.72); font-size: 11px;
|
|
line-height: 1.5; }
|
|
h1 { margin: 0; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase;
|
|
color: #f2b134; }
|
|
h1 + p { margin: 0.15rem 0 0; color: rgba(255,255,255,0.55); }
|
|
#chapters { display: flex; flex-direction: column; gap: 1px; background: rgba(8,12,16,0.45);
|
|
backdrop-filter: blur(6px); border-radius: 6px; padding: 4px; }
|
|
.chapter { display: flex; align-items: baseline; gap: 0.5rem; padding: 0.4rem 0.5rem;
|
|
background: none; border: 0; border-radius: 4px; cursor: pointer; text-align: left;
|
|
font: inherit; font-size: 12px; color: rgba(255,255,255,0.7); }
|
|
.chapter:hover { background: rgba(255,255,255,0.09); }
|
|
.chapter.active { background: rgba(242,177,52,0.2); color: #ffd68a; }
|
|
.num { font-size: 10px; opacity: 0.6; font-variant-numeric: tabular-nums; }
|
|
#detail { position: fixed; right: 1rem; bottom: 2.5rem; }
|
|
#hint { position: fixed; right: 1rem; bottom: 1rem; font-size: 10px;
|
|
color: rgba(20,30,40,0.5); }
|
|
.clock { margin: 0.35rem 0 0; font-size: 10px; letter-spacing: 0.08em;
|
|
color: rgba(255,255,255,0.42); }
|
|
.enter { font: inherit; font-size: 12px; padding: 0.5rem 0.7rem; cursor: pointer;
|
|
text-align: left; border: 0; border-radius: 6px; color: #10161d;
|
|
background: #f2b134; font-weight: 600; }
|
|
.enter:hover { background: #ffc555; }
|
|
.scrub { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.45rem; }
|
|
.scrub input { flex: 1; accent-color: #f2b134; height: 14px; }
|
|
.cities { display: flex; gap: 3px; }
|
|
.city { flex: 1; font: inherit; font-size: 11px; padding: 0.35rem; cursor: pointer;
|
|
border: 0; border-radius: 5px; background: rgba(8,12,16,0.55); color: rgba(255,255,255,0.6);
|
|
backdrop-filter: blur(6px); }
|
|
.city:hover { background: rgba(255,255,255,0.14); }
|
|
.city.active { background: rgba(242,177,52,0.22); color: #ffd68a; }
|
|
.source { position: fixed; left: 1rem; bottom: 1rem; font-size: 10px;
|
|
color: rgba(255,255,255,0.4); background: rgba(8,12,16,0.5); padding: 0.25rem 0.5rem;
|
|
border-radius: 4px; backdrop-filter: blur(6px); }
|
|
.source.live { color: #7ee08a; }
|
|
.scrub button { font: inherit; font-size: 9px; text-transform: uppercase;
|
|
letter-spacing: 0.08em; padding: 0.15rem 0.35rem; cursor: pointer; border: 0;
|
|
border-radius: 3px; background: rgba(255,255,255,0.13); color: rgba(255,255,255,0.7); }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<canvas id="scene"></canvas>
|
|
<div id="panel">
|
|
<div class="card">
|
|
<h1 id="title">San Francisco</h1>
|
|
<p id="subtitle">Tera · Lumbridge Simulate</p>
|
|
<p id="clock" class="clock"></p>
|
|
<div class="scrub">
|
|
<input id="hour" type="range" min="0" max="23.9" step="0.1" value="12" />
|
|
<button id="now" title="follow the wall clock">now</button>
|
|
</div>
|
|
</div>
|
|
<nav id="cities" class="cities"></nav>
|
|
<button id="enter" class="enter">Enter the office →</button>
|
|
<nav id="chapters"></nav>
|
|
<p class="card" id="blurb"></p>
|
|
</div>
|
|
<div class="card" id="detail" hidden></div>
|
|
<p id="source" class="source"></p>
|
|
<p id="hint">drag to orbit · scroll to zoom</p>
|
|
<script type="module" src="/src/main.ts"></script>
|
|
</body>
|
|
</html>
|