feat(visual): planet generator pipeline + HUD icons #117

Closed
jpmschweitzer wants to merge 0 commits from sprint-32/visual into main
Owner

Summary

  • Planet generator pipeline (tooling/planet-gen/) — procedural terrain simulation with Whittaker biome classification, equirectangular heightmap (4096×2048) + globe (512×512) rendering from wiki system data
  • Batch runner with error handling, resume support, atomic writes, determinism verification, and 50% error rate circuit breaker
  • Per-body wiki pages with YAML frontmatter at wiki/star-systems/*/bodies/*/index.md — body definition serves as both data source and wiki page
  • Externalized config — all biome colors, classification tables, and rendering parameters in biomes.toml
  • Implant HUD icons — 13 SVGs per D-086 (stance, status, interaction, inventory)
  • Ran system (GJ-144) generated as proof: 10 bodies with heightmaps, globe renders, and geographic markers
  • Tickets #816 (remove Qdrant) and #817 (batch generation) created

Supports all body types: temperate, arid, frozen, volcanic, barren, oceanic, gas giant (banded + ringed), and moons (half-size, grey, cratered).

Pipeline

wiki/star-systems/*/index.md → scaffold_bodies.py → per-body index.md (frontmatter)
                                                          ↓
                              generate.py ← reads frontmatter → simulate → render
                                                          ↓
                              wiki/star-systems/*/bodies/*/
                                  heightmap.png, globe.png, markers.json, terrain.npz

Test plan

  • tooling/planet-gen/batch --system GJ-144 --force — 10 bodies, 0 errors
  • tooling/planet-gen/batch --system GJ-144 --dry-run — all 10 valid
  • tooling/planet-gen/batch --system GJ-144 --verify-determinism 2 — 2/2 passed
  • Resume: re-run without --force skips all 10
  • ruff check tooling/ — 0 warnings
  • Full batch: tooling/planet-gen/batch across all 301 systems (run by PO)

🤖 Generated with Claude Code

## Summary - **Planet generator pipeline** (`tooling/planet-gen/`) — procedural terrain simulation with Whittaker biome classification, equirectangular heightmap (4096×2048) + globe (512×512) rendering from wiki system data - **Batch runner** with error handling, resume support, atomic writes, determinism verification, and 50% error rate circuit breaker - **Per-body wiki pages** with YAML frontmatter at `wiki/star-systems/*/bodies/*/index.md` — body definition serves as both data source and wiki page - **Externalized config** — all biome colors, classification tables, and rendering parameters in `biomes.toml` - **Implant HUD icons** — 13 SVGs per D-086 (stance, status, interaction, inventory) - **Ran system (GJ-144)** generated as proof: 10 bodies with heightmaps, globe renders, and geographic markers - Tickets #816 (remove Qdrant) and #817 (batch generation) created Supports all body types: temperate, arid, frozen, volcanic, barren, oceanic, gas giant (banded + ringed), and moons (half-size, grey, cratered). ## Pipeline ``` wiki/star-systems/*/index.md → scaffold_bodies.py → per-body index.md (frontmatter) ↓ generate.py ← reads frontmatter → simulate → render ↓ wiki/star-systems/*/bodies/*/ heightmap.png, globe.png, markers.json, terrain.npz ``` ## Test plan - [x] `tooling/planet-gen/batch --system GJ-144 --force` — 10 bodies, 0 errors - [x] `tooling/planet-gen/batch --system GJ-144 --dry-run` — all 10 valid - [x] `tooling/planet-gen/batch --system GJ-144 --verify-determinism 2` — 2/2 passed - [x] Resume: re-run without --force skips all 10 - [x] ruff check tooling/ — 0 warnings - [ ] Full batch: `tooling/planet-gen/batch` across all 301 systems (run by PO) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer added 11 commits 2026-04-06 16:02:04 +02:00
13 SVG icons covering stance indicators (walk/careful/sprint/crouch),
status badges (health, perception), interaction prompts (talk/observe/
follow/examine), and inventory silhouettes (manifest, access token,
comm log).

All D-086 compliant: 1px stroke, #c8d0e0 chrome, round linecaps,
minimal anchor points, no icon fonts, runtime-replaceable via
ShaderMaterial. Sizes: 20×20 (stance/status), 16×16 (actions),
40×40 (inventory). Unblocks client #787.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Validates full heightmap pipeline: pyplatec tectonics → erosion →
dynamic sea level → terrain classification (13 classes) → D8 river
network → settlement placement → geographic PNG + settlement JSON.

Key technical decisions:
- Dynamic sea level via np.percentile (pyplatec output is right-skewed;
  fixed fraction gives ~0.2% land, not 40%)
- Terrain classes as fractions of land_range (not fixed offsets)
- Two-layer model: geographic PNG + human-layer JSON sidecar
- Rivers painted AFTER LANCZOS upscale via NEAREST neighbor mask
  (painting before blurs rivers into invisibility)
- grain_belt removed — reclassified as grassland (natural terrain)
- Irrigation overlay removed — human activity, lives in JSON sidecar

Output: 4096×2048px (1024×512 simulation grid, 5.2s total runtime).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Health icon: replaced overlapping outlined rects (railroad crossing
effect) with a single solid polygon path. Careful stance: redesigned
from diagonal-arm to horizontal T-shape for clear differentiation
from walk at 20px.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
scipy 1.17.1 and Pillow 12.2.0 — both CVE-audited clean against
NVD + OSV (2026-04-06). Required by planet generator pipeline.
Gitignore generated terrain.npz, spike intermediates, and tmp files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full terrain-to-render pipeline at tooling/planet-gen/:
- body_definition_parser: reads system index.md → body definitions
- planet_simulation: FBM + Voronoi ridges, Whittaker biome classification,
  D8 river routing, physics-driven craters (atmo × tectonics scaling)
- render_heightmap: 4096×2048 cartographic maps with hillshade
- planet_renderer: 512×512 globe with terrain UV mapping, clouds, rings
- biomes.toml: externalized color/classification tables (single source)
- scaffold_bodies: creates per-body index.md with YAML frontmatter
- batch: unattended processing with error handling, resume, determinism check

Supports all body types: temperate, arid, frozen, volcanic, barren,
oceanic, gas giant (banded + ringed), and moons (half-size, grey, cratered).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PO-built prototype (FBM terrain, Whittaker biomes, procedural globe)
with test body definitions for all planet types. Replaces pyplatec
approach. Spike validates the pipeline architecture for batch #817.

Includes handover doc, 9 test body definitions, and updated spike
pipeline documentation. Stale pyplatec outputs removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
First system through the planet generator pipeline. Per-body wiki
pages with YAML frontmatter at wiki/star-systems/GJ-144/bodies/.
Each body has: index.md (definition + profile), heightmap.png
(4096×2048), globe.png (512×512), and markers.json (rivers, oceans,
mountain ranges).

Bodies: GJ144b-g + moons. Includes temperate (Kallast, Vethis),
frozen, barren moons, and a ringed gas giant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unused imports (os, sys, math, ImageFilter, gaussian_filter,
MAX_BIOME_ID) flagged by ruff F401.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

Review: sprint-32/visual → main (type: visual)

Reviewers: Hoshe (QA), Araminta (art direction)


Hoshe (QA): REQUEST_CHANGES

Icons conform to D-086 throughout, planet renders consistent, GJ-144 body pages complete. Two high-severity issues:

# Sev File Issue
1 HIGH kallast_terrain.npy 2MB numpy array tracked in git. Gitignore added after commit. git rm --cached needed.
2 HIGH client/assets/icons/*.svg, planets/*.png No .import sidecars for 20 new Godot assets. Auto-import will generate mismatched UIDs.
3 Med icon-set-v01.md icon_tint.gdshader referenced but doesn't exist — undelivered forward reference.
4 Low planet_temperate_terminator.png Anomalously small file (71KB vs 120-157KB peers).
5 Low kallast.json vs GJ144d Spike uses different seed/distance than generated output — undocumented.
6 Low planet_simulation.py Possibly unused logging/math imports missed by ruff pass.

Araminta (Art Direction): REQUEST_CHANGES

Icons faithfully apply D-086 constraints, stance silhouettes distinct at 20px, diamond-eye vocabulary creates visual coherence. Two blockers:

# Sev File Issue
1 BLOCK decisions/perception.md D-086 scope amendment needed — stance icons delivered but D-086 says "deferred to v0.2."
2 BLOCK client/shaders/ Missing icon_tint.gdshader — icons can't be runtime-recolored. Open tracking ticket.
3 Minor GJ144g/index.md Profile table shows gas_giant but frontmatter has gas_giant_ringed.
4 Minor GJ144g-2/index.md atmosphere: none but atmosphere_color has values — should be null.
5 Minor Action icons 4 interaction icons not in D-086 vocabulary — need amendment or doc note.
6 Advisory PIPELINE.md Open questions (resolution, render mode, rivers, clouds) need ticketing before #794 batch.
7 Advisory icon_tint.gdshader ticket Shader must handle both fill and stroke replacement (health icon is fill-only).
8 Advisory icon-set-v01.md §4 Radial menu icons gap — open follow-on ticket.

Verdict: CHANGES REQUESTED

Deduplicated blockers (4): tracked .npy binary, missing .import sidecars, D-086 scope amendment for stance+action icons, shader ticket.

## Review: sprint-32/visual → main (type: visual) **Reviewers:** Hoshe (QA), Araminta (art direction) --- ### Hoshe (QA): REQUEST_CHANGES Icons conform to D-086 throughout, planet renders consistent, GJ-144 body pages complete. Two high-severity issues: | # | Sev | File | Issue | |---|-----|------|-------| | 1 | HIGH | `kallast_terrain.npy` | 2MB numpy array tracked in git. Gitignore added after commit. `git rm --cached` needed. | | 2 | HIGH | `client/assets/icons/*.svg`, `planets/*.png` | No .import sidecars for 20 new Godot assets. Auto-import will generate mismatched UIDs. | | 3 | Med | icon-set-v01.md | `icon_tint.gdshader` referenced but doesn't exist — undelivered forward reference. | | 4 | Low | planet_temperate_terminator.png | Anomalously small file (71KB vs 120-157KB peers). | | 5 | Low | kallast.json vs GJ144d | Spike uses different seed/distance than generated output — undocumented. | | 6 | Low | planet_simulation.py | Possibly unused `logging`/`math` imports missed by ruff pass. | ### Araminta (Art Direction): REQUEST_CHANGES Icons faithfully apply D-086 constraints, stance silhouettes distinct at 20px, diamond-eye vocabulary creates visual coherence. Two blockers: | # | Sev | File | Issue | |---|-----|------|-------| | 1 | BLOCK | decisions/perception.md | D-086 scope amendment needed — stance icons delivered but D-086 says "deferred to v0.2." | | 2 | BLOCK | client/shaders/ | Missing `icon_tint.gdshader` — icons can't be runtime-recolored. Open tracking ticket. | | 3 | Minor | GJ144g/index.md | Profile table shows `gas_giant` but frontmatter has `gas_giant_ringed`. | | 4 | Minor | GJ144g-2/index.md | `atmosphere: none` but `atmosphere_color` has values — should be null. | | 5 | Minor | Action icons | 4 interaction icons not in D-086 vocabulary — need amendment or doc note. | | 6 | Advisory | PIPELINE.md | Open questions (resolution, render mode, rivers, clouds) need ticketing before #794 batch. | | 7 | Advisory | icon_tint.gdshader ticket | Shader must handle both fill and stroke replacement (health icon is fill-only). | | 8 | Advisory | icon-set-v01.md §4 | Radial menu icons gap — open follow-on ticket. | --- ### Verdict: CHANGES REQUESTED **Deduplicated blockers (4):** tracked .npy binary, missing .import sidecars, D-086 scope amendment for stance+action icons, shader ticket.
jpmschweitzer added 1 commit 2026-04-06 16:20:05 +02:00
- Remove tracked kallast_terrain.npy (HIGH — binary in git)
- Amend D-086: stance + interaction icons delivered, not deferred
- Create ticket #818 for icon_tint.gdshader (client team)
- Fix gas giant profile table: suppress gravity/land%/hydrosphere
- Fix atmosphere_color: null when atmosphere is none
- Fix gas_giant_ringed display as gas_giant in profile table
- Re-scaffold + regenerate Ran system with fixes

.import sidecars: not applicable — gitignored by design (client/**/*.import).
Godot auto-generates on first run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

Re-review: sprint-32/visual → main (round 2)

Commit: 0c3eddee — fix(assets): address PR #117 review comments

Issues addressed:

# Issue Status
1 Tracked kallast_terrain.npy (2MB binary) Fixedgit rm --cached
2 Missing .import sidecars Retracted.gitignore has client/**/*.import by design. Godot auto-generates on first run.
3 D-086 scope amendment for stance + action icons Fixed — amendment added to perception.md
4 icon_tint.gdshader tracking ticket Fixed — ticket #818 created
5 GJ144g profile table gas_giant vs gas_giant_ringed Fixed — generator updated
6 GJ144g-2 atmosphere_color should be null Fixed

Advisory items (from round 1, not blocking):

  • PIPELINE.md open questions → team acknowledged, will ticket before #794 batch
  • Shader fill+stroke note → captured in #818 description
  • Radial menu icon gap → deferred per icon-set-v01.md §4

Verdict: APPROVED

No new issues. All blockers resolved or retracted.

## Re-review: sprint-32/visual → main (round 2) **Commit:** `0c3eddee` — fix(assets): address PR #117 review comments ### Issues addressed: | # | Issue | Status | |---|-------|--------| | 1 | Tracked `kallast_terrain.npy` (2MB binary) | **Fixed** — `git rm --cached` | | 2 | Missing `.import` sidecars | **Retracted** — `.gitignore` has `client/**/*.import` by design. Godot auto-generates on first run. | | 3 | D-086 scope amendment for stance + action icons | **Fixed** — amendment added to perception.md | | 4 | `icon_tint.gdshader` tracking ticket | **Fixed** — ticket #818 created | | 5 | GJ144g profile table `gas_giant` vs `gas_giant_ringed` | **Fixed** — generator updated | | 6 | GJ144g-2 `atmosphere_color` should be null | **Fixed** | ### Advisory items (from round 1, not blocking): - PIPELINE.md open questions → team acknowledged, will ticket before #794 batch - Shader fill+stroke note → captured in #818 description - Radial menu icon gap → deferred per icon-set-v01.md §4 ### Verdict: APPROVED No new issues. All blockers resolved or retracted.
jpmschweitzer closed this pull request 2026-04-06 16:23:18 +02:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jpmschweitzer/settled-reach#117