#!/usr/bin/env python3 """Screenshots for docs/screenshots with the desktop build (no browser needed). 1. `cargo test --release --bins export_scenes -- --ignored` writes the scene savegames to /tmp/scenes. 2. `cargo build --profile desktop` 3. `python3 tools/shots_desktop.py [--style hd|pixel] [names...]` runs the game once per scene with DC_SHOT (see the self test in src/main.rs), makes its window float at 1280x800 (Hyprland), and writes docs/screenshots/.png scaled to 1280x800. `title` is the title screen, `bestiary` the bestiary. Needs Pillow (for the scaling) and Hyprland's hyprctl. """ import json, os, subprocess, sys, time ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) GAME = os.path.join(ROOT, "target", "desktop", "dungeoncraft") def window_to_1280x800(): w = "class:miniquad-application" for _ in range(50): time.sleep(0.3) out = subprocess.run(["hyprctl", "clients", "-j"], capture_output=True, text=True).stdout if any(c.get("class") == "miniquad-application" for c in json.loads(out or "[]")): break for d in (f'hl.dsp.window.float({{ action = "on", window = "{w}" }})', f'hl.dsp.window.resize({{ x = 1280, y = 800, relative = false, window = "{w}" }})', f'hl.dsp.window.center({{ window = "{w}" }})'): subprocess.run(["hyprctl", "dispatch", d], capture_output=True) def shot(name, style, after=8): out = f"/tmp/shot-{name}.png" env = dict(os.environ, DC_SHOT=name if name in ("title", "bestiary") else f"/tmp/scenes/{name}.json", DC_SHOT_STYLE=style, DC_SHOT_AFTER=str(after), DC_SHOT_OUT=out) p = subprocess.Popen([GAME], env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) window_to_1280x800() p.wait(timeout=120) from PIL import Image im = Image.open(out).convert("RGB").resize((1280, 800), Image.LANCZOS) dest = os.path.join(ROOT, "docs", "screenshots", ("title-battle" if name == "title" else name) + ".png") im.save(dest, optimize=True) print(dest) if __name__ == "__main__": args = sys.argv[1:] style = "hd" if args[:1] == ["--style"]: style, args = args[1], args[2:] names = args or ["title"] + sorted(f[:-5] for f in os.listdir("/tmp/scenes") if f.endswith(".json")) for n in names: shot(n, style, 14 if n == "title" else 8)