Files
aetherbound-guild/tools/build_rsk001_package.py
T

84 lines
3.5 KiB
Python

#!/usr/bin/env python3
"""Build compact visual handoff boards for the RSK-001 production package."""
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
ROOT = Path(__file__).resolve().parents[1]
PAGE = ROOT / "docs/design-authority/pages/RSK-001-risk-board"
APPROVED = PAGE / "approved/v001/master.png"
STATIC = ROOT / "runtime/assets/entry/rsk_001_risk_board/risk-board-static-master.png"
ACTOR = ROOT / "runtime/assets/entry/recruit_stickers/pf_b01-512.png"
BOARD = PAGE / "reconstruction/v001/deconstruction-board.png"
CONTACT = PAGE / "reconstruction/v001/asset-contact-sheet.png"
def font(size: int):
for path in [
"/System/Library/Fonts/Supplemental/Arial Unicode.ttf",
"/System/Library/Fonts/Supplemental/Arial.ttf",
]:
if Path(path).exists():
return ImageFont.truetype(path, size)
return ImageFont.load_default()
def fit(image: Image.Image, width: int, height: int) -> Image.Image:
copy = image.copy()
copy.thumbnail((width, height), Image.Resampling.LANCZOS)
canvas = Image.new("RGB", (width, height), "#182a31")
canvas.paste(copy, ((width - copy.width) // 2, (height - copy.height) // 2))
return canvas
def deconstruction_board() -> None:
source = Image.open(APPROVED).convert("RGB")
canvas = fit(source, 1600, 900)
draw = ImageDraw.Draw(canvas, "RGBA")
labels = [
("WORLD", (0.01, 0.01, 0.98, 0.98), "#4c9baf"),
("PARTY SNAPSHOT", (0.24, 0.01, 0.74, 0.25), "#d49a3a"),
("THREE EQUAL OPTIONS", (0.07, 0.28, 0.89, 0.77), "#6c9c59"),
("COMMAND RAIL", (0.01, 0.82, 0.98, 0.99), "#a65350"),
]
title_font = font(26)
for label, bounds, colour in labels:
x0, y0, x1, y1 = [int(value * 1600) for value in bounds]
draw.rectangle((x0, y0, x1, y1), outline=colour, width=5)
draw.rounded_rectangle((x0 + 12, y0 + 10, x0 + 320, y0 + 48), 8, fill=colour)
draw.text((x0 + 22, y0 + 16), label, fill="white", font=title_font)
draw.rectangle((22, 22, 370, 76), fill="#101d27cc", outline="#e7c575", width=2)
draw.text((38, 34), "RSK-001 LAYER MAP", fill="#f8e7b0", font=font(24))
BOARD.parent.mkdir(parents=True, exist_ok=True)
canvas.save(BOARD)
def contact_sheet() -> None:
tiles = [
("approved master", Image.open(APPROVED).convert("RGB")),
("runtime clean master", Image.open(STATIC).convert("RGB")),
("recruit texture PF-B01", Image.open(ACTOR).convert("RGBA").convert("RGB")),
]
width, height = 1500, 920
canvas = Image.new("RGB", (width, height), "#16252d")
draw = ImageDraw.Draw(canvas)
draw.text((36, 28), "RSK-001 ASSET CONTACT SHEET", fill="#f8e7b0", font=font(30))
tile_w, tile_h = 700, 380
positions = [(40, 90), (760, 90), (40, 510)]
for (label, image), (x, y) in zip(tiles, positions):
draw.rounded_rectangle((x - 8, y - 8, x + tile_w + 8, y + tile_h + 44), 10, fill="#233842", outline="#b78e4c", width=2)
canvas.paste(fit(image, tile_w, tile_h), (x, y))
draw.text((x + 14, y + tile_h + 10), label, fill="#f8e7b0", font=font(22))
draw.text((760, 525), "Runtime policy", fill="#f8e7b0", font=font(24))
policy = "Static world/frame is reused.\nRecruit identity, labels, values, icons,\nselection and hit areas are engine-owned.\nNo new AI raster asset is required."
draw.multiline_text((760, 570), policy, fill="#e8eef0", font=font(22), spacing=12)
CONTACT.parent.mkdir(parents=True, exist_ok=True)
canvas.save(CONTACT)
if __name__ == "__main__":
deconstruction_board()
contact_sheet()