aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md86
1 files changed, 86 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e387080
--- /dev/null
+++ b/README.md
@@ -0,0 +1,86 @@
+# worldmap-viewer
+
+A 3D globe in the browser for worlds built with [worldgen](../worldgen): fly from orbit down to ground level, inspect
+every value, measure, pin places, refine regions to ≈ 5 km detail, and export terrain squares for game engines.
+Runs locally (binds 127.0.0.1 only); three.js is vendored.
+
+## Setup
+
+Clone next to worldgen (or set `WORLDGEN=/path/to/worldgen`, or put it inside this folder as `worldgen/`):
+
+```
+games/
+ worldgen/ the generator
+ worldmap-viewer/ this
+ myworld/ a world folder (config/, sketch/, out/ …)
+```
+
+```bash
+python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
+.venv/bin/python serve.py --world ../myworld # open http://127.0.0.1:8765 — Ctrl-C stops it
+```
+
+Build the world first (`worldgen/mapgen.py build`). The first start after a build prepares caches (a minute or more
+at res 5); later starts are quick. Tiles render on demand and are cached in the world's `out/`.
+
+## Commands
+
+| Command | What |
+|---|---|
+| `serve.py [--world DIR …] [--res N] [--port 8765] [--lore DIR] [--workers N] [--public [--allow-host NAME] [--bind ADDR]] [--tile-cache-gb GB [--tile-keep-z Z]] [--max-renders N]` | the viewer. `--lore`: a folder of `<id>.md` notes pins may link to. Several `--world`: one server, each world at `/w/<id>/` (id from `[render] name`), a world menu switches; `--res` then applies to all. `--workers N`: render processes (default CPUs − 2, max 6). `--public`: read-only map for anyone — no writes; pins, regions, exports and lore ids are not served, the page hides those tabs; tiles are sent `immutable` (their URL carries the version). `--allow-host NAME`: also answer requests for that public name (a reverse proxy or tunnel on the same machine passes it on); `--bind ADDR` (default 127.0.0.1; another address, e.g. 0.0.0.0 in a container behind a proxy, needs `--public`). `--tile-cache-gb GB`: cap on saved tiles (all worlds); past it the least recently used go (down to 90 %); `--tile-keep-z Z` keeps relief and mesh tiles to zoom Z (a shipped prerender) out of it. `--max-renders N`: at most N tiles rendering or waiting (all worlds), more get 503 + `Retry-After` and the page retries; `--public` defaults it to 4 × workers. Every option can also come from the environment (a container): `WORLDMAP_<OPTION>`, e.g. `WORLDMAP_TILE_CACHE_GB=140`, `WORLDMAP_PUBLIC=1`; repeatable ones as a list (`WORLDMAP_ALLOW_HOST=a.org,b.org`); a command-line flag wins |
+| `mapview.py [--world DIR] refine [--final]` | refine all regions in `places/regions.json` (usually done from the viewer) |
+| `mapview.py export --lat .. --lon .. [--size-km 40] [--res-m 10] [--pixels N] [--name ..] [--era ..]` | heightmap + masks for a game engine |
+| `mapview.py seafloor-preview --region <id>` | image of a refined region's sea floor |
+
+## Using it
+
+- **Globe / Equal Earth / Plate carrée** views; layer menu (relief, elevation, temperature, rainfall, biomes, ground,
+ ores, plates, sea floor, gravity, O₂, …) with a second layer blended **over** it.
+- **Era** menu (if eras.toml has eras). **Overlays**: coasts, lakes, rivers, graticule, regions, pins.
+- Zoom to ground level: **3D** terrain (exaggeration slider), right-drag / Shift+drag to tilt and turn, **N** resets,
+ **👁** ground view. **?** lists all controls.
+- **Inspector**: click any point for every value there. **Measure**: distances, areas, elevation profile.
+- **Pins**: named markers (stored in `places/pins.json`). Search box: pins, `40N 10W`, H3 cell ids.
+- **☀ Sky**: sun position for any day and time; tropics and polar circles.
+- **Regions**: draw an outline, *Save and refine* → real ≈ 5 km erosion, rivers, lakes and biomes in that area
+ (background job; seconds to minutes). Stored in `places/regions.json`. Very large regions take much RAM.
+- **Export**: cut a terrain square (heightmap .f32/.png/.r16, water, biome masks, rivers, pins) into `exports/` for
+ Unity / Godot / Unreal. Each export has a `README.txt` with import settings.
+- The link button copies a URL with the exact view.
+
+The first start after a build prepares caches (a minute or more at res 5); later starts are quick. Tiles render on
+demand and are cached in `out/`.
+
+Public server (container, read-only, copied worlds): `deploy/README.md` (`deploy.py bundle` / `dedupe`, `deploy/Containerfile`).
+
+Low memory: `serve.py --low-memory` / `mapview.py --low-memory …` (or `WORLDGEN_LOW_MEMORY=1`) builds those caches with
+each field written to disk as soon as it is ready (a `.spill-*` folder, removed afterwards) instead of all fields in
+RAM: a slower first start, a lower peak (≈ −40 % for the refined-area cache), the same arrays.
+
+Optional in-world units: `[units]` in world.toml with `span_m`, `league_km`, `moment_s` adds spans/leagues next to
+metres/kilometres, and the sky panel counts moments instead of hours:minutes.
+
+## Files
+
+```
+serve.py server viewer/ browser app (js/, tests/, tools/smoke.sh)
+tiles.py servecache.py refine.py rivers.py seafloor.py export.py mapview.py
+worldgen_path.py finds worldgen
+tests/ python -m unittest discover -s tests -t . · cd viewer && node --test tests/*.test.mjs
+```
+
+## Troubleshooting
+
+- `worldgen not found` → clone it next to this folder or set `WORLDGEN`.
+- Server says no build → build the world first (or pass `--res` to pick one).
+- Port in use → `--port 8766`.
+
+## Licence and credits
+
+MIT, see [LICENSE](LICENSE). Third-party notices: [licenses.md](licenses.md). Credits: [CREDITS.md](CREDITS.md).
+
+## From the author
+
+These projects are things that have been tumbling about in my head for a long time, and I now feel like trying to do something with. The bulk of my focus here is on some of the games that I love, but every time I boot them up, I just fiddle about in the menu and set up mods and fixes for a couple hours, with my drive to play them fizzling out. This is my hope to solve that, and while I am a professional software engineer this would not have happened were it not for the rise of (relatively) cheap AI that could do the bulk of the work with me. If you don't approve, that's fine. I did these things for me, sharing them is something I do in the hopes to help others in similar situations, that just want to play the games they love. Thank you to all that made these playable in the first place, with some luck this finds you, and can bring some joy.
+
+Written with AI assistance (Claude, by Anthropic), used as an engineering tool.