| import gradio as gr |
| import json |
| import os |
| import uuid |
| import time |
| import re |
| from datasets import Dataset, load_dataset |
| from systems.reputation_system import format_reputation_for_ui |
| from systems.inventory_system import get_inventory_markdown, get_inventory_images |
| from systems.relationship_system import get_relationships_markdown |
| from systems.house_points_system import format_house_points_for_ui |
| from systems.spell_system import get_known_spells_markdown |
| |
| |
| |
|
|
| def save_to_hf(dataset_repo, state_json, history_json): |
| data = { |
| "state": [state_json], |
| "history": [history_json] |
| } |
|
|
| ds = Dataset.from_dict(data) |
|
|
| ds.push_to_hub( |
| dataset_repo, |
| private=True |
| ) |
| |
| return "Game Saved ☁️" |
|
|
| def load_from_hf(dataset_repo): |
| ds = load_dataset( |
| dataset_repo, |
| split="train" |
| ) |
|
|
| state_json = ds[0]["state"] |
| history_json = ds[0]["history"] |
|
|
| return state_json, history_json |
|
|
| def load_and_enter_game(dataset_repo, from_char_screen=True): |
| """ |
| Load saved game and switch to game screen. |
| from_char_screen=True → hide char/stat screens and show game screen. |
| from_char_screen=False → already in game screen, just refresh data. |
| """ |
|
|
| try: |
| state_json, history_json = load_from_hf(dataset_repo) |
| state = json.loads(state_json) |
| history = json.loads(history_json) if history_json else [] |
|
|
| |
| default_stats = { |
| "strength": 5, "agility": 5, "intelligence": 5, |
| "charisma": 5, "willpower": 5, |
| "light_dark": 0, "order_chaos": 0, "trouble_level": 0, |
| "reputation": 0, |
| "house_points": 0, |
| "house": "Gryffindor", "year": 3, |
| "traits": [], "aspirations": [], |
| "credits": 150, "inventory": [], |
| "relationships": {}, |
| "dynamic_npcs": {}, |
| "known_spells": {}, |
| } |
| for key, default in default_stats.items(): |
| if key not in state: |
| state[key] = default |
|
|
| |
| trait_line = "" |
| if state.get("traits"): |
| trait_line = f"\n**Traits:** {' · '.join(state['traits'])}" |
| asp_line = "" |
| if state.get("aspirations"): |
| asp_line = f"\n**Aspirations:** {' · '.join(state['aspirations'])}" |
|
|
| |
| stats_md = ( |
| f"**House:** {state['house']} · **Year:** {state['year']}" |
| f"{trait_line}{asp_line}\n\n---\n" |
| f"**Strength:** {state['strength']} \n" |
| f"**Agility:** {state['agility']} \n" |
| f"**Intelligence:** {state['intelligence']} \n" |
| f"**Charisma:** {state['charisma']} \n" |
| f"**Willpower:** {state['willpower']} " |
| ) |
| |
| |
| inventory_md = get_inventory_markdown(state) |
| inventory_images = get_inventory_images(state) |
| relations_md = get_relationships_markdown(state) |
| known_spells_md = get_known_spells_markdown(state) |
| |
| |
| saved_model = state.get("saved_model", "Auto (Language Routing)") |
| saved_image_model = state.get("saved_image_model", "Auto (Recommended)") |
| |
| |
| if from_char_screen: |
| char_screen_update = gr.update(visible=False) |
| stat_screen_update = gr.update(visible=False) |
| game_screen_update = gr.update(visible=True) |
| else: |
| char_screen_update = gr.update() |
| stat_screen_update = gr.update() |
| game_screen_update = gr.update() |
| |
| return ( |
| json.dumps(state), |
| history, |
| char_screen_update, |
| stat_screen_update, |
| game_screen_update, |
| state.get("avatar"), |
| f"### {state.get('name', 'Unknown')}", |
| state["light_dark"], |
| state["order_chaos"], |
| format_reputation_for_ui(state.get("reputation", 0)), |
| format_house_points_for_ui(state.get("house_points", 0)), |
| stats_md, |
| gr.update(), |
| saved_model, |
| saved_image_model, |
| inventory_md, |
| inventory_images, |
| relations_md, |
| known_spells_md, |
| ) |
| except Exception as e: |
| print(f"--- DEBUG INFO [SAVE SYSTEM]: Load error: {e}") |
| |
| empty_inventory_md = "*Your pack is empty.*" |
| empty_inventory_images = [] |
| if from_char_screen: |
| return ( |
| "{}", [], |
| gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), |
| None, "### Error loading game", |
| 0, 0, |
| "🫥 **Unassuming** (0)", |
| "🏠 **+0** House Points — 😐 Unproven", |
| gr.update(), |
| gr.update(), |
| "Auto (Language Routing)", |
| "Auto (Recommended)", |
| empty_inventory_md, empty_inventory_images, |
| "*You haven't gotten close to anyone yet.*", |
| "*You haven't learned any spells yet.*", |
| ) |
| else: |
| |
| return ( |
| "{}", [], |
| gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), |
| None, "### Error loading game", |
| 0, 0, |
| "🫥 **Unassuming** (0)", |
| "🏠 **+0** House Points — 😐 Unproven", |
| gr.update(), |
| gr.update(), |
| "Auto (Language Routing)", |
| "Auto (Recommended)", |
| empty_inventory_md, empty_inventory_images, |
| "*You haven't gotten close to anyone yet.*", |
| "*You haven't learned any spells yet.*", |
| ) |
|
|
| def load_in_game(dataset_repo): |
| """Convenience wrapper for the in-game load button.""" |
| return load_and_enter_game(dataset_repo, from_char_screen=False) |