--- title: "Planetary Screenshot Spec — v0.1" description: "Procedural planet sphere renders for the GTTR body-info-panel and wiki pages. One image per biome_summary type." type: design status: active ticket: "#779" decision_refs: [] author: "Araminta" created: 2026-04-05 updated: 2026-04-05 --- # Planetary Screenshot Spec — v0.1 **Ticket:** #779 **Author:** Araminta **Date:** 2026-04-05 **Status:** Active — assets delivered, awaiting client integration --- ## Display Context Planet screenshots appear in the **body-info-panel** navigator (wireframe: `docs/design/wireframes/navigator/body-info-panel.json`): | Property | Value | |----------|-------| | Container | `planet-screenshot` — 360×360px, `#111820` background | | Sphere display | 240×240px ellipse within the container | | Z-context | Implant fullscreen (z=20), not gameplay layer | | Background | `#0d1117` (navigator panel) | In the **GTTR arrival window** (diegetic implant display during transit), the same asset appears with the same proportions — one image per destination planet. --- ## Asset Inventory **Location:** `client/assets/planets/` **Format:** PNG, 512×512px, RGBA **Display:** Scaled to 240×240 within a 360×360 container | File | `biome_summary` value | Character | |------|-----------------------|-----------| | `planet_temperate.png` | `temperate` | Blue ocean, amber-green continents, cloud cover, polar caps | | `planet_temperate_terminator.png` | `temperate_terminator` | Half gold-scorched day face, half frozen dark face, sharp terminator | | `planet_oceanic.png` | `oceanic` | Deep blue water world, heavy cloud, scattered archipelago | | `planet_arid.png` | `arid` | Warm reddish-brown, dusty, sparse thin polar caps | | `planet_frozen.png` | `frozen` | White-blue ice, exposed grey rock at mid-latitudes | | `planet_volcanic.png` | `volcanic` | Dark basalt, orange lava cloud patterns | | `planet_barren.png` | `barren` | Cratered grey-brown, no atmosphere glow | --- ## Generation Pipeline **Script:** `spikes/planet-renders/generate_planets.py` ```bash # Regenerate all types python3 spikes/planet-renders/generate_planets.py # Single type python3 spikes/planet-renders/generate_planets.py --type temperate # Custom output location python3 spikes/planet-renders/generate_planets.py --output-dir path/to/dir ``` **Dependencies:** `numpy`, `Pillow` (already in requirements) **Technique:** Numpy ray-sphere intersection + Lambertian diffuse + specular + procedural octave-sine texture. Runs without GPU. ~2s for all 7 types. ### Lighting rig | Property | Value | |----------|-------| | Star direction (from surface) | (-0.55, 0.45, 0.70) normalized | | Ambient | 0.22 (dark side is dim, not black) | | Diffuse | 0.78 | | Specular | 0.30 (modest glint) | | Atmosphere rim glow | Blue-white, (1-rim)^5 × 0.7 | ### Texture approach Procedural octave sine noise — no external noise library required. UV coordinates from spherical mapping (lon, lat). Each planet type uses different: - `seed` (shifts continent/feature pattern) - `octaves` (detail level) - `threshold` (land/ocean boundary) - Color palette (per type) --- ## Binding to Atlas Data Each planet in `systems.db` has a `biome_summary` field. The client selects the matching planet image: ```gdscript func planet_image_for_biome(biome: String) -> Texture2D: var path = "res://assets/planets/planet_%s.png" % biome if ResourceLoader.exists(path): return load(path) return load("res://assets/planets/planet_barren.png") # fallback ``` For `biome_summary = "temperate_terminator"`, the image maps directly to `planet_temperate_terminator.png`. --- ## Coverage | `biome_summary` value | Image | Inhabited planets using this type | |-----------------------|-------|------------------------------------| | `temperate` | ✓ | Majority of wave_1/wave_2 inhabited worlds | | `temperate_terminator` | ✓ | Close-orbit M-dwarf worlds (Feldmark, Caparica) | | `oceanic` | ✓ | Aquaculture worlds | | `arid` | ✓ | Mars-analog, dry inner worlds | | `frozen` | ✓ | Outer habitable zone, cold worlds | | `volcanic` | ✓ | Young volcanic, active worlds | | `barren` | ✓ | Airless rocky bodies, uninhabited | | `gas_giant` | — | Not needed (gas giants not inhabited, no panel) | --- ## Visual Grammar Notes All planet renders are consistent with the implant UI aesthetic: - **Background:** `#04060a` space (near-black, matches `#0d1117` panel) - **Star field:** Sparse white dots, random but seeded (reproducible) - **Atmosphere rim:** Blue-white glow on all worlds with atmosphere — signals habitability/breathability at a glance - **Terminator worlds:** Gold/dark split communicates the concept without labels - **Barren worlds:** No rim glow — instantly reads as airless The renders are deliberately non-photorealistic. They're what the player's implant processes during transit — a data-layer visualization, not a photograph. --- ## Future Additions When new `biome_summary` types are added to the atlas schema, add a new renderer function to `generate_planets.py` following the existing pattern. The functions are self-contained — no cross-dependencies. Potential additions as the Reach fills out: - `jungle` — dense green, high cloud, equatorial band - `desert` (distinct from `arid` — hotter, brighter orange) - `swamp` — dark green-brown - `gas_giant_banded` — for the implant wiki page of orbital gas giants