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>
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>
Draw ImplantTheme-styled StyleBoxFlat behind the circular minimap for
visual consistency with other implant components. Stance badge icons
remain blocked by #795 (visual team).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HUD: merge TimeDisplay into ImplantPanel (time/health/perception in one
panel), remove dead tscn nodes, move HUD to InsertOverlay for D-051 bloom.
Interaction prompt: convert from PanelContainer+StyleBoxFlat to Control
with ImplantPanel+ImplantDataRow, fix panel height for 42px minimum.
Tests updated for new scene structure and public API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- DebugOverlay: position comment updated, tscn is source of truth
- GauntletHUD: moved from y:48 to y:252 (below StanceIndicator)
- StanceIndicator: offset_top 192→200, height 26→44px for ImplantPanel
Co-Authored-By: Claude Opus 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>
- HUD status panel moved to y=80 (below TimeDisplay at 16-70)
- Removed redundant time row from HUD (TimeDisplay handles it)
- Debug overlay starts at y=150 (below HUD status panel)
- Stance indicator moved below minimap (y=192, was overlapping at y=16)
- Interaction prompt moved to y=-240 (above dialogue box at -200)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- HUD: programmatically builds ImplantPanel with health/mode/time rows,
replaces raw MarginContainer/VBoxContainer/Labels
- Stance indicator: ImplantPanel with color-coded ImplantDataRow,
replaces custom _draw() with hardcoded bg/text
- Interaction prompt: applies implant theme StyleBox + colors to
existing PanelContainer layout
Minimap left as-is — its circular frame is a distinct diegetic element,
not rectangular panel chrome.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Labels now appear based on zoom level and system importance:
- Always: selected + hovered
- Zoom >= 1.2: hubs, junctions, gateway
- Zoom >= 2.0: all named systems
- Below 1.2: only selected/hovered
Prevents label soup at overview zoom levels.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All named systems get a label below their dot. text_dim for default,
text_primary for selected/hovered. Removed duplicate label from
_draw_selection (now handled by _draw_systems).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Generator now queries bodies/stations tables directly for habitable
count, inhabited count, and total population. All 301 systems have
data — unsettled systems show "0 habitable · 0 inhabited" and "0".
Fixed stale worktree path to systems.db.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
"CORE corridor (hop 1)" with sector color. Bodies back to single line
"1 habitable · 1 inhabited" as originally formatted in the data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Layout now shows each field on its own line:
star type / hop / corridor / habitable / inhabited / pop / GDP
GDP shows "—" placeholder until economics data is available.
Population shows full number without ellipsis.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New GameplayRenderer extends Node2D with built-in occlusion support.
Subclasses override _gameplay_process() and _gameplay_draw() instead
of _process() and _draw() — these are skipped when a fullscreen
implant app covers gameplay.
Migrated all 5 gameplay renderers:
- CursorRenderer: hover detection + bracket drawing paused
- EntityRenderer: position lerping paused
- FogEntities: fog dot rendering paused
- SoundIndicatorRenderer: directional arrows paused
- WorldRenderer: tile/fog/entity updates paused
No more manual occlusion wiring — the base class handles everything.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CursorRenderer z_index=100 so it renders above all HUD/implant layers
- Adjacent systems uses ImplantTextBlock (wraps) instead of ImplantDataRow (clips)
- Panel calls reset_size() before clamping to get accurate height on first frame
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CursorRenderer must always render on top — shouldn't have its z-index
managed by HudGroups. It's a world-space renderer, not a HUD element.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Accidentally deleted when exploring reparenting options. The z-index
model means it stays as a child of HUD — no reparenting needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Moved signals above enum per gdlint class-definitions-order rule.
app_changed signal uses int instead of Mode type to avoid the
forward-reference that forced wrong ordering. Callers compare
against HudGroups.Mode.FULLSCREEN etc unchanged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaced visibility toggling with z-index layer management. Nothing
gets hidden — fullscreen apps render on top, gameplay stays underneath.
Supports future hybrid layouts (insert-mode map alongside gameplay).
Added gameplay_occluded signal: WorldRenderer skips tile/fog/entity
updates when a fullscreen implant app covers it. Prevents wasted
render work behind opaque overlays. Other renderers can connect to
the same signal.
Modes: GAMEPLAY (z=0), INSERT (z=10), FULLSCREEN (z=20), MODAL (z=30).
Star map uses app_changed signal to toggle its own visibility based
on whether its app is active.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gdformat collapsed enum + 3 inline comments into one 300-char line.
Split to multi-line enum with doc comments.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CursorRenderer extends Node2D, not Control — can't be registered in
HudGroups. Removed from gameplay group. Also dropped typed array
annotation to avoid runtime type mismatch errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deeper taxonomy: map is a family of views (starchart, system, station,
planet, location), not one app. Same HudGroups mechanics — just a
more specific path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implant apps use hierarchical groups: implant/map, implant/wiki,
implant/journal, etc. Apps are mutually exclusive with each other
and with gameplay. Opening implant/map hides gameplay + any other
implant app. Closing returns to gameplay.
API: open_app(), close_app(), toggle_app(), is_app_active().
Star map uses implant/map. Future apps register their own group.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New HudGroups autoload manages show/hide of related HUD elements as
groups. Exclusive groups (gameplay, implant) are mutually exclusive —
opening the star map hides stance indicator, minimap, interaction
prompts, etc. Closing it restores them.
Gameplay nodes registered in main.gd _ready(). Star map registers as
implant group and uses toggle_group() instead of direct visibility.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ImplantDataRow uses clip_text + ellipsis instead of wrapping — each
info item stays on one line. Panel position clamped so bottom edge
never exceeds screen bounds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SIZE_FLAGS_FILL → SIZE_FILL, SIZE_FLAGS_SHRINK_END → SIZE_SHRINK_END.
The _FLAGS_ prefix was removed in Godot 4.6.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Panel now clips content and constrains children to its width.
Components set autowrap and SIZE_FLAGS_FILL so text wraps within
the panel instead of overflowing. Bold markdown markers stripped
in ImplantTextBlock constructor.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New component library at client/ui/implant/:
- ImplantTheme: shared Resource with colors, spacing, font sizes
- ImplantPanel: PanelContainer root with themed background/border
- ImplantHeader: title + subtitle
- ImplantSeparator: themed horizontal rule with above/below spacing
- ImplantDataRow: single-line text with optional color override
- ImplantTextBlock: RichTextLabel for wrapping narrative text
- default_implant.tres: default theme resource
Star map info panel refactored from 140 lines of manual draw_string
calls to 50 lines of component composition via _rebuild_info_panel().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Separators now have explicit above (6px) and below (12px) spacing
relative to text baselines. Previously a single 8px block didn't
account for baseline positioning, causing text to merge with
separator lines. Line height bumped to 18px.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Panel now measures all variable content (GTTR text, adjacent systems)
before calculating height. Fixes clipping on hub systems with many
neighbors and long GTTR excerpts. Unified separator spacing (8px).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show system profile popup on select: name, star type, hop distance,
corridor, GTTR excerpt, body count, population, adjacent systems.
Edge rendering changed to show no edges by default, only selected
system's gate lines on click. Star map data extended with wiki fields
for all 301 systems.
Ticket: #780
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add _unhandled_key_input to main.gd: M toggles star_map.toggle_visible()
- Remove topology line from info panel (internal data, not player-facing)
- Cast aperture_count to int (was showing decimal point)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Star map (W1-W3, S3):
- _process visibility guard + dirty flag (no redraw when hidden/unchanged)
- _system_hash masked to 31-bit positive range
- Extracted _find_nearest_system() shared helper
game_state.gd (W4):
- Inline load() in apply_snapshot() replaces per-tick overhead; safe at
runtime because script is already in resource cache
Data pipeline (W5-W6):
- Script-relative path resolution via __file__
- --check mode + make check-star-map staleness target
Minor (S1-S2, S5):
- Removed redundant bone_idx assignment
- Simplified double-negative test assertion
- Documented autoload parse-order convention in CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Autoload scripts are parsed before regular scripts, so class_name
types (CharacterVisualDescriptor, TestHarness, YamlParser) are not
available at parse time. Replace type annotations with untyped vars
and use load() for in-body class references. Fixes all 14 headless
parse errors (9 pre-existing + 5 from Sprint 30 changes).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New StarMapRenderer: 301 systems in concentric hop-rings from player
location, sector-colored, click-to-select with info panel, pan/zoom.
Integrated into HUD (hidden by default), insert state propagation
wired in main.gd. Data enriched from systems.db + star-map.json via
tooling/generate-star-map-data.py regeneration script.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
encode_startup_message() now accepts optional CharacterVisualDescriptor
as third param, serialized via to_dict(). sim_bridge passes the
descriptor from GameState on new game start. apply_snapshot() restores
descriptor from server snapshot on save/load cycle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Infrastructure for floating UI elements (status indicators, thought
bubbles, alert markers). Marker3D at Vector3(0, 0.3, 0) offset from
Head bone, exposed via get_overhead_anchor() public API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Test character model (test_raw.glb) with eye, hair, and body textures
for validation of the character compositor pipeline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per-body-type texture maps (BaseColor, Normal, Roughness/ORM) for all
clothing items across all body types. Adds eyebrow variants, facial
hair (beard, moustache, mutton chops), hair styles (12 variants),
and head templates. Sprint 28 character visuals pipeline output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated clothing models (boots_work, coveralls_basic, jacket_utility,
pants_cargo, shirt_henley) for average_m and reference variants.
Added segmented body textures (BaseColor, Normal, Roughness) for all
body types: average_f, average_m, child, heavy_f, heavy_m, muscular_f,
muscular_m, teen_f, teen_m. Sprint 28 character visuals work.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Body segments: face-based exclusive assignment for all 8 body types
(average/muscular/teen m/f, child) + hips segment
Hair: solidified 20mm, normals recalculated, white masks (was black)
Clothing: peasant tunic/pants/shoes solidified 25mm for all body types
Eye: iris mask from T_Eye_Split.png green channel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>