fix(client): address PR #65 review — POI key, ToldBy parsing, KG dirty flag

- minimap.gd: fix "poi_category" → "category" key mismatch so POI
  colors and shapes render correctly
- journal_panel.gd: parse ToldBy(N) source format, resolve entity
  names from player_knowledge; move confidence/source labels to
  UIStrings per D-042
- observer/mod.rs: add Changed<KnowledgeGraph> dirty flag to skip
  per-tick KG serialization when unchanged
- types.rs: fix stale version doc comment (13 → 14)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 02:41:31 +01:00
co-authored by Claude Opus 4.6
parent a52cf4f494
commit a82eb0748a
6 changed files with 486 additions and 289 deletions
+38 -18
View File
@@ -19,22 +19,9 @@ extends Control
const FADE_IN: float = 0.18
const FADE_OUT: float = 0.25
# D-041 confidence → display label
const CONFIDENCE_LABELS: Dictionary = {
"Direct": "Confirmed",
"KnowsDetails": "Detailed",
"KnowsOf": "Known",
"Suspects": "Unconfirmed",
}
# D-041 source → display label
const SOURCE_LABELS: Dictionary = {
"DirectObservation": "Observed",
"ToldBy": "Told",
"Heard": "Overheard",
"Inferred": "Inferred",
"Background": "Prior",
}
# D-041/D-042: confidence and source labels loaded from UIStrings (data/ui-strings.yaml).
# Keys: knowledge_panel.confidence_{lower} and knowledge_panel.source_{lower}
# Fallback: raw value if key not found (UIStrings returns the key itself).
@onready var panel: PanelContainer = $PanelContainer
@onready var title_label: Label = $PanelContainer/MarginContainer/VBoxContainer/TitleLabel
@@ -135,8 +122,8 @@ func _add_entity_entry(entity: Dictionary) -> void:
rel_label = relationship # fallback if key missing
var state_color: Color = _state_color(state)
var conf_label: String = CONFIDENCE_LABELS.get(confidence, confidence)
var src_label: String = SOURCE_LABELS.get(source, source)
var conf_label: String = UIStrings.get_text("knowledge_panel.confidence_%s" % confidence.to_lower())
var src_label: String = _resolve_source_label(source)
# Build BBCode:
# [color=#hex][b]Name[/b][/color] [color=#rel_hex]Status[/color]
@@ -174,6 +161,39 @@ func _add_entity_entry(entity: Dictionary) -> void:
entries_container.add_child(spacer)
## Resolve a source string from the server into a human-readable label.
## Handles plain keys ("DirectObservation", "Heard") and ToldBy(N) format.
## ToldBy(N) looks up entity_id N in player_knowledge.entities for the name.
func _resolve_source_label(source: String) -> String:
if source.is_empty():
return ""
# ToldBy(entity_id) format — e.g. "ToldBy(12)"
if source.begins_with("ToldBy(") and source.ends_with(")"):
var id_str: String = source.substr(7, source.length() - 8)
var entity_id: int = id_str.to_int()
var name := _entity_name_for_id(entity_id)
var told_prefix: String = UIStrings.get_text("knowledge_panel.source_toldby")
if told_prefix == "knowledge_panel.source_toldby":
told_prefix = "Told"
return "%s: %s" % [told_prefix, name]
# Plain source key — look up UIStrings
var key: String = "knowledge_panel.source_%s" % source.to_lower()
return UIStrings.get_text(key)
## Look up an entity name by stable ID from GameState.player_knowledge.entities.
func _entity_name_for_id(entity_id: int) -> String:
var knowledge: Variant = GameState.player_knowledge
if knowledge == null:
return "#%d" % entity_id
for entity in knowledge.get("entities", []):
if entity is Dictionary and int(entity.get("entity_id", -1)) == entity_id:
return entity.get("name", "#%d" % entity_id)
return "#%d" % entity_id
func _state_color(state: String) -> Color:
match state:
"Contradicted":
+1 -1
View File
@@ -91,7 +91,7 @@ func _draw() -> void:
var dx: float = float(poi.x) - px
var dy: float = float(poi.y) - py
var dist: float = sqrt(dx * dx + dy * dy)
var category: String = poi.get("poi_category", "")
var category: String = poi.get("category", "")
var color: Color = _category_color(category)
if dist < 0.01: