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 # ---------------------------- # SAVE / LOAD (HF DATASET) # ---------------------------- 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 [] # EKSİK STATLARI DOLDUR (eski kayıtlar için) default_stats = { "strength": 5, "agility": 5, "intelligence": 5, "charisma": 5, "willpower": 5, "light_dark": 0, "order_chaos": 0, "trouble_level": 0, "reputation": 0, # ← reputation axis "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 # Build stat display (includes traits & aspirations if present) 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'])}" # Statları formatla 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 helpers — called AFTER state is populated 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) # Kaydedilmiş model seçimlerini al (yoksa "Auto") saved_model = state.get("saved_model", "Auto (Language Routing)") saved_image_model = state.get("saved_image_model", "Auto (Recommended)") # Eğer karakter ekranından geliyorsak, stat_screen'i gizleyip game_screen'i göster 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), # player_state history, # chatbot char_screen_update, # char_screen visibility stat_screen_update, # stat_screen visibility game_screen_update, # game_screen visibility state.get("avatar"), # profile_pic f"### {state.get('name', 'Unknown')}", # profile_info state["light_dark"], # light_dark_slider state["order_chaos"], # order_chaos_slider format_reputation_for_ui(state.get("reputation", 0)), # reputation_text format_house_points_for_ui(state.get("house_points", 0)), # house_points_text stats_md, # stat_display gr.update(), # scene_image (leave as-is) saved_model, # model_selector value saved_image_model, # image_model_selector value inventory_md, inventory_images, relations_md, known_spells_md, ) except Exception as e: print(f"--- DEBUG INFO [SAVE SYSTEM]: Load error: {e}") # Hata durumunda mevcut ekranda kal, uyarı göster (isteğe bağlı) 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)", # reputation_text fallback "🏠 **+0** House Points — 😐 Unproven", # house_points_text fallback gr.update(), # stat_display gr.update(), # scene_image (was missing — shifted every field after it) "Auto (Language Routing)", # model_selector "Auto (Recommended)", # image_model_selector empty_inventory_md, empty_inventory_images, "*You haven't gotten close to anyone yet.*", "*You haven't learned any spells yet.*", ) else: # Oyun içinde hata olursa sadece state'i değiştirme return ( "{}", [], gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), None, "### Error loading game", 0, 0, "🫥 **Unassuming** (0)", # reputation_text fallback "🏠 **+0** House Points — 😐 Unproven", # house_points_text fallback gr.update(), # stat_display gr.update(), # scene_image (was missing — shifted every field after it) "Auto (Language Routing)", # model_selector "Auto (Recommended)", # image_model_selector 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)