Commit Graph
8 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Fable 5 c64231e8ee fix(client): clear the test debt — 2 production bugs, suite fully green (T-973 et al.)
Production fixes surfaced by honest test triage:
- hud_groups.gd: _set_group_z crashed on freed HUD nodes — the typed loop
  variable errors before the is_instance_valid guard runs; prune first
- fog_state.gd: _resize cleared _prev_visible (world-space keys survive
  resizes), so pre-resize tiles never decayed VISIBLE→EXPLORED (D-059)

Test debt (T-928/929/934/935/936/937/938/939, T-864, T-973): lambda
local-capture bugs rewritten with array captures (now assert exact
emission counts), e2e suites updated to the current handshake +
StartupMessage protocol and stream-aware reads against the live binary,
fog perf test measures steady state, chime test pins the shipped 800ms
catalog asset (D-067 amended separately), monologue gdUnit4 API typo,
battery-warning tests follow the MetaScreen on_open lifecycle. 3 sprint2
proof tests revived (corner_reveal had passed from the wrong tile — NPC3
blocks (18,14); route corrected). Soft-skips converted to real do_skip
reporting. T-1068: 7 orphan .gd.uid deleted, _format_pop/_format_radius
deduped into atlas_format.gd (preload, no class_name — headless cache).

Suite: 1264 cases/20 failures → 1268/0, independently re-verified
(2536/2536, exit 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 16:22:01 +02:00
jpmschweitzerandClaude Opus 4.6 3f5b4258ba feat(client): sprint 38 — free camera viewer, archetype strip, test fixes
- Add free camera mode (F4 toggle): WASD pan, scroll zoom, decoupled
  from player position (#898)
- Strip archetype-driven code: remove character_archetype, lattice_profile,
  and lattice color palettes from client (#882)
- Fix confrontation_monologue signal not firing in headless test mode (#867)
- Revive fog state behavioral tests: EXP_EXPLORED persistence, grow-only
  bounds, texture-resize copy, BoundaryWall handling (#879)
- Triage pre-existing test failures: fix examine_display dismiss timing,
  fog test position fragility, rendering snapshot assertions,
  time_display format (#871)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-02 10:19:11 +02:00
jpmschweitzerandClaude Opus 4.6 f24d08f756 refactor(ui): migrate 6 meta screens to MetaScreen pattern (Workstream 2)
Relocates main_menu, character_creation, settings_dialog, debug_console,
bug_report_dialog, loading_screen from flat client/ui/ into structured
client/ui/meta/screens/<name>/. All six now extend MetaScreen instead
of Control; the base handles open/close lifecycle, visibility,
captures_input, and — for overlays — the sim-pause contract.

Screen policies set per Tyre's proposal:
- settings_dialog: pauses_sim=false, PUSHES onto MetaStack
- debug_console: pauses_sim=true, PUSHES (D-088 routing via base)
- bug_report_dialog: pauses_sim=true, PUSHES
- loading_screen: closable_by_escape=false, PUSHES
- main_menu, character_creation: scene-roots, extend MetaScreen for
  the lifecycle contract only, do NOT push onto the stack

character_creation stays at its current surface (tabs, descriptor,
creation_confirmed signal unchanged). Tab consolidation and
CharacterProfile migration happen in Workstreams 5 and 6.

Knock-on changes:
- main.tscn ModalLayer CanvasLayer renamed to MetaLayer; main.gd
  @onready refs updated; constants.gd comment updated; test_client_p3
  and test_ui_framework_sprint15 assertions updated; test_monologue_display
  and .tscn header comments updated.
- OPEN_MENU handler now pushes settings_dialog onto MetaStack before
  calling open(). Full ESC priority chain lands in Workstream 4.
- atlas_app.gd: _unhandled_key_input signature widened from
  InputEventKey to InputEvent with an is-check, per Godot 4 API. Pre-
  existing narrowing was silently tolerated until main.tscn started
  fully instantiating under the new pattern.
- test_client_p3: entity_renderer type annotations corrected from
  ColorRect to Sprite2D (stale since a prior refactor); facing
  indicator rotation assertion switched to angle_difference() for
  modular-safe comparison.

Verification:
- gdlint client/scripts/ client/ui/ — zero problems
- godot --headless --path client --quit — no SCRIPT ERROR
- test_client_p3: 24/24 pass
- test_ui_framework_sprint15: 54/54 pass
- test_implant_nav_stack: 52/52 pass
- test_implant_registry: 42/42 pass
- test_implant_app_lifecycle: 36/36 pass

Workstream 1 foundation (84105916) remains unchanged. Workstreams 3-8
follow: protocol layer, Option A sequencing, 3-tab restructure,
Bookmark tab, location picker, Skills stub.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 21:58:24 +02:00
jpmschweitzerandClaude Sonnet 4.6 677ca9b59d fix(ui): address PR #49 review — 6 warnings + 2 suggestions (#122)
Warnings fixed:
- BBCode injection (line 153): escape [ → [lb] in server text before interpolation
- sort_custom on silent-drop (line 125): sort now only runs on actual insertion/replacement
- clip_contents: add clip_contents=true to MonologueDisplay Control (overflow guard)
- confrontation tick guard (main.gd): _last_confrontation_tick deduplicates same-tick signals
- GameState decoupling: show_monologue() reads lattice_profile once and passes it through
  _show_line() → _build_line_node(); renderer no longer reaches into autoload (D-020)
- Equal-priority eviction: >= tiebreak (was >); FIFO for equal-priority queue overflow

Suggestions fixed:
- Minimum duration clamp: maxf(duration, FADE_IN_SEC + 0.1) — line survives own fade-in
- _label_text bounds check: guard against empty _visible before indexing [0]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 19:06:26 +01:00
jpmschweitzerandClaude Opus 4.6 c71ba8ebb3 test(ui): GameState integration + D-049 compliance tests for monologue display (#122)
7 tests: snapshot round-trip, null/stale clearing, non-dict rejection,
duration/id preservation, canvas layer constant. before_test/after_test
lifecycle hooks prevent state bleed between test cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:43:41 +01:00
jpmschweitzerandClaude Sonnet 4.6 b49d78ef6a fix(ui): guard empty text in show_monologue — no ghost slots or queue entries (#122)
show_monologue() now returns early when text.is_empty(), preventing:
- ghost visible slots with blank labels
- stagger timer advancing on empty calls
- empty strings queuing when slots are full

Tests: add test_show_monologue_with_empty_text_does_not_set_displaying and
two companion cases (stagger timer unchanged, no enqueue when full) anticipating
Hoshe's QA additions to the test suite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 18:41:22 +01:00
jpmschweitzerandClaude Sonnet 4.6 1765e2922f refactor(ui): monologue display — multi-line architecture per Tyre review (#122)
Rewrites the monologue display system per Tyre architecture review (Sprint 14):

Rendering:
- Up to 3 simultaneous visible lines (VBoxContainer, dynamic node creation)
- Lines created programmatically as MarginContainer > RichTextLabel per slot
- Percentage-based anchors: 5% left, 75–98% vertical (25% area from bottom), 50% max width
- Z-layer 7 in UILayer (CanvasLayer 20, D-049)

Queue:
- 5-entry priority queue; highest priority drains first
- On overflow: incoming line replaces lowest-priority queued entry if it outranks it
- Lower/equal priority incoming lines silently dropped when queue full

API:
  show_monologue(text, duration, priority=2, is_urgent=false)
- Replaces old (text, duration, character_type) signature
- main.gd passes priority and is_urgent from MonologueEvent fields
- Confrontation monologue: priority=3, is_urgent=true (D-063)

Colour:
- Reads GameState.lattice_profile at render time (D-032)
- lattice_augmented (detective): standard #d0d4e0 / urgent #e0e8f8
- lattice_baseline (smuggler): standard #d8d0c4 / urgent #f0e4d4
- Fallback for unknown profiles; no crash

Stagger: 0.15s between consecutive fade-ins (spec §5.4)
Opacity: standard 0.85, urgent 1.0; bloom deferred

GameState: adds lattice_profile field, parsed from snapshot

Tests: 27 gdUnit4 test cases — queue order, priority drop, overflow, stagger,
no-overwrite (P0 #477), BBCode output, palette selection, slot lifecycle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 18:39:49 +01:00
jpmschweitzerandClaude Sonnet 4.6 4365871846 feat(ui): monologue display — queue, character colours, italic BBCode (#122)
- Queue management: enqueue on mid-display arrival, drain in order, MAX_QUEUE_DEPTH=8 cap, no-overwrite contract (P0 #477)
- Character colours: detective=#c8e0ff (cool blue), smuggler=#f0c870 (warm amber), fallback to neutral insert text
- Typography: italic via BBCode [i] tags; font size 13px (smaller than dialogue)
- Positioning: bottom-left of viewport, 420×120px, 80px bottom margin above verb list
- main.gd: _get_active_character_type() reads player entity kind.data.character_type; passed to show_monologue() and _on_confrontation_monologue()
- gdUnit4 tests: queue order, depth cap, no-overwrite, BBCode output, colour mapping, fade timer integration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 18:31:13 +01:00