#!/usr/bin/env python3 """Rebuild data/kg/_summary.json by inspecting which tiles are on disk. Each dungeon's floor is assumed to be 16x16 tiles at z=4 (that's the convention kg uses for classic dungeons we sampled). If any tile is missing, report it but keep the floor in the summary so stitching can paste a black-fill placeholder. """ from __future__ import annotations import json from pathlib import Path import re ROOT = Path(__file__).resolve().parent.parent KG_DIR = ROOT / "data" / "kg" REGISTRY = ROOT / "data" / "kg_dungeons.json" ZOOM = 4 COLS = ROWS = 16 def main() -> int: registry = json.loads(REGISTRY.read_text()) dungeons = [] total_missing = 0 for d in registry["dungeons"]: tile_key = d["tile_key"] root = KG_DIR / tile_key if not root.exists(): continue floor_dirs = sorted([p for p in root.iterdir() if p.is_dir() and p.name.startswith("floor")], key=lambda p: int(re.search(r"\d+", p.name).group())) floors = [] for fd in floor_dirs: zd = fd / f"z{ZOOM}" if not zd.exists(): continue present = {p.name for p in zd.glob("*.png")} missing = [] for x in range(COLS): for y in range(ROWS): if f"{x}_{y}.png" not in present: missing.append((x, y)) if not present: continue idx = int(re.search(r"\d+", fd.name).group()) floors.append({ "index": idx, "cols": COLS, "rows": ROWS, "missing_tiles": len(missing), }) total_missing += len(missing) dungeons.append({ "tile_key": tile_key, "name": d["name"], "expansion": "classic", "max_zoom": ZOOM, "floors": floors, "data_fetched": (root / "split_floors.js").exists(), }) summary = {"compiled_hash": "(resynced from disk)", "dungeons": dungeons} (KG_DIR / "_summary.json").write_text(json.dumps(summary, indent=2)) print(f"wrote summary: {len(dungeons)} dungeons, {total_missing} missing tiles total") for d in dungeons: f_str = ", ".join(f"f{f['index']}({f['missing_tiles']}miss)" if f['missing_tiles'] else f"f{f['index']}" for f in d['floors']) flag = "" if d["data_fetched"] else " [no data]" print(f" {d['name']:30s} {f_str}{flag}") return 0 if __name__ == "__main__": raise SystemExit(main())