Three architectural review comments implemented per Tyre's proposals:
#3 — scene_path consumption (full, Option A)
- ImplantRegistry.instantiate_all(parent) loads and instantiates all
registered apps with a declared scene_path. Manifests with empty
scene_path are treated as metadata-only (silently skipped).
- ImplantRegistry.get_app_instance(app_path) returns the live instance.
- hud.tscn no longer direct-instances AtlasApp or EconomicsApp — an
AppsContainer Control holds the registry-managed children.
- hud.gd._ready() calls ImplantRegistry.instantiate_all($AppsContainer).
- main.gd drops @onready vars for atlas_app/economics_app; looks up
both from the registry at the top of _ready().
#6c — schema_version on manifest
- ImplantAppManifest: @export var schema_version: int = 1 (first field).
- ImplantRegistry: const CURRENT_SCHEMA_VERSION := 1; tiered check in
_scan() — older-than-current emits print_verbose, newer-than-current
emits push_warning, both proceed best-effort.
- apps/atlas/app.tres + apps/economics/app.tres: schema_version = 1.
#10 — absorb _on_screen_changed boilerplate into ImplantApp
- Base class gains _screens: Dictionary, _current_screen_id: String,
register_screen(id, screen), current_screen_id(), and a real default
_on_screen_changed implementation that handles leave+hide+enter+show
with has_method guards and same-screen-replace detection.
- atlas_app: deletes _current_screen_id, _get_screen(),
_on_screen_changed() override; on_install() collapses to construct →
setup → wire → register_screen(id, screen) per screen. Preserves
direct screen refs for atlas-specific signal wiring and method calls.
- economics_app: deletes same scaffolding; on_install() reduces to three
lines (construct overview_screen, register_screen, nav.set_default).
Also: replaced Resource.get(name, default) dict-style calls with direct
property access on typed ImplantAppManifest reads (2-arg get() is
Dictionary-only; causes "Too many arguments" parse errors on Resources).
_is_valid_manifest gained a Resource type guard and a property-exists
check.
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>
- 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>
The copy team rewrote ui-strings.yaml with multi-level nesting,
renamed sections, and inline comments. Update the YAML parser to
use a stack-based approach for arbitrary nesting depth, update HUD
and interaction prompt to reference the new key names, and align
tests with the new structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds UIStrings autoload that loads display text from a YAML file,
replacing hardcoded strings in HUD and interaction prompt. Copy team
can now author UI microcopy in client/data/ui-strings.yaml without
touching GDScript. Includes 38 strings across 5 categories and 16
gdUnit4 tests for the parser and lookup API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set up the complete Godot 4.6 client foundation as a pure renderer (D-020):
- project.godot with 2D rendering, autoloads, input actions
- Main scene: Game > World (TileMapLayer, Entities, FogOverlay) + Camera2D + UILayer
- Autoloads: SimBridge (connection state machine + test mode), GameState, InputMapper
- Rendering stubs: WorldRenderer, EntityRenderer, FogRenderer
- UI stubs: HUD (health/perception/time), Minimap, MonologueDisplay
- Input mapping: WASD/arrows, E (interact), Tab (perception), Esc (menu), Space (pause)
- gdUnit4 smoke tests: scene loads, autoloads registered (2/2 passing)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>