---
id: world-map-and-portals/006
title: The two map surfaces — the public site page and the in-game screen
epic: world-map-and-portals
state: done
priority: 2
blocked_by: []
estimate: M
created: 2026-08-15
updated: 2026-08-18
claimed_by: null
claimed_at: null
delivers: []
review_artifact: site/src/pages/world.astro
---

## What landed

Both draw the same graph from the same endpoint, and both copy the approved design
(`Lor World Map Viewer.dc.html`).

- **The website — `/world`**, linked from the main nav. The site's **first runtime fetch**:
  every other page is build-time markdown, so this needed a visible loading state and an honest
  failure state ("the game server isn't answering" rather than an empty world, which would read
  as "Lor is empty"). Layer filter, pan/zoom, per-area detail panel listing the portals in and
  out with their cells and conditions.
- **In the game** — a native Control overlay in `game/world/client/ui/world_map_screen.gd`,
  opened from the accounts screen, following `account_screen.gd`'s structure exactly. 844x390,
  ball radii at half scale with a 22px floor so no tap target falls under 44px, chrome as
  floating pills, no editing affordances anywhere.
- Shared rules, all data-driven rather than hardcoded: radius from grid size, ring colour from
  the area type, fill from access, position from `map_x`/`map_y` with unplaced areas in a row
  along the bottom, nested areas drawn inside their parent on a dotted hairline, solid lines
  public and pink dashed private, one-way gets an arrowhead, criteria get a midpoint dot, and
  the layer switch **filters** — geometry never moves.
- `_shots.gd` renders the in-game screen from sample data, so the drawing can be checked
  without a running server.

## Deliberately left

Clustering above ~20 areas is specified in Handoff 2. With nine seeded areas there is nothing
to cluster and no way to test it, so the expanded case is built and clustering is a marked
follow-up rather than untested speculative code.