Lumbridge Simulate Engine — the city, and the licence it can actually ship under

LSE is the third of the three, beside lumbridge-compute and lumbridge-bench: a
3D engine for walkable places. This first commit is the outside of the world —
San Francisco — plus the seams the inside will attach to.

The engine renders a City and a list of Markers and knows nothing else. It does
not know markers are usually companies and it will never learn that "rejected"
is red; that mapping lives in an adapter. Which is what lets one renderer serve
a private map, a public one, and a self-hoster with no Lumbridge account, none
of them a fork of the others.

Three things were designed around the licence rather than discovered after it,
because each one is a promise Apache 2.0 makes that is easy to break by
accident. No trademarks in the repo — logos are fetched at runtime, and
public/logos/ is gitignored. No OpenStreetMap-derived coordinates, which is why
every coastline in cities/sf.ts was traced by hand: Nominatim output is ODbL,
share-alike, and would attach to the whole pack. And no FlightRadar24 client —
their terms forbid scraping and redistribution, so flights are an interface
with a simulator and open community ADS-B behind it.

The privacy constraint and the licence constraint turned out to want the same
thing. Geocoded company positions and pipeline status both stay behind Workie's
API; the open repo holds the city and the renderer. The tempting shortcut —
commit an sf-companies.json — breaks both at once.

Ported out of Workie, where a 3D city engine had no business living. Workie's
/live is deleted rather than deprecated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Karti Tripathi
2026-08-04 21:49:08 -07:00
commit 67f8df8d53
20 changed files with 4789 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
<!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); }
</style>
</head>
<body>
<canvas id="scene"></canvas>
<div id="panel">
<div class="card">
<h1>San Francisco</h1>
<p>Lumbridge Simulate Engine</p>
</div>
<nav id="chapters"></nav>
<p class="card" id="blurb"></p>
</div>
<div class="card" id="detail" hidden></div>
<p id="hint">drag to orbit · scroll to zoom</p>
<script type="module" src="/src/main.ts"></script>
</body>
</html>