PRD-023 · /explore zoom-in detail layer — make planet focus a destination, not just a closeup
Status · Draft Date · 2026-06-03 Owner · Marko Closes into · GH issue #301, per-slice implementation issues Builds on · #287 (planet-relative camera + 4K LOD + natural satellites + atmospheric halos)
Why this is a PRD. Spans three subsystems: visual rendering (new 3D primitives + texture swaps + shader-ish overlays), data (fleet entries for active orbiters that aren't yet in
/fleet/orbiter/, plus new "active-around-planet" relations), and UX (decision matrix for what's "always-on detail" vs what's gated by the Science Lens vs what lives in the HUD/panel). One owner, one categorisation decision, one source of truth before per-feature slices start.
What
After #287 the user can fly into a planet, get the 4K texture + atmospheric halo + moons. The view is beautiful but passive — it shows a textured sphere with moons, nothing more. There's no reason to stay zoomed in.
This PRD locks the spec for turning the planet-focus pose into a destination with story-rich layers a user would actually explore:
- Always-on detail — physical features that are simply there (mission spacecraft orbiting, ring shadows, axial tilt, city lights). No toggle.
- Science Lens additions — conceptual physics overlays gated on the existing lens toggle (Hill sphere, Lagrange points, magnetic field, sub-solar point).
- HUD / info-panel additions — text + UI affordances (light-time, scale comparison, planet stats, prograde indicator).
The full set spans ~10 distinct features. This PRD groups them, picks the marquee 4 for the first slice, and surfaces the fleet-data implications.
The META decision
Where does each feature belong — zoom-in detail, Science Lens, or HUD?
The principle:
| Category | What belongs here | Why |
|---|---|---|
| Always-on detail | Things that exist in physical reality at the depicted moment | A user shouldn't have to toggle a layer to see that Jupiter has rings, that Mars has spacecraft around it, or that Earth has city lights. These are facts. |
| Science Lens | Conceptual physics that's invisible to the eye | Magnetic fields, Lagrange points, Hill spheres — you can't see these by looking at the planet. Lens makes the physics-of-the-system visible by user choice. |
| HUD / panel | Reference info, scale anchors, navigation cues | Light-time, gravity, "Earth diameter at this scale" — text + tiny UI affordances. Always-on text-y stuff, not 3D geometry. |
Each candidate feature classified below.
Categorised feature catalogue
Always-on zoom-in detail (Slice A)
These render on every planet at every zoom level below PLANET_LOD_IN_RATIO. No user toggle.
| # | Feature | Per-body specifics | Data needs |
|---|---|---|---|
| 1 | Active orbiters as 3D glyphs | Mars: MRO, MAVEN, Mars Express, ExoMars TGO, Hope, Mangalyaan, Tianwen-1. Jupiter: Juno. Saturn: (none active; historical Cassini ghost path). Venus: Akatsuki. Earth: ISS + Tiangong (already on /earth — link or render here too). | Per-orbiter altitude_km + inclination_deg in /fleet/orbiter/<id>.json. Today partial; need to backfill for missions that lack it. |
| 2 | Spin axis with obliquity tilt | Line through planet centre at real axial tilt. Earth 23°, Uranus 98°, Venus 177°. | axialTilt field in planets.json (already present). |
| 3 | Ring shadow on Saturn | Dark band across Saturn's cloud tops where rings occlude sunlight. Anti-solar projection of ring annulus onto sphere. | None — geometric only. |
| 4 | Galilean shadows on Jupiter | Real-time transit shadow dots for Io/Europa/Ganymede/Callisto on Jupiter's day side when geometrically possible. | None — projection of moon position onto planet surface. |
| 5 | Earth's night-side city lights | Swap to a city-lights texture on the night hemisphere. Standard astro-visualisation trick. | New 4k_earth_lights.jpg texture (NASA Black Marble, public domain). |
| 6 | Hero spacecraft trajectory | Per planet, one notable mission's path drawn as a fading arc. Voyager 2's outbound from Uranus / Neptune. Juno's polar plunge at Jupiter. Cassini grand-finale at Saturn. | Per-mission trajectory polylines — could derive from existing /fly cislunar data or hand-author short arcs per body. |
Marquee 4 for the first slice (highest visual-return per LOC):
- A1 — Active orbiters at Mars (5+ active missions, immediate "you're visiting" feel)
- A2 — Spin axis on Uranus (Uranus on its side is the single most "wait what" fact in the solar system)
- A3 — Saturn's ring shadow (the iconic photo, every Saturn render needs it)
- A4 — Earth's city lights (most viscerally "alive" detail, swaps a texture)
Remaining items (Galilean shadows, hero trajectories, other-planet orbiters) land in Slice C.
Science Lens additions (Slice B)
Toggled by the existing Science Lens button. Conceptual physics overlays that don't appear in nature.
| # | Feature | Description | Where the lens unlocks it |
|---|---|---|---|
| 7 | Magnetic field / radiation belts | Stylised teardrop shell around the planet showing magnetosphere shape. Jupiter's tail extends to Saturn's orbit. Earth Van Allen. | New lens layer magnetosphere |
| 8 | Hill sphere boundary | Translucent wireframe sphere at the gravity-dominance radius. The "you're in this planet's authority" volume. | New lens layer hill-sphere |
| 9 | Lagrange points L1–L5 | Five labeled markers around the orbit. L2 = JWST sits here. L4/L5 = Trojan asteroids. | New lens layer lagrange-points |
| 10 | Sub-solar point + terminator emphasis | Pulsing dot at planet's noon longitude + sharper day/night line. Anchors "the Sun is THAT way". | Currently the gravity arrows do this implicitly — promote to its own layer? |
Marquee 2 for Slice B:
- B1 — Hill sphere (universal, simple geometry, sci-fi-rich)
- B2 — Lagrange points (educational, scientifically real, photogenic markers)
Remaining items (magnetic field, sub-solar point) land in Slice D.
HUD / panel additions (Slice E — polish)
Always-on text + UI. No 3D geometry.
| # | Feature | Description |
|---|---|---|
| 11 | Light-time + distance HUD | "5.2 AU · 43 light-minutes from Sun" overlay near the panel header. |
| 12 | Earth silhouette comparison | Faint Earth-radius ghost sphere in viewport corner. Instant "Jupiter is 11× Earth" read. |
| 13 | Compass rose / prograde indicator | Tiny widget on the planet's orbit showing prograde direction + spin direction. |
| 14 | Planet stats overlay | Floating semitransparent labels — GRAVITY, ATMOSPHERIC PRESSURE, ROTATION PERIOD — sci-fi "tactical scan" feel. |
Slice order
Slice A — Marquee 4 always-on detail (orbiters at Mars + Uranus tilt + Saturn ring shadow + Earth city lights)
Slice B — Marquee 2 lens overlays (Hill sphere + Lagrange points)
Slice C — Remaining always-on detail (Galilean shadows + hero trajectories + other-planet orbiters)
Slice D — Remaining lens overlays (magnetic field + sub-solar point)
Slice E — HUD polish (light-time + Earth-comparison + compass + stats overlay)Each slice ships as its own commit + e2e check. /explore baseline e2e regression suite stays green throughout.
Data implications — fleet additions
Active orbiters that need fleet entries (or backfill of altitude_km + inclination_deg) for Slice A's rendering:
| Planet | Mission | In /fleet/orbiter/? | Notes |
|---|---|---|---|
| Mars | MRO | yes (mro.json) | Verify altitude_km/inclination_deg present |
| Mars | MAVEN | check | If missing, add |
| Mars | Mars Express | yes (mars-express.json) | Verify orbit params |
| Mars | ExoMars TGO | check | If missing, add |
| Mars | Hope (EMM) | check | If missing, add (UAE — flags "global space programs" memory) |
| Mars | Mangalyaan | yes (mangalyaan.json) | Verify orbit params |
| Mars | Tianwen-1 | check | China; verify present |
| Jupiter | Juno | yes (juno.json) | Verify orbit params |
| Venus | Akatsuki | check | If missing, add (JAXA) |
| Earth | ISS, Tiangong | yes (separate route) | Cross-link only |
The "global space programs" memory applies: ensure CNSA / ISRO / JAXA / Roscosmos / UAESA orbiters are present alongside NASA's, not silently dropped.
Out of scope
- Real-time spacecraft positions — pinned orbits are fine for v1; live ephemerides are a separate initiative.
- Surface-route changes — /earth /moon /mars stay independent. /explore zoom-in is the only route touched.
- Heliocentric view — wide zoom unchanged. Only the planet-focus pose (below
PLANET_LOD_IN_RATIO) gets the new layers. - i18n strings for the new HUD labels — Slice E ships en-US; locale propagation is a separate slice once strings stabilise.
Risks + open questions
- Crowding. Each layer adds visual weight. The previous Jupiter-focus screenshot was already busy with moons + halo + arrows. Need a clear visibility hierarchy. → Mitigation: per-slice screenshots in PR descriptions; user-pref toggles in Slice E if needed.
- Fleet-data debt. Backfilling orbital params for the missing orbiters is real work — Akatsuki, Hope, MAVEN, ExoMars TGO need accurate altitude + inclination. → Slice A spec includes the data audit as Step 0.
- Decision: do magnetic field + sub-solar lens layers belong in Slice D, or do they actually belong in Slice A? Reasonable counter-argument: magnetic field is a physical thing that exists (Earth's aurora is the visible proof). → Keep in lens for v1; revisit after Slice A ships and we see how busy the focus view feels.
Done definition
- Slices A + B shipped (marquee 4 always-on + marquee 2 lens)
- /explore e2e regression suite green
- /fleet has entries for every orbiter rendered as a 3D glyph in Slice A
- Each planet's zoom-in shows ≥ 1 new layer (orbiter, ring shadow, axial tilt, city lights, hero arc) beyond #287's baseline
- Slices C-E filed as discrete follow-up issues with concrete scope (not "phase 2" hand-waves)