--- title: "Sprint 18 — Touch (Client)" description: "Test plan for Sprint 18 client scope covering minimap POI rendering (#151), dialogue UI hardening and examine result display (#174), and knowledge/journal panel (#264)." type: test-plan status: active ticket: "#151, #174, #264" created: 2026-02-25 updated: 2026-02-25 --- # Test Plan: Sprint 18 — Touch (Client) - **Date**: 2026-02-25 - **Sprint**: 18 (Touch) - **Spec references**: D-013, D-041, D-042, D-049, D-061, D-062, D-063, D-064, D-078 - **Tickets**: #151 (minimap rendering), #174 (dialogue UI hardening + examine result), #264 (knowledge/journal display) - **QA Engineer**: Hoshe --- ## Summary Sprint 18 client scope delivers three UI features: 1. **#151** — Minimap overlay rendering POIs from snapshot 2. **#174** — Dialogue UI hardening (D-062/D-063/D-064) + examine result display overlay 3. **#264** — Knowledge/journal panel displaying accumulated KG facts Automated tests: `client/tests/test_dialogue_sprint18.gd`, `client/tests/test_journal_sprint18.gd` Manual tests: this document (section §Manual Test Procedures) --- ## #151: Minimap Rendering ### Spec reference D-013 (diegetic insert/POI system), D-015 (fixed-north, player-centered), D-049 (z-layer 6) ### Automated (unit-testable) - `GameState.poi_list` accessible via snapshot or `current_snapshot.poi_list` → Covered: `test_journal_sprint18.gd::test_gamestate_poi_list_field_exists_or_in_entities` - `CANVAS_INSERT = 10` sanity check → Covered: `test_journal_sprint18.gd::test_canvas_insert_constant_is_10` ### Edge cases - **Empty POI list**: minimap frame still renders (frame is always present per D-013) - **POI beyond minimap radius**: renders as directional arrow at border, not dot - **POI at exactly player position**: dot at center - **All POI categories**: `NavPoint`, `PersonOfInterest` — distinct colors/shapes ### Manual test procedure 1. Start game with a clean save (no discovered POIs) 2. **Verify**: minimap insert frame is visible, empty, no dots/arrows 3. Move player near a NavPoint POI; trigger discovery 4. **Verify**: colored dot appears on minimap at correct compass position 5. **Verify**: dot color/shape matches expected category visual (see `data/ui-strings.yaml`) 6. Move player so a POI is beyond minimap radius 7. **Verify**: directional arrow appears at minimap border pointing toward POI 8. **Verify**: player dot remains centered; minimap does not rotate or scroll 9. Open dialogue box; **verify**: minimap remains visible (not hidden by dialogue) ### Performance check - 150×150 map, 15 NPCs, 8+ discovered POIs → minimap renders without visible frame drop --- ## #174: Dialogue UI Hardening + Examine Result Display ### Spec reference D-061 (box spec), D-062 (invisible locked options), D-063 (confrontation), D-064 (walk-away), D-078 (overheard log) ### Automated coverage Test file: `client/tests/test_dialogue_sprint18.gd` | Test | D-ref | Status | |------|-------|--------| | D-062: rendered options have mouse_filter=STOP | D-062 | Written | | D-062: no lock icon children on options | D-062 | Written | | D-062: MAX_OPTIONS = 3 | D-061 | Written | | D-062: 4 options → only 3 render | D-061/D-062 | Written | | D-063: CONFRONTATION_BEAT_DURATION in [1.0, 2.0] | D-063 | Written | | D-063: CONFRONTATION_DIM_ALPHA < 1.0 | D-063 | Written | | D-063: confrontation_monologue signal fires | D-063 | Written | | D-063: standard option does NOT fire beat signal | D-063 | Written | | D-064: _WALK_AWAY_ACTIONS not empty | D-064 | Written | | D-064: cardinal directions in walk-away list | D-064 | Written | | D-064: dialogue_dismissed signal exists | D-064 | Written | | GameState current_dialogue set from snapshot | D-061 | Written | | GameState current_dialogue null when absent | D-061 | Written | | GameState current_examine_result field exists | #174 | Written (test-first) | | GameState current_examine_result set from snapshot | #174 | Written (test-first) | | GameState current_examine_result null when absent | #174 | Written (test-first) | | BBCode escape brackets in server text | — | Written | | _log_dirty flag optimization | — | Written | | D-061 max height ratio = 0.2 | D-061 | Written | | D-064 FADE_OUT = 0.3s | D-064 | Written | | D-078 passive glyph = ┃ | D-078 | Written | ### Items requiring Stig implementation (test-first stubs will fail until done) - `GameState.current_examine_result` field + `apply_snapshot()` handler - Examine result overlay scene (`res://ui/examine_overlay.tscn` or similar) - Auto-dismiss timer: 4–6 seconds (wire `current_examine_result` to overlay) ### Manual test procedure — D-062 (invisible locked options) 1. Enter dialogue with an NPC that has some filtered options (server omits locked ones) 2. **Verify**: dialogue box shows only the options the server sent — no grayed-out entries, no lock icons 3. **Verify**: all visible options respond to click/key press 4. **Verify**: pressing 1, 2, 3 selects the corresponding option (key bindings active) 5. **Red flag**: if you see any visual element that appears "disabled" or "locked" — that is a D-062 violation ### Manual test procedure — D-063 (confrontation beat) 1. Enter dialogue with an NPC that has a confrontation option (italic monologue beat) 2. **Verify**: confrontation option renders identically to standard options (same style — no bold, no icon) 3. Select the confrontation option 4. **Verify**: a first-person internal monologue appears (italic, MonologueDisplay) 5. **Verify**: dialogue box dims for ~1.5 seconds during beat 6. **Verify**: after beat, option is sent and conversation ends normally 7. **Verify**: audio dip applies during confrontation beat ### Manual test procedure — Examine result display (#174 new feature) 1. Stand adjacent to an NPC; press Examine key (TBD — coordinate with server team) 2. **Verify**: a brief text overlay appears (non-interactive, no response options) 3. **Verify**: overlay is diegetically styled (insert layer, not a dialogue box) 4. **Verify**: overlay auto-dismisses after 4–6 seconds without player input 5. **Verify**: different characters (detective vs smuggler) receive different text for the same NPC 6. **Verify**: overlay does not appear over a dialogue box (mutual exclusion) --- ## #264: Knowledge/Journal Display ### Spec reference D-041 (knowledge graph data model), D-042 (UIStrings), D-013 (insert layer) ### Automated coverage Test file: `client/tests/test_journal_sprint18.gd` | Test | D-ref | Status | |------|-------|--------| | GameState.player_knowledge field exists | D-041 | Written (test-first) | | GameState.player_knowledge set from snapshot | D-041 | Written (test-first) | | GameState.player_knowledge null when absent | D-041 | Written (test-first) | | Facts array survives snapshot roundtrip | D-041 | Written (test-first) | | KnowledgeConfidence levels documented | D-041 | Written | | Fact state values documented | D-041 | Written | | Journal scene exists at path | #264 | Written (test-first) | | UIStrings has journal section | D-042 | Written (test-first) | | CANVAS_INSERT = 10 | D-013 | Written | | POI list accessible for minimap | #151 | Written | ### Items requiring Stig implementation (test-first stubs will fail until done) - `GameState.player_knowledge` field + `apply_snapshot()` handler - Journal panel scene (`res://ui/journal_panel.tscn`) - Journal panel `refresh()` or `_refresh()` method - UIStrings keys: `journal.title`, `journal.confidence.*`, `journal.no_facts` - Toggle key (likely `J`) wired to panel visibility - Mutual exclusion: journal closes when dialogue opens and vice versa ### Manual test procedure 1. Accumulate KG facts by examining NPCs and participating in dialogue 2. Press the journal toggle key (likely `J`) 3. **Verify**: journal panel opens as an insert-layer overlay (diegetic styling) 4. **Verify**: entities are listed with header ("What I know about Kael Davan") 5. **Verify**: each fact shows: fact text, confidence level, source, game-time timestamp 6. **Verify**: `Direct` confidence facts are most prominent (visually) 7. **Verify**: `Stale` facts appear dimmer than `Active` facts 8. **Verify**: `Contradicted` facts are visually distinct (strikethrough or amber tint) 9. Open dialogue box; **verify**: journal panel closes automatically 10. Close dialogue; re-open journal; **verify**: state preserved 11. Press `J` again; **verify**: journal panel closes ### Edge cases - **Empty journal**: no facts accumulated → journal shows "No data" message (UIStrings key) - **Many facts**: 20+ facts → scroll works, panel stays within insert layer bounds - **Contradicted + Stale**: a fact can be both — verify combined visual treatment - **Game time 00:00**: timestamp displays correctly (midnight edge case) --- ## Test Coverage Summary | Ticket | Automated tests | Manual procedure documented | Ready to run | |--------|----------------|----------------------------|--------------| | #151 minimap | 2 (structural) | Yes | Blocked on Stig (#151 in_progress) | | #174 dialogue hardening | 25 | Yes | All pass today (code exists) | | #174 examine result | 5 (test-first) | Yes | Blocked (GameState field missing) | | #264 journal display | 8 (test-first) | Yes | Blocked (scene + field missing) | ### Test files to run ```bash # gdUnit4 headless (see docs/DEVOPS.md for full command) # test_dialogue_sprint18.gd — expect: 25 pass (dialogue), 5 fail (examine, test-first) # test_journal_sprint18.gd — expect: 3 pass (constants), 8 fail (test-first) ``` ### Sprint 18 completion criteria (client) Per `sprint-18/joint.md`: - [ ] Minimap renders POIs — discovered POI shows dot; player centered; at least one distant POI shows arrow - [ ] Journal panel opens — at least one KG fact with confidence, source, game-time visible - [ ] Examine result displays — overlay fires on Examine, auto-dismisses, differs by character - [ ] No locked/grayed dialogue options anywhere in the UI (D-062)