fix(client): address PR #24 review — 5 critical bugs, 3 warnings, 8 suggestions

Critical:
- Protocol test assertions updated v6→v7 (test_protocol_v6.gd)
- Dialogue signal connections wired (option_selected→DialogueResponse,
  dialogue_dismissed→DialogueEnd sent to server via SimBridge)
- Consume-once race fixed: _consume_dialogue() checks is_dialogue_active()
  before re-showing; dialogue_id tracking prevents re-trigger during fade
- Dialogue box responsive: _update_layout() clamps width to MAX_WIDTH_PX
  (832px) or 65% viewport, height to 20% viewport (MAX_HEIGHT_RATIO)
- Auto-pause added: SimBridge.send_input(PAUSE) on dialogue open/close

Warnings:
- Test coverage: 16 new tests in test_protocol_v7.gd (pending_recognitions
  decode, current_dialogue, GameState, SimBridge mock data, insert colors)
- queue_redraw() optimization: early return when no entities and no pings
- Fixed 200px height → responsive 20% viewport via _update_layout()

Suggestions:
- WASD detection refactored to _WALK_AWAY_ACTIONS array loop
- Button colors reference Constants.INSERT_COLOR_TEXT/HOVER/ACTIVE
- Named constants: COLOR_TRANSITION_START, SILHOUETTE_APPEAR_THRESHOLD,
  SILHOUETTE_SIZE with explanatory comments
- Bounds check: MAX_PENDING_RECOGNITIONS=64 with truncation warning
- Mock dialogue sustained across ticks (not 1-tick flash)
- COLOR_PING coupling with cursor documented as intentional
- Consume helpers extracted: _consume_monologue(), _consume_dialogue()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 01:30:15 +01:00
co-authored by Claude Opus 4.6
parent 90a80e73df
commit 6d6b59c17b
9 changed files with 430 additions and 47 deletions
+19 -6
View File
@@ -18,7 +18,9 @@ const TILE_SIZE: int = Constants.TILE_SIZE
# D-059: Fog entity colors
const COLOR_UNRECOGNIZED := Color("#555566") # Neutral grey blob
const COLOR_PING := Color("#c8d0e0") # Insert white-blue (D-056 cursor default)
# Intentionally matches Constants.INSERT_COLOR_TEXT / cursor default (#c8d0e0).
# Sonar pings are insert-generated — same visual language as cursor and HUD overlays.
const COLOR_PING := Color("#c8d0e0") # Insert white-blue (D-048/D-056)
# Animation timing
const PULSE_PERIOD: float = 0.8 # Breathing pulse cycle (seconds)
@@ -34,6 +36,13 @@ const DRIFT_PERIOD: float = 2.0 # Seconds per drift wander
# Entity blob rendering
const BLOB_RADIUS: float = 10.0
const SILHOUETTE_SCALE: float = 1.3 # Silhouette slightly larger than blob
# Transition thresholds: recognition progress mapped from remaining_ticks/total_delay_ticks.
# Color transition starts at 50% to compress the visual change into ~0.3s (D-060).
const COLOR_TRANSITION_START: float = 0.5
# Silhouette (body shape hint) appears after 80% progress — recognition nearly complete.
const SILHOUETTE_APPEAR_THRESHOLD: float = 0.3
# Silhouette size: approximate torso-sized rectangle in pixels at TILE_SIZE=32 scale.
const SILHOUETTE_SIZE := Vector2(6.0, 10.0)
# Internal state — no child nodes, pure data + _draw()
var _entities: Dictionary = {} # entity_id -> {pos, drift_offset, drift_target, drift_timer, progress}
@@ -42,6 +51,10 @@ var _time: float = 0.0
func _process(delta: float) -> void:
# Early return when idle — skip queue_redraw() when nothing to draw
if _entities.is_empty() and _pings.is_empty():
return
_time += delta
# Animate drifts
@@ -119,12 +132,12 @@ func _draw() -> void:
# Color transition: grey → D-033 teal based on recognition progress
# Transition begins at 50% progress (D-060: ~0.3s visual transition within delay window)
var progress: float = e.progress
var color_t: float = clampf((progress - 0.5) / 0.5, 0.0, 1.0)
var color_t: float = clampf((progress - COLOR_TRANSITION_START) / (1.0 - COLOR_TRANSITION_START), 0.0, 1.0)
var blob_color: Color = COLOR_UNRECOGNIZED.lerp(Constants.ENTITY_COLOR_UNKNOWN, color_t)
blob_color.a = pulse_alpha
# Blob — unrecognized: plain circle. Recognized: larger glow + inner shape
if color_t < 0.01:
if color_t < 1e-3:
# Pure unrecognized: grey blob, no silhouette (D-059)
draw_circle(world_pos, BLOB_RADIUS, blob_color)
else:
@@ -133,11 +146,11 @@ func _draw() -> void:
glow_color.a *= 0.4
draw_circle(world_pos, BLOB_RADIUS * SILHOUETTE_SCALE, glow_color)
draw_circle(world_pos, BLOB_RADIUS, blob_color)
# Faint silhouette: small rectangle hint (body shape emerging from fog)
if color_t > 0.3:
# Faint silhouette: body shape rectangle emerges late in recognition
if color_t > SILHOUETTE_APPEAR_THRESHOLD:
var sil_color := blob_color
sil_color.a *= 0.6
var sil_size := Vector2(6.0, 10.0) * color_t
var sil_size := SILHOUETTE_SIZE * color_t
draw_rect(Rect2(world_pos - sil_size * 0.5, sil_size), sil_color)
# Draw sound pings — concentric expanding rings