Files
settled-reach/docs/design/planetary-screenshots-spec.md
T
jpmschweitzerandClaude Sonnet 4.6 1cffc83dd7 feat(assets): procedural planet renders for wiki/GTTR — #779
7 planet type PNGs (512×512px RGBA) covering all biome_summary values:
temperate, temperate_terminator, oceanic, arid, frozen, volcanic, barren.

Pure Python ray-sphere renderer (spikes/planet-renders/generate_planets.py)
— numpy/PIL only, no Godot dependency, ~2s for all 7 types. Seeded from
body_id for reproducibility. Resolves Q-064 (Godot 3D planet plugin
evaluation — superseded by headless Python approach).

Assets at client/assets/planets/, 512×512 RGBA, displayed at 240×240 in
the body-info-panel navigator and GTTR arrival window.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 08:19:06 +02:00

158 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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