#!/usr/bin/env python3 """Validate core romance data files.""" from __future__ import annotations import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] DATA = ROOT / "data" def load_json(path: Path) -> dict: with path.open("r", encoding="utf-8") as handle: return json.load(handle) def fail(message: str) -> None: print(f"ERROR: {message}", file=sys.stderr) raise SystemExit(1) def main() -> None: characters_doc = load_json(DATA / "characters.json") locations_doc = load_json(DATA / "locations.json") progression_doc = load_json(DATA / "progression.json") minimum_age = characters_doc["content_rules"]["minimum_age"] locations = {location["id"] for location in locations_doc["locations"]} character_ids: set[str] = set() for character in characters_doc["characters"]: character_id = character["id"] if character_id in character_ids: fail(f"duplicate character id: {character_id}") character_ids.add(character_id) if character["age"] < minimum_age: fail( f"{character['display_name']} is {character['age']}; " f"minimum age is {minimum_age}" ) for location_id in character["preferred_locations"]: if location_id not in locations: fail(f"{character_id} references missing preferred location {location_id}") first_location = character["first_encounter"]["location"] if first_location not in locations: fail(f"{character_id} references missing first encounter location {first_location}") event_stages = [] for event in character["date_events"]: event_stages.append(event["stage"]) event_location = event["location"] if event_location not in locations: fail(f"{character_id} references missing date location {event_location}") if event_stages != [1, 2, 3]: fail(f"{character_id} date event stages must be [1, 2, 3]") for hook in character["adult_event_hooks"]: flags = set(hook["required_flags"]) if "consent_confirmed" not in flags: fail(f"{character_id} adult event hook lacks consent_confirmed") if "lovers" not in flags: fail(f"{character_id} adult event hook lacks lovers flag") adult_requirements = progression_doc["adult_event_requirements"] if adult_requirements["minimum_character_age"] != minimum_age: fail("progression minimum age does not match character content rules") print( "Validated " f"{len(character_ids)} characters, " f"{len(locations)} locations, " f"{len(progression_doc['relationship_stages'])} relationship stages." ) if __name__ == "__main__": main()