Files
tera/README.md
Karti Tripathi 36471bbad7 Tera, because Simulate was already spoken for
Two names in this repo were quietly colliding with things that already ship.

`lumbridge-simulate` is a Rust crate in the private monorepo — the Governor's
memory-admission simulator, with a public product page — and in its vocabulary
a "Scene" is a set of models, not a three.js scene. Naming a 3D engine the same
thing would have put two different meanings on both words at once.

Meanwhile world1.lumbridgecorp.com has been serving <title>Tera — Lumbridge</title>
since before any of this: the world already had a name.

So the map view is Tera, the interiors product is Spaces, an Office is one
building's interior and a Space is a room inside it. ARCHITECTURE.md opens with
that table now, because the next few thousand lines all depend on it.

The Phaser 2D world comes down rather than being migrated. Its tileset is
precisely what stopped it being open-sourceable, and there are no real users to
strand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 22:09:44 -07:00

89 lines
2.9 KiB
Markdown

# Tera
The map view of **Lumbridge Simulate** — cities from above, in three.js.
Its other half, **Spaces**, is the offices you walk into: one engine and one
asset library, seen from outside and from inside.
Apache 2.0. Runs at [tera.lumbridgecorp.com](https://tera.lumbridgecorp.com).
![San Francisco](docs/sf.jpg)
---
## What it is
An engine plus data packs. The engine renders terrain, coastline, a built city
on real street grids, bridges, roads, markers and air traffic. A *city pack* is
pure data — coastlines, hills, districts, landmarks, camera chapters — so adding
a city is a data contribution anyone can review, not a fork.
San Francisco ships today. Los Angeles / Orange County / Riverside is next; New
York after that.
## Quick start
```bash
npm install
npm run dev
```
## Using the engine
```ts
import { createScene } from "@lumbridge/tera/engine/scene.ts";
import SAN_FRANCISCO from "@lumbridge/tera/cities/sf.ts";
const scene = createScene(canvas, {
city: SAN_FRANCISCO,
markerPalette: { hiring: 0x4ade80, closed: 0xef4444 },
});
scene.setMarkers([
{ id: "1", lat: 37.7765, lng: -122.4241, label: "Somewhere", colorKey: "hiring" },
]);
```
The engine renders `Marker[]` and looks colours up by `colorKey` in a palette
you supply. It does not know what your markers *mean* — that mapping lives in
your adapter. This is what lets one renderer serve a private map coloured by
one scheme and a public map coloured by another, without either being a fork.
## Adding a city
Write `src/cities/<id>.ts` exporting a `City`. Trace the coastline and parks by
hand, place hills as radial peaks, and give each district its street bearing.
Two rules, and they are not stylistic:
- **Do not import geometry from OpenStreetMap.** OSM and Nominatim output is
ODbL — share-alike, and incompatible with this repo's licence.
- **Do not commit logos or brand assets.** They are trademarks, not code.
See [ARCHITECTURE.md](ARCHITECTURE.md) §3 for the full reasoning, and
[NOTICE](NOTICE) for the attribution and data-provenance statement.
## Aircraft
The engine takes a `FlightSource`. Two ship here: `SimulatedFlights` (original,
flies real approach and departure corridors) and `AdsbFlights` (open community
ADS-B feeds such as adsb.lol).
FlightRadar24 is deliberately absent — their terms forbid scraping and forbid
redistributing their data, so a client for it cannot live in an Apache-2.0
repository. Commercial sources belong in private deployments. The best long-term
answer is an RTL-SDR receiver: first-party data with nothing to comply with.
## Layout
```
src/engine/ renderer — terrain, blocks, structures, markers, flights, scene
src/cities/ data packs — pure geography, no code
src/adapters/ where outside data plugs in
```
`engine` never imports `cities`; neither imports `adapters`.
## Licence
Apache License 2.0 — see [LICENSE](LICENSE) and [NOTICE](NOTICE).