fix(client): address PR #109 review — 6 warnings + 5 suggestions

Star map (W1-W3, S3):
- _process visibility guard + dirty flag (no redraw when hidden/unchanged)
- _system_hash masked to 31-bit positive range
- Extracted _find_nearest_system() shared helper

game_state.gd (W4):
- Inline load() in apply_snapshot() replaces per-tick overhead; safe at
  runtime because script is already in resource cache

Data pipeline (W5-W6):
- Script-relative path resolution via __file__
- --check mode + make check-star-map staleness target

Minor (S1-S2, S5):
- Removed redundant bone_idx assignment
- Simplified double-negative test assertion
- Documented autoload parse-order convention in CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-05 00:12:48 +02:00
co-authored by Claude Opus 4.6
parent 0d5323f66c
commit c94c5d7acb
9 changed files with 116 additions and 76 deletions
+62 -42
View File
@@ -1,8 +1,9 @@
#!/usr/bin/env python3
"""Generate client/data/star_map_data.json from star-map.json + systems.db.
Run from the project root (any worktree):
Run from any directory — paths are resolved relative to this script's location:
python3 tooling/generate-star-map-data.py
python3 tooling/generate-star-map-data.py --check # exit 1 if committed JSON is stale
Sources:
docs/design/star-map.json — graph topology (nodes + edges)
@@ -16,42 +17,36 @@ import json
import os
import sqlite3
import sys
import tempfile
# Resolve project root from this script's location: tooling/ is one level below root.
# Works regardless of cwd — no fragile relative path guessing.
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
_PROJECT_ROOT = os.path.dirname(_SCRIPT_DIR)
# Worktree layout: settled-reach/{client,server,main}/
# This script lives in client/tooling/, so _PROJECT_ROOT = client/.
# The parent of _PROJECT_ROOT is the worktree parent where sibling dirs live.
_WORKTREE_PARENT = os.path.dirname(_PROJECT_ROOT)
STAR_MAP_PATH = os.path.join(_PROJECT_ROOT, "docs", "design", "star-map.json")
SYSTEMS_DB_PATH = os.path.join(_WORKTREE_PARENT, "server", "server", "data", "systems.db")
OUTPUT_PATH = os.path.join(_PROJECT_ROOT, "client", "data", "star_map_data.json")
def find_file(candidates: list[str]) -> str | None:
for p in candidates:
if os.path.exists(p):
return p
return None
def main() -> None:
# Find star-map.json
star_map_path = find_file([
"docs/design/star-map.json",
"../docs/design/star-map.json",
"../../docs/design/star-map.json",
])
if not star_map_path:
print("ERROR: docs/design/star-map.json not found", file=sys.stderr)
def generate() -> dict:
"""Generate the enriched star map data dict."""
if not os.path.exists(STAR_MAP_PATH):
print(f"ERROR: star-map.json not found at {STAR_MAP_PATH}", file=sys.stderr)
sys.exit(1)
if not os.path.exists(SYSTEMS_DB_PATH):
print(f"ERROR: systems.db not found at {SYSTEMS_DB_PATH}", file=sys.stderr)
sys.exit(1)
# Find systems.db
db_path = find_file([
"server/server/data/systems.db",
"../server/server/data/systems.db",
"../../server/server/data/systems.db",
])
if not db_path:
print("ERROR: server/server/data/systems.db not found", file=sys.stderr)
sys.exit(1)
# Load star map topology
with open(star_map_path) as f:
with open(STAR_MAP_PATH) as f:
star_map = json.load(f)
# Load DB data
conn = sqlite3.connect(db_path)
conn = sqlite3.connect(SYSTEMS_DB_PATH)
conn.row_factory = sqlite3.Row
cur = conn.cursor()
cur.execute(
@@ -61,7 +56,6 @@ def main() -> None:
db_lookup = {row["system_id"]: dict(row) for row in cur.fetchall()}
conn.close()
# Merge
nodes = []
for n in star_map["nodes"]:
sid = n["system_id"]
@@ -82,9 +76,9 @@ def main() -> None:
nodes.sort(key=lambda x: (x["hop_distance"], x["system_id"]))
output = {
return {
"_meta": {
"generated_from": f"{star_map_path} + {db_path}",
"generated_from": "star-map.json + systems.db",
"system_count": len(nodes),
"edge_count": len(star_map["edges"]),
"note": "Client-side star map data. Regenerate with: tooling/generate-star-map-data.py",
@@ -93,15 +87,41 @@ def main() -> None:
"edges": star_map["edges"],
}
# Write output
out_path = find_file(["client/data"]) or "client/data"
os.makedirs(out_path, exist_ok=True)
out_file = os.path.join(out_path, "star_map_data.json")
with open(out_file, "w") as f:
json.dump(output, f, indent=2, ensure_ascii=False)
print(f"Generated {out_file}")
print(f" Nodes: {len(nodes)}, Edges: {len(star_map['edges'])}")
def write_output(data: dict, path: str) -> None:
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
f.write("\n")
def main() -> None:
check_mode = "--check" in sys.argv
data = generate()
if check_mode:
# Generate to temp file and compare against committed JSON
if not os.path.exists(OUTPUT_PATH):
print(f"STALE: {OUTPUT_PATH} does not exist — run without --check to generate")
sys.exit(1)
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as tmp:
json.dump(data, tmp, indent=2, ensure_ascii=False)
tmp.write("\n")
tmp_path = tmp.name
try:
with open(tmp_path) as a, open(OUTPUT_PATH) as b:
if a.read() != b.read():
print(f"STALE: {OUTPUT_PATH} differs from generated output")
print("Run: python3 tooling/generate-star-map-data.py")
sys.exit(1)
print(f"OK: {OUTPUT_PATH} is up to date")
finally:
os.unlink(tmp_path)
else:
write_output(data, OUTPUT_PATH)
print(f"Generated {OUTPUT_PATH}")
print(f" Nodes: {data['_meta']['system_count']}, Edges: {data['_meta']['edge_count']}")
if __name__ == "__main__":