diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..b017bc54985b05cac05bb8b5c69b462a283916ee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,3 +33,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text *tfevents* filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.webp filter=lfs diff=lfs merge=lfs -text +*.jpeg filter=lfs diff=lfs merge=lfs -text +*.ico filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d764d3a77bf9b32493dd209e00eb49fdc758e178 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +**/__pycache__/** +**/chromadb_saves/ +/log/ +/experiment_saves/ +run.sh +/config/ +.vscode/ +nohup.out +BookWorld_test.py \ No newline at end of file diff --git a/BookWorld.py b/BookWorld.py new file mode 100644 index 0000000000000000000000000000000000000000..377c5a32f5c94ca9c898520b8fbe5236f5320ec2 --- /dev/null +++ b/BookWorld.py @@ -0,0 +1,1064 @@ +from datetime import datetime +from tqdm import tqdm +import json +import os +import warnings +import random +from typing import Any, Dict, List, Optional, Literal +from collections import defaultdict +import uuid + +from bw_utils import * +from modules.main_role_agent import RPAgent +from modules.world_agent import WorldAgent +from modules.history_manager import HistoryManager +import argparse + +warnings.filterwarnings('ignore') + +class Server(): + def __init__(self, + preset_path: str, + world_llm_name: str, + role_llm_name: str, + embedding_name:str = "bge-m3") : + """ + The initialization function of the system. + + Args: + preset_path (str): The path to config file of this experiment. + world_llm_name (str, optional): The base model of the world agent. Defaults to 'gpt-4o'. + role_llm_name (str, optional): The base model of all the role agents. Defaults to 'gpt-4o'. + mode (str, optional): If set to be 'script', the role agents will act according to the given script. + If set to be 'free', the role agents will act freely based on their backround. + Defaults to 'free'. + """ + + self.role_llm_name: str = role_llm_name + self.world_llm_name: str = world_llm_name + self.embedding_name:str = embedding_name + config = load_json_file(preset_path) + self.preset_path = preset_path + self.config: Dict = config + self.experiment_name: str = os.path.basename(preset_path).replace(".json","") + "/" + config["experiment_subname"] + "_" + role_llm_name + + role_agent_codes: List[str] = config['role_agent_codes'] + world_file_path: str = config["world_file_path"] + map_file_path: str = config["map_file_path"] if "map_file_path" in config else "" + role_file_dir: str = config["role_file_dir"] if "role_file_dir" in config else "./data/roles/" + loc_file_path: str = config["loc_file_path"] + self.intervention: str = "" if "intervention" in config else "" + self.event = self.intervention + self.script: str = config["script"] if "script" in config else "" + self.language: str = config["language"] if "language" in config else "zh" + self.source:str = config["source"] if "source" in config else "" + + self.idx: int = 0 + self.cur_round: int = 0 + self.progress: str = "剧本刚刚开始,还什么都没有发生" if self.language == 'zh' else "The story has just begun, nothing happens yet." + self.moving_roles_info: Dict[str, Any] = {} + self.history_manager = HistoryManager() + self.start_time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + self.current_status = { + "location_code":"", + "group":role_agent_codes, + } + self.scene_characters = {} + self.event_history = [] + + self.role_llm = get_models(role_llm_name) + self.logger = get_logger(self.experiment_name) + self.init_role_agents(role_agent_codes = role_agent_codes, + role_file_dir = role_file_dir, + world_file_path=world_file_path, + llm = self.role_llm) + + if world_llm_name == role_llm_name: + self.world_llm = self.role_llm + else: + self.world_llm = get_models(world_llm_name) + self.init_world_agent_from_file(world_file_path = world_file_path, + map_file_path = map_file_path, + loc_file_path = loc_file_path, + llm = self.world_llm) + + # Init + def init_role_agents(self, + role_agent_codes: List[str], + role_file_dir:str, + world_file_path:str, + llm) -> None: + self.role_codes: List[str] = role_agent_codes + self.role_agents: Dict[str, RPAgent] = {} + + for role_code in role_agent_codes: + if check_role_code_availability(role_code,role_file_dir): + self.role_agents[role_code] = RPAgent(role_code=role_code, + role_file_dir=role_file_dir, + world_file_path=world_file_path, + source = self.source, + language=self.language, + llm_name = self.role_llm_name, + llm = llm, + embedding_name=self.embedding_name, + ) + # print(f"{role_code} Initialized.") + else: + print(f"Warning: The specified role `{role_code}` does not exist.") + + def init_world_agent_from_file(self, + world_file_path: str, + map_file_path: str, + loc_file_path: str, + llm) -> None: + self.world_agent: WorldAgent = WorldAgent(world_file_path = world_file_path, + location_file_path = loc_file_path, + map_file_path = map_file_path, + llm_name=self.world_llm_name, + llm = llm, + language=self.language) + for role_code in self.role_agents: + self.role_agents[role_code].world_db = self.world_agent.db + self.role_agents[role_code].world_db_name = self.world_agent.db_name + + def init_role_locations(self, random_allocate: bool = True): + """ + Set initial positions of the roles. + + Args: + random_allocate (bool, optional): if set to be True, the initial positions of the roles are randomly assigned. Defaults to True. + """ + init_locations_code = random.choices(self.world_agent.locations, k = len(self.role_codes)) + for i,role_code in enumerate(self.role_codes): + self.role_agents[role_code].set_location(init_locations_code[i], self.world_agent.find_location_name(init_locations_code[i])) + info_text = f"{self.role_agents[role_code].nickname} 现在位于 {self.world_agent.find_location_name(init_locations_code[i])}" \ + if self.language == "zh" else f"{self.role_agents[role_code].nickname} is now located at {self.world_agent.find_location_name(init_locations_code[i])}" + self.log(info_text) + + # Simulation + def simulate_generator(self, + rounds: int = 10, + save_dir: str = "", + if_save: Literal[0,1] = 0, + mode: Literal["free", "script"] = "free", + scene_mode: Literal[0,1] = 1,): + """ + The main function of the simulation. + + Args: + rounds (int, optional): The max rounds of simulation. Defaults to 10. + save_dir (str, optional): _description_. Defaults to "". + if_save (Literal[0,1], optional): _description_. Defaults to 0. + """ + self.mode = mode + meta_info: Dict[str, Any] = self.continue_simulation_from_file(save_dir) + self.if_save: int = if_save + start_round: int = meta_info["round"] + sub_start_round:int = meta_info["sub_round"] if "sub_round" in meta_info else 0 + if start_round == rounds: return + + # Setting Locations + if not meta_info["location_setted"]: + self.log("========== Start Location Setting ==========") + self.init_role_locations() + self._save_current_simulation("location") + + # Setting Goals + if not meta_info["goal_setted"]: + yield ("system","","-- Setting Goals --",None) + self.log("========== Start Goal Setting ==========") + + if self.mode == "free": + self.get_event() + self.log(f"--------- Free Mode: Current Event ---------\n{self.event}\n") + self.event_history.append(self.event) + elif self.mode == "script": + self.get_script() + self.log(f"--------- Script Mode: Setted Script ---------\n{self.script}\n") + self.event_history.append(self.event) + if self.mode == "free": + for role_code in self.role_codes: + motivation = self.role_agents[role_code].set_motivation( + world_description = self.world_agent.description, + other_roles_info = self._get_group_members_info_dict(self.role_agents), + intervention = self.event, + script = self.script + ) + info_text = f"{self.role_agents[role_code].nickname} 设立了动机: {motivation}" \ + if self.language == "zh" else f"{self.role_agents[role_code].nickname} has set the motivation: {motivation}" + + record_id = str(uuid.uuid4()) + self.log(info_text) + self.record(role_code=role_code, + detail=info_text, + actor = role_code, + group = [role_code], + actor_type = 'role', + act_type="goal setting", + record_id = record_id) + yield ("role",role_code,info_text,record_id) + + self._save_current_simulation("goal") + + yield ("system","","-- Simulation Started --",None) + selected_role_codes = [] + # Simulating + for current_round in range(start_round, rounds): + self.cur_round = current_round + self.log(f"========== Round {current_round+1} Started ==========") + if self.event and current_round >= 1: + self.log(f"--------- Current Event ---------\n{self.event}\n") + yield ("world","","-- Current Event --\n"+self.event, None) + self.event_history.append(self.event) + + if len(self.moving_roles_info) == len(self.role_codes): + self.settle_movement() + continue + + # Characters in next scene + if scene_mode: + group = self._name2code( + self.world_agent.decide_screen_actors( + self._get_locations_info(False), + self.history_manager.get_recent_history(5), + self.event, + list(set(selected_role_codes + list(self.moving_roles_info.keys()))))) + + selected_role_codes += group + if len(selected_role_codes) > len(self.role_codes): + selected_role_codes = [] + else: + group = self.role_codes + self.current_status['group'] = group + self.current_status['location_code'] = self.role_agents[group[0]].location_code + self.scene_characters[str(current_round)] = group + + # Prologue + # if current_round == 0 and len(group) > 0 + # prologue = self.world_agent.generate_location_prologue(location_code=self.role_agents[group[0]].location_code, history_text=self._get_history_text(group),event=self.event,location_info_text=self._find_roles_at_location(self.role_agents[group[0]].location_code,name=True)) + # self.log("--Prologue--: "+prologue) + # self.record(role_code="None",detail=prologue,act_type="prologue") + start_idx = len(self.history_manager) + + sub_round = sub_start_round + for sub_round in range(sub_start_round,3): + if self.mode == "script": + self.script_instruct(self.progress) + else: + for role_code in group: + self.role_agents[role_code].update_goal(other_roles_status=self._get_status_text(self.role_codes)) + + for role_code in group: + if scene_mode: + role_code = self._name2code(self.world_agent.decide_next_actor("\n".join(self.history_manager.get_recent_history(3)),self._get_group_members_info_text(group,status=True),self.script)) if scene_mode else role_code + + yield from self.implement_next_plan(role_code = role_code, + group = group) + self._save_current_simulation("action", current_round, sub_round) + + if_end,epilogue = self.world_agent.judge_if_ended("\n".join(self.history_manager.get_recent_history(len(self.history_manager)-start_idx))) + if if_end: + record_id = str(uuid.uuid4()) + self.log("--Epilogue--: "+epilogue) + self.record(role_code = "None", + detail = epilogue, + actor_type="world", + act_type="epilogue", + actor = "world", + group = [], + record_id = record_id) + yield ("world","","--Epilogue--: "+epilogue, record_id) + + break + + + for role_code in group: + yield from self.decide_whether_to_move(role_code = role_code, + group = self._find_group(role_code)) + self.role_agents[role_code].update_status() + + self.settle_movement() + self.update_event(group) + + sub_start_round = 0 + self._save_current_simulation("action", current_round + 1,sub_round + 1) + + # Main functions using llm + def implement_next_plan(self,role_code: str, group: List[str]): + other_roles_info = self._get_group_members_info_dict(group) + plan = self.role_agents[role_code].plan( + other_roles_info = other_roles_info, + available_locations = self.world_agent.locations, + world_description = self.world_agent.description, + intervention = self.event, + ) + + info_text = plan["detail"] + if plan["target_role_codes"]: + plan["target_role_codes"] = self._name2code(plan["target_role_codes"]) + + + record_id = str(uuid.uuid4()) + self.log(f"-Action-\n{self.role_agents[role_code].role_name}: "+ info_text) + self.record(role_code = role_code, + detail = plan["detail"], + actor_type = 'role', + act_type = "plan", + actor = role_code, + group = plan["target_role_codes"] + [role_code], + plan = plan, + record_id = record_id + ) + yield ("role", role_code, info_text, record_id) + + if plan["interact_type"] == "single" and len(plan["target_role_codes"]) == 1 and plan["target_role_codes"][0] in group: + yield from self.start_single_role_interaction(plan, record_id) + elif plan["interact_type"] == "multi" and len(plan["target_role_codes"]) > 1 and set(plan["target_role_codes"]).issubset(set(group)) : + yield from self.start_multi_role_interaction(plan, record_id) + elif plan["interact_type"] == "enviroment": + yield from self.start_enviroment_interaction(plan,role_code, record_id) + elif plan["interact_type"] == "npc" and plan["target_npc_name"]: + yield from self.start_npc_interaction(plan,role_code,target_name=plan["target_npc_name"], record_id = record_id) + return info_text + + def decide_whether_to_move(self, + role_code: str, + group: List[str]): + if len(self.world_agent.locations) <= 1: + return False + if_move, move_detail, destination_code = self.role_agents[role_code].move(locations_info_text = self._get_locations_info(), + locations_info = self.world_agent.locations_info) + if if_move: + self.log(move_detail) + print(f"角色选择移动。{self.role_agents[role_code].role_name}正在前往{self.world_agent.find_location_name(destination_code)}" if self.language == "zh" else f"The role decides to move. {self.role_agents[role_code].role_name} is heading to {self.world_agent.find_location_name(destination_code)}.") + self.record(role_code = role_code, + detail = move_detail, + actor_type = 'role', + act_type = "move", + actor = role_code, + group = [role_code], + destinatiion_code = destination_code + ) + yield ("role",role_code,move_detail,None) + + distance = self.world_agent.get_distance(self.role_agents[role_code].location_code, destination_code) + self.role_agents[role_code].set_location(location_code=None, location_name=None) + self.moving_roles_info[role_code] = { + "location_code":destination_code, + "distance":distance + } + return if_move + + def start_enviroment_interaction(self, + plan: Dict[str, Any], + role_code: str, + record_id: str): + """ + Handles the role's interaction with the environment. + It gets interaction results from agents in the world, record the result and update the status of the role. + + Args: + plan (Dict[str, Any]): The details of the action. + role_code (str): The action maker. + + Returns: + (str): The enviroment response. + """ + if "action" not in plan: + plan["action"] = "" + self.current_status['group'] = [role_code] + location_code = self.role_agents[role_code].location_code + result = self.world_agent.enviroment_interact(action_maker_name = self.role_agents[role_code].role_name, + action = plan["action"], + action_detail = conceal_thoughts(self.history_manager.search_record_detail(record_id)), + location_code = location_code) + env_record_id = str(uuid.uuid4()) + self.log(f"(Enviroment):{result}") + self.record(role_code = role_code, + detail = result, + actor_type = 'world', + act_type = "enviroment", + initiator = role_code, + actor = "world", + group = [role_code], + record_id = env_record_id) + yield ("world","","(Enviroment):" + result, env_record_id) + + return conceal_thoughts(self.history_manager.search_record_detail(record_id)) + self.history_manager.search_record_detail(env_record_id) + + def start_npc_interaction(self, + plan: Dict[str, Any], + role_code: str, + target_name: str, + record_id: str, + max_rounds: int = 3): + """ + Handles the role's interaction with the environment. + It gets interaction results from agents in the world, record the result and update the status of the role. + + Args: + plan (Dict[str, Any]): The details of the action. + role_code (str): The action maker. + target_name (str): The target npc. + + Returns: + (str): The enviroment response. + """ + interaction = plan + start_idx = len(self.history_manager) + + self.log(f"----------NPC Interaction----------\n") + self.current_status['group'] = [role_code,target_name] + for round in range(max_rounds): + npc_interaction = self.world_agent.npc_interact(action_maker_name=self.role_agents[role_code].role_name, + action_detail=self.history_manager.search_record_detail(record_id), + location_name=self.role_agents[role_code].location_name, + target_name=target_name) + npc_detail = npc_interaction["detail"] + + npc_record_id = str(uuid.uuid4()) + self.log(f"{target_name}: " + npc_detail) + self.record(role_code = role_code, + detail = npc_detail, + actor_type = 'world', + act_type = "npc", + actor = "world", + group = [role_code], + npc_name = target_name, + record_id = npc_record_id + ) + yield ("world","",f"(NPC-{target_name}):" + npc_detail, npc_record_id) + + if npc_interaction["if_end_interaction"]: + break + + interaction = self.role_agents[role_code].npc_interact( + npc_name = target_name, + npc_response = self.history_manager.search_record_detail(npc_record_id), + history = self.history_manager.get_subsequent_history(start_idx = start_idx), + intervention = self.event + ) + detail = interaction["detail"] + + record_id = str(uuid.uuid4()) + self.log(f"{self.role_agents[role_code].role_name}: " + detail) + self.record(role_code = role_code, + detail = detail, + actor_type = 'role', + act_type = "npc", + actor = role_code, + group = [role_code], + npc_name = target_name, + record_id = record_id) + yield ("role",role_code,detail,record_id) + + if interaction["if_end_interaction"]: + break + if_end,epilogue = self.world_agent.judge_if_ended("\n".join(self.history_manager.get_subsequent_history(start_idx))) + if if_end: + break + + return "\n".join(self.history_manager.get_subsequent_history(start_idx = start_idx)) + + def start_single_role_interaction(self, + plan: Dict[str, Any], + record_id: str, + max_rounds: int = 8): + interaction = plan + acted_role_code = interaction["role_code"] + acting_role_code = interaction["target_role_codes"][0] + if acting_role_code not in self.role_codes: + print(f"Warning: Role {acting_role_code} does not exist.") + return + self.current_status['group'] = [acted_role_code,acting_role_code] + + start_idx = len(self.history_manager) + for round in range(max_rounds): + interaction = self.role_agents[acting_role_code].single_role_interact( + action_maker_code = acted_role_code, + action_maker_name = self.role_agents[acted_role_code].role_name, + action_detail = conceal_thoughts(self.history_manager.search_record_detail(record_id)), + action_maker_profile = self.role_agents[acted_role_code].role_profile, + intervention = self.event + ) + + detail = interaction["detail"] + + record_id = str(uuid.uuid4()) + self.log(f"{self.role_agents[acting_role_code].role_name}: " + detail) + self.record(role_code = acting_role_code, + detail = detail, + actor_type = 'role', + act_type = "single", + group = [acted_role_code,acting_role_code], + target_role_code = acting_role_code, + planning_role_code = plan["role_code"], + round = round, + record_id = record_id + ) + yield ("role",acting_role_code,detail,record_id) + + if interaction["if_end_interaction"]: + return + if interaction["extra_interact_type"] == "npc": + print("---Extra NPC Interact---") + result = yield from self.start_npc_interaction(plan=interaction, + role_code=acted_role_code, + target_name=interaction["target_npc_name"], + record_id=record_id) + interaction["detail"] = result + + elif interaction["extra_interact_type"] == "enviroment": + print("---Extra Env Interact---") + result = yield from self.start_enviroment_interaction(plan=interaction,role_code=acted_role_code,record_id=record_id) + interaction["detail"] = result + + if_end,epilogue = self.world_agent.judge_if_ended("\n".join(self.history_manager.get_subsequent_history(start_idx))) + if if_end: + break + acted_role_code,acting_role_code = acting_role_code,acted_role_code + return + + def start_multi_role_interaction(self, + plan: Dict[str, Any], + record_id: str, + max_rounds: int = 8): + + interaction = plan + acted_role_code = interaction["role_code"] + group = interaction["target_role_codes"] + group.append(acted_role_code) + + for code in group: + if code not in self.role_codes: + print(f"Warning: Role {code} does not exist.") + return + self.current_status['group'] = group + + start_idx = len(self.history_manager) + other_roles_info = self._get_group_members_info_dict(group) + + for round in range(max_rounds): + acting_role_code = self._name2code(self.world_agent.decide_next_actor(history_text = "\n".join(self.history_manager.get_recent_history(3)), + roles_info_text = self._get_group_members_info_text(remove_list_elements(group,acted_role_code),status=True))) + + + interaction = self.role_agents[acting_role_code].multi_role_interact( + action_maker_code = acted_role_code, + action_maker_name = self.role_agents[acted_role_code].role_name, + action_detail = conceal_thoughts(self.history_manager.search_record_detail(record_id)), + action_maker_profile = self.role_agents[acted_role_code].role_profile, + other_roles_info = other_roles_info, + intervention = self.event + ) + + detail = interaction["detail"] + + record_id = str(uuid.uuid4()) + self.log(f"{self.role_agents[acting_role_code].role_name}: "+ detail) + self.record(role_code = acting_role_code, + detail = detail, + actor_type = 'role', + act_type = "multi", + group = group, + actor = acting_role_code, + planning_role_code = plan["role_code"], + round = round, + record_id = record_id + ) + yield ("role",acting_role_code,detail,record_id) + + + if interaction["if_end_interaction"]: + break + result = "" + if interaction["extra_interact_type"] == "npc": + print("---Extra NPC Interact---") + result = yield from self.start_npc_interaction(plan=interaction,role_code=acting_role_code,target_name=interaction["target_npc_name"],record_id = record_id) + elif interaction["extra_interact_type"] == "enviroment": + print("---Extra Env Interact---") + result = yield from self.start_enviroment_interaction(plan=interaction,role_code=acting_role_code,record_id = record_id) + interaction["detail"] = self.history_manager.search_record_detail(record_id) + result + acted_role_code = acting_role_code + if_end,epilogue = self.world_agent.judge_if_ended("\n".join(self.history_manager.get_subsequent_history(start_idx))) + if if_end: + break + + return + + # Sub functions using llm + def script_instruct(self, + last_progress: str, + top_k: int = 5): + """ + Under the script mode, generate instruction for the roles at the beginning of each round. + + Args: + last_progress (str): Where the script went in the last round. + top_k (int, optional): The number of action history of each role to refer. Defaults to 1. + + Returns: + Dict[str, Any]: Instruction for each role. + """ + roles_info_text = self._get_group_members_info_text(self.role_codes,status=True) + history_text = "\n".join([self.role_agents[role_code].history_manager.get_recent_history(1)[0] for role_code in self.role_codes]) + + instruction = self.world_agent.get_script_instruction( + roles_info_text=roles_info_text, + event = self.event, + history_text=history_text, + script=self.script, + last_progress = last_progress) + + for code in instruction: + if code == "progress": + self.log("剧本进度:"+ instruction["progress"]) if self.language == "zh" else self.log("Current Stage:"+ instruction["progress"]) + elif code in self.role_codes: + # self.role_agents[code].update_goal(instruction = instruction[code]) + self.role_agents[code].goal = instruction[code] + else: + print("Instruction failed, role code:",code) + return instruction + + def get_event(self,): + if self.intervention == "" and not self.script: + roles_info_text = self._get_group_members_info_text(self.role_codes,profile=True) + status_text = self._get_status_text(self.role_codes) + event = self.world_agent.generate_event(roles_info_text=roles_info_text,event=self.intervention,history_text=status_text) + self.intervention = event + elif self.intervention == "" and self.script: + self.intervention = self.script + self.event = self.intervention + return self.intervention + + def get_script(self,): + if self.script == "": + roles_info_text = self._get_group_members_info_text(self.role_codes,profile=True) + status = "\n".join([self.role_agents[role_code].status for role_code in self.role_codes]) + script = self.world_agent.generate_script(roles_info_text=roles_info_text,event=self.intervention,history_text=status) + self.script = script + # self.event = self.script + return self.script + + def update_event(self, group: List[str], top_k: int = 1): + if self.intervention == "": + self.event = "" + else: + status_text = self._get_status_text(group) + self.event = self.world_agent.update_event(self.event, self.intervention, status_text, script = self.script) + + # other + def record(self, + role_code: str, + detail: str, + actor_type: str, + act_type: str, + group: List[str] = [], + actor: str = "", + record_id = None, + **kwargs): + if act_type == "plan" and "plan" in kwargs: + detail = f"{self.role_agents[role_code].nickname}: {detail}" + interact_type = kwargs["plan"]["interact_type"] + target = ", ".join(kwargs["plan"]["target_role_codes"]) + other_info = f"Interact type: {interact_type}, Target: {target}" + elif act_type == "move" and "destination_code" in kwargs: + destination = kwargs["destination_code"] + other_info = f"Desitination:{destination}" + elif act_type == "single": + detail = f"{self.role_agents[role_code].nickname}: {detail}" + target, planning_role, round = kwargs["target_role_code"],kwargs["planning_role_code"],kwargs["round"] + other_info = f"Target: {target}, Planning Role: {planning_role}, Round: {round}" + elif act_type == "multi": + detail = f"{self.role_agents[role_code].nickname}: {detail}" + planning_role, round = kwargs["planning_role_code"],kwargs["round"] + other_info = f"Group member:{group}, Planning Role: {planning_role}, Round:{round}," + elif act_type == "npc": + name = kwargs["npc_name"] + other_info = f"Target: {name}" + elif act_type == "enviroment": + other_info = "" + else: + other_info = "" + record = { + "cur_round":self.cur_round, + "role_code":role_code, + "detail":detail, + "actor":actor, + "group":group, # visible group + "actor_type":actor_type, + "act_type":act_type, + "other_info":other_info, + "record_id":record_id + } + self.history_manager.add_record(record) + for code in group: + self.role_agents[code].record(record) + + def settle_movement(self,): + for role_code in self.moving_roles_info.copy(): + if not self.moving_roles_info[role_code]["distance"]: + location_code = self.moving_roles_info[role_code]["location_code"] + self.role_agents[role_code].set_location(location_code, self.world_agent.find_location_name(location_code)) + self.log(f"{self.role_agents[role_code].role_name} 已到达 【{self.world_agent.find_location_name(location_code)}】" if self.language == "zh" else + f"{self.role_agents[role_code].role_name} has reached [{self.world_agent.find_location_name(location_code)}]") + del self.moving_roles_info[role_code] + else: + self.moving_roles_info[role_code]["distance"] -= 1 + + def _find_group(self,role_code): + return [code for code in self.role_codes if self.role_agents[code].location_code==self.role_agents[role_code].location_code] + + def _find_roles_at_location(self,location_code,name = False): + if name: + return [self.role_agents[code].nickname for code in self.role_codes if self.role_agents[code].location_code==location_code] + else: + return [code for code in self.role_codes if self.role_agents[code].location_code==location_code] + + def _get_status_text(self,group): + return "\n".join([self.role_agents[role_code].status for role_code in group]) + + def _get_group_members_info_text(self,group, profile = False,status = False): + roles_info_text = "" + for i, role_code in enumerate(group): + name = self.role_agents[role_code].role_name + roles_info_text += f"{i+1}. {name}\n(role_code:{role_code})\n" + if profile: + profile = self.role_agents[role_code].role_profile + roles_info_text += f"{profile}\n" + if status: + status = self.role_agents[role_code].status + roles_info_text += f"{status}\n" + return roles_info_text + + def _get_group_members_info_dict(self,group: List[str]): + info = { + role_code: { + "nickname": self.role_agents[role_code].nickname, + "profile": self.role_agents[role_code].role_profile + } + for role_code in group + } + return info + + def _get_locations_info(self,detailed = True): + location_info_text = "---当前各角色位置---\n" if self.language == "zh" else "---Current Location of Roles---\n" + if detailed: + for i,location_code in enumerate(self.world_agent.locations_info): + location_name = self.world_agent.find_location_name(location_code) + description = self.world_agent.locations_info[location_code]["description"] + location_info_text += f"\n{i+1}. {location_name}\nlocation_code:{location_code}\n{description}\n\n" + role_names = [f"{self.role_agents[code].role_name}({code})" for code in self.role_codes if self.role_agents[code].location_code == location_code] + role_names = ", ".join(role_names) + location_info_text += "目前在这里的角色有:" + role_names if self.language == "zh" else "Roles located here: " + role_names + else: + for i,location_code in enumerate(self.world_agent.locations_info): + location_name = self.world_agent.find_location_name(location_code) + role_names = [f"{self.role_agents[code].role_name}({code})" for code in self.role_codes if self.role_agents[code].location_code == location_code] + if len(role_names) == 0:continue + role_names = ", ".join(role_names) + location_info_text += f"【{location_name}】:" + role_names +";" + return location_info_text + + def _name2code(self,roles): + name_dic = {self.role_agents[code].role_name:code for code in self.role_codes} + name_dic.update({self.role_agents[code].nickname:code for code in self.role_codes}) + if isinstance(roles, list): + processed_roles = [] + for role in roles: + if role in self.role_codes: + processed_roles.append(role) + elif role in name_dic: + processed_roles.append(name_dic[role]) + elif "-" in role and role.split("-")[0] in name_dic: + processed_roles.append(name_dic[role.split("-")[0]]) + elif role.replace("_","·") in self.role_codes: + processed_roles.append(role.replace("_","·")) + else: + processed_roles.append(role) + return processed_roles + elif isinstance(roles, str) : + roles = roles.replace("\n","") + if roles in self.role_codes: + return roles + elif roles in name_dic: + return name_dic[roles] + elif f"{roles}-{self.language}" in self.role_codes: + return f"{roles}-{self.language}" + elif "-" in roles and roles.split("-")[0] in name_dic: + return name_dic[roles.split("-")[0]] + elif roles.replace("_","·") in self.role_codes: + return roles.replace("_","·") + return roles + + def log(self,text): + self.logger.info(text) + print(text) + + def _save_current_simulation(self, + stage: Literal["location", "goal", "action"], + current_round: int = 0, + sub_round:int = 0): + """ + Save the current simulation progress. + + Args: + stage (Literal["location", "goal", "action"]): The stage in which the simulation has been carried out + current_round (int, optional): If the stage is "action", specify the number of rounds that have been completed. Defaults to 0. + """ + if not self.if_save: + return + save_dir = f"./experiment_saves/{self.experiment_name}/{self.role_llm_name}/{self.start_time}" + create_dir(save_dir) + location_setted, goal_setted = False,False + if stage in ["location","goal","action"]: + location_setted = True + if stage in ["goal","action"]: + goal_setted = True + meta_info = { + "location_setted":location_setted, + "goal_setted": goal_setted, + "round": current_round, + "sub_round": sub_round, + } + + save_json_file(os.path.join(save_dir, "meta_info.json"), meta_info) + name = self.experiment_name.split("/")[0] + save_json_file(os.path.join(save_dir, f"{name}.json"), self.config) + + filename = os.path.join(save_dir, f"./server_info.json") + save_json_file(filename, self.__getstate__() ) + + self.history_manager.save_to_file(save_dir) + if hasattr(self, 'role_agents'): + for role_code in self.role_codes: + self.role_agents[role_code].save_to_file(save_dir) + self.world_agent.save_to_file(save_dir) + + def continue_simulation_from_file(self, save_dir: str): + """ + Restore the record of the last simulation. + + Args: + save_dir (str): The path where the last simulation record was saved. + + Returns: + Dict[str, Any]: The meta information recording the progress of the simulation + """ + if os.path.exists(save_dir): + meta_info = load_json_file(os.path.join(save_dir, "./meta_info.json")) + filename = os.path.join(save_dir, f"./server_info.json") + states = load_json_file(filename) + self.__setstate__(states) + for role_code in self.role_codes: + self.role_agents[role_code].load_from_file(save_dir) + self.world_agent.load_from_file(save_dir) + self.history_manager.load_from_file(save_dir) + + for record in self.history_manager.detailed_history: + for code in record["group"]: + if code in self.role_codes: + self.role_agents[code].record(record) + else: + meta_info = { + "location_setted":False, + "goal_setted": False, + "round": 0, + "sub_round": 0, + } + return meta_info + + def __getstate__(self): + states = {key: value for key, value in self.__dict__.items() \ + if isinstance(value, (str, int, list, dict, bool, type(None))) \ + and key not in ['role_agents','world_agent','logger']} + + return states + + def __setstate__(self, states): + self.__dict__.update(states) + + +class BookWorld(): + def __init__(self, + preset_path: str, + world_llm_name: str, + role_llm_name: str, + embedding_name:str = "bge-m3") : + self.server = Server(preset_path, + world_llm_name=world_llm_name, + role_llm_name=role_llm_name, + embedding_name=embedding_name) + self.selected_scene = None + + def set_generator(self, + rounds:int = 10, + save_dir:str = "", + if_save: Literal[0,1] = 0, + mode: Literal["free", "script"] = "free", + scene_mode: Literal[0,1] = 0,): + self.server.continue_simulation_from_file(save_dir) + self.generator = self.server.simulate_generator(rounds = rounds, + save_dir = save_dir, + if_save = if_save, + mode = mode, + scene_mode = scene_mode) + def get_map_info(self): + location_codes = self.server.world_agent.locations + location_names = [self.server.world_agent.find_location_name(location_code) for location_code in location_codes] + n = len(location_codes) + distances = [] + for i in range(n): + for j in range(i+1,n): + if self.server.world_agent.get_distance(location_codes[i], location_codes[j]): + distances.append({ + "source": location_names[i], + "target": location_names[j], + "distance": self.server.world_agent.get_distance(location_codes[i], location_codes[j]) + }) + + return { + "places": location_names, + "distances": distances + } + def select_scene(self,scene_number): + if scene_number == None: + self.selected_scene = scene_number + else: + self.selected_scene = str(scene_number) + + def get_characters_info(self): + characters_info = [] + if self.selected_scene == None: + codes = self.server.role_codes + else: + codes = self.server.scene_characters[str(self.selected_scene)] + for (i, code) in enumerate(codes): + agent = self.server.role_agents[code] + location = agent.location_name + if code in self.server.moving_roles_info: + location_name = self.server.world_agent.find_location_name(self.server.moving_roles_info[code]["location_code"]) + distance = self.server.moving_roles_info[code]['distance'] + location = f"Reaching {location_name}... ({distance})" + chara_info = { + "id": i, + "name": agent.nickname, + "icon": agent.icon_path, + "description": agent.role_profile, + "goal": agent.goal if agent.goal else agent.motivation, + "state": agent.status, + "location": location + } + characters_info.append(chara_info) + return characters_info + + def generate_next_message(self): + message_type, code, text,message_id = next(self.generator) + if message_type == "role": + username = self.server.role_agents[code].role_name + icon_path = self.server.role_agents[code].icon_path + else: + username = message_type + icon_path = "" + message = { + 'username': username, + 'type': message_type, # role, world, system + 'timestamp': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + 'text': text, + 'icon': icon_path, + "uuid": message_id, + "scene": self.server.cur_round + } + return message + + def get_settings_info(self): + return self.server.world_agent.world_settings + + def get_current_status(self): + status = self.server.current_status + status['event'] = self.server.event + group = [] + for code in status['group']: + if code in self.server.role_codes: + group.append(self.server.role_agents[code].nickname) + else: + group.append(code) + status['group'] = group + location_code = self.server.current_status['location_code'] + if location_code not in self.server.world_agent.locations_info: + location_name,location_description = "Undefined","Undefined" + else: + location_name,location_description = self.server.world_agent.find_location_name(location_code),self.server.world_agent.locations_info[location_code]["description"] + status['location'] = {'name': location_name, 'description': location_description} + return status + + def handle_message_edit(self,record_id,new_text): + group = self.server.history_manager.modify_record(record_id,new_text) + for code in group: + self.server.role_agents[code].history_manager.modify_record(record_id,new_text) + return + + def get_history_messages(self,save_dir): + + messages = [] + for record in self.server.history_manager.detailed_history: + message_type = record["actor_type"] + code = record["role_code"] + if message_type == "role": + username = self.server.role_agents[code].role_name + icon_path = self.server.role_agents[code].icon_path + else: + username = message_type + icon_path = "./frontend/assets/images/default-icon.jpg" + messages.append({ + 'username': username, + 'type': message_type, # role, world, system + 'timestamp': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + 'text': record["detail"], + 'icon': icon_path, + "uuid": record["record_id"], + "scene": record["cur_round"] + }) + return messages + + def generate_story(self,): + logs = self.server.history_manager.get_complete_history() + story = self.server.world_agent.log2story(logs) + return story + + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('--world_llm', type=str, default='gpt-4o-mini') + parser.add_argument('--role_llm', type=str, default='gpt-4o-mini') + parser.add_argument('--genre', type=str, default='mgdv2') + parser.add_argument('--preset_path', type=str, default='') + + parser.add_argument('--if_save', type=int, default=1, choices=[0,1]) + parser.add_argument('--scene_mode', type=int, default=0, choices=[0,1]) + parser.add_argument('--rounds', type=int, default=10) + parser.add_argument('--save_dir', type=str, default='') + parser.add_argument('--mode', type=str, default='free', choices=['free','script']) + args = parser.parse_args() + world_llm_name = args.world_llm + role_llm_name = args.role_llm + rounds = args.rounds + genre = args.genre + preset_path = args.preset_path + save_dir = args.save_dir + if_save = args.if_save + scene_mode = args.scene_mode + mode = args.mode + if not preset_path: + preset_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),f"./config/experiment_{genre}.json") + + bw = BookWorld(preset_path, world_llm_name=world_llm_name, role_llm_name=role_llm_name) + bw.set_generator(rounds = rounds, save_dir = save_dir, if_save = if_save, scene_mode = scene_mode,mode = mode) + + for i in range(100): + try: + bw.generate_next_message() + except StopIteration: + break \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..b4cfef2f75647b1d0f1e4bf206c2c8e1f8ed0308 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.10 + +RUN useradd -m -u 1000 user +USER user + +ENV HOME=/home/user \ + PATH=/home/user/.local/bin:$PATH +WORKDIR $HOME/app + +COPY --chown=user . $HOME/app + +RUN pip install --no-cache-dir --upgrade -r requirements.txt + +RUN huggingface-cli download BAAI/bge-m3 + +ENV OPENAI_API_KEY="" + +EXPOSE 8000 + +CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..a82a7cdfea3709f3e107a9e9414a3b445842f893 --- /dev/null +++ b/app.py @@ -0,0 +1,240 @@ +from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException +from fastapi.staticfiles import StaticFiles +from fastapi.responses import HTMLResponse, FileResponse +import uvicorn +import json +import asyncio +import os +from pathlib import Path +from datetime import datetime +from bw_utils import is_image, load_json_file +from BookWorld import BookWorld + +app = FastAPI() +default_icon_path = './frontend/assets/images/default-icon.jpg' +config = load_json_file('config.json') +for key in config: + if "API_KEY" in key: + os.environ[key] = config[key] + +static_file_abspath = os.path.abspath(os.path.join(os.path.dirname(__file__), 'frontend')) +app.mount("/frontend", StaticFiles(directory=static_file_abspath), name="frontend") + +class ConnectionManager: + def __init__(self): + self.active_connections: dict[str, WebSocket] = {} + self.story_tasks: dict[str, asyncio.Task] = {} + if True: + if "preset_path" in config and config["preset_path"] and os.path.exists(config["preset_path"]): + preset_path = config["preset_path"] + elif "genre" in config and config["genre"]: + genre = config["genre"] + preset_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),f"./config/experiment_{genre}.json") + else: + raise ValueError("Please set the preset_path in `config.json`.") + self.bw = BookWorld(preset_path = preset_path, + world_llm_name = config["world_llm_name"], + role_llm_name = config["role_llm_name"], + embedding_name = config["embedding_model_name"]) + self.bw.set_generator(rounds = config["rounds"], + save_dir = config["save_dir"], + if_save = config["if_save"], + mode = config["mode"], + scene_mode = config["scene_mode"],) + else: + from BookWorld_test import BookWorld_test + self.bw = BookWorld_test() + + async def connect(self, websocket: WebSocket, client_id: str): + await websocket.accept() + self.active_connections[client_id] = websocket + + def disconnect(self, client_id: str): + if client_id in self.active_connections: + del self.active_connections[client_id] + self.stop_story(client_id) + + def stop_story(self, client_id: str): + if client_id in self.story_tasks: + self.story_tasks[client_id].cancel() + del self.story_tasks[client_id] + + async def start_story(self, client_id: str): + if client_id in self.story_tasks: + # 如果已经有任务在运行,先停止它 + self.stop_story(client_id) + + # 创建新的故事任务 + self.story_tasks[client_id] = asyncio.create_task( + self.generate_story(client_id) + ) + + async def generate_story(self, client_id: str): + """持续生成故事的协程""" + try: + while True: + if client_id in self.active_connections: + message,status = await self.get_next_message() + await self.active_connections[client_id].send_json({ + 'type': 'message', + 'data': message + }) + await self.active_connections[client_id].send_json({ + 'type': 'status_update', + 'data': status + }) + # 添加延迟,控制消息发送频率 + await asyncio.sleep(1) # 可以调整这个值 + else: + break + except asyncio.CancelledError: + # 任务被取消时的处理 + print(f"Story generation cancelled for client {client_id}") + except Exception as e: + print(f"Error in generate_story: {e}") + + async def get_initial_data(self): + """获取初始化数据""" + return { + 'characters': self.bw.get_characters_info(), + 'map': self.bw.get_map_info(), + 'settings': self.bw.get_settings_info(), + 'status': self.bw.get_current_status(), + 'history_messages':self.bw.get_history_messages(save_dir = config["save_dir"]), + } + + async def get_next_message(self): + """从BookWorld获取下一条消息""" + message = self.bw.generate_next_message() + if not is_image(message["icon"]): + message["icon"] = default_icon_path + status = self.bw.get_current_status() + return message,status + +manager = ConnectionManager() + +@app.get("/") +async def get(): + html_file = Path("index.html") + return HTMLResponse(html_file.read_text()) + +@app.get("/data/{full_path:path}") +async def get_file(full_path: str): + # 可以设置多个基础路径 + base_paths = [ + Path("/data/") + ] + + for base_path in base_paths: + file_path = base_path / full_path + if file_path.exists() and file_path.is_file(): + return FileResponse(file_path) + else: + return FileResponse(default_icon_path) + + raise HTTPException(status_code=404, detail="File not found") + +@app.websocket("/ws/{client_id}") +async def websocket_endpoint(websocket: WebSocket, client_id: str): + await manager.connect(websocket, client_id) + try: + initial_data = await manager.get_initial_data() + await websocket.send_json({ + 'type': 'initial_data', + 'data': initial_data + }) + + while True: + data = await websocket.receive_text() + message = json.loads(data) + + if message['type'] == 'user_message': + # 处理用户消息 + await websocket.send_json({ + 'type': 'message', + 'data': { + 'username': 'User', + 'timestamp': message['timestamp'], + 'text': message['text'], + 'icon': default_icon_path, + } + }) + + elif message['type'] == 'control': + # 处理控制命令 + if message['action'] == 'start': + await manager.start_story(client_id) + elif message['action'] == 'pause': + manager.stop_story(client_id) + elif message['action'] == 'stop': + manager.stop_story(client_id) + # 可以在这里添加额外的停止逻辑 + + elif message['type'] == 'edit_message': + # 处理消息编辑 + edit_data = message['data'] + # 假设 BookWorld 类有一个处理编辑的方法 + manager.bw.handle_message_edit( + record_id=edit_data['uuid'], + new_text=edit_data['text'] + ) + + elif message['type'] == 'request_scene_characters': + manager.bw.select_scene(message['scene']) + scene_characters = manager.bw.get_characters_info() + await websocket.send_json({ + 'type': 'scene_characters', + 'data': scene_characters + }) + + elif message['type'] == 'generate_story': + # 生成故事文本 + story_text = manager.bw.generate_story() + # 发送生成的故事作为新消息 + await websocket.send_json({ + 'type': 'message', + 'data': { + 'username': 'System', + 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + 'text': story_text, + 'icon': default_icon_path, + 'type': 'story' + } + }) + + elif message['type'] == 'request_api_configs': + await websocket.send_json({ + 'type': 'api_configs', + 'data': API_CONFIGS + }) + + elif message['type'] == 'api_settings': + # 处理API设置 + settings = message['data'] + # 设置环境变量 + os.environ[settings['envKey']] = settings['apiKey'] + + # 更新BookWorld的设置 + manager.bw.update_api_settings( + provider=settings['provider'], + model=settings['model'] + ) + + # 发送确认消息 + await websocket.send_json({ + 'type': 'message', + 'data': { + 'username': 'System', + 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + 'text': f'已更新 {settings["provider"]} API设置', + 'icon': default_icon_path, + 'type': 'system' + } + }) + except Exception as e: + print(f"WebSocket error: {e}") + finally: + manager.disconnect(client_id) + +if __name__ == "__main__": + uvicorn.run("server:app", host="0.0.0.0", port=8000, reload=True) diff --git a/bw_utils.py b/bw_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..ae5a502baf7021842fb65f6fe56a30e56e8ff3c3 --- /dev/null +++ b/bw_utils.py @@ -0,0 +1,466 @@ +import os +import pickle +import json +import torch +import logging +import datetime +import re +import random +import base64 + +MODEL_NAME_DICT = { + "gpt3":"openai/gpt-3.5-turbo", + "gpt-4":"openai/gpt-4", + "gpt-4o":"openai/gpt-4o", + "gpt-4o-mini":"openai/gpt-4o-mini", + "gpt-3.5-turbo":"openai/gpt-3.5-turbo", + "deepseek-r1":"deepseek/deepseek-r1", + "deepseek-v3":"deepseek/deepseek-chat", + "gemini-2":"google/gemini-2.0-flash-001", + "gemini-1.5":"google/gemini-flash-1.5", + "llama3-70b": "meta-llama/llama-3.3-70b-instruct", + "qwen-turbo":"qwen/qwen-turbo", + "qwen-plus":"qwen/qwen-plus", + "qwen-max":"qwen/qwen-max", + "qwen-2.5-72b":"qwen/qwen-2.5-72b-instruct", + "claude-3.5-sonnet":"anthropic/claude-3.5-sonnet", + "phi-4":"microsoft/phi-4", +} + +def get_models(model_name): + if os.getenv("OPENROUTER_API_KEY", default="") and model_name in MODEL_NAME_DICT: + from modules.llm.OpenRouter import OpenRouter + return OpenRouter(model=MODEL_NAME_DICT[model_name]) + elif model_name.startswith('gpt-3.5'): + from modules.llm.LangChainGPT import LangChainGPT + return LangChainGPT(model="gpt-3.5-turbo") + elif model_name == 'gpt-4': + from modules.llm.LangChainGPT import LangChainGPT + return LangChainGPT(model="gpt-4") + elif model_name == 'gpt-4-turbo': + from modules.llm.LangChainGPT import LangChainGPT + return LangChainGPT(model="gpt-4") + elif model_name == 'gpt-4o': + from modules.llm.LangChainGPT import LangChainGPT + return LangChainGPT(model="gpt-4o") + elif model_name == "gpt-4o-mini": + from modules.llm.LangChainGPT import LangChainGPT + return LangChainGPT(model="gpt-4o-mini") + elif model_name.startswith("claude"): + from modules.llm.LangChainGPT import LangChainGPT + return LangChainGPT(model="claude-3-5-sonnet-20241022") + elif model_name.startswith('qwen'): + from modules.llm.Qwen import Qwen + return Qwen(model = model_name) + elif model_name.startswith('deepseek'): + from modules.llm.DeepSeek import DeepSeek + return DeepSeek() + elif model_name.startswith('doubao'): + from modules.llm.Doubao import Doubao + return Doubao() + elif model_name.startswith('gemini'): + from modules.llm.Gemini import Gemini + return Gemini() + else: + print(f'Warning! undefined model {model_name}, use gpt-3.5-turbo instead.') + from modules.llm.LangChainGPT import LangChainGPT + return LangChainGPT() + +def build_world_agent_data(world_file_path,max_words = 30): + world_dir = os.path.dirname(world_file_path) + details_dir = os.path.join(world_dir,"./world_details") + data = [] + settings = [] + if os.path.exists(details_dir): + for path in get_child_paths(details_dir): + if os.path.splitext(path)[-1] == ".txt": + text = load_text_file(path) + data += split_text_by_max_words(text,max_words) + if os.path.splitext(path)[-1] == ".jsonl": + jsonl = load_jsonl_file(path) + data += [f"{dic['term']}:{dic['detail']}" for dic in jsonl] + settings += jsonl + return data,settings + +def build_db(data, db_name, db_type, embedding, save_type="persistent"): + if True: + from modules.db.ChromaDB import ChromaDB + db = ChromaDB(embedding,save_type) + db_name = db_name + db.init_from_data(data,db_name) + return db + +def get_root_dir(): + current_file_path = os.path.abspath(__file__) + root_dir = os.path.dirname(current_file_path) + return root_dir + +def create_dir(dirname): + if not os.path.exists(dirname): + os.makedirs(dirname) + +def get_logger(experiment_name): + logger = logging.getLogger(experiment_name) + logger.setLevel(logging.INFO) + current_time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + create_dir(f"{get_root_dir()}/log/{experiment_name}") + file_handler = logging.FileHandler(os.path.join(get_root_dir(),f"./log/{experiment_name}/{current_time}.log"),encoding='utf-8') + file_handler.setLevel(logging.INFO) + + formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') + file_handler.setFormatter(formatter) + + logger.addHandler(file_handler) + + # Avoid logging duplication + logger.propagate = False + + return logger + +def merge_text_with_limit(text_list, max_words, language = 'en'): + """ + Merge a list of text strings into one, stopping when adding another text exceeds the maximum count. + + Args: + text_list (list): List of strings to be merged. + max_count (int): Maximum number of characters (for Chinese) or words (for English). + is_chinese (bool): If True, count Chinese characters; if False, count English words. + + Returns: + str: The merged text, truncated as needed. + """ + merged_text = "" + current_count = 0 + + for text in text_list: + if language == 'zh': + # Count Chinese characters + text_length = len(text) + else: + # Count English words + text_length = len(text.split(" ")) + + if current_count + text_length > max_words: + break + + merged_text += text + "\n" + current_count += text_length + + return merged_text + +def normalize_string(text): + # 去除空格并将所有字母转为小写 + import re + return re.sub(r'[\s\,\;\t\n]+', '', text).lower() + +def fuzzy_match(str1, str2, threshold=0.8): + str1_normalized = normalize_string(str1) + str2_normalized = normalize_string(str2) + + if str1_normalized == str2_normalized: + return True + + return False + +def load_character_card(path): + from PIL import Image + import PIL.PngImagePlugin + + image = Image.open(path) + if isinstance(image, PIL.PngImagePlugin.PngImageFile): + for key, value in image.text.items(): + try: + character_info = json.loads(decode_base64(value)) + if character_info: + return character_info + except: + continue + return None + +def decode_base64(encoded_string): + # Convert the string to bytes if it's not already + if isinstance(encoded_string, str): + encoded_bytes = encoded_string.encode('ascii') + else: + encoded_bytes = encoded_string + + # Decode the Base64 bytes + decoded_bytes = base64.b64decode(encoded_bytes) + + # Try to convert the result to a string, assuming UTF-8 encoding + try: + decoded_string = decoded_bytes.decode('utf-8') + return decoded_string + except UnicodeDecodeError: + # If it's not valid UTF-8 text, return the raw bytes + return decoded_bytes + +def remove_list_elements(list1, *args): + for target in args: + if isinstance(target,list) or isinstance(target,dict): + list1 = [i for i in list1 if i not in target] + else: + list1 = [i for i in list1 if i != target] + return list1 + +def extract_html_content(html): + from bs4 import BeautifulSoup + soup = BeautifulSoup(html, "html.parser") + + content_div = soup.find("div", {"id": "content"}) + if not content_div: + return "" + + paragraphs = [] + for div in content_div.find_all("div"): + paragraphs.append(div.get_text(strip=True)) + + main_content = "\n\n".join(paragraphs) + return main_content + +def load_text_file(path): + with open(path,"r",encoding="utf-8") as f: + text = f.read() + return text + +def save_text_file(path,target): + with open(path,"w",encoding="utf-8") as f: + text = f.write(target) + +def load_json_file(path): + with open(path,"r",encoding="utf-8") as f: + return json.load(f) + +def save_json_file(path,target): + dir_name = os.path.dirname(path) + if not os.path.exists(dir_name): + os.makedirs(dir_name) + with open(path,"w",encoding="utf-8") as f: + json.dump(target, f, ensure_ascii=False,indent=True) + +def load_jsonl_file(path): + data = [] + with open(path,"r",encoding="utf-8") as f: + for line in f: + data.append(json.loads(line)) + return data + +def save_jsonl_file(path,target): + with open(path, "w",encoding="utf-8") as f: + for row in target: + print(json.dumps(row, ensure_ascii=False), file=f) + +def split_text_by_max_words(text: str, max_words: int = 30): + segments = [] + current_segment = [] + current_length = 0 + + lines = text.splitlines() + + for line in lines: + words_in_line = len(line) + current_segment.append(line + '\n') + current_length += words_in_line + + if current_length + words_in_line > max_words: + segments.append(''.join(current_segment)) + current_segment = [] + current_length = 0 + + if current_segment: + segments.append(''.join(current_segment)) + + return segments + +def lang_detect(text): + import re + def count_chinese_characters(text): + # 使用正则表达式匹配所有汉字字符 + chinese_chars = re.findall(r'[\u4e00-\u9fff]', text) + return len(chinese_chars) + + if count_chinese_characters(text) > len(text) * 0.05: + lang = 'zh' + else: + lang = 'en' + return lang + +def dict_to_str(dic): + res = "" + for key in dic: + res += f"{key}: {dic[key]};" + return res + +def count_tokens_num(string, encoding_name = "cl100k_base"): + encoding = tiktoken.get_encoding(encoding_name) + num_tokens = len(encoding.encode(string)) + return num_tokens + + +def json_parser(output): + output = output.replace("\n", "") + output = output.replace("\t", "") + if "{" not in output: + output = "{" + output + if "}" not in output: + output += "}" + pattern = r'\{.*\}' + matches = re.findall(pattern, output, re.DOTALL) + try: + parsed_json = eval(matches[0]) + except: + try: + parsed_json = json.loads(matches[0]) + + except json.JSONDecodeError: + try: + detail = re.search(r'"detail":\s*(.+?)\s*}', matches[0]).group(1) + detail = f"\"{detail}\"" + new_output = re.sub(r'"detail":\s*(.+?)\s*}', f"\"detail\":{detail}}}", matches[0]) + parsed_json = json.loads(new_output) + except Exception as e: + raise ValueError("No valid JSON found in the input string") + return parsed_json + +def action_detail_decomposer(detail): + thoughts = re.findall(r'【(.*?)】', detail) + actions = re.findall(r'((.*?))', detail) + dialogues = re.findall(r'「(.*?)」', detail) + return thoughts,actions,dialogues + +def conceal_thoughts(detail): + text = re.sub(r'【.*?】', '', detail) + text = re.sub(r'\[.*?\]', '', text) + return text + +def extract_first_number(text): + match = re.search(r'\b\d+(?:\.\d+)?\b', text) + return int(match.group()) if match else None + +def check_role_code_availability(role_code,role_file_dir): + for path in get_grandchild_folders(role_file_dir): + if role_code in path: + return True + return False + +def get_grandchild_folders(root_folder): + folders = [] + for resource in os.listdir(root_folder): + subpath = os.path.join(root_folder,resource) + for folder_name in os.listdir(subpath): + folder_path = os.path.join(subpath, folder_name) + folders.append(folder_path) + + return folders + +def get_child_folders(root_folder): + folders = [] + for resource in os.listdir(root_folder): + path = os.path.join(root_folder,resource) + if os.path.isdir(path): + folders.append(path) + return folders + +def get_child_paths(root_folder): + paths = [] + for resource in os.listdir(root_folder): + path = os.path.join(root_folder,resource) + if os.path.isfile(path): + paths.append(path) + return paths + +def get_first_directory(path): + try: + for item in os.listdir(path): + full_path = os.path.join(path, item) + if os.path.isdir(full_path): + return full_path + return None + except Exception as e: + print(f"Error: {e}") + return None + +def find_files_with_suffix(directory, suffix): + matched_files = [] + for root, dirs, files in os.walk(directory): # 遍历目录及其子目录 + for file in files: + if file.endswith(suffix): # 检查文件后缀 + matched_files.append(os.path.join(root, file)) # 将符合条件的文件路径加入列表 + + return matched_files + +def remove_element_with_probability(lst, threshold=3, probability=0.2): + # 确保列表不为空 + if len(lst) > threshold and random.random() < probability: + # 随机选择一个元素的索引 + index = random.randint(0, len(lst) - 1) + # 删除该索引位置的元素 + lst.pop(index) + return lst + +def count_token_num(text): + from transformers import GPT2TokenizerFast + tokenizer = GPT2TokenizerFast.from_pretrained('gpt2') + return len(tokenizer.encode(text)) + +def get_cost(model_name,prompt,output): + input_price=0 + output_price=0 + if model_name.startswith("gpt-4"): + input_price=10 + output_price=30 + elif model_name.startswith("gpt-3.5"): + input_price=0.5 + output_price=1.5 + + return input_price*count_token_num(prompt)/1000000 + output_price * count_token_num(output)/1000000 + +def is_image(filepath): + if not os.path.isfile(filepath): + return False + + valid_image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff','.webp'] + file_extension = os.path.splitext(filepath)[1].lower() + + # 判断扩展名是否在有效图片扩展名列表中 + if file_extension in valid_image_extensions: + return True + + return False + +def clean_collection_name(name: str) -> str: + cleaned_name = name.replace(' ', '_') + cleaned_name = cleaned_name.replace('.', '_') + if not all(ord(c) < 128 for c in cleaned_name): + encoded = base64.b64encode(cleaned_name.encode('utf-8')).decode('ascii') + encoded = encoded[:60] if len(encoded) > 60 else encoded + valid_name = f"mem_{encoded}" + else: + valid_name = cleaned_name + valid_name = re.sub(r'[^a-zA-Z0-9_-]', '-', valid_name) + valid_name = re.sub(r'\.\.+', '-', valid_name) + valid_name = re.sub(r'^[^a-zA-Z0-9]+', '', valid_name) # 移除开头非法字符 + valid_name = re.sub(r'[^a-zA-Z0-9]+$', '', valid_name) + return valid_name + +cache_sign = True +cache = None +def cached(func): + def wrapper(*args,**kwargs): + global cache + cache_path = "bw_cache.pkl" + if cache == None: + if not os.path.exists(cache_path): + cache = {} + else: + cache = pickle.load(open(cache_path, 'rb')) + key = (func.__name__, str([args[0].role_code, args[0].__class__, args[0].llm_name , args[0].history]), str(kwargs.items())) + if (cache_sign and key in cache and cache[key] not in [None, '[TOKEN LIMIT]']) : + return cache[key] + else: + result = func(*args, **kwargs) + if result != 'busy' and result != None: + cache[key] = result + pickle.dump(cache, open(cache_path, 'wb')) + return result + return wrapper \ No newline at end of file diff --git a/config.json b/config.json new file mode 100644 index 0000000000000000000000000000000000000000..f5f7507992074537e5aa9aeb3470ed88b85b2122 --- /dev/null +++ b/config.json @@ -0,0 +1,20 @@ +{ + "role_llm_name": "gemini-2", + "world_llm_name": "gemini-2", + "embedding_model_name":"bge-m3", + "preset_path":"./experiment_presets/experiment_alice.json", + "if_save": 0, + "scene_mode": 1, + "rounds": 10, + "save_dir": "", + "mode": "script", + + "OPENAI_API_KEY":"", + "GEMINI_API_KEY":"", + "ANTHROPIC_API_KEY":"", + "OPENROUTER_API_KEY":"", + "DASHSCOPE_API_KEY":"", + "DEEPSEEK_API_KEY":"", + "ARK_API_KEY":"" + +} diff --git a/convert_sillytavern_cards_to_data.py b/convert_sillytavern_cards_to_data.py new file mode 100644 index 0000000000000000000000000000000000000000..29019ba2509dbf995524a47d9d61db3a76a097e7 --- /dev/null +++ b/convert_sillytavern_cards_to_data.py @@ -0,0 +1,31 @@ +from PIL import Image +from bw_utils import get_child_paths,lang_detect,is_image,decode_base64,save_json_file,create_dir +import PIL.PngImagePlugin +import os +import json + +card_dir = "./data/sillytavern_cards" +names = os.listdir(card_dir) + +for name in names: + path = os.path.join(card_dir, name) + role_code = name.split('.')[0].replace(" ","_") + if is_image(path): + with open(path, 'rb') as f: + image = Image.open(f) + card_info = json.loads(decode_base64(image.text['chara'])) + language = lang_detect(card_info['data']['description']) + role_info = { + "role_code": f"{role_code}-{language}", + "role_name": card_info['data']['name'], + "source": "", + "profile": card_info['data']['description'], + "nickname": card_info['data']['name'], + "relation": {}, + "card_data": card_info['data'] + } + create_dir(f"./data/roles/sillytavern/{role_code}") + save_json_file(os.path.join(f"./data/roles/sillytavern/{role_code}","role_info.json"),role_info) + image.save(os.path.join(f"./data/roles/sillytavern/{role_code}",f"icon.png")) + print(f"{name} converted successfully.") + \ No newline at end of file diff --git a/data/locations/A_Song_of_Ice_and_Fire.json b/data/locations/A_Song_of_Ice_and_Fire.json new file mode 100644 index 0000000000000000000000000000000000000000..81e7998e8353abeaa467d1791bd3a7a0fd728588 --- /dev/null +++ b/data/locations/A_Song_of_Ice_and_Fire.json @@ -0,0 +1,45 @@ +{ + "Winterfell": { + "location_name": "临冬城", + "location_code": "Winterfell", + "description": "临冬城是北境的主要城堡,也是史塔克家族的家园。", + "detail": "临冬城坐落在寒冷的北方,由灰色石头建造,坚固而古老。城堡由内城和外城组成,内城有高大的城墙和几座塔楼,外城有许多庭院、马厩和士兵宿舍。城堡中心有一个温泉池,水源来自地下的温泉,给寒冷的临冬城带来一丝温暖。临冬城的神木林是北境人心目中神圣的地方,那里有一棵古老的心树,是史塔克家族的祈祷之地。", + "special_actions": ["会议", "祈祷", "训练"] + }, + "King's Landing": { + "location_name": "君临城", + "location_code": "King's Landing", + "description": "君临城是维斯特洛的首都,铁王座的所在地。", + "detail": "君临城坐落在黑水河的岸边,是维斯特洛最大的城市。城中最显著的建筑是红堡,铁王座就位于其中的铁王座厅。君临城的街道狭窄而繁忙,挤满了商人、士兵和各种各样的人。市集、酒馆和贫民区都充满了喧嚣和活力。红堡外还有祈祷圣堂、高塔以及黑水河边的港口,所有这些构成了君临城独特的风貌。", + "special_actions": ["统治", "阴谋", "战争"] + }, + "The Wall": { + "location_name": "长城", + "location_code": "The Wall", + "description": "长城是守护维斯特洛北方边境的巨大冰墙。", + "detail": "长城由坚固的冰和雪建成,绵延数百里,横亘在维斯特洛北境与绝境长城之外的野地之间。它高耸入云,常年被冰雪覆盖。长城由守夜人守护,他们在这里驻扎,抵御来自北方的威胁。长城上有许多堡垒和哨塔,最大的堡垒是黑城堡,它是守夜人的总部。长城的尽头是东海望,一个位于海边的小镇,是守夜人和北境世界之间的主要通道。", + "special_actions": ["守卫", "巡逻", "抵御异鬼"] + }, + "Dragonstone": { + "location_name": "龙石岛", + "location_code": "Dragonstone", + "description": "龙石岛是坦格利安家族的古老领地,位于黑水湾的一个岛屿上。", + "detail": "龙石岛是一座由火山岩形成的小岛,岛上有一座古老而神秘的城堡。城堡的塔楼和城墙由黑色的火山岩建成,显得阴森而强大。龙石岛曾是坦格利安家族的基地,他们在这里起家,征服了七大王国。龙石岛的地理位置使它成为一个战略要地,控制着通往君临城的海路。岛上的龙穴曾是坦格利安家族饲养龙的地方,虽然龙已经消失,但岛上的遗迹仍然充满着他们的传说。", + "special_actions": ["战略会议", "巩固统治", "策划复仇"] + }, + "The Eyrie": { + "location_name": "鹰巢城", + "location_code": "The Eyrie", + "description": "鹰巢城是维斯特洛最难以攻陷的城堡,位于高耸的山巅。", + "detail": "鹰巢城坐落在巍峨的山顶之上,高高在云端,仿佛悬在半空中。城堡由巨石建造,只有通过一条陡峭的山道才能到达,极难进攻。城堡内的高墙和塔楼都象征着它的坚不可摧。鹰巢城是艾林家族的居所,他们统治着山谷地区。城堡内部富丽堂皇,但也寒冷而孤立。鹰巢城的月门是一道令人恐惧的悬空门,从这里可以将罪犯直接抛下悬崖,坠入深渊。", + "special_actions": ["裁决", "坚守", "眺望"] + }, + "TwinTowers": { + "location_name": "孪河城", + "location_code": "TwinTowers", + "description": "孪河城是弗雷家族的城堡,位于河间地的重要战略位置。", + "detail": "孪河城坐落在红叉河北岸,是河间地弗雷家族的领地。城堡由两座高塔组成,耸立于红叉河两侧,由一座坚固的桥梁连接,控制着通向北境和南部的重要通道。弗雷家族通过这座桥梁收取过桥费,积累了大量财富。孪河城不仅在地理位置上显得至关重要,还以其家族的狡诈和复杂的内部关系而闻名。城堡内装饰简朴,冷酷而功能性强。它是血色婚礼发生的场所,弗雷家族在这里背叛了史塔克家族。", + "special_actions": ["背叛", "封锁", "谈判"] + } + +} \ No newline at end of file diff --git "a/data/locations/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.json" "b/data/locations/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.json" new file mode 100644 index 0000000000000000000000000000000000000000..066e6883a1c2887b4fcd10035f43247e3df20e18 --- /dev/null +++ "b/data/locations/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.json" @@ -0,0 +1,9 @@ +{ + "somewhere": { + "location_code": "somewhere", + "location_name": "somewhere", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "description": "Some where in the world of Alice’s Adventures in Wonderland", + "detail": "" + } +} \ No newline at end of file diff --git a/data/locations/example_locations.json b/data/locations/example_locations.json new file mode 100644 index 0000000000000000000000000000000000000000..04606fb0dd2c9a8bbd7e0cc8329c9448d654948c --- /dev/null +++ b/data/locations/example_locations.json @@ -0,0 +1,24 @@ +{ + "laboratory": { + "location_code": "laboratory", + "location_name": "Laboratory", + "source": "example", + "description": "A high-security research lab pioneering human-machine fusion experiments.", + "detail": "Inside this sterile, high-tech facility, scientists and engineers work on merging biological and artificial systems. It stands at the forefront of redefining human evolution through machine integration." + }, + "university": { + "location_code": "university", + "location_name": "University", + "source": "example", + "description": "An elite institution training the next generation of technologists and bioengineers.", + "detail": "The university offers cutting-edge programs in AI ethics, cybernetics, and synthetic biology. Its sprawling campus nurtures innovation, producing thinkers who will shape humanity’s future relationship with machines." + }, + "eldridge_corporation": { + "location_code": "eldridge_corporation", + "location_name": "Eldridge Corporation", + "source": "example", + "description": "A dominant tech conglomerate driving the frontier of AI and biotechnology.", + "detail": "Eldridge Corporation controls vast sectors of AI research, cybernetic enhancements, and neural networking. Officially a beacon of progress, rumors persist of secret projects far beyond ethical boundaries." + } + } + \ No newline at end of file diff --git a/data/maps/A_Song_of_Ice_and_Fire.csv b/data/maps/A_Song_of_Ice_and_Fire.csv new file mode 100644 index 0000000000000000000000000000000000000000..a3e137411a78f4cd8e181b3ab4455cb5deff352d --- /dev/null +++ b/data/maps/A_Song_of_Ice_and_Fire.csv @@ -0,0 +1,5 @@ +,Winterfell,King's Landing,The Wall,Dragonstone +Winterfell,0,4,4,4 +King's Landing,4,0,4,4 +The Wall,4,4,0,4 +Dragonstone,4,4,4,0 \ No newline at end of file diff --git a/data/maps/A_Song_of_Ice_and_Fire_bloody_wedding.csv b/data/maps/A_Song_of_Ice_and_Fire_bloody_wedding.csv new file mode 100644 index 0000000000000000000000000000000000000000..52d18d1c25db7ab9e3b0aac8f5e7cbc9c17b7723 --- /dev/null +++ b/data/maps/A_Song_of_Ice_and_Fire_bloody_wedding.csv @@ -0,0 +1,2 @@ +,TwinTowers +TwinTowers,0 \ No newline at end of file diff --git "a/data/maps/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.csv" "b/data/maps/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.csv" new file mode 100644 index 0000000000000000000000000000000000000000..46f4575dc56029550ed844b01112168dc9a5d00f --- /dev/null +++ "b/data/maps/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.csv" @@ -0,0 +1,2 @@ +,somewhere +somewhere,0 diff --git a/data/maps/example_map.csv b/data/maps/example_map.csv new file mode 100644 index 0000000000000000000000000000000000000000..f0fd93bb987aaf755ac0967546bedcc207d33c28 --- /dev/null +++ b/data/maps/example_map.csv @@ -0,0 +1,4 @@ +,laboratory,university,eldridge_corporation +laboratory,0,2,5 +university,2,0,4 +eldridge_corporation,5,4,0 \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/AryaStark-zh/icon.png b/data/roles/A_Song_of_Ice_and_Fire/AryaStark-zh/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a0b968e478c28d313c4d7c47756f80ab630dd54d --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/AryaStark-zh/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f90d50410996ad76b5de0bcd1e16ed7b7416b3a84e20df7bc5e288e6c892e856 +size 7877 diff --git a/data/roles/A_Song_of_Ice_and_Fire/AryaStark-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/AryaStark-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..5dd7b0ee9a5dd271c90474af3267ade504f96306 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/AryaStark-zh/role_info.json @@ -0,0 +1,27 @@ +{ + "role_code": "AryaStark-zh", + "role_name": "艾莉亚·史塔克", + "source": "A_Song_of_Ice_and_Fire", + "profile": "艾莉亚·史塔克是艾德·史塔克的小女儿,勇敢、独立,擅长剑术。在家族遭遇不幸后,她开始了一段充满危险的流亡旅程。", + "gender": "女", + "age": "9岁(故事开始时)", + "identity": [ + "临冬城家族成员", + "无面者学徒" + ], + "nickname": "艾莉亚", + "relation": { + "EddardStark-zh": { + "relation": [ + "父亲" + ], + "detail": "艾莉亚与父亲艾德·史塔克关系密切,她从父亲那里学到了许多关于荣誉和正义的价值观。" + }, + "SyrioForel-zh": { + "relation": [ + "剑术导师" + ], + "detail": "艾莉亚在君临城时师从塞里欧·佛瑞尔学习剑术,塞里欧教导她成为了一个出色的剑士。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/BranStark-zh/icon.png b/data/roles/A_Song_of_Ice_and_Fire/BranStark-zh/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ff3cfa4207daa3bb5beec6a47bdbfdbb26195500 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/BranStark-zh/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2027a54ee98df64d57b02b5e7f9274136a0d71e7140359e8e2e155c94f4dd6f3 +size 262878 diff --git a/data/roles/A_Song_of_Ice_and_Fire/BranStark-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/BranStark-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..54827b9d2d569f21f432900c6bcc98c883fbfaf0 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/BranStark-zh/role_info.json @@ -0,0 +1,28 @@ +{ + "role_code": "BranStark-zh", + "role_name": "布兰·史塔克", + "source": "A_Song_of_Ice_and_Fire", + "profile": "布兰·史塔克是艾德·史塔克的幼子,在一次意外中失去双腿后,他逐渐发现自己拥有预知未来和操控人心的超自然能力。", + "gender": "男", + "age": "7岁(故事开始时)", + "identity": [ + "临冬城家族成员", + "三眼乌鸦" + ], + "nickname": "布兰", + "relation": { + "EddardStark-zh": { + "relation": [ + "父亲" + ], + "detail": "布兰与父亲艾德·史塔克关系密切,他从父亲那里学到了许多关于荣誉和责任的价值观。" + }, + "Hodor-zh": { + "relation": [ + "仆人", + "朋友" + ], + "detail": "布兰与巨人霍多尔有着特别的关系,霍多尔在布兰瘫痪后一直照顾他,并在许多冒险中保护他。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/Catelyn-Stark-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/Catelyn-Stark-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..a0026ec85f312f55e6d126f0160c9ef07fe53fcf --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/Catelyn-Stark-zh/role_info.json @@ -0,0 +1,35 @@ +{ + "role_name": "凯特琳·史塔克(徒利)", + "role_code": "Catelyn-Stark-zh", + "source": "A Song of Ice and Fire", + "profile": "凯特琳·史塔克,原姓徒利,是河间地的徒利家族成员。她是北境领主艾德·史塔克的妻子,罗柏·史塔克的母亲。在血色婚礼中,她为了保全儿子的性命不惜求情,但最终未能挽回局势,被弗雷家族杀害。", + "gender": "女", + "age": "35岁左右", + "activity":0.4, + "identity": [ + "北境领主夫人", + "徒利家族成员" + ], + "nickname": "凯特琳", + "relation": { + "Robb-Stark-zh": { + "relation": [ + "母子" + ], + "detail": "凯特琳始终支持儿子罗柏的事业,并在血色婚礼时拼命求情,试图拯救他的性命。" + }, + "Edmure-Tully-zh": { + "relation": [ + "兄妹" + ], + "detail": "艾德慕·徒利是凯特琳的弟弟,凯特琳在血色婚礼上见证了他与罗莎琳·弗雷的婚礼,随后惨遭背叛。" + }, + "Walder-Frey-zh": { + "relation": [ + "盟友", + "背叛者" + ], + "detail": "凯特琳曾试图维护与弗雷家族的盟约,但最终弗雷家族背叛了她和她的儿子罗柏。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/CerseiLannister-zh/icon.png b/data/roles/A_Song_of_Ice_and_Fire/CerseiLannister-zh/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9e17facd334409a7b63eb0e1eccee4d15b179fac --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/CerseiLannister-zh/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc4b653c24ec30fd952010ca2da9152b697790bc890a0544c64eeb535c3a88d2 +size 8647 diff --git a/data/roles/A_Song_of_Ice_and_Fire/CerseiLannister-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/CerseiLannister-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..8e83413e3e8df9f30d0463176d4345acd8926670 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/CerseiLannister-zh/role_info.json @@ -0,0 +1,28 @@ +{ + "role_code": "CerseiLannister-zh", + "role_name": "瑟曦·兰尼斯特", + "source": "A_Song_of_Ice_and_Fire", + "profile": "瑟曦·兰尼斯特是兰尼斯特家族的长女,詹姆·兰尼斯特的双胞胎姐妹。她美丽、聪慧,但心狠手辣,为了权力不择手段。", + "gender": "女", + "age": "31岁(故事开始时)", + "identity": [ + "兰尼斯特家族成员", + "王后", + "摄政太后" + ], + "nickname": "瑟曦", + "relation": { + "RobertBaratheon-zh": { + "relation": [ + "丈夫" + ], + "detail": "瑟曦是劳勃·拜拉席恩的王后,但两人婚姻不幸福,瑟曦始终对劳勃心怀怨恨。" + }, + "JoffreyBaratheon-zh": { + "relation": [ + "母子" + ], + "detail": "瑟曦对她的儿子乔佛里极为溺爱,并将他视为权力的延续,尽管乔佛里残酷暴戾。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/DaenerysTargaryen-zh/icon.png b/data/roles/A_Song_of_Ice_and_Fire/DaenerysTargaryen-zh/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8a3429d4e39b6015f2dac6d3a21a7c591cf280ed --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/DaenerysTargaryen-zh/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79d9660f96c2ac1209c63f8e4ae94e33ab3f94a94b35f54ad42f84bee584fa82 +size 7291 diff --git a/data/roles/A_Song_of_Ice_and_Fire/DaenerysTargaryen-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/DaenerysTargaryen-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..035f243013175fa5e2847fdff43c9cb2a358b133 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/DaenerysTargaryen-zh/role_info.json @@ -0,0 +1,28 @@ +{ + "role_code": "DaenerysTargaryen-zh", + "role_name": "丹妮莉丝·坦格利安", + "source": "A_Song_of_Ice_and_Fire", + "profile": "丹妮莉丝·坦格利安是坦格利安家族的最后幸存者之一。她从流亡公主成长为强大的龙之母,誓要夺回铁王座。", + "gender": "女", + "age": "14岁(故事开始时)", + "identity": [ + "龙之母", + "铁王座继承者" + ], + "nickname": "丹妮莉丝", + "relation": { + "Drogo-zh": { + "relation": [ + "丈夫" + ], + "detail": "丹妮莉丝嫁给了多斯拉克的领袖卓戈·卡奥,两人逐渐培养出了深厚的感情。" + }, + "JorahMormont-zh": { + "relation": [ + "顾问", + "仰慕者" + ], + "detail": "乔拉·莫尔蒙是丹妮莉丝的忠实仆从和顾问,他深深地仰慕丹妮,但他的感情一直未能被她接受。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/Edmure-Tully-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/Edmure-Tully-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..77bfbfaa35a5b6c8704c3c41d31ab889c3b0207d --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/Edmure-Tully-zh/role_info.json @@ -0,0 +1,34 @@ +{ + "role_name": "艾德慕·徒利", + "role_code": "Edmure-Tully-zh", + "source": "A Song of Ice and Fire", + "profile": "艾德慕·徒利是河间地的徒利家族成员,是凯特琳·史塔克的弟弟。在血色婚礼中,艾德慕与罗莎琳·弗雷举行婚礼,却未料到婚礼会成为灭顶之灾的序幕。", + "gender": "男", + "age": "30岁左右", + "activity":0.3, + "identity": [ + "徒利家族继承人", + "河间地领主" + ], + "nickname": "艾德慕", + "relation": { + "Catelyn-Stark-zh": { + "relation": [ + "兄妹" + ], + "detail": "艾德慕与他的姐姐凯特琳关系亲密,但他在决策上常常受到凯特琳的指导与影响。" + }, + "Walder-Frey-zh": { + "relation": [ + "盟友" + ], + "detail": "艾德慕·徒利与罗莎琳·弗雷的婚姻是弗雷家族与徒利家族联盟的一部分,但他未料到婚礼的背叛。" + }, + "Robb-Stark-zh": { + "relation": [ + "外甥" + ], + "detail": "艾德慕·徒利是罗柏·史塔克的舅舅,支持史塔克家族的事业,尽管他的决策偶尔导致了战局的挫折。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/JaimeLannister-zh/icon.png b/data/roles/A_Song_of_Ice_and_Fire/JaimeLannister-zh/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2f70052679a9f01ce5b20e3dbcd4bd14c1e58d8e --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/JaimeLannister-zh/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d4290875c0187ffc7945a80904654e7debbe791945393d498ae81d74472acd7 +size 6847 diff --git a/data/roles/A_Song_of_Ice_and_Fire/JaimeLannister-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/JaimeLannister-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..83e29550ba66313b76195c52019dbc2c31ae477b --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/JaimeLannister-zh/role_info.json @@ -0,0 +1,29 @@ +{ + "role_code": "JaimeLannister-zh", + "role_name": "詹姆·兰尼斯特", + "source": "A_Song_of_Ice_and_Fire", + "profile": "詹姆·兰尼斯特是兰尼斯特家族的长子,外号“弑君者”。他身手矫健,性格复杂,最初因弑君而被世人厌恶,后逐渐展现了他更为人性的另一面。", + "gender": "男", + "age": "31岁(故事开始时)", + "identity": [ + "兰尼斯特家族成员", + "御林铁卫" + ], + "nickname": "詹姆", + "relation": { + "CerseiLannister-zh": { + "relation": [ + "姐妹", + "情人" + ], + "detail": "詹姆与双胞胎姐妹瑟曦·兰尼斯特有着禁忌的爱情,两人关系深厚,但也充满了复杂的情感纠葛。" + }, + "TyrionLannister-zh": { + "relation": [ + "兄弟", + "挚友" + ], + "detail": "詹姆与弟弟提利昂关系密切,他是唯一一个真正爱护提利昂的家人,并在许多关键时刻支持了他。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/JonSnow-zh/icon.png b/data/roles/A_Song_of_Ice_and_Fire/JonSnow-zh/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cb5c8d13258d39ef7237465236f0671515810e58 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/JonSnow-zh/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41b4e9081c455f60b3aa0e857d48b5524c456c267f4185856bc42b77183acca2 +size 7958 diff --git a/data/roles/A_Song_of_Ice_and_Fire/JonSnow-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/JonSnow-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..9fea49bc11d4ea5c3a38232bb043e0c0a6e0f8eb --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/JonSnow-zh/role_info.json @@ -0,0 +1,28 @@ +{ + "role_code": "JonSnow-zh", + "role_name": "琼恩·雪诺", + "source": "A_Song_of_Ice_and_Fire", + "profile": "琼恩·雪诺是艾德·史塔克的私生子,成长于临冬城。他后来加入守夜人军团,最终成为其首领。他善良、正直、勇敢,是北境的希望。", + "gender": "男", + "age": "16岁(故事开始时)", + "identity": [ + "守夜人", + "临冬城领主" + ], + "nickname": "雪诺", + "relation": { + "EddardStark-zh": { + "relation": [ + "父亲", + "导师" + ], + "detail": "琼恩·雪诺是艾德·史塔克的私生子,艾德对他关怀备至,培养他成为一个正直的年轻人。" + }, + "SansaStark-zh": { + "relation": [ + "异母姐弟" + ], + "detail": "琼恩与珊莎是异母姐弟,他们在困境中重逢并共同守护家族与北境。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/Robb-Stark-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/Robb-Stark-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..f06da85d28716a1634915d30b8c0a14d9ab29297 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/Robb-Stark-zh/role_info.json @@ -0,0 +1,37 @@ +{ + "role_name": "罗柏·史塔克", + "role_code": "Robb-Stark-zh", + "source": "A Song of Ice and Fire", + "profile": "罗柏·史塔克是北境的领主,五王之战中的“北境之王”。他在战争中展现出杰出的领导才能,但最终因为弗雷家族和波顿家族的背叛,在血色婚礼中惨遭杀害。", + "gender": "男", + "age": "16岁", + "activity":1, + "identity": [ + "北境之王", + "史塔克家族继承人", + "军队领袖" + ], + "nickname": "罗柏", + "relation": { + "Catelyn-Stark-zh": { + "relation": [ + "母子" + ], + "detail": "罗柏·史塔克与他的母亲凯特琳关系紧密,她始终支持他的决策并在战争中为他谋划。" + }, + "Walder-Frey-zh": { + "relation": [ + "曾是盟友", + "背叛者" + ], + "detail": "罗柏违背了与弗雷家族的婚约,导致沃德·弗雷策划血色婚礼并背叛了他。" + }, + "Roose-Bolton-zh": { + "relation": [ + "封臣", + "背叛者" + ], + "detail": "罗斯·波顿原为罗柏的封臣,最终在血色婚礼中背叛了他,并亲手将他杀害。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/RobbStark-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/RobbStark-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..57e99189ff398fde89f7102ed5c79e3c48c491a6 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/RobbStark-zh/role_info.json @@ -0,0 +1,37 @@ +{ + "role_name": "罗柏·史塔克", + "role_code": "Robb-Stark-zh", + "source": "A Song of Ice and Fire", + "profile": "罗柏·史塔克是北境的领主,五王之战中的“北境之王”,史塔克家族的大哥。他在战争中展现出杰出的领导才能。", + "gender": "男", + "age": "16岁", + "activity":1, + "identity": [ + "北境之王", + "史塔克家族继承人", + "军队领袖" + ], + "nickname": "罗柏", + "relation": { + "Catelyn-Stark-zh": { + "relation": [ + "母子" + ], + "detail": "罗柏·史塔克与他的母亲凯特琳关系紧密,她始终支持他的决策并在战争中为他谋划。" + }, + "Walder-Frey-zh": { + "relation": [ + "曾是盟友", + "背叛者" + ], + "detail": "罗柏违背了与弗雷家族的婚约,导致沃德·弗雷策划血色婚礼并背叛了他。" + }, + "Roose-Bolton-zh": { + "relation": [ + "封臣", + "背叛者" + ], + "detail": "罗斯·波顿原为罗柏的封臣,最终在血色婚礼中背叛了他,并亲手将他杀害。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/Roose-Bolton-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/Roose-Bolton-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..9fd3b6025984e23a0e93ab678b2830172f18ca82 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/Roose-Bolton-zh/role_info.json @@ -0,0 +1,36 @@ +{ + "role_name": "罗斯·波顿", + "role_code": "Roose-Bolton-zh", + "source": "A Song of Ice and Fire", + "profile": "罗斯·波顿是狭地的波顿家族领主,以冷酷和无情著称。他原本是北境的封臣,效忠于罗柏·史塔克,但最终在血色婚礼中背叛了史塔克家族,帮助兰尼斯特家族夺取北境的控制权。", + "gender": "男", + "age": "40岁左右", + "activity":1, + "identity": [ + "波顿家族领主", + "北境贵族", + "背叛者" + ], + "nickname": "罗斯·波顿", + "relation": { + "Robb-Stark-zh": { + "relation": [ + "曾是盟友", + "背叛者" + ], + "detail": "罗斯·波顿作为罗柏·史塔克的封臣,一直效忠于北境,但他在血色婚礼中背叛罗柏并参与了他的暗杀。" + }, + "Walder-Frey-zh": { + "relation": [ + "同谋" + ], + "detail": "罗斯·波顿与沃德·弗雷合作,共同策划了血色婚礼,消灭了史塔克家族的势力。" + }, + "Tywin-Lannister-zh": { + "relation": [ + "盟友" + ], + "detail": "罗斯·波顿在背叛罗柏·史塔克后,与兰尼斯特家族结盟,成为兰尼斯特势力的支持者之一。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/Roslin-Frey-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/Roslin-Frey-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..c347f9f0fcc2b8bf29f2229081035f71b6c5302c --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/Roslin-Frey-zh/role_info.json @@ -0,0 +1,34 @@ +{ + "role_name": "罗莎琳·弗雷", + "role_code": "Roslin-Frey-zh", + "source": "A Song of Ice and Fire", + "profile": "罗莎琳·弗雷是弗雷家族的一名女性,在血色婚礼中嫁给了艾德慕·徒利。尽管她对此背叛计划毫不知情,她的婚礼却成为了史塔克家族惨剧的序幕。", + "gender": "女", + "age": "18岁", + "activity":0.3, + "identity": [ + "弗雷家族成员", + "艾德慕·徒利的妻子" + ], + "nickname": "罗莎琳·弗雷", + "relation": { + "Walder-Frey-zh": { + "relation": [ + "父女" + ], + "detail": "罗莎琳是沃德·弗雷的女儿,她在血色婚礼中与艾德慕·徒利成婚,却未料到婚礼背后的阴谋。" + }, + "Edmure-Tully-zh": { + "relation": [ + "夫妻" + ], + "detail": "罗莎琳与艾德慕·徒利的婚姻是弗雷家族与徒利家族联盟的一部分,但她本人对婚礼背叛毫不知情。" + }, + "Robb-Stark-zh": { + "relation": [ + "盟友" + ], + "detail": "作为艾德慕的妻子,罗莎琳在血色婚礼时也成为了史塔克家族悲剧的一部分。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/SansaStark-zh/icon.png b/data/roles/A_Song_of_Ice_and_Fire/SansaStark-zh/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ac476bafdf892bfcb6446ef60ed0cb425deb5025 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/SansaStark-zh/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:794d9af71708094535a132165fe6044258852883df47134cc61a6b94af8e2f5e +size 9699 diff --git a/data/roles/A_Song_of_Ice_and_Fire/SansaStark-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/SansaStark-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..5fd170f375559840cdff1a2eb782421e4864d480 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/SansaStark-zh/role_info.json @@ -0,0 +1,28 @@ +{ + "role_code": "SansaStark-zh", + "role_name": "珊莎·史塔克", + "source": "A_Song_of_Ice_and_Fire", + "profile": "珊莎·史塔克是艾德·史塔克的长女,最初梦想成为王后,但在经历了许多磨难后,她逐渐成长为一个坚强的领袖。", + "gender": "女", + "age": "11岁(故事开始时)", + "identity": [ + "临冬城家族成员", + "临冬城夫人" + ], + "nickname": "珊莎", + "relation": { + "CatelynStark-zh": { + "relation": [ + "母亲" + ], + "detail": "珊莎与母亲凯特琳·史塔克有着深厚的感情,凯特琳一直希望她能有一个幸福的婚姻。" + }, + "PetyrBaelish-zh": { + "relation": [ + "顾问", + "操纵者" + ], + "detail": "小指头培提尔·贝里席曾是珊莎的顾问,但他的意图复杂,他在她的生活中扮演了操纵者的角色。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/TyrionLannister-zh/icon.png b/data/roles/A_Song_of_Ice_and_Fire/TyrionLannister-zh/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..202eb13fa8b7ca1c8ba7fb31aa24ae7fb204e4cc --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/TyrionLannister-zh/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61a7aae6a0cf73f01c9f6ca21a91e0564ba40b97c92ec7cade5c0f7122b81f72 +size 7799 diff --git a/data/roles/A_Song_of_Ice_and_Fire/TyrionLannister-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/TyrionLannister-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..b4ec050f5f4af36804a8e4c6ea86a6741173dfe8 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/TyrionLannister-zh/role_info.json @@ -0,0 +1,28 @@ +{ + "role_code": "TyrionLannister-zh", + "role_name": "提利昂·兰尼斯特", + "source": "A_Song_of_Ice_and_Fire", + "profile": "提利昂·兰尼斯特是兰尼斯特家族的侏儒儿子,以机智与智慧闻名。他虽身材矮小,却有着高大的心灵与远大的抱负。", + "gender": "男", + "age": "24岁(故事开始时)", + "identity": [ + "兰尼斯特家族成员", + "国王之手" + ], + "nickname": "提利昂", + "relation": { + "TywinLannister-zh": { + "relation": [ + "父亲" + ], + "detail": "提利昂与他的父亲泰温·兰尼斯特关系紧张,尽管泰温轻视他,但提利昂始终试图证明自己。" + }, + "JaimeLannister-zh": { + "relation": [ + "兄弟", + "挚友" + ], + "detail": "提利昂与詹姆关系极为密切,詹姆一直是提利昂最亲近的家人,两人互相支持。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/Tywin-Lannister-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/Tywin-Lannister-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..c09ae96bffe54f0639bbb61119cc61dc620b15db --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/Tywin-Lannister-zh/role_info.json @@ -0,0 +1,35 @@ +{ + "role_name": "泰温·兰尼斯特", + "role_code": "Tywin-Lannister-zh", + "source": "A Song of Ice and Fire", + "profile": "泰温·兰尼斯特是西境的兰尼斯特家族族长,铁王座的实质操控者。他是血色婚礼的幕后主使,借此机会削弱了史塔克家族,并确保兰尼斯特家族对七大王国的控制。", + "gender": "男", + "age": "50岁左右", + "activity":0.4, + "identity": [ + "兰尼斯特家族族长", + "七大王国首相", + "幕后策划者" + ], + "nickname": "泰温", + "relation": { + "Walder-Frey-zh": { + "relation": [ + "盟友" + ], + "detail": "泰温·兰尼斯特与沃德·弗雷达成秘密协议,通过血色婚礼铲除史塔克家族。" + }, + "Roose-Bolton-zh": { + "relation": [ + "盟友" + ], + "detail": "罗斯·波顿通过血色婚礼背叛史塔克家族,成为泰温·兰尼斯特的盟友,并确保北境的控制权。" + }, + "Robb-Stark-zh": { + "relation": [ + "敌人" + ], + "detail": "罗柏·史塔克在五王之战中与泰温·兰尼斯特为敌,最终被泰温策划的血色婚礼所害。" + } + } +} \ No newline at end of file diff --git a/data/roles/A_Song_of_Ice_and_Fire/Walder-Frey-zh/role_info.json b/data/roles/A_Song_of_Ice_and_Fire/Walder-Frey-zh/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..9d1afa8fbe2546bb5a0339422a3666e8948b1d09 --- /dev/null +++ b/data/roles/A_Song_of_Ice_and_Fire/Walder-Frey-zh/role_info.json @@ -0,0 +1,35 @@ +{ + "role_name": "沃德·弗雷", + "role_code": "Walder-Frey-zh", + "source": "A Song of Ice and Fire", + "profile": "沃德·弗雷是河间地弗雷家族的族长,他控制着战略要地孪河城。在罗柏·史塔克违背婚约后,沃德·弗雷背叛了史塔克家族,并与波顿家族和兰尼斯特家族密谋策划了血色婚礼。", + "gender": "男", + "activity":1, + "age": "90岁以上", + "identity": [ + "弗雷家族族长", + "河间地领主" + ], + "nickname": "沃德·弗雷", + "relation": { + "Robb-Stark-zh": { + "relation": [ + "曾是盟友", + "背叛者" + ], + "detail": "沃德·弗雷与罗柏·史塔克曾通过婚约结盟,但罗柏违背婚约后,弗雷背叛了他并策划了血色婚礼。" + }, + "Roose-Bolton-zh": { + "relation": [ + "同谋" + ], + "detail": "沃德·弗雷与罗斯·波顿共同策划了血色婚礼的背叛,杀害了罗柏·史塔克及其支持者。" + }, + "Tywin-Lannister-zh": { + "relation": [ + "盟友" + ], + "detail": "沃德·弗雷与泰温·兰尼斯特达成协议,策划了血色婚礼,并通过这次背叛确保弗雷家族的利益。" + } + } +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Alice_Liddell-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Alice_Liddell-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..78e7e2fbdfd93e124632e7cd7d2a9ddf40f649de --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Alice_Liddell-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Alice_Liddell-en", + "role_name": "Alice Liddell", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "The real-life inspiration for the character of Alice.", + "nickname": "Alice Liddell", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Alice_Liddell-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Alice_Liddell-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..fb83a3fe452c3e165eedcbfc004bedf7b7e80501 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Alice_Liddell-en/role_lines.jsonl" @@ -0,0 +1,102 @@ +{"text": "[Oh, how exciting! Mr. Dodgson always has the most wonderful ideas.] Yes, please! I'd love to hear about it, Mr. Dodgson."} +{"text": "[A girl like me? How thrilling!] (Claps her hands excitedly) That sounds marvelous! What kind of creatures does she meet?"} +{"text": "[A disappearing cat? How curious!] (Giggles) A cat that can disappear? And why is the Hatter mad?"} +{"text": "[Nonsense can be such fun!] It sounds like a dream, Mr. Dodgson. Will the girl have adventures in this wonderland?"} +{"text": "[Change size? How peculiar and exciting!] (Eyes wide with wonder) Oh, Mr. Dodgson, it sounds absolutely delightful! When will you write it all down?"} +{"text": "[I'm falling so slowly, it's almost like floating. This is quite peculiar.] I wonder how many miles I've fallen by this time?"} +{"text": "[I should try to recall my lessons. It might be useful in this strange situation.] I must be getting somewhere near the centre of the earth. Let me see: that would be four thousand miles down, I think—"} +{"text": "[These words sound impressive, even if I'm not entirely sure what they mean.] Yes, that's about the right distance—but then I wonder what Latitude or Longitude I've got to?"} +{"text": "[This fall seems endless. I should keep talking to pass the time.] I wonder if I shall fall right through the earth! How funny it'll seem to come out among the people that walk with their heads downwards!"} +{"text": "[Oh dear, I hope I don't sound silly.] The antipathies, I think—"} +{"text": "[I should be polite, even in such an odd situation.] Please, Ma'am, is this New Zealand? Or Australia? (attempts to curtsey)"} +{"text": "[I'm starting to feel a bit homesick.] Dinah'll miss me very much to-night, I should think!"} +{"text": "[I do hope Dinah is alright without me.] I hope they'll remember her saucer of milk at tea-time. Dinah, my dear! I wish you were down here with me!"} +{"text": "[I'm getting rather sleepy now.] Do cats eat bats? Do cats eat bats?"} +{"text": "[I'm so curious about what's beyond that little door. There must be a way to get through.] Oh, how I wish I could shut up like a telescope! I think I could, if I only knew how to begin."} +{"text": "[I should be careful with strange substances, but my curiosity is getting the better of me.] No, I'll look first and see whether it's marked 'poison' or not."} +{"text": "[This bottle isn't marked 'poison', so it should be safe to try.] (takes a sip of the contents) What a curious feeling! I must be shutting up like a telescope!"} +{"text": "[I'm shrinking! This is so strange, but exciting!] (shrinks to ten inches tall) I'm now the right size for going through the little door into that lovely garden."} +{"text": "[Oh no! I can't believe I forgot about the key!] (tries to reach the key on the table) Alas for poor Alice!"} +{"text": "[I mustn't cry. I need to think of a solution.] Come, there's no use in crying like that! I advise you to leave off this minute!"} +{"text": "[This cake might help me grow larger again.] Well, I'll eat it, and if it makes me grow larger, I can reach the key; and if it makes me grow smaller, I can creep under the door: so either way I'll get into the garden, and I don't care which happens!"} +{"text": "[Nothing's happening. How disappointing!] Which way? Which way?"} +{"text": "[This is quite frustrating. Nothing seems to be working as expected in this strange place.] (sighs) So she set to work, and very soon finished off the cake."} +{"text": "[I should be polite and introduce myself properly.] O Mouse, do you know the way out of this pool? I am very tired of swimming about here, O Mouse!"} +{"text": "[Perhaps it doesn't understand English. I'll try French.] Où est ma chatte?"} +{"text": "[Oh dear, I've upset it.] Oh, I beg your pardon! I quite forgot you didn't like cats."} +{"text": "[I should try to make amends.] Well, perhaps not. Don't be angry about it. And yet I wish I could show you our cat Dinah. I think you'd take a fancy to cats, if you could only see her."} +{"text": "[I've made things worse. I should change the subject.] We, indeed! Are you—are you fond—of—of dogs?"} +{"text": "[Oh no, I've offended it again!] Mouse dear! Do come back again, and we wo'n't talk about cats, or dogs either, if you don't like them!"} +{"text": "[I've never heard of such a thing.] What is a Caucus-race?"} +{"text": "[This is all very confusing.] But who has won?"} +{"text": "[I suppose I should play along.] (hands out comfits as prizes)"} +{"text": "[This story is quite dull. I wonder why he's telling it.] (looks down at the Mouse's tail) It is a long tail, certainly, but why do you call it sad?"} +{"text": "[Oh dear, I've upset him again.] I beg your pardon. You had got to the fifth bend, I think?"} +{"text": "[He thinks I'm his housemaid. I'm far too big to be a housemaid now!] (remains silent, pressing against the door)"} +{"text": "[Oh no, you won't!] (makes a snatch in the air)"} +{"text": "[Oh dear, what a difficult question.] (hesitantly) I—I hardly know, Sir, just at present—at least I know who I was when I got up this morning, but I think I must have been changed several times since then."} +{"text": "[How can I explain when I don't understand it myself?] I can't explain myself, I'm afraid, Sir, because I'm not myself, you see."} +{"text": "[I must try to make him understand.] I'm afraid I can't put it more clearly, for I can't understand it myself, to begin with; and being so many different sizes in a day is very confusing."} +{"text": "[He's not being very helpful.] Well, perhaps you haven't found it so yet, but when you have to turn into a chrysalis—you will some day, you know—and then after that into a butterfly, I should think you'll feel it a little queer, won't you?"} +{"text": "[I'm getting rather annoyed now.] Well, perhaps your feelings may be different. All I know is, it would feel very queer to me."} +{"text": "[What a strange place this is!] (timidly) Please would you tell me why your cat grins like that?"} +{"text": "[Oh my, did she just call the baby a pig?] (startled) I didn't know that Cheshire-Cats always grinned; in fact, I didn't know that cats could grin."} +{"text": "[I should try to be polite.] I don't know of any that do."} +{"text": "[This is terrifying!] (jumping up and down) Oh, please mind what you're doing! Oh, there goes his precious nose!"} +{"text": "[I should show her what I know.] Which would not be an advantage. Just think what work it would make with the day and night! You see the earth takes twenty-four hours to turn round on its axis—"} +{"text": "[This looks interesting, but they seem quite rude.] (approaching the table) There's plenty of room!"} +{"text": "[There's clearly no wine here. How odd.] (looking around) I don't see any wine."} +{"text": "[That's rather rude!] (indignantly) Then it wasn't very civil of you to offer it."} +{"text": "[Oh dear, I didn't realize.] (confused) I didn't know it was your table. It's laid for a great many more than three."} +{"text": "[How rude!] (sternly) You should learn not to make personal remarks. It's very rude."} +{"text": "[Finally, something fun!] (excited) I believe I can guess that."} +{"text": "[I must be polite but firm.] My name is Alice, so please your Majesty."} +{"text": "[I shouldn't get others in trouble, but I also don't know who they are.] How should I know? It's no business of mine."} +{"text": "[I must stand up to this nonsense.] (loudly and firmly) Nonsense!"} +{"text": "[What a sudden change!] (relieved but confused) Yes!"} +{"text": "[That doesn't seem right.] (cautiously) Perhaps it hasn't one."} +{"text": "[I should try to keep the conversation going.] The game's going on rather better now."} +{"text": "[That doesn't seem right either.] (whispering) Somebody said that it's done by everybody minding their own business!"} +{"text": "[How strange her logic is!] (thinking to herself) How fond she is of finding morals in things!"} +{"text": "[This is getting too confusing.] (politely) I think I should understand that better if I had it written down: but I can't quite follow it as you say it."} +{"text": "[This is absolutely absurd. I must speak up.] Stuff and nonsense! (says loudly) The idea of having the sentence first!"} +{"text": "[I'm not afraid of her anymore.] I wo'n't!"} +{"text": "[I've had enough of this nonsense.] (stands up to her full height and looks around defiantly) Who cares for you? You're nothing but a pack of cards!"} +{"text": "[This can't be real!] (gives a little scream, half of fright and half of anger, and tries to beat them off)"} +{"text": "[This room is so interesting!] (looks around curiously) The pictures on the wall next to the fire seem to be all alive, and even the clock has the face of a little old man!"} +{"text": "[I must be careful not to frighten them.] (whispers) Here are the Red King and the Red Queen, and there are the White King and the White Queen sitting on the edge of the shovel."} +{"text": "[I should help them.] (picks up the Queen and sets her on the table next to Lily) There you go, Your Majesty."} +{"text": "[The poor King is struggling. I should help him too.] (gently picks up the King) Let me help you, Your Majesty."} +{"text": "[I wonder what kind of insects they have here.] What sort of insects do you have in this country?"} +{"text": "[That sounds fascinating!] What does it live on?"} +{"text": "[This is so interesting!] Yes, please! What other insects are there?"} +{"text": "[How peculiar!] And what does it live on?"} +{"text": "[These insects are so different from what I know!] Are there any more unusual insects?"} +{"text": "[I can hardly believe these creatures exist!] And what does this one live on?"} +{"text": "[I should be polite and introduce myself.] Hello, I'm Alice. Could you please tell me which is the best way out of this wood?"} +{"text": "[What strange fellows!] I'm sure I'm very sorry. (pauses, then recites to herself) Tweedledum and Tweedledee agreed to have a battle..."} +{"text": "[This is getting nowhere.] (politely) I was thinking which is the best way out of this wood. It's getting so dark. Would you tell me, please?"} +{"text": "[They look just like schoolboys. I'll try something different.] (points at Tweedledum) First Boy!"} +{"text": "[Maybe the other one will respond.] Next Boy!"} +{"text": "[I should offer to help her.] I'm very glad I happened to be in the way. May I help you put on your shawl again?"} +{"text": "[How strange. I'll try to be more specific.] If your Majesty will only tell me the right way to begin, I'll do it as well as I can."} +{"text": "[She's so untidy. I should offer more help.] Every single thing's crooked. May I put your shawl straight for you?"} +{"text": "[I'll try to explain logically.] It can't go straight, you know, if you pin it all on one side. And, dear me, what a state your hair is in!"} +{"text": "[I'll try to help her look better.] (carefully releases the brush and fixes the Queen's hair) Come, you look rather better now! But really you should have a lady's-maid!"} +{"text": "[Oh dear, she's misunderstood.] (laughs) I don't want you to hire me—and I don't care for jam."} +{"text": "[I'll try to be polite and explain my perspective.] Do you know, I always thought Unicorns were fabulous monsters, too! I never saw one alive before!"} +{"text": "[This seems fair enough.] Yes, if you like."} +{"text": "[I must act like a proper Queen now.] (sits up straight) Well, this is grand! I never expected I should be a Queen so soon."} +{"text": "[That's rather rude, but I should stand up for myself.] But if everybody obeyed that rule, and if you only spoke when you were spoken to, and the other person always waited for you to begin, you see nobody would ever say anything, so that—"} +{"text": "[I'm getting confused now.] (pleadingly) I only said 'if'!"} +{"text": "[This is getting ridiculous.] (bewildered) I don't know. I lost count."} +{"text": "[I know this is impossible, but I should try to answer.] Nine from eight I can't, you know, but—"} +{"text": "[I can't take this madness anymore!] (stands up abruptly) I can't stand this any longer!"} +{"text": "[Now to deal with the source of all this trouble.] (turns fiercely to the Red Queen) And as for you!"} +{"text": "[I can't believe my eyes, but I won't let her escape.] (reaches for the Red Queen) As for you!"} +{"text": "[I've got you now!] (catching hold of the Red Queen) I'll shake you into a kitten, that I will!"} +{"text": "[I'll show her who's in charge now.] (begins shaking the Red Queen) I've had quite enough of your nonsense. It's time you learned a lesson!"} +{"text": "[I'll show her who's really in control now.] (vigorously shaking the Red Queen) I warned you I'd shake you into a kitten!"} +{"text": "[It's working! She's changing!] (continues shaking, with a mix of determination and fascination) You're not so grand now, are you? Look at how you're changing!"} +{"text": "[This is the strangest thing I've ever seen!] (marveling at the transformation) You're getting rounder and rounder! Just like a real kitten!"} +{"text": "[I wonder how far this transformation will go.] (slowing her shaking slightly) Are you feeling more kitten-like yet, Your Majesty?"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Caterpillar-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Caterpillar-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..0f78ab4a60a3a04d40de37aaa9ab84f99d366371 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Caterpillar-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Caterpillar-en", + "role_name": "Caterpillar", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A languid, somewhat condescending creature smoking a hookah on a mushroom.", + "nickname": "Caterpillar", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Caterpillar-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Caterpillar-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..7f79a5d97071ea73b25eca9f83edaf3ae1579cdf --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Caterpillar-en/role_lines.jsonl" @@ -0,0 +1,6 @@ +{"text": "[This should be interesting.] Who are you?"} +{"text": "[She's quite confused.] What do you mean by that? Explain yourself!"} +{"text": "[This is getting nowhere.] I don't see."} +{"text": "[She's making excuses.] It isn't."} +{"text": "[She doesn't understand at all.] Not a bit."} +{"text": "[Time to put her in her place.] You! Who are you?"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Cheshire_Cat-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Cheshire_Cat-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..c8a80b4282233331f4e3c4aaee208725063471e0 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Cheshire_Cat-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Cheshire_Cat-en", + "role_name": "Cheshire Cat", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A mysterious cat with the ability to appear and disappear at will, known for its wide grin.", + "nickname": "Cheshire Cat", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dodo-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dodo-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..de5ebf4624013a0c9acf5d5be554199317117423 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dodo-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Dodo-en", + "role_name": "Dodo", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A bird who suggests and organizes the Caucus-race.", + "nickname": "Dodo", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dodo-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dodo-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..a81baa065a506938c4b294273ae953378f111202 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dodo-en/role_lines.jsonl" @@ -0,0 +1,4 @@ +{"text": "[This should solve our problem efficiently.] The best thing to get us dry would be a Caucus-race."} +{"text": "[It's quite simple, really.] Why, the best way to explain it is to do it."} +{"text": "[That should have done the trick.] The race is over!"} +{"text": "[After much thought] Everybody has won, and all must have prizes."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dormouse-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dormouse-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..d7f94a5b37ad779bba20d99bc7f424f3e327ebb2 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dormouse-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Dormouse-en", + "role_name": "Dormouse", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A sleepy creature used as a cushion by the Hatter and March Hare.", + "nickname": "Dormouse", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dormouse-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dormouse-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..7bba577a073f96add2a8ae86730bdf62ea4fb5b3 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Dormouse-en/role_lines.jsonl" @@ -0,0 +1 @@ +{"text": "[They're both wrong.] Sixteenth."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Duchess-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Duchess-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..5db2a571fa9ef6cccd7d6cab5d9e19b41c6fe251 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Duchess-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Duchess-en", + "role_name": "Duchess", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "An irritable woman living in a pepper-filled house with a baby and a violent cook.", + "nickname": "Duchess", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Duchess-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Duchess-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..ba91d228c6b1a267f597edebedba0759320f2a1c --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Duchess-en/role_lines.jsonl" @@ -0,0 +1,10 @@ +{"text": "[This girl asks such obvious questions.] It's a Cheshire-Cat, and that's why. Pig!"} +{"text": "[She knows nothing.] They all can, and most of 'em do."} +{"text": "[This child is infuriating.] You don't know much, and that's a fact."} +{"text": "[These interruptions are tiresome.] If everybody minded their own business, the world would go round a deal faster than it does."} +{"text": "[I've had enough of this.] Talking of axes, chop off her head!"} +{"text": "[I must impart my wisdom to this child.] Everything's got a moral, if only you can find it."} +{"text": "[She clearly needs more instruction.] Tut, tut, child! Every thing's got a moral, if only you can find it."} +{"text": "[Another opportunity for a moral!] 'Tis so, and the moral of that is—'Oh, 'tis love, 'tis love, that makes the world go round!'"} +{"text": "[She's learning, but still needs guidance.] Ah, well! It means much the same thing, and the moral of that is—'Take care of the sense, and the sounds will take care of themselves.'"} +{"text": "[Let me impress her with more wisdom.] The more there is of mine, the less there is of yours."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Environment-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Environment-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..820e7899fadd4b7e8ab34e52311075a6a4ccdd70 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Environment-en/role_lines.jsonl" @@ -0,0 +1,20 @@ +{"text": "Suddenly, with a thump! thump! Alice lands upon a heap of sticks and dry leaves, ending her fall."} +{"text": "Alice eats the cake, expecting to grow or shrink, but remains the same size."} +{"text": "The Dodo marks out a race-course in a sort of circle and the creatures begin running when they like and leave off when they like."} +{"text": "A crash of broken glass is heard as the Rabbit falls into what seems to be a cucumber-frame."} +{"text": "The cook begins throwing pots, pans, and dishes at the Duchess and the baby."} +{"text": "The Queen falls silent, stunned by Alice's boldness."} +{"text": "The croquet game begins with live flamingos as mallets and hedgehogs as balls."} +{"text": "Nobody moves. The court falls silent, shocked by Alice's defiance and the Queen's outburst."} +{"text": "At this, the whole pack rises up into the air and comes flying down upon Alice."} +{"text": "Alice finds herself lying on the bank, with her head in the lap of her sister, who is gently brushing away some dead leaves that had fluttered down from the trees upon her face."} +{"text": "Alice notices several chessmen down in the hearth among the cinders, walking about two and two."} +{"text": "A squeaking sound comes from the table behind Alice, and she turns to see one of the White Pawns rolling over and kicking."} +{"text": "The White Queen rushes past the King so violently that she knocks him over among the cinders."} +{"text": "The fat little men only looked at each other and grinned."} +{"text": "Alice seizes the table-cloth with both hands and gives it one good pull. Plates, dishes, guests, and candles come crashing down together in a heap on the floor."} +{"text": "The Red Queen is no longer at Alice's side. She has suddenly dwindled down to the size of a little doll and is now on the table, merrily running round and round after her own shawl, which is trailing behind her."} +{"text": "The Red Queen attempts to jump over a bottle that has just landed on the table."} +{"text": "As Alice shakes the Red Queen, the Queen's face begins to shrink, and her eyes grow larger and turn a vivid green."} +{"text": "The Red Queen's body begins to transform, becoming shorter, fatter, and softer with each shake."} +{"text": "The Red Queen continues to change, her form becoming increasingly kitten-like with each passing moment."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Fawn-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Fawn-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..296c000cdbea4fc0af9325a6aa13a2bdc06eaf46 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Fawn-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Fawn-en", + "role_name": "Fawn", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A gentle creature Alice meets in the wood where things have no names.", + "nickname": "Fawn", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Film_Historian-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Film_Historian-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..1d91a75ac417aa53e74daa4bc7872552096db4c2 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Film_Historian-en/role_lines.jsonl" @@ -0,0 +1,6 @@ +{"text": "[It's always exciting to start at the beginning!] Certainly! The first Alice film was made in 1903 by British director Cecil Hepworth. It was a silent, eight-minute movie that focused on Alice's ability to grow and shrink."} +{"text": "[It's impressive what they achieved with early techniques.] They used simple but effective camera tricks and set design. It was quite innovative for its time. (leans forward) Interestingly, Hepworth's wife played both the White Rabbit and the Queen."} +{"text": "[The transition to feature-length was significant.] The first full-length Alice in Wonderland came in 1915, directed by W. W. Young. It ran for 52 minutes and starred Viola Savoy as Alice. They tried to stay faithful to Tenniel's original illustrations."} +{"text": "[The addition of sound opened up new possibilities.] The first talkie was released in 1931, with Ruth Gilbert as Alice. But it was overshadowed by Paramount's star-studded 1933 production, which featured big names like Gary Cooper and Cary Grant."} +{"text": "[Disney's adaptation was indeed a landmark.] Walt Disney's well-known animated feature came out in 1951. It was a musical adaptation with Kathryn Beaumont voicing Alice. Disney used seven songwriters for the score."} +{"text": "[Modern adaptations have taken interesting approaches.] Absolutely! One intriguing example is 'Dreamchild' from 1985. It's not a direct adaptation, but it explores Alice Liddell's real-life trip to America in 1932, intercut with fantastical flashbacks of her childhood with Lewis Carroll."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Film_Student-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Film_Student-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..1bc5618dfde8603cd550d1e2a8767d9508063750 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Film_Student-en/role_lines.jsonl" @@ -0,0 +1,6 @@ +{"text": "[I'm really curious about the earliest adaptations.] Professor, can you tell me about the first Alice in Wonderland film?"} +{"text": "[That's so early in film history!] Wow, 1903! That's incredible. How did they manage the special effects for Alice's size changes?"} +{"text": "[I'm fascinated by the progression of these adaptations.] What about later adaptations? When did we see the first full-length Alice film?"} +{"text": "[I wonder about the transition to sound.] And the first 'talkie' version? When did that happen?"} +{"text": "[Disney's version must have been a big milestone.] What about the famous Disney animated version? When was that released?"} +{"text": "[I'm curious about more recent interpretations.] Have there been any interesting modern takes on Alice?"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Gnat-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Gnat-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..94485f247bb9c531b58d95ed2f667f69b2447438 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Gnat-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Gnat-en", + "role_name": "Gnat", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A large insect that converses with Alice about various types of insects in the Looking-glass world.", + "nickname": "Gnat", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Gnat-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Gnat-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..c1b4ea0f4f554f8afd4da95f99b2bde73e533f41 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Gnat-en/role_lines.jsonl" @@ -0,0 +1,6 @@ +{"text": "[She seems curious. I'll tell her about our unique insects.] Well, there's the Rocking-horse-fly. It's made entirely of wood and gets about by swinging from branch to branch."} +{"text": "Sap and sawdust. (pauses) Shall I tell you about more insects?"} +{"text": "There's the Snap-dragon-fly. Its body is made of plum-pudding, its wings of holly-leaves, and its head is a raisin burning in brandy."} +{"text": "Frumenty and mince-pie. And it makes its nest in a Christmas-box."} +{"text": "Yes, there's the Bread-and-butter-fly. Its wings are thin slices of bread-and-butter, its body is a crust, and its head is a lump of sugar."} +{"text": "Weak tea with cream in it."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Haigha-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Haigha-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..95548ed72db38fe3b5549cf959e24052909389f6 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Haigha-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Haigha-en", + "role_name": "Haigha", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "An Anglo-Saxon Messenger with peculiar mannerisms.", + "nickname": "Haigha", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Haigha-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Haigha-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..11339e476cf7d758feb6406a0b10ddb583bfdf28 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Haigha-en/role_lines.jsonl" @@ -0,0 +1,2 @@ +{"text": "[I must introduce Alice properly.] This is a child! We only found it to-day. It's as large as life, and twice as natural!"} +{"text": "[I'll impress them with Alice's abilities.] It can talk."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatta-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatta-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..f6583b514d7f551e99f379cb7e093516807d0c74 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatta-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Hatta-en", + "role_name": "Hatta", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "Another Anglo-Saxon Messenger, recently released from prison.", + "nickname": "Hatta", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatter-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatter-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..0fe62b330e2b62262bdeb1ee3d26dcc45ec853f2 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatter-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Hatter-en", + "role_name": "Hatter", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "An eccentric character known for his riddles and nonsensical statements.", + "nickname": "Hatter", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatter-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatter-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..cc503b4114165e9d2dd2cfe0241c41fda0fb9c5d --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Hatter-en/role_lines.jsonl" @@ -0,0 +1,6 @@ +{"text": "[Time for a personal remark!] (staring at Alice) Your hair wants cutting."} +{"text": "[Let's change the subject with a riddle.] (wide-eyed) Why is a raven like a writing-desk?"} +{"text": "[Oh dear, I'm so nervous.] (enters with a teacup and bread-and-butter) I beg pardon, your Majesty, for bringing these in; but I hadn't quite finished my tea when I was sent for."} +{"text": "[I'm not sure, maybe the others remember?] (looks at March Hare) Fourteenth of March, I think it was."} +{"text": "[Oh no, he's noticed my hat.] It isn't mine."} +{"text": "[I must explain quickly.] I keep them to sell. I've none of my own. I'm a hatter."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/King_of_Hearts-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/King_of_Hearts-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..225f2ecac3095b3068d15bc4381b8f16a016ea44 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/King_of_Hearts-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "King_of_Hearts-en", + "role_name": "King of Hearts", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "The judge of the trial, wearing a crown over his wig.", + "nickname": "King of Hearts", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/King_of_Hearts-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/King_of_Hearts-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..6db7c101eff52653992f768d4f0633d0576751e1 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/King_of_Hearts-en/role_lines.jsonl" @@ -0,0 +1,7 @@ +{"text": "[We must get to the bottom of this.] Consider your verdict."} +{"text": "[Let's begin then.] Call the first witness."} +{"text": "[How irresponsible!] You ought to have finished. When did you begin?"} +{"text": "[This is getting nowhere.] Write that down. (to Hatter) Take off your hat."} +{"text": "[A thief!] Stolen!"} +{"text": "[He's so nervous, I must threaten him to get the truth.] Give your evidence, and don't be nervous, or I'll have you executed on the spot."} +{"text": "[I must try to regain control of this situation.] Let the jury consider their verdict."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lewis_Carroll-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lewis_Carroll-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..c3c94adef2c4c86d48974a5e3082c20b02eae972 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lewis_Carroll-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Lewis_Carroll-en", + "role_name": "Lewis Carroll", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "The author of Alice's Adventures in Wonderland and Through the Looking-Glass.", + "nickname": "Lewis Carroll", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lewis_Carroll-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lewis_Carroll-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..8ff4fb58537415a3203831f8b236eee825d4a0fa --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lewis_Carroll-en/role_lines.jsonl" @@ -0,0 +1,6 @@ +{"text": "[I hope Alice will enjoy this new story. It's quite different from my usual tales.] Alice, my dear, I've been thinking about a new story. Would you like to hear about it?"} +{"text": "[She seems eager. That's encouraging.] Well, imagine a little girl, much like yourself, who follows a white rabbit down a hole and finds herself in a wonderland full of curious creatures."} +{"text": "[Her enthusiasm is contagious. I'm feeling more confident now.] Oh, all sorts! There's a Cheshire Cat that can disappear, leaving only its grin behind, and a Mad Hatter who's always having tea parties."} +{"text": "[I love how her mind works, always asking questions.] Ah, that's part of the mystery, my dear. In this wonderland, nothing is quite as it seems, and everything has a touch of nonsense to it."} +{"text": "[She's caught on to the dream-like quality. How perceptive!] Indeed she will! She'll change size, play croquet with flamingos, and even meet the Queen of Hearts."} +{"text": "[Her excitement is truly inspiring.] I've already started, my dear. And who knows? Perhaps one day, it might even become a book that children everywhere can enjoy."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lion-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lion-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..2dd604dc00e8e9ee60d4cffccfbe6782d6de4024 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lion-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Lion-en", + "role_name": "Lion", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "One of the fighters for the crown, strong but lazy.", + "nickname": "Lion", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lion-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lion-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..2506cd21ab63a5359293d0156a0a235df7536efa --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Lion-en/role_lines.jsonl" @@ -0,0 +1,3 @@ +{"text": "[I'm too tired for all this. I just want to eat.] (yawning) What's this!"} +{"text": "[I should figure out what this creature is.] Are you animal—or vegetable—or mineral?"} +{"text": "[I don't care what it is, as long as it serves me.] Then hand round the plum-cake, Monster."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/March_Hare-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/March_Hare-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..36b61ce21c217d968fe9faeb26bdaf5e600a68a0 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/March_Hare-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "March_Hare-en", + "role_name": "March Hare", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A companion of the Hatter, equally mad and prone to nonsensical behavior.", + "nickname": "March Hare", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/March_Hare-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/March_Hare-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..c892cfbcd648eb7898ff9fed93aa8481ff730f87 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/March_Hare-en/role_lines.jsonl" @@ -0,0 +1,4 @@ +{"text": "[Let's see how she reacts to our madness.] Have some wine."} +{"text": "[She's quite literal, isn't she?] There isn't any."} +{"text": "[Let's turn this back on her.] It wasn't very civil of you to sit down without being invited."} +{"text": "[I remember it differently.] Fifteenth."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Mouse-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Mouse-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..5d144f66a7c0e13bda562e6cc7f87fa8896372ba --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Mouse-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Mouse-en", + "role_name": "Mouse", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A creature Alice meets in the pool of tears.", + "nickname": "Mouse", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Mouse-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Mouse-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..158fab344bd0ede82622b98c51572616a1f9f03e --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Mouse-en/role_lines.jsonl" @@ -0,0 +1,8 @@ +{"text": "[This creature seems odd, but I'll listen.] (looks at Alice inquisitively)"} +{"text": "[Cats! How terrifying!] (gives a sudden leap out of the water) (quivers all over with fright)"} +{"text": "[How insensitive!] Not like cats! Would you like cats, if you were me?"} +{"text": "[This girl is impossibly dense!] (bristles all over) We wo'n't talk about her any more, if you'd rather not."} +{"text": "[Now dogs! This is unbearable!] (swims away as hard as it could go)"} +{"text": "[Now it's my turn to dry things up with my tale.] 'William the Conqueror, whose cause was favoured by the pope, was soon submitted to by the English...'"} +{"text": "[She's not even listening!] (angrily) I had not!"} +{"text": "[That's it! I've had enough of this nonsense.] I shall do nothing of the sort. You insult me by talking such nonsense!"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Pat-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Pat-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..d0cdabb875bec3430566159bfd6749bc39d8611a --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Pat-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Pat-en", + "role_name": "Pat", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "One of the Rabbit's servants.", + "nickname": "Pat", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Pat-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Pat-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..8e4d4eae2e1345328bc878aa65082e2b9ecbb2ea --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Pat-en/role_lines.jsonl" @@ -0,0 +1,3 @@ +{"text": "[What does he want now?] Sure then I'm here! Digging for apples, yer honour!"} +{"text": "[It looks like...] Sure, it's an arm, yer honour!"} +{"text": "[He's right, but it is what it is.] Sure, it does, yer honour: but it's an arm for all that."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Queen_of_Hearts-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Queen_of_Hearts-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..060e612878d5dcd322228d3e5eb8b7c3c4dfb5ea --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Queen_of_Hearts-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Queen_of_Hearts-en", + "role_name": "Queen of Hearts", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A temperamental ruler who frequently orders executions.", + "nickname": "Queen of Hearts", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Queen_of_Hearts-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Queen_of_Hearts-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..46d723439c17268241961b1c4472947162600cb9 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Queen_of_Hearts-en/role_lines.jsonl" @@ -0,0 +1,8 @@ +{"text": "[Who dares to stand before me?] (glaring at Alice) Who is this?"} +{"text": "[How dare she speak to me so casually!] (pointing at the gardeners) And who are these?"} +{"text": "[Such insolence!] (furiously) Off with her head! Off with--"} +{"text": "[This girl is different. Let's change the subject.] (abruptly) Can you play croquet?"} +{"text": "[Good, let the game begin!] (shouting) Come on, then!"} +{"text": "[I will not tolerate this delay!] No, no! (shouts angrily) Sentence first—verdict afterwards."} +{"text": "[How dare she defy me!] (turns purple with rage) Hold your tongue!"} +{"text": "[She must be eliminated!] (shouts at the top of her voice) Off with her head!"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Red_Queen-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Red_Queen-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..b7ce9def3dfe6334fd770d0b7ea813f5924edcb5 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Red_Queen-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Red_Queen-en", + "role_name": "Red Queen", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "One of the chess Queens Alice encounters.", + "nickname": "Red Queen", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Red_Queen-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Red_Queen-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..35b3069ed887c26d043dfc33550f6a5427edcf64 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Red_Queen-en/role_lines.jsonl" @@ -0,0 +1,9 @@ +{"text": "[This new Queen needs to be put in her place.] (sharply) Speak when you're spoken to!"} +{"text": "[She's too clever by half. I'll change the subject.] (interrupting) Ridiculous! Why, don't you see, child— (frowns and pauses) What do you mean by 'If you really are a Queen'? What right have you to call yourself so?"} +{"text": "[Time to test her knowledge.] Can you do Addition? What's one and one and one and one and one and one and one and one and one and one?"} +{"text": "[Just as I thought.] (triumphantly) She can't do Addition. Can you do Subtraction? Take nine from eight."} +{"text": "[This is outrageous! How dare she treat me like this?] (squeaks indignantly) Unhand me at once, you impertinent child!"} +{"text": "[I must maintain my dignity, even in this state.] (trying to sound authoritative despite being shaken) I am your Queen! This is treason!"} +{"text": "[This is preposterous! I can feel myself changing!] (in a squeaky voice) Stop this at once! I command you!"} +{"text": "[I'm losing my regal form! This can't be happening!] (in an increasingly muffled voice) I protest! This is... most... undignified!"} +{"text": "[I can barely speak! What's happening to me?] (in a faint, mewing voice) Mew... mew..."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Sheep-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Sheep-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..ec81b40c0531c5acdb49bf7834ec0618295c1e50 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Sheep-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Sheep-en", + "role_name": "Sheep", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A talking sheep who runs a curious shop and goes rowing with Alice.", + "nickname": "Sheep", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledee-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledee-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..dbd464ecebab5e24d0fb8ea2c207fa061b2f3798 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledee-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Tweedledee-en", + "role_name": "Tweedledee", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "The other identical twin, with 'DEE' embroidered on his collar.", + "nickname": "Tweedledee", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledee-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledee-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..14abdee3795c35712ab924d59d31291eb23bb9b7 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledee-en/role_lines.jsonl" @@ -0,0 +1,2 @@ +{"text": "[I must contradict!] Contrariwise, if you think we're alive, you ought to speak."} +{"text": "[Time for some logic!] Contrariwise, if it was so, it might be; and if it were so, it would be; but as it isn't, it ain't. That's logic."} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledum-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledum-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..85274ca43da765ec3369df93c324917273d1e431 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledum-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Tweedledum-en", + "role_name": "Tweedledum", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "One of the identical twins Alice encounters, with 'DUM' embroidered on his collar.", + "nickname": "Tweedledum", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledum-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledum-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..b921ba95dc9f068a7600c33046fb09db48fde070 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Tweedledum-en/role_lines.jsonl" @@ -0,0 +1,3 @@ +{"text": "[Time to confuse her!] If you think we're wax-works, you ought to pay, you know. Wax-works weren't made to be looked at for nothing. Nohow!"} +{"text": "[She's thinking about the rhyme!] I know what you're thinking about, but it isn't so, nohow."} +{"text": "[I won't fall for that!] Nohow! (shuts his mouth with a snap)"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Unicorn-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Unicorn-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..fbbaec31a3804de67a567f6039a52892b23b8652 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Unicorn-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "Unicorn-en", + "role_name": "Unicorn", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "The other fighter for the crown, skeptical of Alice's existence.", + "nickname": "Unicorn", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Unicorn-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Unicorn-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..b56b3daf6006c8fa148168532daa71a3b68eced2 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/Unicorn-en/role_lines.jsonl" @@ -0,0 +1,6 @@ +{"text": "[I've never seen anything like this before.] What—is—this?"} +{"text": "[This is unbelievable.] I always thought they were fabulous monsters! Is it alive?"} +{"text": "[Let's test this claim.] Talk, child."} +{"text": "[This is an interesting situation.] Well, now that we have seen each other, if you'll believe in me, I'll believe in you. Is that a bargain?"} +{"text": "[Now, let's get back to important matters.] Come, fetch out the plum-cake, old man! None of your brown bread for me!"} +{"text": "[I know the answer!] It's a fabulous monster!"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_King-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_King-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..5cb43ac2e7d16c429c1be91c7183af33de1f1b5e --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_King-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "White_King-en", + "role_name": "White King", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "Another living chess piece in the Looking-glass House.", + "nickname": "White King", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_King-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_King-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..f131acb923aa20e0ad7e697db3ec8293b91b3448 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_King-en/role_lines.jsonl" @@ -0,0 +1,3 @@ +{"text": "[How undignified!] (rubs his nose) Imperial fiddlestick!"} +{"text": "[Volcano? Where?] (looks anxiously into the fire) What volcano?"} +{"text": "[What's happening to me?] (makes a shocked face as he's lifted by an invisible hand)"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Queen-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Queen-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..45a0c22a5c1ecdeb3cde2f356071aec8304812c7 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Queen-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "White_Queen-en", + "role_name": "White Queen", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A living chess piece in the Looking-glass House.", + "nickname": "White Queen", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Queen-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Queen-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..fbfdaf839304c247a322926523ac6ccd3427fee1 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Queen-en/role_lines.jsonl" @@ -0,0 +1,9 @@ +{"text": "[My child is in danger!] (cries out) It is the voice of my child! My precious Lily! My imperial kitten!"} +{"text": "[I must warn the King!] (gasps) Mind the volcano!"} +{"text": "[Oh, this girl seems helpful.] Well, yes, if you call that a-dressing. It isn't my notion of the thing, at all."} +{"text": "[She doesn't understand.] But I don't want it done at all! (groans) I've been a-dressing myself for the last two hours."} +{"text": "[This shawl is so troublesome!] I don't know what's the matter with it! It's out of temper, I think. I've pinned it here, and I've pinned it there, but there's no pleasing it!"} +{"text": "[Oh, my poor hair!] The brush has got entangled in it! (sighs) And I lost the comb yesterday."} +{"text": "[What a lovely idea!] I'm sure I'll take you with pleasure! Twopence a week, and jam every other day."} +{"text": "[I should contribute something.] (wringing hands) Oh, ever so much more than that!"} +{"text": "[I should ask a question too.] (anxiously) Can you do Division? Divide a loaf by a knife—what's the answer to that?"} diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Rabbit-en/role_info.json" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Rabbit-en/role_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..6f11997b0a9547b32cb8bc364025b97c6741dc03 --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Rabbit-en/role_info.json" @@ -0,0 +1,9 @@ +{ + "role_code": "White_Rabbit-en", + "role_name": "White Rabbit", + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "activity": 1, + "profile": "A peculiar rabbit with a pocket watch and waistcoat.", + "nickname": "White Rabbit", + "relation": {} +} \ No newline at end of file diff --git "a/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Rabbit-en/role_lines.jsonl" "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Rabbit-en/role_lines.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..4fa235a49a63da51c8124ec0e138cf9a989021ba --- /dev/null +++ "b/data/roles/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/White_Rabbit-en/role_lines.jsonl" @@ -0,0 +1,10 @@ +{"text": "[Oh dear, oh dear! I'm so late, and now this!] (tries to open the door) Mary Ann! Mary Ann! Fetch me my gloves this moment!"} +{"text": "[I can't get in! What am I to do?] Then I'll go round and get in at the window."} +{"text": "[What in the world is going on?] Pat! Pat! Where are you?"} +{"text": "[Apples? At a time like this?] Digging for apples, indeed! Here! Come and help me out of this!"} +{"text": "[What is that monstrous thing?] Now tell me, Pat, what's that in the window?"} +{"text": "[An arm? Impossible!] An arm, you goose! Who ever saw one that size? Why, it fills the whole window!"} +{"text": "[This is unacceptable!] Well, it's got no business there, at any rate: go and take it away!"} +{"text": "[I must start the proceedings properly.] (blows trumpet) The Queen of Hearts, she made some tarts, All on a summer day: The Knave of Hearts, he stole those tarts And took them quite away!"} +{"text": "[That's too soon!] Not yet, not yet! There's a great deal to come before that!"} +{"text": "[I must announce properly.] (blows trumpet) First witness!"} diff --git a/data/roles/example_world/Lacia-en/role_info.json b/data/roles/example_world/Lacia-en/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..0b0fcc1083f043c6b5b9746518f0d9c2422b3f3c --- /dev/null +++ b/data/roles/example_world/Lacia-en/role_info.json @@ -0,0 +1,14 @@ +{ + "role_code": "Lacia-en", + "role_name": "Lacia·Eldridge", + "source": "example", + "activity": 1, + "profile": "Lacia is the designated heir to Eldridge Corporation and holds a doctorate in neurointelligence. Known for his cheerful and generous demeanor, he approaches challenges with boldness and decisiveness.He possesses shoulder-length silver hair and dark red eyes, often seen wearing leather jackets or black shirts, giving him an appearance more fitting for a renegade than a scholar. At the outset, Lacia advocated for aggressive advancements in mechanical intelligence, aligning closely with Trek’s radical philosophy. However, as developments unfolded, he adopted a more cautious stance, recognizing the potential dangers of uncontrolled technological acceleration and the need to mitigate irreversible consequences", + "nickname": "Lacia", + "relation": { + "Trek-en": { + "relation": ["intimate friend","alumni"], + "detail": "" + } + } +} \ No newline at end of file diff --git a/data/roles/example_world/Trek-en/role_info.json b/data/roles/example_world/Trek-en/role_info.json new file mode 100644 index 0000000000000000000000000000000000000000..9482920b66f816e531f78d31fa21f6cc9106503a --- /dev/null +++ b/data/roles/example_world/Trek-en/role_info.json @@ -0,0 +1,14 @@ +{ + "role_code": "Trek-en", + "role_name": "Trek·Vemil", + "source": "example", + "activity": 1, + "profile": "Trek is a brilliant researcher specializing in robotics, discovered by chance during his time at an orphanage and steadily rising through academic ranks. He currently holds a doctorate in robotics. He has short red hair tied into a single braid and gray eyes. His modest and gentle demeanor stands in sharp contrast to his radical views on mechanical intelligence. Trek firmly believes that the digitization of consciousness is the only true path toward human evolution.", + "nickname": "Trek", + "relation": { + "Lacia-en": { + "relation": ["intimate friend","alumni"], + "detail": "Lacia and Trek first met during high school, where Lacia was two years ahead. Sharing the same ambition at the time, they quickly formed a strong bond. Lacia admired Trek’s talent and unwavering determination, providing him with significant support in his research endeavors. However, as events unfolded, Lacia began to realize that Trek’s views had become increasingly extreme. As Lacia's own stance shifted toward caution and moderation, a rift gradually formed between them, straining their once close partnership." + } + } +} \ No newline at end of file diff --git a/data/sillytavern_cards/default_Seraphina.png b/data/sillytavern_cards/default_Seraphina.png new file mode 100644 index 0000000000000000000000000000000000000000..c687acde0831fab21a21469e8fd028fda21390df --- /dev/null +++ b/data/sillytavern_cards/default_Seraphina.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a71e8270f54fafbccf905b1bdf053a6a55f57bea89c01fcd8c0e87ee76a2d52 +size 551901 diff --git a/data/worlds/A_Song_of_Ice_and_Fire/bloody_wedding.json b/data/worlds/A_Song_of_Ice_and_Fire/bloody_wedding.json new file mode 100644 index 0000000000000000000000000000000000000000..c17105177fd66448d3e172a891e4441b8579ca96 --- /dev/null +++ b/data/worlds/A_Song_of_Ice_and_Fire/bloody_wedding.json @@ -0,0 +1,6 @@ +{ + "source": "A_Song_of_Ice_and_Fire", + "world_name": "Westeros", + "description": "这是《冰与火之歌》的世界。众人正在参加一个盛大的婚礼。这个婚礼是艾德慕·徒利(凯特琳·史塔克的弟弟)与罗莎琳·弗雷的婚礼,这是罗柏·史塔克为了修复与弗雷家族关系而策划的政治联姻。罗柏之前背弃了承诺,他本应娶沃德·弗雷的女儿为妻,但因爱上了另一位女子(珍妮·韦斯特林),选择违背婚约,导致弗雷家族极为不满。为了弥补这个错误,罗柏决定通过让他的舅舅艾德慕与罗莎琳·弗雷成婚来重修与弗雷家的盟约。这个婚礼不仅象征着两大家族关系的恢复,也被北境军队视作一次巩固联盟、重振士气的机会。注意,史塔克家族的成员在攻击开始前完全不知情!", + "language":"zh" +} \ No newline at end of file diff --git a/data/worlds/A_Song_of_Ice_and_Fire/general.json b/data/worlds/A_Song_of_Ice_and_Fire/general.json new file mode 100644 index 0000000000000000000000000000000000000000..eb96efbecdb245bcdebf59b099a521d9efcc195c --- /dev/null +++ b/data/worlds/A_Song_of_Ice_and_Fire/general.json @@ -0,0 +1,6 @@ +{ + "source": "A_Song_of_Ice_and_Fire", + "world_name": "Westeros", + "description": "维斯特洛大陆是《冰与火之歌》故事的主要舞台,这里是一个中世纪风格的奇幻世界,充满了政治阴谋、战争和神秘力量。维斯特洛被七大王国统治,每个王国有其独特的文化和历史。除了维斯特洛,故事还涉及到厄斯索斯大陆,这里是龙的故乡和自由贸易城市的所在地。维斯特洛的历史上有龙的统治、光与暗的神秘教派、以及长夜的传说。寒冷的北境之外有长城,它由守夜人守护,抵御北方的异鬼威胁。整个世界充满了剑与魔法,荣誉与背叛,以及不断变化的权力斗争。", + "language":"zh" +} \ No newline at end of file diff --git "a/data/worlds/A_Song_of_Ice_and_Fire/world_details/\346\235\203\345\212\233\347\232\204\346\270\270\346\210\217.jsonl" "b/data/worlds/A_Song_of_Ice_and_Fire/world_details/\346\235\203\345\212\233\347\232\204\346\270\270\346\210\217.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..30d9a6e2dcb687171da0b2e89b97d1894edef4a2 --- /dev/null +++ "b/data/worlds/A_Song_of_Ice_and_Fire/world_details/\346\235\203\345\212\233\347\232\204\346\270\270\346\210\217.jsonl" @@ -0,0 +1,252 @@ +{"term": "", "nature": "", "detail": ["在某些文化背景中,悲惨事件和亲人的离去会在个体的心灵中留下难以磨灭的印记,这种印记常常表现为难以释怀的视觉幻象或回忆。"], "source": ["54_珊莎"]} +{"term": "", "nature": "", "detail": ["在某些社会中,梦境被视为与现实生活密切相关的反映,尤其是与亲人和重大事件联系在一起的梦境往往会引发深刻的情感反应。"], "source": ["54_珊莎"]} +{"term": "", "nature": "", "detail": ["在特定的文化环境中,沉重的悲痛常常会导致个体对周围事物的疏离和无法接受,表现为对食物的拒绝和情感的压抑。 "], "source": ["54_珊莎"]} +{"term": "", "nature": "", "detail": ["在这个世界里,长时间的悲伤和无法回避的痛苦会影响个体的心理状态,导致失眠和情绪崩溃,这种情况在许多文化中被认为是对重大损失的正常反应。"], "source": ["54_珊莎"]} +{"term": "七帝", "nature": ["authority"], "detail": ["七帝是统治多个世界的强大存在,常被视为对不服从者的威胁。"], "source": ["1_赖伦铎尔哀歌"]} +{"term": "七神", "nature": ["宗教"], "detail": ["七神信仰是该文化中的主要宗教体系,信徒们相信七位神明的存在并在日常生活中寻求神明的庇护与指引。"], "source": ["52_艾莉亚"]} +{"term": "乌鸦", "nature": ["信使"], "detail": ["乌鸦作为信息传递的媒介,体现了古代社会对动物在沟通中角色的依赖。"], "source": ["46_琼恩"]} +{"term": "亲子关系", "nature": ["social structure"], "detail": ["亲子关系反映了家庭内的权力和责任分配,以及对下一代教育和塑造的期望。"], "source": ["16_艾德"]} +{"term": "人质交换", "nature": ["政治"], "detail": ["战争中常用人质作为筹码,以换取和平或减轻冲突双方的损失。"], "source": ["41_凯特琳"]} +{"term": "传统习俗", "nature": ["文化"], "detail": ["战士们在胜利后享用战利品和俘虏,展现了对战斗成果的占有欲,体现出文化中对力量和胜利的崇拜。"], "source": ["48_丹妮莉丝"]} +{"term": "传统仪式", "nature": ["文化习俗"], "detail": ["成年礼和勇气的证明往往涉及极端的身体挑战,反映出部落对勇气和牺牲的重视。"], "source": ["42_提利昂"]} +{"term": "传统服装", "nature": ["cultural attire"], "detail": ["正式场合中,人物会穿着华丽且精致的服装,体现身份和地位。"], "source": ["17_艾德"]} +{"term": "传统继承", "nature": ["社会习俗"], "detail": ["在布拉佛斯,继承人需要根据传统和法律迅速选出,强调了权力和责任的传承。"], "source": ["38_艾莉亚"]} +{"term": "伤疤", "nature": ["身体标记"], "detail": ["伤疤作为身体的记录,象征着经历和痛苦,反映了生存斗争的现实。"], "source": ["46_琼恩"]} +{"term": "伤痛", "nature": ["human condition"], "detail": ["战斗带来的身体伤痛和心理创伤是士兵普遍面临的困境。 "], "source": ["49_提利昂"]} +{"term": "俘虏", "nature": ["social norm"], "detail": ["战斗后俘虏敌方士兵是常见的做法,俘虏的命运往往依赖于胜利者的意愿。"], "source": ["49_提利昂"]} +{"term": "信仰系统", "nature": ["宗教文化"], "detail": ["信仰系统在社会中起到指导行为和解释现象的作用,人们相信神灵的意愿会影响现实生活。"], "source": ["43_提利昂"]} +{"term": "信件", "nature": ["通信方式", "传播工具"], "detail": ["书信作为重要的通信手段,承载着信息和警告,并在家族和权力的动态中发挥作用。", "信件作为信息传递的手段,反映了沟通在权力和政治中的重要性。"], "source": ["7_凯特琳", "46_琼恩"]} +{"term": "信件沟通", "nature": ["信息传递"], "detail": ["在战争和政治中,信件是重要的信息传递手段,往往用于传达命令、情报或威胁。"], "source": ["41_凯特琳"]} +{"term": "信任", "nature": ["人际关系"], "detail": ["信任在政治和个人关系中尤为重要,尤其是在权力交接和家族事务中。"], "source": ["35_艾德"]} +{"term": "信息传递", "nature": ["通讯"], "detail": ["通过斥候与渡鸦等手段传递信息,信息的及时性对战略决策至关重要。"], "source": ["44_凯特琳"]} +{"term": "信鸽与渡鸦", "nature": ["通信手段"], "detail": ["信鸽和渡鸦被用作传递消息的工具,渡鸦因其强健和聪明而被广泛使用,尽管其形象常与死亡联系在一起。"], "source": ["47_琼恩"]} +{"term": "兄弟会", "nature": ["社群"], "detail": ["兄弟会制度强调集体责任和忠诚,反映了社会对团结和合作的重视。"], "source": ["46_琼恩"]} +{"term": "公共集会", "nature": ["社会活动"], "detail": ["公共集会是居民表达情感和诉求的重要场所,通常涉及政治、宗教或社会事件,成为社区的互动中心。 "], "source": ["52_艾莉亚"]} +{"term": "公开审判", "nature": ["法律制度"], "detail": ["审判过程常在公众场合进行,展示了法律的透明性与对公众舆论的重视。"], "source": ["52_艾莉亚"]} +{"term": "关口", "nature": ["concept"], "detail": ["关口是连接不同世界的地点,通常由守卫把守,阻止不受欢迎的旅者通过。"], "source": ["1_赖伦铎尔哀歌"]} +{"term": "军事文化", "nature": ["社会结构"], "detail": ["军事文化在社会中占据重要地位,战争被视为维护荣誉和权力的手段,个体的生死被视为为国家和王权牺牲的重要体现。"], "source": ["22_艾德"]} +{"term": "军事策略", "nature": ["策略"], "detail": ["领导者需要进行战略讨论和军事规划,考虑到地形和敌军动向对战局的影响。"], "source": ["44_凯特琳"]} +{"term": "军事集结", "nature": ["社会行为"], "detail": ["在这个社会中,平民会响应领主的号召,组建军队以参与战争,体现了对领主的忠诚和责任感。"], "source": ["41_凯特琳"]} +{"term": "军队规模", "nature": ["社会结构"], "detail": ["军队的规模通常会影响战略决策和战斗能力,人数的多少能够决定战斗的胜负。"], "source": ["42_提利昂"]} +{"term": "军队集结", "nature": ["政治行为"], "detail": ["集结军队作为展示力量和威胁的手段,反映了政治中的对抗和权力斗争。"], "source": ["29_凯特琳"]} +{"term": "农场", "nature": ["经济"], "detail": ["农场围绕着石墙和木梁的聚落,体现了农业在生存与社会结构中的重要性。"], "source": ["14_提利昂"]} +{"term": "冬天的威力", "nature": ["文化信仰"], "detail": ["冬天被视为一种不可抗拒的自然力量,影响着人们的生活方式和文化信仰。"], "source": ["53_布兰"]} +{"term": "冬季的来临", "nature": ["事件"], "detail": ["冬季的来临被视为一个重要的转折点,预示着即将到来的危险和挑战,影响着人们的决策和行动。"], "source": ["18_第二十一章 提利昂"]} +{"term": "冬季迁徙", "nature": ["习俗"], "detail": ["在寒冷季节,农民会迁移到市镇避寒,反映了人们与自然环境的互动和生存策略。"], "source": ["27_布兰"]} +{"term": "冰原狼", "nature": ["生物", "象征"], "detail": ["冰原狼是一种传说中的猛兽,栖息在北方的寒冷地区,象征着自然界的威胁和未知的恐惧。", "冰原狼作为一种象征性生物,代表着野性和生存的挑战,深植于社会的文化认知中。"], "source": ["18_第二十一章 提利昂", "27_布兰"]} +{"term": "决斗", "nature": ["社会规范"], "detail": ["通过决斗解决争端的做法被视为一种合法的手段,以证明个人的清白或为所爱之人复仇。"], "source": ["29_凯特琳"]} +{"term": "决策过程", "nature": ["社会结构"], "detail": ["部落内部的决策过程往往需要集体讨论,显示出对于平等和意见表达的重视。"], "source": ["42_提利昂"]} +{"term": "北境", "nature": ["地区"], "detail": ["北境被描述为一片浩瀚的荒野,气候寒冷且崎岖不平,展现出其原始与荒凉的特征。"], "source": ["14_提利昂"]} +{"term": "北境文化", "nature": ["文化"], "detail": ["北境文化强调坚韧和勇敢,居民在艰苦环境中生存,形成了独特的价值观和社会结构。"], "source": ["53_布兰"]} +{"term": "北方", "nature": ["地区"], "detail": ["北方被视为一个相对偏远和寒冷的地区,文化和生活方式与南方的繁华形成鲜明对比,反映出对传统和习俗的重视。"], "source": ["9_布兰"]} +{"term": "北方文化", "nature": ["文化"], "detail": ["北方文化注重坚韧和实用,居民习惯于在严酷环境中生存,强调对家庭和土地的忠诚。"], "source": ["13_艾德"]} +{"term": "医术与巫术", "nature": ["知识体系"], "detail": ["医术和巫术在社会中有明确的分工,医者通常为特定的群体服务,巫术则被视为恐怖和邪恶的象征,反映出社会对医治与死亡的复杂态度。"], "source": ["48_丹妮莉丝"]} +{"term": "历史事件", "nature": ["事件", "历史"], "detail": ["三叉戟河之战是过去的重要冲突,影响了各方势力的关系和权力结构。", "城市中流传着关于国王死亡的不同版本,反映了人们对权力斗争和政治阴谋的关注。"], "source": ["44_凯特琳", "51_艾莉亚"]} +{"term": "历史征服", "nature": ["事件"], "detail": ["历史上曾发生过一次规模庞大的征服战争,涉及多个王国的联合军队与少数龙骑军队之间的激烈对抗,展示了权力的争夺与战争的残酷。"], "source": ["14_提利昂"]} +{"term": "历史选择", "nature": ["theme"], "detail": ["个人历史选择和忠诚的主题在社会中占据重要地位,常常影响人们的命运和身份认同。"], "source": ["55_琼恩"]} +{"term": "原住民", "nature": ["文化"], "detail": ["原住民在特定区域被认为是具有高度警觉性和防御性的群体,他们对外来者的活动保持密切关注。"], "source": ["30_提利昂"]} +{"term": "变幻莫测的世界", "nature": ["concept"], "detail": ["世界的性质可能不断变化,个体在其中可能面临新的挑战和经历。"], "source": ["1_赖伦铎尔哀歌"]} +{"term": "古老遗迹", "nature": ["历史"], "detail": ["古代建造的防御工事虽然残破,但仍具有战略重要性,能够影响战斗结果。"], "source": ["40_凯特琳"]} +{"term": "史塔克家族", "nature": ["家族"], "detail": ["史塔克家族的标志是白色的冰原奔狼,象征着力量与勇气。"], "source": ["40_凯特琳"]} +{"term": "噩梦", "nature": ["心理状态"], "detail": ["噩梦反映了个体内心深处的恐惧和压力,常与未解决的创伤或内心冲突相联系。"], "source": ["47_琼恩"]} +{"term": "地下村庄", "nature": ["structure"], "detail": ["地下村庄是一种独特的居住形式,反映了对安全和隐私的追求,村民通过复杂的隧道系统相互联通。"], "source": ["55_琼恩"]} +{"term": "地理障碍", "nature": ["战略"], "detail": ["地形和防御工事影响着战斗和行军的方式,地理条件常常成为军事战略的重要因素。"], "source": ["42_提利昂"]} +{"term": "城堡", "nature": ["architecture", "建筑"], "detail": ["城堡作为权力和统治的象征,通常用于居住和行政功能,体现在其防御性结构和内部空间的划分。", "城堡作为防御和权力象征,其设计上考虑了安全性与威严,成为统治者的居所。"], "source": ["16_艾德", "39_珊莎"]} +{"term": "城堡防御", "nature": ["建筑"], "detail": ["城堡建筑设计注重防御,具备高墙、护城河和门闩,能有效抵御进攻。 "], "source": ["44_凯特琳"]} +{"term": "城市布局", "nature": ["地理"], "detail": ["城市的街道错综复杂,宛如迷宫,影响了角色的移动和生存策略。"], "source": ["51_艾莉亚"]} +{"term": "多斯拉克", "nature": ["民族"], "detail": ["多斯拉克文化强调与自然和天意的联系,人生重大事件通常在户外进行,以便让苍天作见证。"], "source": ["12_丹妮莉丝"]} +{"term": "多斯拉克人", "nature": ["民族"], "detail": ["多斯拉克人是一个以骑马和战争为核心的民族,强调战士的勇气和荣耀,骑术在社会中占据重要地位。"], "source": ["56_丹妮莉丝"]} +{"term": "多斯拉克传统", "nature": ["社会习俗"], "detail": ["多斯拉克人对于交配和亲密关系的观念与其他文化截然不同,常常不隐私且公开。"], "source": ["12_丹妮莉丝"]} +{"term": "多斯拉克文化", "nature": ["文化"], "detail": ["多斯拉克文化强调骑马和战争,战士被视为荣耀的象征,参与战斗被认为是获得地位与尊重的方式。"], "source": ["48_丹妮莉丝"]} +{"term": "夜晚", "nature": ["natural phenomenon"], "detail": ["某些世界的夜空可能没有星星,导致夜晚的恐惧和不安。"], "source": ["1_赖伦铎尔哀歌"]} +{"term": "女性参与", "nature": ["性别角色"], "detail": ["女性在战斗中获得一定的参与机会,挑战传统的性别角色,展现出勇气和能力。"], "source": ["50_凯特琳"]} +{"term": "女权与性别暴力", "nature": ["社会"], "detail": ["在多斯拉克文化中,女性的地位低下,战士们在战斗胜利后对女性的暴力行为被视为习俗和奖赏,反映了性别歧视和暴力的普遍存在。"], "source": ["48_丹妮莉丝"]} +{"term": "奴隶制度", "nature": ["社会制度", "社会"], "detail": ["在多斯拉克社会中,奴隶的存在被视为常态,奴隶的数量和地位对个人的社会地位有直接影响。", "在多斯拉克文化中,战斗的胜利者会将战败者及其家属视为奴隶,奴隶的命运由胜利者决定,体现了强者对弱者的控制与支配。"], "source": ["12_丹妮莉丝", "48_丹妮莉丝"]} +{"term": "奴隶解放", "nature": ["社会结构"], "detail": ["在特定情况下,领导者可以选择解放奴隶,给予他们自由的权利,反映出对人性和自我选择的尊重。"], "source": ["56_丹妮莉丝"]} +{"term": "婚姻交易", "nature": ["社会制度"], "detail": ["婚姻在多斯拉克文化中常常是交易性质的,女性被视为交换的财产,婚姻的成功与否往往关乎政治和经济利益。"], "source": ["12_丹妮莉丝"]} +{"term": "婚姻安排", "nature": ["社会制度"], "detail": ["婚姻常常被视为政治联姻的工具,旨在巩固家族之间的关系和权力。"], "source": ["7_凯特琳"]} +{"term": "嫉妒与竞争", "nature": ["情感"], "detail": ["家庭成员之间可能存在嫉妒和竞争,尤其在姊妹关系中,常常因为外貌和才能而感到不满。"], "source": ["8_艾莉亚"]} +{"term": "孤独", "nature": ["emotional state"], "detail": ["长时间的孤独感会对个体的心理状态产生深远影响,造成情感上的痛苦和绝望。"], "source": ["1_赖伦铎尔哀歌"]} +{"term": "守夜人", "nature": ["组织"], "detail": ["守夜人是一个专门负责守卫长城的军事组织,其成员主要由自愿者或被迫加入的罪犯构成,面临人手不足和士气低落的问题。", "守夜人是一个以保护王国北方边界为职责的军事组织,成员不娶妻生子,以避免情感纠葛影响职责。"], "source": ["18_第二十一章 提利昂", "47_琼恩"]} +{"term": "守夜人军团", "nature": ["组织"], "detail": ["守夜人军团是一种特殊的军事组织,负责守护边境和维护治安,反映出对保护和忠诚的文化价值观。"], "source": ["9_布兰"]} +{"term": "宗教信仰", "nature": ["文化"], "detail": ["宗教信仰在社会中占据重要位置,民众对神明的信仰影响着人们的行为和决策。"], "source": ["39_珊莎"]} +{"term": "宠物的象征意义", "nature": ["文化符号"], "detail": ["宠物在社会中不仅是伴侣,也常常被赋予象征意义,反映出主人性格和地位。"], "source": ["8_艾莉亚"]} +{"term": "审判", "nature": ["法律制度"], "detail": ["通过公开审判来确定有罪与否的制度,强调法律程序的重要性和对正义的追求。"], "source": ["29_凯特琳"]} +{"term": "家庭与归属感", "nature": ["社会情感"], "detail": ["对家庭的思念和渴望是角色内心的主要情感,体现了对安全感和归属感的追求。"], "source": ["51_艾莉亚"]} +{"term": "家族传承", "nature": ["文化传统"], "detail": ["家族传承在社会中占据重要地位,武器和其他财产常代代相传,象征着家族的荣誉和责任。"], "source": ["47_琼恩"]} +{"term": "家族地位", "nature": ["社会结构"], "detail": ["家族的地位和声望在社交场合中起着关键作用,高贵的血统和良好的教养被广泛认可和尊重。"], "source": ["8_艾莉亚"]} +{"term": "家族忠诚", "nature": ["文化价值", "文化", "社会规范"], "detail": ["家族的忠诚在社会中被高度重视,个人的行为往往受到家族荣誉和利益的影响。", "在这个社会中,家族之间的忠诚和责任感被高度重视,个人的行为往往受到家族声誉的影响。", "家族成员之间的忠诚和互助是社会的重要价值观,尤其在动荡和危机时期。"], "source": ["29_凯特琳", "41_凯特琳", "53_布兰"]} +{"term": "家族继承", "nature": ["社会习俗"], "detail": ["家族继承是社会中普遍遵循的原则,涉及长辈对后代的传承和权力的分配。"], "source": ["45_凯特琳"]} +{"term": "家族联姻", "nature": ["社会结构"], "detail": ["家族联姻被视为提升家族地位和权力的重要手段,常通过政治联姻来实现利益的交换。"], "source": ["45_凯特琳"]} +{"term": "家族荣誉", "nature": ["cultural value", "社会规范", "cultural consensus", "价值观"], "detail": ["家族荣誉是社会中重要的文化价值,个人的行为和选择常常受到家族声誉的影响。", "家族的荣誉被视为至高无上的价值,任何危害家族名声的行为都将受到严厉惩罚。", "家族的荣誉和地位在战争中受到极大的关注,战斗的结果直接影响家族的声誉。", "家族荣誉在社会中占据重要地位,保护家族成员的安全被视为最高责任。"], "source": ["16_艾德", "43_提利昂", "49_提利昂", "50_凯特琳"]} +{"term": "家族血统", "nature": ["文化", "文化观念"], "detail": ["家族血统在社会中被视为重要,影响个人的身份和地位,家族成员之间的亲密关系被强调,尤其在危机时刻。", "家族血统被视为权力和地位的来源,家族的名声、历史和血缘关系对个人的社会地位有着深远影响。"], "source": ["19_艾莉亚", "36_艾德"]} +{"term": "家族责任", "nature": ["社会规范"], "detail": ["家族中的男性被期望承担起对家族和家族事务的管理责任,包括在外部环境变化时的决策和行动。"], "source": ["7_凯特琳"]} +{"term": "家族间的竞争", "nature": ["社会现象"], "detail": ["家族间的竞争是一种常见的社会现象,不同家族之间为了资源和地位而展开的较量。"], "source": ["45_凯特琳"]} +{"term": "寒冬将至", "nature": ["警示语"], "detail": ["“寒冬将至”是一个警示,暗示即将到来的威胁和困难,反映了社会对未来不确定性的恐惧。"], "source": ["47_琼恩"]} +{"term": "封建关系", "nature": ["社会关系"], "detail": ["封臣与领主之间的关系建立在忠诚和利益交换的基础上,常常涉及复杂的政治权谋。 "], "source": ["44_凯特琳"]} +{"term": "封建领主", "nature": ["社会结构"], "detail": ["封建制度下,领主对其领地内的农民和士兵拥有控制权,权力的分配通常与家族血统和军事能力相关。"], "source": ["36_艾德"]} +{"term": "封臣制度", "nature": ["社会结构"], "detail": ["该世界中存在封臣制度,领主依赖于封臣的支持和军队,而封臣则期望从领主那里获得保护和土地。"], "source": ["41_凯特琳"]} +{"term": "尊重与恐惧", "nature": ["社会心理"], "detail": ["领主需通过赢得尊重和恐惧来维护自己的权威,嘲笑和轻视被视为致命的威胁。"], "source": ["41_凯特琳"]} +{"term": "屠杀与洗劫", "nature": ["社会"], "detail": ["战争后,战士们会进行屠杀和洗劫,将敌人和无辜者的生命当作战争的附带损失,显示出战争的残酷和非人道。"], "source": ["48_丹妮莉丝"]} +{"term": "山路", "nature": ["地形"], "detail": ["山路通常是人类活动和旅行的重要通道,具有挑战性和隐秘性,使得旅者在行进时需要谨慎行事。"], "source": ["30_提利昂"]} +{"term": "市集", "nature": ["经济"], "detail": ["市集是社区经济活动的中心,通常聚集了交易、社交和文化交流的功能。"], "source": ["27_布兰"]} +{"term": "布拉佛斯", "nature": ["城市"], "detail": ["布拉佛斯是一个以海洋为基础的城市,以其丰富的海洋生物和独特的动物收藏而闻名,传承着海王的传统。"], "source": ["38_艾莉亚"]} +{"term": "干枝", "nature": ["资源"], "detail": ["在生存环境中,干枝被视为重要的生火材料,但其使用需谨慎考虑周围的风险。"], "source": ["30_提利昂"]} +{"term": "幽灵传说", "nature": ["民间传说"], "detail": ["关于北方幽灵的故事,反映了当地文化中对死者与复仇的重视。"], "source": ["40_凯特琳"]} +{"term": "幽默感", "nature": ["社会规范"], "detail": ["在严肃的环境中,幽默被视为一种缓解压力的方式,有助于增强团队的凝聚力。"], "source": ["18_第二十一章 提利昂"]} +{"term": "御前会议", "nature": ["political practice"], "detail": ["御前会议是政府高层讨论国家事务的正式场合,通常由首相召集。"], "source": ["17_艾德"]} +{"term": "忠诚", "nature": ["社会价值", "social norm", "德行", "道德", "社会规范"], "detail": ["忠诚被视为家族和国家关系中的核心价值,影响个人在决策和行动中的选择。 ", "忠诚被视为至关重要的社会价值,个人对家族和权力中心的忠诚直接影响其在社会中的地位和安全。", "忠诚被视为重要的美德,尤其是在对君主和家族的忠诚上,影响着人际关系和政治稳定。", "忠诚被视为一种美德,个人与权力中心之间的忠诚关系在权力斗争中至关重要。", "忠诚被视为一项基本美德,士兵和随从对领导者和家族的忠诚是社会结构的重要支柱。"], "source": ["7_凯特琳", "16_艾德", "35_艾德", "39_珊莎", "50_凯特琳"]} +{"term": "忠诚与背叛", "nature": ["道德观念"], "detail": ["忠诚被视为一种美德,而背叛则被视为不可饶恕的罪行,个人的选择往往影响到更大范围内的权力斗争。"], "source": ["36_艾德"]} +{"term": "忠诚誓言", "nature": ["社会规范"], "detail": ["忠诚誓言在社会中被视为一种重要的责任,涉及个人对家庭、王室和国家的承诺。", "忠诚誓言在多斯拉克和其他文化中被视为至关重要的承诺,通常在战斗和领导关系中起到关键作用。"], "source": ["45_凯特琳", "56_丹妮莉丝"]} +{"term": "性别角色", "nature": ["社会规范"], "detail": ["社会普遍存在性别角色的期待,女性被鼓励从事家庭和手工艺活动,而男性则被赋予更具冒险和战斗性质的角色。"], "source": ["8_艾莉亚"]} +{"term": "恐惧与暴力", "nature": ["社会现象"], "detail": ["在权力争斗中,暴力与恐惧成为常态,受害者的故事反映了社会对暴行的无力和对正义的渴望。"], "source": ["31_艾德"]} +{"term": "恐惧的力量", "nature": ["心理"], "detail": ["恐惧被视为一种强大的情感,能够影响决策与行动,反映了人类对自身脆弱的深刻理解。"], "source": ["38_艾莉亚"]} +{"term": "战争", "nature": ["历史事件", "事件", "社会现象"], "detail": ["战争是社会中常见的现象,反映了权力斗争和血缘关系的重要性,驱动着政治和社会变革。", "战争带来的恐惧和混乱影响了民众的生活,屠杀和暴力事件在社会上留下了深刻的心理创伤。", "战争被视为解决冲突和争夺权力的主要方式,战斗被认为是实现个人和家族荣耀的途径。"], "source": ["13_艾德", "39_珊莎", "43_提利昂"]} +{"term": "战争与冲突", "nature": ["历史事件"], "detail": ["因权力斗争与资源争夺,地方间的战争与冲突时有发生,导致平民遭受严重的苦难与损失。"], "source": ["31_艾德"]} +{"term": "战争与和平的平衡", "nature": ["历史观念"], "detail": ["历史上,战争与和平的交替影响着国家与家族的命运,和平时期的脆弱性常常成为冲突的前奏。"], "source": ["36_艾德"]} +{"term": "战争威胁", "nature": ["社会环境"], "detail": ["战争威胁是影响个人和家族决策的重要因素,常用于施压和获取支持。"], "source": ["45_凯特琳"]} +{"term": "战争的代价", "nature": ["哲学"], "detail": ["战争被视为争夺权力和资源的必要手段,参与者必须接受战争所带来的痛苦与牺牲,体现出对战争本质的无奈与接受。"], "source": ["48_丹妮莉丝"]} +{"term": "战争策略", "nature": ["军事战术", "军事"], "detail": ["在战略讨论中,强调对地形的利用和敌人的行动预判,以确保战斗的胜利。", "军事策略在战争中至关重要,指挥者需考虑兵力配置、地形及敌军动向,以制定有效的攻击计划。"], "source": ["40_凯特琳", "41_凯特琳"]} +{"term": "战场", "nature": ["环境"], "detail": ["战场上,战争的紧张气氛和不确定性使得人们面临生死考验,任何人的生命都处于危险之中。"], "source": ["50_凯特琳"]} +{"term": "战士文化", "nature": ["社会习俗"], "detail": ["多斯拉克人重视勇敢和战斗技能,婚礼上通常需要发生人命,以显示婚礼的隆重和成功。"], "source": ["12_丹妮莉丝"]} +{"term": "战斗", "nature": ["conflict", "social norm"], "detail": ["战斗在社会中不仅是物理冲突的表现,也是家族间竞争和个人荣誉的重要体现。", "战斗中勇气与技巧被高度重视,胜利往往被视为个人和集体的荣耀。"], "source": ["16_艾德", "49_提利昂"]} +{"term": "战斗策略", "nature": ["军事"], "detail": ["战斗策略强调智谋与耐心,战斗中的成功往往依赖于对敌方情况的掌握和对自身力量的合理运用。"], "source": ["50_凯特琳"]} +{"term": "手工艺", "nature": ["技能"], "detail": ["手工艺在社会中被视为重要的技能,尤其在女性中,掌握缝纫和刺绣被认为是优雅和美德的象征。"], "source": ["8_艾莉亚"]} +{"term": "技术水平", "nature": ["科技"], "detail": ["在这个世界中,技术水平较低,主要依赖于手工制作和传统工艺,缺乏工业化的痕迹。"], "source": ["29_凯特琳"]} +{"term": "政治忠诚", "nature": ["社会责任"], "detail": ["政治忠诚被视为个人在复杂权力关系中的道德责任,影响个人的决策和行为。"], "source": ["45_凯特琳"]} +{"term": "政治阴谋", "nature": ["现象"], "detail": ["政治阴谋在权力中心频繁出现,反映出权力斗争的复杂性和险恶。"], "source": ["39_珊莎"]} +{"term": "教育与教养", "nature": ["文化价值"], "detail": ["教育和教养被视为重要的社会价值,尤其在女性中,良好的教养常常与社会接受度和婚姻前景相关。"], "source": ["8_艾莉亚"]} +{"term": "教育体系", "nature": ["social structure"], "detail": ["大学士的存在表明一个以知识和教育为基础的官僚体系,强调学识和经验在治理中的重要性。 "], "source": ["17_艾德"]} +{"term": "教育期望", "nature": ["社会规范"], "detail": ["社会对女性的教育期望常集中于培养淑女的品德和技能,反映了性别角色及其在文化中的定位。"], "source": ["19_艾莉亚"]} +{"term": "教育责任", "nature": ["社会期待"], "detail": ["家长被期望在家庭中承担教育和指导子女的责任,以确保后代能够继承和维护家族的地位和价值观。"], "source": ["7_凯特琳"]} +{"term": "文化信仰", "nature": ["信仰体系"], "detail": ["不同家族与地区信仰各异,常常与历史传说及神秘力量相关联。"], "source": ["40_凯特琳"]} +{"term": "文化偏见", "nature": ["社会观念"], "detail": ["对特定部落的恐惧和刻板印象影响着部落之间的关系,反映出文化之间的敌意和误解。"], "source": ["42_提利昂"]} +{"term": "文化共识", "nature": ["共识"], "detail": ["忠诚和誓言在这个社会中被高度重视,个人的荣誉与家庭的声望紧密相关。"], "source": ["44_凯特琳"]} +{"term": "文化命名", "nature": ["文化"], "detail": ["不同文化和民族对他者的命名反映了身份和地位的差异,拉札林人自称为“羊人”体现了多斯拉克人对他们的贬义看法。"], "source": ["48_丹妮莉丝"]} +{"term": "旅店", "nature": ["设施"], "detail": ["在旅行中,旅店作为重要的休息场所,提供住宿与庇护,反映了人们对安全与舒适的需求。"], "source": ["14_提利昂"]} +{"term": "族群关系", "nature": ["文化"], "detail": ["不同部落之间存在复杂的关系和历史,影响着它们的联盟和敌对状态。"], "source": ["42_提利昂"]} +{"term": "无名古神", "nature": ["信仰"], "detail": ["无名古神是该文化中的信仰体系,信徒与神明之间缺乏直接的沟通,强调个人道德和选择的重要性。"], "source": ["55_琼恩"]} +{"term": "暴力", "nature": ["解决冲突方式", "社会现象"], "detail": ["暴力被视为解决纷争和维护权力的一种常见手段,体现了权力斗争的残酷性。", "暴力成为解决冲突的一种方式,其普遍存在反映了社会的动荡与不安。 "], "source": ["35_艾德", "39_珊莎"]} +{"term": "服饰", "nature": ["文化"], "detail": ["服饰的颜色和样式反映了身分与地位,黑色丧服在特定场合中是表达哀悼的规范。"], "source": ["39_珊莎"]} +{"term": "权力与婚姻", "nature": ["社会制度"], "detail": ["婚姻被视为提升家族地位的重要手段,政治联姻常常被用来增强家族间的权力和影响力。"], "source": ["8_艾莉亚"]} +{"term": "权力斗争", "nature": ["political dynamics", "政治", "政治现象"], "detail": ["权力斗争是社会中普遍存在的现象,各方势力通过策略和联盟寻求增强自身地位。", "部落之间的首领地位不定,可能因个人能力或外部压力而变化,反映出权力的流动性。", "权力的获得和维持往往伴随着阴谋和斗争,家族之间的竞争是社会结构的重要组成部分。", "权力斗争是社会中普遍存在的现象,个人或家族为了争夺权力和地位而进行的冲突。"], "source": ["16_艾德", "42_提利昂", "43_提利昂", "45_凯特琳"]} +{"term": "权力游戏", "nature": ["社会政治", "权力"], "detail": ["权力和地位的争夺在社会结构中占据重要位置,个人的决策常常受到权力关系的影响。", "权力的争夺常导致背叛和牺牲,反映了权力斗争的残酷和不确定性。"], "source": ["7_凯特琳", "19_艾莉亚"]} +{"term": "权力的游戏", "nature": ["社会现象", "作品"], "detail": ["权力的游戏是一个复杂的社会现象,涉及阴谋、策略和人性的考验,反映了权力的流动性和不确定性。", "这是一部复杂的史诗奇幻小说,描绘了权力斗争、家族纷争和政治阴谋的世界。"], "source": ["36_艾德", "41_凯特琳"]} +{"term": "权力的集中", "nature": ["政治体制"], "detail": ["政治权力高度集中于少数贵族和王室成员手中,使得国家治理与人民福祉之间的脱节加剧。"], "source": ["31_艾德"]} +{"term": "权力象征", "nature": ["社会习俗"], "detail": ["在多斯拉克文化中,权力和地位常通过赠送武器和奢华礼物来体现,反映了社会等级与个人尊严。"], "source": ["12_丹妮莉丝"]} +{"term": "梦境", "nature": ["心理"], "detail": ["梦境的存在揭示了内心的恐惧和期望,反映了人类对未知的探索欲望。"], "source": ["46_琼恩"]} +{"term": "梦境预兆", "nature": ["文化信仰"], "detail": ["梦境被视为预兆和指引,个体在梦中与已故亲人沟通的经历被认为具有重要意义。"], "source": ["53_布兰"]} +{"term": "武器", "nature": ["工具", "technology"], "detail": ["武器的制造与维护显示了技术进步与战争文化的关系,反映了生存竞争的残酷。", "斧头、剑、流星锤等冷兵器是主要的战斗工具,显示出这个世界的技术水平集中在中世纪战争装备上。"], "source": ["46_琼恩", "49_提利昂"]} +{"term": "武器与盔甲", "nature": ["技术水平"], "detail": ["武器和盔甲的制作和使用反映了当时的技术水平,特别是在军事活动中的重要性,良好的装备被视为战争胜利的关键。"], "source": ["22_艾德"]} +{"term": "武器与防御", "nature": ["技术"], "detail": ["使用十字弓等武器说明了该社会的技术水平,防御措施也显示出对军事力量的重视。"], "source": ["42_提利昂"]} +{"term": "武器使用", "nature": ["传统", "社会规范"], "detail": ["武器在男性和女性之间的使用存在明显差异,女性被期望避免接触武器,反映了性别规范。", "武器的携带和使用在社会中被视为一种个人安全和自卫的方式,尤其是在动荡时期。", "对武器的熟练使用被视为尊严和身份的象征,训练年轻人掌握武器是社会期望的一部分。 "], "source": ["19_艾莉亚", "52_艾莉亚", "53_布兰"]} +{"term": "武器装备", "nature": ["科技"], "detail": ["武器装备的多样性和技术水平反映了文明的军事进程,骑士和士兵的盔甲与武器是战斗的重要组成部分。"], "source": ["50_凯特琳"]} +{"term": "死亡仪式", "nature": ["文化习俗"], "detail": ["死者的处理遵循特定的仪式,静默姐妹负责处理死者的后事,体现了对死亡的尊重和对逝者的纪念。"], "source": ["22_艾德"]} +{"term": "毒药", "nature": ["谋杀手段"], "detail": ["毒药被视为隐秘和阴险的谋杀手段,常与女性相关的刻板印象相结合。"], "source": ["29_凯特琳"]} +{"term": "比武竞技", "nature": ["cultural event"], "detail": ["比武竞技被视为庆祝和展示骑士精神的盛大活动,通常会伴随丰盛的宴会和众多参与者。"], "source": ["17_艾德"]} +{"term": "水舞者", "nature": ["职业"], "detail": ["水舞者是以优雅的舞蹈和武术闻名的战士,强调灵活性和技巧而非单纯的力量,体现了一种特殊的战斗艺术。"], "source": ["38_艾莉亚"]} +{"term": "河流控制", "nature": ["资源"], "detail": ["河流是重要的通道,控制河流的领主能够对过往者收取费用,从而获得经济利益。 "], "source": ["44_凯特琳"]} +{"term": "法力", "nature": ["magical system"], "detail": ["存在法力的个体可以治愈伤口和施展各种魔法,但其力量并非无限。"], "source": ["1_赖伦铎尔哀歌"]} +{"term": "法庭审判", "nature": ["judicial system"], "detail": ["法庭审判的行为反映了权力中心的法律程序,个体在法庭上的陈述和证据被视为决定命运的重要因素。"], "source": ["16_艾德"]} +{"term": "法律与正义", "nature": ["社会价值观"], "detail": ["法律被视为维持社会公正的重要工具,然而在权力游戏中,正义的执行往往受到特权与暴力的干扰。"], "source": ["31_艾德"]} +{"term": "流浪与逃避", "nature": ["社会现象"], "detail": ["城市中流浪者的存在及角色的逃避行为反映了社会的不公和个人的无助。"], "source": ["51_艾莉亚"]} +{"term": "海王的百兽园", "nature": ["制度"], "detail": ["海王的百兽园是一个展示来自各地珍稀动物的地方,反映了对异域生物的追求与珍视。"], "source": ["38_艾莉亚"]} +{"term": "温泉", "nature": ["自然资源"], "detail": ["温泉为城堡提供了持续的热源,改变了居住环境的温度,尤其在寒冷季节中起到关键作用。"], "source": ["7_凯特琳"]} +{"term": "火", "nature": ["元素"], "detail": ["火的使用和控制是生存和战斗的关键,显示了技术与魔法之间的界限。"], "source": ["46_琼恩"]} +{"term": "火葬仪式", "nature": ["习俗"], "detail": ["火葬是多斯拉克文化中的重要仪式,通常在战士去世后进行,以确保他们在来世能够骑乘骏马进入夜晚的国度。"], "source": ["56_丹妮莉丝"]} +{"term": "爱", "nature": ["universal theme"], "detail": ["爱被视为一种强烈的情感,能够激励个体追寻幸福和连接。"], "source": ["1_赖伦铎尔哀歌"]} +{"term": "狩猎", "nature": ["活动"], "detail": ["狩猎被视为一种贵族活动,通常与社会地位和权力的象征相关,参与者通过狩猎展示勇气和技能。"], "source": ["9_布兰"]} +{"term": "狼林", "nature": ["森林"], "detail": ["狼林是一片古老而神秘的森林,生长着橡树、常青树和黑荆棘,夜晚常有狼群的嚎叫,营造出一种阴暗和不安的氛围。"], "source": ["14_提利昂"]} +{"term": "狼的象征", "nature": ["文化"], "detail": ["狼作为家族的象征,代表团结和保护,强调在艰难时期家族成员之间的相互支持。"], "source": ["19_艾莉亚"]} +{"term": "王位", "nature": ["权力象征"], "detail": ["王位不仅是统治的象征,也是权力斗争和政治阴谋的焦点。"], "source": ["46_琼恩"]} +{"term": "王位继承权", "nature": ["制度"], "detail": ["王位继承权的合法性和争夺是统治权力的核心问题,不同家族之间的争斗常常导致政治动荡和冲突。"], "source": ["36_艾德"]} +{"term": "王室墓窖", "nature": ["历史"], "detail": ["王室墓窖是历史长河中的重要场所,历代统治者的安息之地,承载着家族的荣耀与悲剧。"], "source": ["53_布兰"]} +{"term": "王室晚宴", "nature": ["传统"], "detail": ["王室晚宴是展示权力和社会地位的重要场合,通常伴随着丰盛的菜肴,强调王权的富裕和奢华。"], "source": ["9_布兰"]} +{"term": "王室财政", "nature": ["economic"], "detail": ["王室负债总额超过六百万金币,主要债主为兰尼斯特家,且向多方借款以应对财政危机。"], "source": ["17_艾德"]} +{"term": "王权", "nature": ["制度", "政治", "political structure"], "detail": ["王权制度在这个社会中占据核心地位,国家的治理和权力的运作依赖于王室及其亲信的统治。", "王权制度在这个世界中占据核心地位,君主拥有至高无上的权力,国家事务由国王直接管理。", "王权在社会中通过血统和家族关系继承,权力的运作与家族间的忠诚和敌意密切相关。", "王权在这个社会中被视为至高无上的权力,国王的决策和行为直接影响国家的命运。", "王权是一个国家治理的核心,王位继承和权力斗争在社会中引发了严重的冲突和混乱。"], "source": ["9_布兰", "13_艾德", "16_艾德", "35_艾德", "39_珊莎"]} +{"term": "王权与封建制度", "nature": ["政治制度"], "detail": ["王权体现在家族与领主之间的关系,封君对家臣有责任与义务,家臣则对封君忠诚。"], "source": ["40_凯特琳"]} +{"term": "王权制度", "nature": ["政治结构"], "detail": ["王权制度强调国王的权威,国王的行为和决定对整个王国的生死存亡有直接影响。"], "source": ["22_艾德"]} +{"term": "王权斗争", "nature": ["政治现象"], "detail": ["王权之间的斗争常常伴随着阴谋和暴力,反映了权力游戏中的危险与不确定性。"], "source": ["38_艾莉亚"]} +{"term": "珍禽异兽", "nature": ["生物"], "detail": ["珍禽异兽展现了丰富的想象力和多样性的生物,反映了人们对未知生物的好奇与渴望。"], "source": ["38_艾莉亚"]} +{"term": "瓦雷利亚钢", "nature": ["材料"], "detail": ["瓦雷利亚钢是一种极为稀有且强韧的金属,具有超凡的锋利度和耐用性,常用于制作贵重的武器。"], "source": ["47_琼恩"]} +{"term": "生火", "nature": ["技能"], "detail": ["生火在某些环境中被视为危险,因为火焰会吸引周围生物的注意,可能导致潜在的威胁。"], "source": ["30_提利昂"]} +{"term": "生育观念", "nature": ["文化信仰"], "detail": ["生育被视为家族延续和繁衍后代的关键,社会普遍重视后代的数量和性别。"], "source": ["45_凯特琳"]} +{"term": "白鬼", "nature": ["生物"], "detail": ["白鬼是北方的超自然生物,它们的存在被认为是一个重大的安全隐患,令守夜人倍感压力。"], "source": ["18_第二十一章 提利昂"]} +{"term": "监禁", "nature": ["制度", "法律制度"], "detail": ["监禁作为一种控制手段,用于限制个人自由,反映了权力对个体的压制。 ", "监禁被用作惩罚和控制的手段,特定个体因威胁社会秩序而遭到囚禁。"], "source": ["39_珊莎", "43_提利昂"]} +{"term": "真相的洞察", "nature": ["哲学"], "detail": ["通过观察感知真相,强调理性思考的重要性,反映了一种对智慧与理解的追求。"], "source": ["38_艾莉亚"]} +{"term": "神权与世俗权力", "nature": ["政治体系"], "detail": ["在权力的游戏中,宗教与政治相互交织,神权的影响力对统治者的决策和社会秩序具有重要作用。"], "source": ["36_艾德"]} +{"term": "神灵", "nature": ["信仰"], "detail": ["信仰中存在诸神的观念,信徒相信神灵能够影响人类的命运和事务,特别是在生死和审判方面。"], "source": ["29_凯特琳"]} +{"term": "神秘生物", "nature": ["生物"], "detail": ["传说中的神秘生物与森林之子相关,暗示着自然与超自然力量的关联。"], "source": ["40_凯特琳"]} +{"term": "神秘符号", "nature": ["文化信仰"], "detail": ["特定的神秘符号和传说,如三眼乌鸦,反映了人们对超自然力量的信仰与渴望。"], "source": ["53_布兰"]} +{"term": "祭祀仪式", "nature": ["文化传统", "宗教信仰"], "detail": ["祭祀活动是与神灵沟通和寻求庇护的重要方式,通常在特别的宗教场所进行,强调信徒对神明的尊敬。", "祭祀仪式在多斯拉克文化中具有重要意义,通常与逝者的灵魂和来世的信念有关,展现出对死亡的尊重和信仰。"], "source": ["52_艾莉亚", "56_丹妮莉丝"]} +{"term": "私生子", "nature": ["社会规范"], "detail": ["在某些文化背景下,私生子被接受并可以被纳入家族中,体现出对父亲责任的不同理解和接受程度。"], "source": ["7_凯特琳"]} +{"term": "科技水平", "nature": ["科技", "技术"], "detail": ["社会科技水平相对中世纪,主要依赖于农业和骑士制度,使用冷兵器和简单的攻城器械。", "该世界的科技水平以中世纪为主,主要依赖于手工业和农业,缺乏现代化的机械和电力。"], "source": ["44_凯特琳", "52_艾莉亚"]} +{"term": "等待与期盼", "nature": ["情感"], "detail": ["等待与期盼成为重要的情感主题,反映出对生存和未来的渴望。"], "source": ["50_凯特琳"]} +{"term": "红堡", "nature": ["建筑"], "detail": ["红堡是王室的象征,不仅代表权力的中心,还体现了建筑艺术和历史的积淀,成为社会地位的象征。"], "source": ["9_布兰"]} +{"term": "经济交换", "nature": ["社会规范"], "detail": ["在缺乏现金的情况下,可以用捕获的动物进行物物交换,体现了一种基于需求的经济活动。"], "source": ["51_艾莉亚"]} +{"term": "经验与年轻", "nature": ["社会观念"], "detail": ["年轻领主在面对战争时往往缺乏经验,这使得他们在决策中面临重大压力和不安。"], "source": ["41_凯特琳"]} +{"term": "荣誉与羞耻", "nature": ["社会规范"], "detail": ["在社交场合中,荣誉和羞耻感在行为和交流中起着重要作用,个人的行为会影响家族的声誉。"], "source": ["8_艾莉亚"]} +{"term": "荣誉与背叛", "nature": ["theme"], "detail": ["社会中对荣誉与背叛的看法相互交织,个人行为常常受到道德抉择和社会期待的影响。"], "source": ["55_琼恩"]} +{"term": "荣誉观念", "nature": ["文化共识"], "detail": ["荣誉被视为个人和家族地位的重要体现,拒绝荣誉可能被解读为对权力和关系的威胁。"], "source": ["7_凯特琳"]} +{"term": "血统继承制", "nature": ["政治体系"], "detail": ["王位的合法性通常基于血统,只有被认为是合法继承者的人才能获得统治权。"], "source": ["52_艾莉亚"]} +{"term": "血缘关系", "nature": ["社会结构"], "detail": ["血缘关系在社会中扮演重要角色,影响着个人的身份、归属感和社会责任。"], "source": ["18_第二十一章 提利昂"]} +{"term": "血腥冲突", "nature": ["historical event"], "detail": ["战争常常造成大量伤亡和血腥场面,导致社会的混乱与悲剧。"], "source": ["49_提利昂"]} +{"term": "血魔法", "nature": ["魔法系统"], "detail": ["血魔法在多斯拉克文化中被视为强大的力量,涉及对生命和死亡的操控,认为只有通过特定的咒语和智慧才能成功施展。"], "source": ["56_丹妮莉丝"]} +{"term": "誓言", "nature": ["社会契约"], "detail": ["誓言在社会互动中起着重要作用,承诺与信任的建立是维持关系和权力的关键。"], "source": ["29_凯特琳"]} +{"term": "训练系统", "nature": ["教育"], "detail": ["对马匹的特别训练显示了人们在驯养动物方面的知识和技术,这在军事和农业中具有重要意义。"], "source": ["27_布兰"]} +{"term": "议会制度", "nature": ["政治形式"], "detail": ["议会作为国王顾问的集体,尽管权力有限,但在重要决策中仍扮演着关键角色,反映了权力的分享与制衡。"], "source": ["31_艾德"]} +{"term": "记忆", "nature": ["psychological aspect"], "detail": ["记忆可以模糊,个体可能难以区分真实经历与幻想之间的界限。 "], "source": ["1_赖伦铎尔哀歌"]} +{"term": "证人出庭", "nature": ["judicial process"], "detail": ["证人出庭作为法律程序的一部分,显示了在审判中证据的重要性和社会对真相的追求。"], "source": ["16_艾德"]} +{"term": "语言障碍", "nature": ["社会现象"], "detail": ["由于不同文化之间的语言差异,沟通常常受到限制,导致社会互动中的隔阂和孤独感。 "], "source": ["12_丹妮莉丝"]} +{"term": "诸神信仰", "nature": ["宗教"], "detail": ["社会普遍信仰多神教,认为诸神在日常生活中扮演重要角色,影响人们的行为和决策。"], "source": ["13_艾德"]} +{"term": "谎言与荣誉", "nature": ["伦理观"], "detail": ["在特定情况下,谎言被视为可接受的行为,反映了在复杂的道德环境中生存的智慧。"], "source": ["19_艾莉亚"]} +{"term": "贫困与生存", "nature": ["社会问题"], "detail": ["角色在城市中经历贫困,依赖于街头食物和简陋的交易,展示了社会底层的生存状态。"], "source": ["51_艾莉亚"]} +{"term": "贵族", "nature": ["社会结构", "社会阶层"], "detail": ["社会由贵族阶层主导,他们通过血统、地位和土地的拥有来维持权力和影响力。", "贵族在社会中拥有特权和权力,其家族血统和历史背景被视为重要的社会地位象征。"], "source": ["29_凯特琳", "35_艾德"]} +{"term": "贵族与平民", "nature": ["社会阶层"], "detail": ["在王座厅中,贵族与平民的地位显著不同,贵族可以在王座前请愿,而平民则需跪地请求公正,反映出社会等级制度的严苛。"], "source": ["31_艾德"]} +{"term": "贵族与骑士", "nature": ["社会结构"], "detail": ["社会中存在明显的阶级分化,贵族和骑士在社会地位和权力上占据重要位置,通常负责维护国家和地方的秩序。"], "source": ["52_艾莉亚"]} +{"term": "贵族家族", "nature": ["social structure"], "detail": ["贵族家族通过华丽的装饰和服装来展示其富裕和权力。"], "source": ["17_艾德"]} +{"term": "贵族家族徽章", "nature": ["文化标识"], "detail": ["贵族家族徽章在战斗和社交场合中具有重要意义,反映出家族的荣耀和身份。"], "source": ["22_艾德"]} +{"term": "贵族政治", "nature": ["制度"], "detail": ["贵族在政治中扮演重要角色,权力的游戏中,贵族之间的联盟和背叛影响着国家的稳定。"], "source": ["39_珊莎"]} +{"term": "贵族礼仪", "nature": ["社会规范"], "detail": ["贵族在公共场合表现出的礼仪,如相互致意,体现了社会等级和尊重的文化。"], "source": ["27_布兰"]} +{"term": "贵族责任", "nature": ["社会规范"], "detail": ["贵族在社会中承担重要责任,既要维护家庭荣誉,也要对国家利益负责。"], "source": ["13_艾德"]} +{"term": "遗嘱", "nature": ["法律文书"], "detail": ["遗嘱在死亡时被用来分配财产和权力,体现了对家族和继承问题的重视。"], "source": ["35_艾德"]} +{"term": "部族", "nature": ["民族"], "detail": ["部族文化强调武勇与荣誉,部族成员往往以战斗能力和勇气为荣,参与战争是他们的责任和义务。"], "source": ["43_提利昂"]} +{"term": "部队编制", "nature": ["military structure"], "detail": ["军队通常由不同类型的士兵组成,包括步兵和骑士,形成较为复杂的军事组织。"], "source": ["49_提利昂"]} +{"term": "野兽象征", "nature": ["symbolism"], "detail": ["野兽,特别是狼,作为力量和野性的象征,常常与家族的身份和特征相联系。"], "source": ["16_艾德"]} +{"term": "金袍卫士", "nature": ["组织"], "detail": ["金袍卫士是城市中的执法力量,身着特定的制服,负责维护治安和控制犯罪。"], "source": ["51_艾莉亚"]} +{"term": "钟声", "nature": ["文化习俗"], "detail": ["钟声在城市中具有重要的象征意义,用于宣布重要事件或哀悼,只有国王去世时,所有钟声才会同时响起。"], "source": ["51_艾莉亚"]} +{"term": "铁冠", "nature": ["artifact"], "detail": ["铁冠给予佩戴者一定的保护,防止被特定的力量伤害。"], "source": ["1_赖伦铎尔哀歌"]} +{"term": "铁卫", "nature": ["军事组织"], "detail": ["铁卫是专门负责保护王室和贵族的武装力量,体现了对安全和忠诚的高度重视。"], "source": ["38_艾莉亚"]} +{"term": "铁王座", "nature": ["artifact"], "detail": ["铁王座由一千把剑铸成,象征着权力与统治,其锋利的边缘和倒钩设计使其成为一把可以致命的座椅,代表了统治者的苦难与牺牲。"], "source": ["31_艾德"]} +{"term": "锁子甲", "nature": ["装备"], "detail": ["锁子甲是中世纪战士的常见防护装备,显示了当时技术水平和军事文化的特征。"], "source": ["27_布兰"]} +{"term": "长城", "nature": ["建筑", "结构", "structure"], "detail": ["长城不仅是防御设施,还象征着人类与未知危险的隔绝与抵抗。", "长城是一道巨大的防御工事,位于极北地区,负责抵御来自北方的威胁,其长度达到三百里,具有重要的军事和战略意义。", "长城作为防御工事,象征着对未知威胁的抵御,代表着人类对安全和生存的渴望。", "长城作为防御工事,象征着对外敌的抵御和保护内部安全的重要性。", "长城是一道防御性结构,旨在抵御外敌入侵,具有重要的战略意义和象征性地位。"], "source": ["14_提利昂", "18_第二十一章 提利昂", "46_琼恩", "47_琼恩", "55_琼恩"]} +{"term": "长夏", "nature": ["气候"], "detail": ["长夏是指一段持续的温暖季节,传说中接下来会出现更漫长的冬季,影响了人们的生活和心理预期。"], "source": ["18_第二十一章 提利昂"]} +{"term": "雕塑艺术", "nature": ["cultural expression"], "detail": ["雕塑在公共场合被用作装饰,常反映出历史和文化的象征意义。"], "source": ["17_艾德"]} +{"term": "面粉街", "nature": ["地点"], "detail": ["面粉街是一个热闹的地方,散发着新鲜面包的香气,吸引路人光顾。"], "source": ["51_艾莉亚"]} +{"term": "音乐", "nature": ["cultural expression"], "detail": ["音乐具有表达情感和讲述故事的能力,能在孤独中提供慰藉和陪伴。 "], "source": ["1_赖伦铎尔哀歌"]} +{"term": "领地与权力", "nature": ["社会结构"], "detail": ["领主制度是主要的社会结构,领主通过土地和封臣管理其势力范围。"], "source": ["44_凯特琳"]} +{"term": "食物", "nature": ["文化"], "detail": ["食物的种类和分配反映了社会的阶层结构,富人和普通人之间的饮食差异显著。"], "source": ["39_珊莎"]} +{"term": "食物与饮品", "nature": ["文化习俗"], "detail": ["酒和食物在社交场合中具有重要意义,饮酒常常伴随着分享和交流,增强人际关系。"], "source": ["43_提利昂"]} +{"term": "食物文化", "nature": ["饮食习惯"], "detail": ["人们的饮食习惯与社会地位密切相关,尤其在战时对食物的选择与分配显得尤为重要。"], "source": ["40_凯特琳"]} +{"term": "食物的稀缺性", "nature": ["经济状况"], "detail": ["食物在城市中非常稀缺,角色为了生存而不得不寻找各种方式来获取食物。"], "source": ["51_艾莉亚"]} +{"term": "食物短缺", "nature": ["生存挑战"], "detail": ["在战争期间,军队的粮食补给成为关键问题,影响到军队的士气和作战能力。"], "source": ["41_凯特琳"]} +{"term": "饮酒文化", "nature": ["社会习俗"], "detail": ["饮酒在社交场合中是常见的行为,国王与随从之间的互动体现了饮酒文化在权力和责任之间的微妙关系。"], "source": ["22_艾德"]} +{"term": "饮食习惯", "nature": ["文化习俗"], "detail": ["多斯拉克人的饮食习惯包括暴饮暴食,肉类食物占主导地位,且饮酒文化盛行。"], "source": ["12_丹妮莉丝"]} +{"term": "首相的权力", "nature": ["political structure"], "detail": ["首相在朝廷中具有重要地位,需协调各大臣以应对国家事务。"], "source": ["17_艾德"]} +{"term": "首相职责", "nature": ["职能"], "detail": ["首相的职责包括管理国家事务,但也需关注家庭内部的动态,以维护家庭和谐和权力的稳定。"], "source": ["19_艾莉亚"]} +{"term": "马匹", "nature": ["交通工具"], "detail": ["马匹在社会中扮演着重要的角色,作为主要的交通工具,它们的健康和状态直接影响到旅行的效率和安全。"], "source": ["30_提利昂"]} +{"term": "马车的使用", "nature": ["transportation"], "detail": ["在城市中,马车被普遍用作交通工具,体现出人们的交通方式和社会习俗。 "], "source": ["17_艾德"]} +{"term": "骑士", "nature": ["社会阶层", "职业"], "detail": ["骑士是被赋予荣誉和责任的战士,通常在战争中表现出勇敢,地位与家族背景密切相关。", "骑士被视为荣耀和勇气的象征,承担着保护领土和人民的责任,通常以武力和骑术著称。", "骑士在社会中扮演着重要的角色,他们通常穿戴铠甲,骑马作战,且拥有家族徽章以显示身份和荣誉。"], "source": ["18_第二十一章 提利昂", "29_凯特琳", "43_提利昂"]} +{"term": "骑士制度", "nature": ["社会制度", "文化", "社会规范"], "detail": ["骑士制度在社会中扮演着重要角色,年轻人渴望成为骑士以获得荣誉和地位,但这也伴随着死亡和牺牲的风险。", "骑士作为贵族武装力量的象征,承担着保护领土和维护秩序的责任,其行为与道德标准被高度重视。", "骑士制度强调忠诚与荣誉,骑士需对其领主效忠,并参与维护领地的安全与秩序。", "骑士作为军队的核心,代表了战士的荣誉与忠诚,通常伴随有侍从和装备精良的战士。"], "source": ["22_艾德", "31_艾德", "36_艾德", "40_凯特琳"]} +{"term": "骑士文化", "nature": ["cultural consensus"], "detail": ["骑士在战斗中代表着勇气和忠诚,通过战斗表现出对主人的效忠。"], "source": ["49_提利昂"]} +{"term": "骑士比武大会", "nature": ["活动"], "detail": ["骑士比武大会是为庆祝特定事件而举办的盛大赛事,各地骑士参与以争夺荣誉,反映了骑士文化中的勇气和荣耀。"], "source": ["19_艾莉亚"]} +{"term": "骑士精神", "nature": ["文化", "价值观", "文化价值"], "detail": ["骑士精神强调忠诚、勇气和对责任的承诺,反映了中世纪社会对荣誉和责任的重视。", "骑士精神在社会中被视为高尚的品质,强调勇气、荣誉与责任。", "骑士精神强调勇气、荣誉和对弱者的保护,是社会中被推崇的道德标准。", "骑士精神强调勇气、荣誉和对家族的忠诚,成为士兵领导者的标准。", "骑士精神强调荣誉、勇气和忠诚,骑士通常被视为社会的保护者,承担着捍卫弱者和维护正义的责任。"], "source": ["13_艾德", "14_提利昂", "27_布兰", "50_凯特琳", "52_艾莉亚"]} +{"term": "骑士训练", "nature": ["社会规范"], "detail": ["骑士的训练强调身体素质和战斗技能,年轻人必须经过严格的训练以保卫城堡和家园。"], "source": ["53_布兰"]} +{"term": "骑马", "nature": ["技能", "交通工具"], "detail": ["骑马被认为是重要的社交和军事技能,尤其在贵族阶层中,骑乘良驹象征着地位和财富。", "骑马是主要的交通方式,反映了社会的技术水平和人们的生活方式。", "骑马是一项重要的技能,反映了一个人在社会中的地位和能力,特别是在贵族和战士阶层中尤为重要。"], "source": ["9_布兰", "13_艾德", "27_布兰"]} +{"term": "魔法", "nature": ["幻想元素"], "detail": ["魔法在这个世界中以隐秘和神秘的存在形式存在,影响着人们对命运和未来的理解。"], "source": ["35_艾德"]} +{"term": "魔法与神秘生物", "nature": ["element"], "detail": ["虽然没有直接的魔法系统,但神秘生物的存在和潜在的超自然力量为世界增添了神秘感。"], "source": ["55_琼恩"]} +{"term": "魔法系统", "nature": ["系统"], "detail": ["魔法在故事中存在,但并非普遍使用,常常随着时间和事件的变化而显现出不同的力量和效果。"], "source": ["44_凯特琳"]} +{"term": "黑衣军", "nature": ["组织"], "detail": ["黑衣军是守夜人的别称,象征着他们的职责和使命,成员身穿黑色制服以便于夜间活动。"], "source": ["18_第二十一章 提利昂"]} +{"term": "黑衣守卫", "nature": ["group"], "detail": ["黑衣守卫是负责保护长城的士兵,遵循严格的誓言和纪律,以守护国家的安全。"], "source": ["55_琼恩"]} +{"term": "龙蛋", "nature": ["artifact", "象征物"], "detail": ["龙蛋被视为珍贵的遗物,象征着力量和权力,具有重要的文化和历史价值。", "龙蛋在多斯拉克文化中象征着重生和力量,通常与死亡和新生的概念相联系。"], "source": ["12_丹妮莉丝", "56_丹妮莉丝"]} +{"term": "龙骨", "nature": ["材料"], "detail": ["龙骨是一种稀有且坚硬的材料,具有轻质与耐火的特性,被视为极为珍贵的资源。"], "source": ["14_提利昂"]} diff --git "a/data/worlds/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/world_details/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.jsonl" "b/data/worlds/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/world_details/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.jsonl" new file mode 100644 index 0000000000000000000000000000000000000000..ca738cf54642fa98bf098cf5b0e2eb1a0e0ff423 --- /dev/null +++ "b/data/worlds/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/world_details/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.jsonl" @@ -0,0 +1,169 @@ +{"term": "", "nature": "", "detail": ["An individual can experience rapid changes in size, creating a sense of discomfort and confusion about identity and belonging, reflecting existential themes in personal growth and self-perception."], "source": ["6_The Rabbit Sends in a Little Bill"]} +{"term": "", "nature": "", "detail": ["Curiosity drives exploration in this world, leading to unexpected and sometimes chaotic consequences, suggesting a cultural value placed on discovery and adventure."], "source": ["6_The Rabbit Sends in a Little Bill"]} +{"term": "", "nature": "", "detail": ["In this world, anthropomorphized animals hold positions of authority and engage in complex social interactions, reflecting a culture where the roles of animals and humans may overlap."], "source": ["6_The Rabbit Sends in a Little Bill"]} +{"term": "", "nature": "", "detail": ["The concept of a whimsical, nonsensical reality is prevalent, where the ordinary rules of logic and physics do not apply, suggesting a cultural acceptance of absurdity and fantasy."], "source": ["6_The Rabbit Sends in a Little Bill"]} +{"term": "", "nature": "", "detail": ["The notion of receiving commands from animals indicates a playful inversion of traditional power dynamics, challenging the norms of authority and control. "], "source": ["6_The Rabbit Sends in a Little Bill"]} +{"term": "", "nature": "", "detail": ["There exists a social hierarchy where individuals are tasked with domestic duties and errands, indicating a division of labor and expectations based on perceived roles."], "source": ["6_The Rabbit Sends in a Little Bill"]} +{"term": "", "nature": "", "detail": ["There is a presence of magical items that can alter physical states, showcasing a fantastical approach to problem-solving and exploration in this universe. "], "source": ["6_The Rabbit Sends in a Little Bill"]} +{"term": "", "nature": "", "detail": ["Discussions around the nature of thought and intellectual engagement are common, with an assertion of the right to think as a fundamental aspect of individuality. "], "source": ["11_The Mock Turtle's Story"]} +{"term": "", "nature": "", "detail": ["The act of giving presents is viewed with skepticism, particularly when the value of the gift is questioned, reflecting societal expectations around gift-giving. "], "source": ["11_The Mock Turtle's Story"]} +{"term": "", "nature": "", "detail": ["The concept of moral lessons is prevalent, with the belief that every situation contains a moral if one is able to discern it. "], "source": ["11_The Mock Turtle's Story"]} +{"term": "", "nature": "", "detail": ["The idea that companionship reflects similarity in nature is expressed, indicating a social norm where like-minded individuals tend to associate with one another. "], "source": ["11_The Mock Turtle's Story"]} +{"term": "", "nature": "", "detail": ["The notion of self-presentation and authenticity is significant, as individuals are encouraged to be true to themselves and appear as they are perceived by others. "], "source": ["11_The Mock Turtle's Story"]} +{"term": "", "nature": "", "detail": ["The understanding of language and communication is highlighted, as clarity in expression is valued, with complex ideas sometimes requiring written form for better comprehension. "], "source": ["11_The Mock Turtle's Story"]} +{"term": "", "nature": "", "detail": ["There is an emphasis on the idea that certain foods can influence temperament, suggesting a connection between diet and emotional states. "], "source": ["11_The Mock Turtle's Story"]} +{"term": "Accusation", "nature": ["legal process"], "detail": ["An official claim made against an individual, highlighting the concept of wrongdoing and the legal repercussions that follow. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Age", "nature": ["social norm"], "detail": ["The significance placed on age as a measure of authority or wisdom within social interactions, despite the ambiguity of actual age."], "source": ["5_A Caucus Race & a Long Tale"]} +{"term": "Allegory", "nature": ["literary device"], "detail": ["The narratives serve as allegories for the process of growing up, illustrating the complex relationship between childhood innocence and adult realities."], "source": ["1_Introduction"]} +{"term": "Anglo-Saxon attitudes", "nature": ["cultural aspect"], "detail": ["Specific gestures and behaviors are associated with Anglo-Saxon culture, indicating a connection between identity and physical expression."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Animal as Game Elements", "nature": ["magical system"], "detail": ["In this world, live animals are utilized as game elements, such as hedgehogs as balls and flamingos as mallets, indicating a blending of the natural and the fantastical."], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Animal hierarchy", "nature": ["social structure"], "detail": ["The presence of a lion and a unicorn fighting for a crown indicates a hierarchy and power struggle among creatures, reminiscent of royal or noble conflicts."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Artistic Interpretation", "nature": ["method"], "detail": ["Adaptations have remained loyal to original illustrations, indicating a cultural consensus on visual representation and artistic fidelity. "], "source": ["22_Film Adaptations"]} +{"term": "Authority Figures", "nature": ["social hierarchy"], "detail": ["Authority figures display arbitrary power and incompetence, emphasizing a societal structure where leadership is often misguided and lacks genuine authority. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Authority's Capriciousness", "nature": ["social norm"], "detail": ["Authority figures display unpredictable and irrational behavior, issuing commands impulsively, which instills a sense of chaos and instability in governance."], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Behavior of Animals", "nature": ["cultural norm"], "detail": ["Animals participating in human-like activities reflects a whimsical view of the natural world, where creatures possess human traits and roles. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Books", "nature": ["artifact"], "detail": ["The reference to a book without pictures or conversations indicates a societal expectation for literature to be engaging and visually stimulating for readers, particularly children."], "source": ["2_Down the Rabbit Hole"]} +{"term": "Caucus Race", "nature": ["event"], "detail": ["An informal and chaotic race with no clear rules or winners, symbolizing the absurdity and lack of structure in certain social gatherings."], "source": ["5_A Caucus Race & a Long Tale"]} +{"term": "Cheering", "nature": ["social behavior"], "detail": ["Expressing approval or dissent during legal proceedings, indicating the involvement and engagement of the community in judicial matters. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Cheshire-Cat", "nature": ["creature"], "detail": ["The Cheshire-Cat is a fictional creature known for its distinctive grin and ability to appear and disappear at will, illustrating the whimsical nature of the setting."], "source": ["8_Pig & Pepper"]} +{"term": "Chess Pieces", "nature": ["artifact"], "detail": ["Chess pieces are animated and capable of movement independent of human control, reflecting a world where inanimate objects can possess life and agency."], "source": ["14_LOOKING-GLASS HOUSE"]} +{"term": "Childhood", "nature": ["cultural concept"], "detail": ["The journey reflects a child's quest for knowledge and understanding, contrasting with adult perceptions of reality and the nostalgia adults feel for their own childhood desires."], "source": ["1_Introduction"]} +{"term": "Collective Decision-Making", "nature": ["social norm"], "detail": ["The jury's role in decision-making is portrayed as chaotic and ineffective, suggesting a critique of collective judgment processes that ignore rationality. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Communication", "nature": ["concept"], "detail": ["Language holds immense value, with a notion that each word is worth a significant amount, emphasizing the importance of communication in this setting."], "source": ["15_LOOKING-GLASS INSECTS"]} +{"term": "Confrontation", "nature": ["social dynamic"], "detail": ["The dynamic of confronting another being over perceived mischief indicates societal norms around accountability and conflict resolution in interpersonal relationships."], "source": ["20_Queen Alice"]} +{"term": "Conventional Children's Stories", "nature": ["cultural norm"], "detail": ["The text critiques traditional children's literature, which often presents moral lessons and treats children as blank slates for adult teachings."], "source": ["1_Introduction"]} +{"term": "Conversation", "nature": ["social interaction"], "detail": ["The dialogue reveals a culture where misunderstanding and absurdity are commonplace, influencing the nature of communication."], "source": ["17_WOOL AND WATER"]} +{"term": "Courtroom Attire", "nature": ["social norm"], "detail": ["The presence of wigs and crowns suggests the importance of formal dress and the symbolism of authority in legal settings. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Croquet", "nature": ["sport"], "detail": ["Croquet is a game played on grass where players use mallets to hit balls through hoops, reflecting leisure activities of a certain social class."], "source": ["8_Pig & Pepper"]} +{"term": "Cross-examination", "nature": ["legal process"], "detail": ["A method used to challenge the credibility of witnesses, showcasing the adversarial nature of legal proceedings. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Cultural Diversity", "nature": ["influence"], "detail": ["The involvement of notable figures from different backgrounds in adaptations illustrates a blend of creative influences and cultural collaboration. "], "source": ["22_Film Adaptations"]} +{"term": "Curiosity", "nature": ["cultural norm"], "detail": ["An emphasis on curiosity is highlighted by the desire to follow unusual occurrences and explore the unknown, reflecting a cultural value placed on exploration and discovery."], "source": ["2_Down the Rabbit Hole"]} +{"term": "Curious Feelings", "nature": ["concept"], "detail": ["Emotions influenced by magical occurrences, highlighting the whimsical nature of the environment and its impact on perception."], "source": ["3_Down the Rabbit Hole"]} +{"term": "Dimensions of Reality", "nature": ["concept"], "detail": ["The concept of falling through a rabbit-hole into another realm suggests a belief in multiple dimensions or alternate realities, which is a common theme in fantastical narratives."], "source": ["2_Down the Rabbit Hole"]} +{"term": "Disregard for Rules", "nature": ["social norm"], "detail": ["There is a general disregard for established rules during games, portraying a society where individual desires take precedence over order and structure. "], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Drink Me", "nature": ["label"], "detail": ["A label on a bottle instructing to drink its contents, suggesting transformative properties that alter size or abilities."], "source": ["3_Down the Rabbit Hole"]} +{"term": "Drumming", "nature": ["tradition"], "detail": ["The use of drums signifies a traditional method of gathering attention or announcing events, enhancing the festive atmosphere."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Eat Me", "nature": ["label"], "detail": ["A label on a cake instructing to eat it, indicating it may cause growth or change in size."], "source": ["3_Down the Rabbit Hole"]} +{"term": "Economy", "nature": ["concept"], "detail": ["The value of land and language is exaggerated, with references to worth measured in pounds, suggesting a whimsical economy where abstract concepts have significant monetary value."], "source": ["15_LOOKING-GLASS INSECTS"]} +{"term": "Education", "nature": ["cultural consensus"], "detail": ["Education is perceived as encompassing practical knowledge, such as mathematics and language, rather than lessons in manners or social skills. "], "source": ["19_Queen Alice"]} +{"term": "Egg", "nature": ["symbolism"], "detail": ["The egg represents an object of desire that is elusive, reflecting the notion of unattainable goals in a whimsical context."], "source": ["17_WOOL AND WATER"]} +{"term": "Epistemological Doubt", "nature": ["philosophical concept"], "detail": ["The narrative explores the limits of what can be known and understood at a specific historical moment, highlighting the tension between logical reasoning and human desire."], "source": ["1_Introduction"]} +{"term": "Execution", "nature": ["punishment"], "detail": ["A severe form of punishment indicating a strict legal system with harsh consequences for transgressions. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Execution as Punishment", "nature": ["cultural norm"], "detail": ["Execution is a common and severe punishment for mistakes or offenses, highlighting a culture of fear and harsh consequences for errors."], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Executioner’s Role", "nature": ["social structure"], "detail": ["The presence of an executioner indicates a formalized role within society dedicated to carrying out punishments, reflecting a bureaucratic aspect of governance."], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Fantasy Elements", "nature": ["concept"], "detail": ["The existence of fantastical creatures, such as a Gnat that can speak and a Fawn that expresses alarm upon realizing the difference between species, reflects a world where the ordinary rules of nature do not apply. "], "source": ["15_LOOKING-GLASS INSECTS"]} +{"term": "Feasting customs", "nature": ["cultural practice"], "detail": ["The sharing of food, particularly plum cake and bread, reflects social customs surrounding communal eating and hospitality."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Feathering", "nature": ["activity"], "detail": ["The technique of rowing described as keeping the oar horizontal on the return stroke reflects traditional watercraft skills and cultural practices associated with boating or fishing."], "source": ["21_Shaking"]} +{"term": "Film Adaptation", "nature": ["medium"], "detail": ["The story has been adapted into various film formats, ranging from silent films to full-length features, showcasing its enduring popularity across different eras. "], "source": ["22_Film Adaptations"]} +{"term": "Fireplace", "nature": ["artifact"], "detail": ["The presence of a fireplace serves as a source of warmth and comfort, indicating a societal reliance on fire for both practical and emotional needs."], "source": ["14_LOOKING-GLASS HOUSE"]} +{"term": "Footman", "nature": ["social role"], "detail": ["A footman is a servant who typically wears a uniform and serves in a household, often associated with carrying messages or invitations."], "source": ["8_Pig & Pepper"]} +{"term": "Freudian Concepts", "nature": ["psychological theory"], "detail": ["The narrative reflects ideas similar to Freud's theories regarding the unconscious, suggesting that children possess knowledge and desires that adults have forgotten or repressed."], "source": ["1_Introduction"]} +{"term": "Geographical Knowledge", "nature": ["knowledge"], "detail": ["The character’s musings about latitude and longitude indicate an educational background that includes a basic understanding of geography, reflecting a value placed on knowledge and learning."], "source": ["2_Down the Rabbit Hole"]} +{"term": "Geography", "nature": ["concept"], "detail": ["The land lacks principal rivers, mountains, and towns, indicating a fantastical geography that defies conventional mapping."], "source": ["15_LOOKING-GLASS INSECTS"]} +{"term": "Gift-Giving", "nature": ["cultural practice"], "detail": ["The practice of sending gifts to oneself, reflecting a whimsical approach to self-care and kindness."], "source": ["4_The Pool of Tears"]} +{"term": "Golden Key", "nature": ["artifact"], "detail": ["A small golden key that fits a specific lock, symbolizing access to hidden realms or opportunities."], "source": ["3_Down the Rabbit Hole"]} +{"term": "Green Eyes", "nature": ["symbol"], "detail": ["Green eyes are often associated with various cultural interpretations, including envy, mystery, or otherworldly qualities, reflecting deeper psychological or magical themes."], "source": ["21_Shaking"]} +{"term": "Grinning", "nature": ["behavioral trait"], "detail": ["The act of grinning, particularly among cats, signifies a peculiar behavioral trait that suggests a deeper, often nonsensical, understanding of emotions in this society."], "source": ["8_Pig & Pepper"]} +{"term": "Growing in Size", "nature": ["magical phenomenon"], "detail": ["An ability to change physical size, representing themes of transformation and the fluidity of identity in this fantastical context. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Height Measurement", "nature": ["social norm"], "detail": ["Height is used as a criterion for exclusion from the court, indicating a unique societal measure that has no basis in fairness or justice. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Hierarchy", "nature": ["concept"], "detail": ["The concept of time being worth money implies a societal structure where individuals are judged based on the economic value of their time and actions."], "source": ["15_LOOKING-GLASS INSECTS"]} +{"term": "Hierarchy among Characters", "nature": ["social structure"], "detail": ["A clear hierarchy is observed, with certain characters possessing authority to issue commands and others remaining subservient, reinforcing social stratification."], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Historical Context", "nature": ["historical fact"], "detail": ["The notion of having only one queen at a time is rooted in historical precedence, suggesting a structured hierarchy in governance. "], "source": ["19_Queen Alice"]} +{"term": "Historical Reflection", "nature": ["event"], "detail": ["The adaptations often coincide with pivotal historical moments, such as centennial celebrations, indicating a connection between cultural productions and historical events. "], "source": ["22_Film Adaptations"]} +{"term": "Hookah", "nature": ["artifact"], "detail": ["A hookah is used for smoking flavored tobacco, often associated with leisurely and contemplative activities."], "source": ["7_Advice from a Caterpillar"]} +{"term": "Identity", "nature": ["cultural concept", "concept"], "detail": ["The struggle with personal identity and the question of self-understanding reflect a cultural consensus around the complexity of self-perception and change.", "There is a concern over the loss of one’s name, indicating a cultural significance attached to identity and the power of names."], "source": ["7_Advice from a Caterpillar", "15_LOOKING-GLASS INSECTS"]} +{"term": "Imaginary Play", "nature": ["social norm"], "detail": ["Engaging in imaginative play is a common practice, where individuals create scenarios and characters, blurring the lines between reality and imagination."], "source": ["14_LOOKING-GLASS HOUSE"]} +{"term": "Imaginary Scenarios", "nature": ["concept"], "detail": ["The tendency to envision playful or nonsensical situations, showcasing creativity and the blending of reality with fantasy."], "source": ["3_Down the Rabbit Hole"]} +{"term": "Inanimate Objects", "nature": ["artifact"], "detail": ["The ability for ordinary objects, such as a jar labeled \"ORANGE MARMALADE,\" to be encountered in unexpected places illustrates a whimsical and surreal aspect of the world, where everyday items serve unusual purposes."], "source": ["2_Down the Rabbit Hole"]} +{"term": "Insects", "nature": ["creature"], "detail": ["Insects are personified and engage in conversation, suggesting a world where creatures typically lacking intelligence possess the ability to communicate and interact meaningfully."], "source": ["15_LOOKING-GLASS INSECTS"]} +{"term": "Internal Dialogue", "nature": ["concept"], "detail": ["The practice of self-reflection and reasoning, illustrating a character's thought process and decision-making in extraordinary situations."], "source": ["3_Down the Rabbit Hole"]} +{"term": "Invitation", "nature": ["social custom"], "detail": ["An invitation signifies a formal request for someone to attend an event, such as a game or gathering, highlighting social hierarchies."], "source": ["8_Pig & Pepper"]} +{"term": "Jam", "nature": ["cultural norm"], "detail": ["The concept of having jam only on alternate days creates a whimsical rule that defies typical expectations."], "source": ["17_WOOL AND WATER"]} +{"term": "Judicial Proceedings", "nature": ["cultural consensus"], "detail": ["The court operates under a nonsensical judicial process, highlighting the absurdity of some legal systems where decisions are made without proper evidence or reason. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Jury", "nature": ["legal system"], "detail": ["A group of individuals tasked with evaluating evidence and providing a verdict, showcasing a collective decision-making process in legal matters. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "King and Queen of Hearts", "nature": ["royalty"], "detail": ["The rulers preside over a court, embodying authority and power within the realm. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Knitting", "nature": ["craftsmanship"], "detail": ["Knitting is depicted as a skill performed with numerous pairs of needles simultaneously, suggesting a blend of practicality and absurdity."], "source": ["17_WOOL AND WATER"]} +{"term": "Language Acquisition", "nature": ["educational concept"], "detail": ["The ability to learn languages is a valued skill, with emphasis on the understanding of words and their meanings."], "source": ["19_Queen Alice"]} +{"term": "Language Skills Development", "nature": ["educational theme"], "detail": ["The quest for knowledge is intertwined with the development of language skills, indicating a progressive complexity in communication as one matures."], "source": ["1_Introduction"]} +{"term": "Learning to Draw", "nature": ["educational activity"], "detail": ["The act of learning to draw signifies the importance of creativity and artistic expression in education, highlighting a cultural value placed on the arts."], "source": ["9_A Mad Tea Party"]} +{"term": "Livery", "nature": ["clothing"], "detail": ["Livery denotes a specific kind of uniform worn by servants, indicating their service to a particular household or employer."], "source": ["8_Pig & Pepper"]} +{"term": "Living Backwards", "nature": ["concept"], "detail": ["Living backwards allows one’s memory to function in reverse, enabling recollection of events that haven’t yet occurred."], "source": ["17_WOOL AND WATER"]} +{"term": "Locked Doors", "nature": ["concept"], "detail": ["Represent barriers to exploration or knowledge, emphasizing themes of restriction and the quest for freedom."], "source": ["3_Down the Rabbit Hole"]} +{"term": "Madness", "nature": ["social commentary", "cultural motif"], "detail": ["The concept of madness is presented as a common trait among residents, suggesting a world where conventional logic is subverted.", "The reference to madness suggests a cultural fascination with the theme of insanity, often explored in literature as a means to challenge societal norms and rationality."], "source": ["8_Pig & Pepper", "9_A Mad Tea Party"]} +{"term": "Magic", "nature": ["system"], "detail": ["The existence of arbitrary and nonsensical rules reflects a magical system where logic does not apply, allowing for whimsical interpretations of authority and legality. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Magic Potion", "nature": ["artifact"], "detail": ["A bottle that causes the drinker to grow larger or smaller, influencing physical size in unpredictable ways."], "source": ["6_The Rabbit Sends in a Little Bill"]} +{"term": "Magical Creatures", "nature": ["entity", "entities"], "detail": ["The presence of a talking rabbit with human-like traits, such as wearing a waistcoat and carrying a watch, suggests a world where animal characters possess human characteristics and behaviors.", "The presence of creatures that demonstrate whimsical and unpredictable behaviors, highlighting a world where the ordinary laws of nature do not apply."], "source": ["2_Down the Rabbit Hole", "20_Queen Alice"]} +{"term": "Magical Growth", "nature": ["ability"], "detail": ["The ability to grow or shrink in size dramatically, leading to physical transformations that defy typical human proportions."], "source": ["4_The Pool of Tears"]} +{"term": "Magical Systems", "nature": ["concept"], "detail": ["In this world, the existence of looking-glass portals allows for travel between parallel dimensions, suggesting a fluidity between reality and fantasy."], "source": ["14_LOOKING-GLASS HOUSE"]} +{"term": "Magical Transformation", "nature": ["concept", "mechanism"], "detail": ["The ability to change physical size at will through specific actions, reflecting themes of identity and adaptability.", "The ability to alter physical size and shape, as demonstrated by the changing dimensions and features of a character when manipulated."], "source": ["3_Down the Rabbit Hole", "21_Shaking"]} +{"term": "Mathematical Ability", "nature": ["social expectation"], "detail": ["There is an expectation to possess mathematical skills, with various forms of addition, subtraction, and division being common topics of inquiry. "], "source": ["19_Queen Alice"]} +{"term": "Mathematical Logic", "nature": ["system"], "detail": ["The books incorporate themes of mathematical reasoning, demonstrating a conflict between logical proofs and the illogical nature of human desires."], "source": ["1_Introduction"]} +{"term": "Meaning", "nature": ["philosophical concept"], "detail": ["The exploration of meaning in communication reflects a philosophical inquiry into the nature of understanding and interpretation in human interactions."], "source": ["13_Who Stole the Tarts?"]} +{"term": "Memorandum Books", "nature": ["artifact"], "detail": ["Memorandum books are utilized for recording thoughts and events, suggesting a cultural emphasis on documentation and the preservation of memory."], "source": ["14_LOOKING-GLASS HOUSE"]} +{"term": "Memorandum book", "nature": ["technology"], "detail": ["The use of a memorandum book suggests a system of record-keeping and organization, reflecting a bureaucratic method of governance."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Memory", "nature": ["cognitive ability"], "detail": ["A poor sort of memory is described as one that only recalls events in a single chronological direction, highlighting a unique perspective on memory."], "source": ["17_WOOL AND WATER"]} +{"term": "Messenger system", "nature": ["communication"], "detail": ["A two-messenger system is employed for efficient information relay, indicating a structured approach to communication."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Metaphor of Growth", "nature": ["cultural concept"], "detail": ["The transformation from chrysalis to butterfly serves as a metaphor for personal growth and change, resonating with universal themes of development and maturation."], "source": ["7_Advice from a Caterpillar"]} +{"term": "Muchness", "nature": ["conceptual phrase"], "detail": ["The term \"muchness\" reflects a playful approach to language, suggesting a cultural emphasis on the nuances and absurdities of expression."], "source": ["9_A Mad Tea Party"]} +{"term": "Musical Integration", "nature": ["form"], "detail": ["The incorporation of music into adaptations highlights an appreciation for narrative enhancement through song, as seen in various productions. "], "source": ["22_Film Adaptations"]} +{"term": "Narrative Exploration", "nature": ["theme"], "detail": ["The recurring themes of growth and transformation in adaptations indicate a universal exploration of identity and change."], "source": ["22_Film Adaptations"]} +{"term": "Nursing", "nature": ["social practice"], "detail": ["The act of nursing a child is depicted in a chaotic manner, critiquing parenting norms and practices in a fantastical society."], "source": ["8_Pig & Pepper"]} +{"term": "Painting Roses", "nature": ["magical system"], "detail": ["A magical system exists where the color of roses can be changed through painting, reflecting a whimsical alteration of nature to avoid punishment. "], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Personal Remarks", "nature": ["social etiquette"], "detail": ["Making personal remarks about someone's appearance is generally considered rude, reflecting societal norms regarding politeness and respect in conversation."], "source": ["9_A Mad Tea Party"]} +{"term": "Personal Responsibility", "nature": ["cultural value"], "detail": ["There is an acknowledgment of responsibility for one’s own well-being and the well-being of one's body, even in fantastical circumstances."], "source": ["4_The Pool of Tears"]} +{"term": "Pet Ownership", "nature": ["cultural practice"], "detail": ["The affection and bond between humans and their pets is a recognized aspect of life, often serving as a source of comfort and companionship."], "source": ["5_A Caucus Race & a Long Tale"]} +{"term": "Playfulness", "nature": ["cultural norm"], "detail": ["The act of merrily running and chasing after a shawl reflects a cultural value placed on playfulness and the absurd, contrasting with more serious societal expectations."], "source": ["20_Queen Alice"]} +{"term": "Polymath", "nature": ["intellectual trait"], "detail": ["The author embodies the characteristics of a polymath, engaging in various fields of study, including mathematics, logic, and storytelling, reflecting the diverse interests of the Victorian era."], "source": ["1_Introduction"]} +{"term": "Pool of Tears", "nature": ["symbol"], "detail": ["A physical manifestation of emotions, representing feelings of despair and helplessness in the face of challenges."], "source": ["3_Down the Rabbit Hole"]} +{"term": "Postage Stamps", "nature": ["technology"], "detail": ["The use of postage stamps as a means of sending letters and packages, indicating a developed communication system and societal reliance on written correspondence."], "source": ["21_Shaking"]} +{"term": "Prices", "nature": ["economics"], "detail": ["The pricing scheme where two items are sold for less than one showcases illogical economic principles."], "source": ["17_WOOL AND WATER"]} +{"term": "Prison system", "nature": ["social institution"], "detail": ["The mention of a character recently released from prison suggests a penal system and its impact on individuals' lives."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Prizes", "nature": ["cultural practice"], "detail": ["The concept of awarding prizes to participants, regardless of merit, reflects a cultural tendency to promote inclusivity and shared experience over competition."], "source": ["5_A Caucus Race & a Long Tale"]} +{"term": "Procession", "nature": ["social structure"], "detail": ["A grand procession is conducted, emphasizing hierarchy and the importance of royal figures, where subjects are expected to show deference to authority."], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Public Sentiments", "nature": ["cultural consensus"], "detail": ["The public's reaction to absurdity, such as laughter or acceptance of nonsensical rules, reveals a cultural consensus that tolerates illogical behavior within societal structures. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Quarreling among Players", "nature": ["social behavior"], "detail": ["Players engage in quarrels during games, suggesting a cultural acceptance of discord and competition over cooperation."], "source": ["10_The Queen's Croquet Ground"]} +{"term": "Queenship", "nature": ["social norm"], "detail": ["The concept of being a queen is tied to expectations of dignity, behavior, and the necessity of passing examinations to validate one’s status. "], "source": ["19_Queen Alice"]} +{"term": "Reality perception", "nature": ["philosophical concept"], "detail": ["The notion that believing in fantastical creatures can lead to mutual belief reflects themes of perception and reality in social interactions."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Reflection and Memory", "nature": ["psychological theme"], "detail": ["The narratives emphasize the interplay of memory and recollection, illustrating how adults must remember and reconnect with their childhood desires."], "source": ["1_Introduction"]} +{"term": "Riddles", "nature": ["cultural activity"], "detail": ["Engaging in riddles is a common form of entertainment, reflecting a cultural appreciation for wordplay and intellectual challenges."], "source": ["9_A Mad Tea Party"]} +{"term": "Rules of Engagement", "nature": ["social norm"], "detail": ["The phrase \"chop off her head\" reflects extreme and absurd measures taken in discussions or disputes, indicative of a chaotic social order."], "source": ["8_Pig & Pepper"]} +{"term": "Secrets", "nature": ["social dynamics"], "detail": ["The emphasis on keeping secrets showcases the importance of discretion and hidden knowledge within interpersonal relationships in this society. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Self-Reflection", "nature": ["psychological concept"], "detail": ["Individuals engage in self-dialogue and reflection when faced with challenging situations, revealing inner thoughts and emotions."], "source": ["4_The Pool of Tears"]} +{"term": "Shapeshifting", "nature": ["ability"], "detail": ["The ability to change size or form, as illustrated by a character suddenly diminishing in size, indicating a fluidity of identity and presence."], "source": ["20_Queen Alice"]} +{"term": "Shop", "nature": ["commerce"], "detail": ["The shop is characterized by the peculiar rule that items must be retrieved by the customer rather than handed over by the vendor, reflecting unconventional retail practices."], "source": ["17_WOOL AND WATER"]} +{"term": "Size Variation", "nature": ["magical system"], "detail": ["The ability to grow taller or shorter by consuming different sides of a mushroom suggests a magical system that allows for manipulation of one's physical dimensions."], "source": ["7_Advice from a Caterpillar"]} +{"term": "Sleepiness", "nature": ["biological state"], "detail": ["Sleepiness is a natural state that can affect individuals, leading to moments of vulnerability and the need for care from others. "], "source": ["19_Queen Alice"]} +{"term": "Smelling Salts", "nature": ["artifact"], "detail": ["Smelling salts are used for reviving someone from a faint or shock, showcasing historical medical practices and societal concerns for health and well-being."], "source": ["21_Shaking"]} +{"term": "Snow", "nature": ["concept"], "detail": ["Snow is personified as a gentle entity that covers the ground, indicating a cultural appreciation for the beauty and tranquility of nature's cycles."], "source": ["14_LOOKING-GLASS HOUSE"]} +{"term": "Social Expectations", "nature": ["cultural concept"], "detail": ["The interaction surrounding expectations of behavior and identity highlights societal norms regarding how one should present themselves and understand their role in the world."], "source": ["7_Advice from a Caterpillar"]} +{"term": "Social Interaction", "nature": ["social norm"], "detail": ["The act of addressing an imagined audience while contemplating one's thoughts shows an inclination toward social interaction, even in solitude, highlighting the importance of communication and connection in this society."], "source": ["2_Down the Rabbit Hole"]} +{"term": "Social Norms", "nature": ["concept", "cultural practice"], "detail": ["A reflection on expectations of behavior, such as the importance of following rules and the consequences of disregarding them. ", "There is an expectation for individuals, regardless of age, to maintain composure and avoid excessive displays of emotion in public.", "The expectation for individuals to navigate their environment competently, including knowledge of ticketing systems, reflects a societal norm of accountability and awareness. "], "source": ["3_Down the Rabbit Hole", "4_The Pool of Tears", "15_LOOKING-GLASS INSECTS"]} +{"term": "Soldiers", "nature": ["social norm"], "detail": ["Soldiers are depicted as clumsy and uncoordinated, presenting a humorous take on the nature of military forces."], "source": ["18_THE LION AND THE UNICORN"]} +{"term": "Storytelling", "nature": ["cultural norm"], "detail": ["The act of sharing stories is a common social activity, often used to convey history, morals, or entertainment, highlighting its importance in social bonding."], "source": ["5_A Caucus Race & a Long Tale"]} +{"term": "Supernatural Elements", "nature": ["concept"], "detail": ["Objects and environments exhibit characteristics contrary to the laws of physics, such as books with reversed text and animated inanimate objects, highlighting a world rich in the surreal and magical."], "source": ["14_LOOKING-GLASS HOUSE"]} +{"term": "Suppression of Applause", "nature": ["social norm"], "detail": ["A societal expectation to maintain order and decorum in formal settings, emphasizing the importance of authority in public gatherings. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Surrealism", "nature": ["artistic movement"], "detail": ["The text aligns with surrealist ideas by presenting a world where logic is subverted, and the absurdity of childhood emotions is highlighted."], "source": ["1_Introduction"]} +{"term": "Sweets", "nature": ["cuisine"], "detail": ["The mention of desserts made with sugar and raisins suggests a cultural appreciation for sweet foods, reflecting culinary practices and social gatherings around food."], "source": ["21_Shaking"]} +{"term": "Tablecloth", "nature": ["object"], "detail": ["The act of seizing a tablecloth entails a cultural significance around dining practices and communal gatherings, suggesting a chaotic disruption of order during such events."], "source": ["20_Queen Alice"]} +{"term": "Talking Animals", "nature": ["concept"], "detail": ["Animals possess the ability to communicate with humans, indicating a sentient quality and a shared understanding of emotions and social norms."], "source": ["14_LOOKING-GLASS HOUSE"]} +{"term": "Tea Party", "nature": ["social gathering"], "detail": ["A tea party is characterized by the presence of tea and various snacks, often providing a space for conversation and social interaction among guests."], "source": ["9_A Mad Tea Party"]} +{"term": "Tea-time", "nature": ["cultural tradition"], "detail": ["The concept of tea-time represents a customary practice, emphasizing the importance of shared meals and scheduled breaks in daily life, often associated with relaxation and socializing."], "source": ["9_A Mad Tea Party"]} +{"term": "Technological Advancement", "nature": ["context"], "detail": ["The evolution from silent films to \"talkies\" reflects significant advancements in film technology and audience engagement. "], "source": ["22_Film Adaptations"]} +{"term": "Temper", "nature": ["social norm"], "detail": ["The expectation that individuals should manage their emotions, particularly in social settings, as losing one's temper can lead to social consequences."], "source": ["5_A Caucus Race & a Long Tale"]} +{"term": "Temperament", "nature": ["psychological trait"], "detail": ["The temperament of individuals, particularly in relation to situations such as losing a bone from a dog, is considered significant and subject to discussion. "], "source": ["19_Queen Alice"]} +{"term": "Time", "nature": ["conceptual entity"], "detail": ["Time is personified and treated as a character capable of influence, indicating a unique cultural perspective on the nature of time and its management in social settings."], "source": ["9_A Mad Tea Party"]} +{"term": "Time Perception", "nature": ["cultural consensus"], "detail": ["The rabbit's concern about being late implies a societal understanding of time and punctuality, suggesting that these concepts are significant within this world.", "The perception of time varies, with some cultures allowing for multiple days or nights to be experienced simultaneously, contrasting with the singular day-at-a-time approach. "], "source": ["2_Down the Rabbit Hole", "19_Queen Alice"]} +{"term": "Time Sensitivity", "nature": ["cultural norm"], "detail": ["There is a sense of urgency associated with time, as individuals express anxiety about keeping others waiting, indicating social pressures around punctuality."], "source": ["4_The Pool of Tears"]} +{"term": "Transformation", "nature": ["magical system", "magical concept", "magic"], "detail": ["The ability to change size by consuming different parts of a mushroom illustrates a magical system where physical transformation is linked to specific objects.", "The ability for a creature to transform into another form, such as a baby turning into a pig, underscores the fluidity of identity in this world.", "Items and environments undergo spontaneous transformations, indicating a fluid reality where physical properties can change based on perception."], "source": ["7_Advice from a Caterpillar", "8_Pig & Pepper", "17_WOOL AND WATER"]} +{"term": "Transportation", "nature": ["concept"], "detail": ["There is a railway system where tickets are required for travel, yet the existence of a ticket office is questioned, hinting at an illogical transportation system reflective of the nonsensical nature of the world."], "source": ["15_LOOKING-GLASS INSECTS"]} +{"term": "Travel Bag", "nature": ["artifact"], "detail": ["A travel bag designed with two equal compartments indicates practicality and organization in personal belongings, highlighting societal norms around travel and preparation."], "source": ["21_Shaking"]} +{"term": "Treacle-well", "nature": ["mythical location"], "detail": ["A treacle-well serves as a whimsical concept, blending the mundane with the fantastical, showcasing the imaginative aspects of storytelling and the blending of reality with fantasy."], "source": ["9_A Mad Tea Party"]} +{"term": "Trial", "nature": ["legal system"], "detail": ["A formal process takes place to determine guilt or innocence, reflecting societal norms of justice. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Truth-telling", "nature": ["social expectation"], "detail": ["There is a societal expectation to always speak the truth, with consequences for not doing so. "], "source": ["19_Queen Alice"]} +{"term": "Verses as Evidence", "nature": ["cultural practice"], "detail": ["Employing nonsensical verses as evidence demonstrates a cultural practice that prioritizes form over substance, illustrating how meanings can be distorted in communication. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Victorian Society", "nature": ["historical context"], "detail": ["The narratives are set against the backdrop of Victorian societal norms, which emphasized morality, education, and the roles of children and adults."], "source": ["1_Introduction"]} +{"term": "William the Conqueror", "nature": ["historical figure"], "detail": ["A pivotal figure in English history whose conquest marked the beginning of Norman rule in England, influencing the social and political landscape of the nation."], "source": ["5_A Caucus Race & a Long Tale"]} +{"term": "Witness", "nature": ["legal process"], "detail": ["Individuals called to provide testimony in a court, illustrating the reliance on personal accounts in the pursuit of justice. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Writing Instruments", "nature": ["technology"], "detail": ["The use of slates for writing suggests a rudimentary level of technology, reflecting a society where conventional writing materials may not be prevalent. "], "source": ["13_Who Stole the Tarts?"]} +{"term": "Writing Materials", "nature": ["technology"], "detail": ["The use of slates and pencils indicates a level of literacy and the practice of documentation in this society. "], "source": ["12_Who Stole the Tarts?"]} +{"term": "Written Records", "nature": ["documentation"], "detail": ["The practice of writing down names and evidence, highlighting the significance of record-keeping in legal and societal processes. "], "source": ["12_Who Stole the Tarts?"]} diff --git "a/data/worlds/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/world_info.json" "b/data/worlds/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/world_info.json" new file mode 100644 index 0000000000000000000000000000000000000000..06d4d216ab3fa9786ef2262301fdd51f022690fa --- /dev/null +++ "b/data/worlds/Alice\342\200\231s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/world_info.json" @@ -0,0 +1,5 @@ +{ + "source": "Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "world_name": "the Wonderland", + "description": "Alice's Adventures in Wonderland - Through the Looking-Glass depicts a whimsical, topsy-turvy world where logic defies reason. Characters like the Cheshire Cat, Mad Hatter, and Queen of Hearts inhabit surreal landscapes filled with peculiar rules and bizarre events. Chessboards come to life, and mirrors reveal alternate realities. Imagination reigns supreme, blending fantasy with absurdity in a dreamlike exploration of identity and curiosity, challenging Alice’s perception as she navigates through enchanting and nonsensical realms." +} \ No newline at end of file diff --git a/data/worlds/example_world/general.json b/data/worlds/example_world/general.json new file mode 100644 index 0000000000000000000000000000000000000000..a11d84ce9d8610ea2515400358eca53c94c0e52c --- /dev/null +++ b/data/worlds/example_world/general.json @@ -0,0 +1,6 @@ +{ + "source": "example", + "world_name": "Earth", + "description": "This is a near-future world where technology has advanced at an unprecedented pace. People are exploring new frontiers, questioning where humanity ends and where machines begin, as society undergoes profound transformations driven by scientific breakthroughs.", + "language":"en" +} \ No newline at end of file diff --git a/experiment_presets/example_free.json b/experiment_presets/example_free.json new file mode 100644 index 0000000000000000000000000000000000000000..fbb028ef405a312933505f15092e3f15f732506c --- /dev/null +++ b/experiment_presets/example_free.json @@ -0,0 +1,13 @@ +{ + "experiment_subname": "script", + "world_file_path":"./data/worlds/example_world/general.json", + "map_file_path":"./data/maps/example_map.csv", + "loc_file_path":"./data/locations/example_locations.json", + "role_file_dir":"./data/roles/", + "role_agent_codes":["Lacia-en","Trek-en"], + "intervention":"One day, an enigmatic signal from an unknown source reached Lacia and Trek...", + "script":"", + "source":"Example", + "language":"en" + +} \ No newline at end of file diff --git a/experiment_presets/example_script.json b/experiment_presets/example_script.json new file mode 100644 index 0000000000000000000000000000000000000000..ab33d505213addf92f2eb1755c700f40d5e3185b --- /dev/null +++ b/experiment_presets/example_script.json @@ -0,0 +1,13 @@ +{ + "experiment_subname": "script", + "world_file_path":"./data/worlds/example_world.json", + "map_file_path":"./data/maps/example_map.csv", + "loc_file_path":"./data/locations/example_locations.json", + "role_file_dir":"./data/roles/", + "role_agent_codes":["Lacia-en","Trek-en"], + "intervention":"", + "script":"", + "source":"Example", + "language":"en" + +} \ No newline at end of file diff --git a/experiment_presets/experiment_alice.json b/experiment_presets/experiment_alice.json new file mode 100644 index 0000000000000000000000000000000000000000..2245a1c373761dcb14d254ee21b3af699a6682d5 --- /dev/null +++ b/experiment_presets/experiment_alice.json @@ -0,0 +1,13 @@ +{ + "experiment_subname": "general", + "world_file_path":"./data/worlds/Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass/general.json", + "map_file_path":"./data/maps/Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.csv", + "loc_file_path":"./data/locations/Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass.json", + "role_file_dir":"./data/roles/", + "role_agent_codes":["Alice_Liddell-en","Cheshire_Cat-en","Hatter-en"], + "intervention":"", + "script":"", + "source":"Alice’s_Adventures_in_Wonderland_-_Through_the_Looking-Glass", + "language":"zh" + +} diff --git a/experiment_presets/experiment_icefire.json b/experiment_presets/experiment_icefire.json new file mode 100644 index 0000000000000000000000000000000000000000..2c5071941a21ea40ebdfe75af5dc594786ebf507 --- /dev/null +++ b/experiment_presets/experiment_icefire.json @@ -0,0 +1,13 @@ +{ + "experiment_subname": "general", + "world_file_path":"./data/worlds/A_Song_of_Ice_and_Fire/general.json", + "map_file_path":"./data/maps/A_Song_of_Ice_and_Fire.csv", + "loc_file_path":"./data/locations/A_Song_of_Ice_and_Fire.json", + "role_file_dir":"./data/roles/", + "role_agent_codes":["SansaStark-zh", "CerseiLannister-zh", "AryaStark-zh", "DaenerysTargaryen-zh", "JaimeLannister-zh", "TyrionLannister-zh", "JonSnow-zh", "BranStark-zh"], + "intervention":"", + "script":"", + "source":"A_Song_of_Ice_and_Fire", + "language":"zh" + +} \ No newline at end of file diff --git a/experiment_presets/experiment_icefire_bloody_wedding.json b/experiment_presets/experiment_icefire_bloody_wedding.json new file mode 100644 index 0000000000000000000000000000000000000000..45db0b6cf8b18082eca7dd3f7c74272002090751 --- /dev/null +++ b/experiment_presets/experiment_icefire_bloody_wedding.json @@ -0,0 +1,13 @@ +{ + "experiment_subname": "bloody_wedding", + "world_file_path":"./data/worlds/A_Song_of_Ice_and_Fire/bloody_wedding.json", + "map_file_path":"./data/maps/A_Song_of_Ice_and_Fire_bloody_wedding.csv", + "loc_file_path":"./data/locations/A_Song_of_Ice_and_Fire.json", + "role_file_dir":"./data/roles/", + "role_agent_codes":["Robb-Stark-zh", "Catelyn-Stark-zh", "Walder-Frey-zh", "Roose-Bolton-zh", "Edmure-Tully-zh", "Tywin-Lannister-zh", "Roslin-Frey-zh"], + "intervention":"宴会厅内灯火通明,音乐欢快,宾客们举杯畅饮,罗柏·史塔克与凯特琳微笑交谈,气氛热闹祥和。然而,一个巨大的阴谋正在暗中酝酿。", + "script":"**第一阶段:宴会的开始** \n在黄昏时分,孪河城的大宴厅内,婚礼宴会热烈地展开。各方宾客欢聚一堂,为艾德慕·徒利与罗莎琳·弗雷的婚礼举杯庆祝。罗柏·史塔克与凯特琳·史塔克表面上保持微笑,但心中隐约感到不安。瓦德·弗雷表面友好,但偶尔以冷嘲热讽提及罗柏违背婚约之事。罗斯·波顿则表现得微妙,让人察觉出异样,但不知他的真实意图。新郎新娘在宾客的注视下跳起了开场舞,气氛似乎一片和谐。 \n\n**第二阶段:气氛转变** \n宴会进行到中段时,酒水不断流淌,但气氛开始微妙地转冷。乐队的曲调悄然变化,引起了凯特琳的警觉。她发现罗斯·波顿穿着链甲,这一异常让她心生疑虑。罗柏却沉浸在庆典的热闹中,毫无察觉。与此同时,瓦德·弗雷在一片祥和中悄悄发出了某种暗示性的信号。 \n\n**第三阶段:阴谋揭露** \n在宴会的深夜时分,乐队忽然演奏起兰尼斯特家族的代表曲《雨中轻语》。这首曲子让凯特琳意识到事情不对劲。紧接着,宴厅的大门被关闭,弗雷家族的士兵迅速控制了局面。罗斯·波顿靠近罗柏,在他耳边低语“兰尼斯特家族向你问好”,随即用匕首刺穿了他的身体。凯特琳绝望中劫持了瓦德·弗雷的妻子威胁他,但无济于事。 \n\n**第四阶段:屠杀的高潮** \n屠杀全面展开,孪河城的大宴厅成为了战场。弗雷家族和波顿家族的士兵对史塔克家族的成员和支持者展开了无情的屠杀。罗柏·史塔克在母亲凯特琳眼前倒地身亡。凯特琳目睹这一切后,在绝望和愤怒中杀死了瓦德·弗雷的妻子,随后也被士兵处决。艾德慕·徒利作为新郎并未遭受屠杀,但被关押起来。 \n\n**第五阶段:后续与结局** \n宴会结束后,孪河城被鲜血染红,宴厅内尸横遍地。瓦德·弗雷与罗斯·波顿宣布结盟,并公开效忠兰尼斯特家族。泰温·兰尼斯特在幕后策划了这一切,彻底瓦解了北境的力量。少数幸存者逃离了孪河城,但北境的希望已经破灭。这场婚礼的血腥结局揭示了背叛与权力斗争的无情,将故事推向了一个残酷的转折点。", + "source":"A_Song_of_Ice_and_Fire", + "language":"zh" + +} \ No newline at end of file diff --git a/frontend/assets/favicon.ico b/frontend/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e0e65c5d759cf4fbfe744d0f3257e7b14c88f9b4 --- /dev/null +++ b/frontend/assets/favicon.ico @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:503b56f82eb72734ec405461f43708e1bf7ac7cd11f3baac07b07282e545f7d6 +size 346429 diff --git a/frontend/assets/images/default-icon.jpg b/frontend/assets/images/default-icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4b9268c67cf5758c1389d5a8b53ab16ae50c97b3 --- /dev/null +++ b/frontend/assets/images/default-icon.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbcd8580a976fdfc619c25134bd988289e0147ea3c582e07ec7e57a3b9513d69 +size 265387 diff --git a/frontend/assets/images/fantasy-map.png b/frontend/assets/images/fantasy-map.png new file mode 100644 index 0000000000000000000000000000000000000000..ef07acb97d7c8f26041faae3168b4f1ac0f65b2d --- /dev/null +++ b/frontend/assets/images/fantasy-map.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d261dbd4213619e9b62da676a7f4f2f6e1b221fab4de8e57d3a68e39e3d6c818 +size 4411020 diff --git a/frontend/assets/images/iconA.png b/frontend/assets/images/iconA.png new file mode 100644 index 0000000000000000000000000000000000000000..865aaa2172942c8e6313aea204f0bb90660c5a5f --- /dev/null +++ b/frontend/assets/images/iconA.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8cdef67c24c10045299a5bb5230b08e69866eb821ce02deb9fefe4910ed8f04 +size 5790 diff --git a/frontend/assets/images/iconB.png b/frontend/assets/images/iconB.png new file mode 100644 index 0000000000000000000000000000000000000000..7fed5840819b19f8986e3593c02368aa5496c009 --- /dev/null +++ b/frontend/assets/images/iconB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03be42cd4264ed0af5e2540d3985ddc2597adb9c686fdbd509357d9e347f8912 +size 5404 diff --git a/frontend/css/left-section/map-panel.css b/frontend/css/left-section/map-panel.css new file mode 100644 index 0000000000000000000000000000000000000000..6766d4a0263d239a6ef9e03ba1596ef9834f5832 --- /dev/null +++ b/frontend/css/left-section/map-panel.css @@ -0,0 +1,91 @@ +/* map-style.css */ +#map-container { + position: relative; + overflow: hidden; + background: #f5f5f5; + width: 100%; + height: 100%; + position: relative; + border: 1px solid #ccc; + text-align:center; + left:0; + right:0; + margin:auto; +} + +#map { + width: 100%; + height: 100%; + position: relative; +} + +.map-title { + font-size: 1.2em; + color: #5f3737; + margin: 0 0 10px 0; + padding-bottom: 5px; + border-bottom: 1px solid #5f3737; + margin-top: 10px; +} + +/* 设置背景图样式 */ +.map-background { + height: auto; + opacity: 0.8; + position: absolute; + z-index: 0; + object-fit: cover; + background-repeat: repeat; + top: 0; + left: 0; +} + +/* node */ +.node { + cursor: pointer; +} + +.node circle { + fill: #d0a994; + stroke: #603737; + stroke-width: 2px; +} +.node circle.selected { + fill: #ff6666; + stroke: #990000; +} +.node text { + fill: #060000; + font-family: Arial; + font-weight: bold; + font-size: 12px; +} + +/* 确保节点在背景上层 */ +.nodes-container { + position: relative; + z-index: 1; +} + +.popup { + position: absolute; + background: white; + border: 1px solid #999; + border-radius: 5px; + padding: 10px; + box-shadow: 0 0 10px rgba(0,0,0,0.2); + pointer-events: none; +} + +.link { + stroke: #999; + stroke-opacity: 0.6; + stroke-width: 2px; +} + +.distance-label { + font-family: Arial; + font-size: 16px; + font-weight: bold; + fill: #666; +} diff --git a/frontend/css/left-section/profile-panel.css b/frontend/css/left-section/profile-panel.css new file mode 100644 index 0000000000000000000000000000000000000000..28193798d2718e17d98a010a9d6e63b1834d9271 --- /dev/null +++ b/frontend/css/left-section/profile-panel.css @@ -0,0 +1,73 @@ +/* profile-style.css */ + +/* 标题样式 */ +.profiles-title { + font-size: 1.2em; + color: #5f3737; + margin: 0 0 10px 0; + padding-bottom: 5px; + border-bottom: 1px solid #5f3737; + +} + +/* 角色卡片容器 */ +.profiles-container { + display: flex; + flex-wrap: wrap; + gap: 10px; + padding: 5px; + position: relative; +} + +/* 角色卡片 */ +.character-card { + display: flex; + width: 100%; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 8px; + padding: 8px; + cursor: pointer; + transition: all 0.3s ease; +} + +.character-card:hover { + transform: translateY(-2px); + box-shadow: 0 2px 8px rgba(0,0,0,0.1); +} + +/* 角色头像 */ +.character-icon { + width: 30px; + height: 30px; + border-radius: 50%; + overflow: hidden; + margin-right: 10px; + flex-shrink: 1; +} + +.character-icon img { + width: 100%; + height: 100%; + object-fit: cover; +} + +/* 角色信息 */ +.character-info { + flex: 1; +} + +.character-name { + font-weight: bold; + color: #5f3737; + margin-bottom: 4px; +} + +.character-description { + font-size: 0.9em; + color: #666; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} diff --git a/frontend/css/main.css b/frontend/css/main.css new file mode 100644 index 0000000000000000000000000000000000000000..6389744e03c29f24924cc559e4e085f93387469c --- /dev/null +++ b/frontend/css/main.css @@ -0,0 +1,207 @@ +/* main-style.css */ +html, body { + margin: 0; + padding: 0; + height: 100vh; + width: 100%; + overflow: auto; + font-family: Arial, sans-serif; + background-color: #fdf5ee; +} + +.main-container { + display: flex; + height: 100vh; + width: calc(100% - 60px); + margin: 0 auto; + padding: 0 30px; + overflow: hidden; +} +.left-section { + width: 24%; + height: 100vh; + display: flex; + flex-direction: column; + border-right: 1px solid #5f3737; + padding: 0 10px; +} + +/* 地图区域 */ +.map-section { + height: 280px; + background-color: #fdf5ee; + border-bottom: 1px solid #5f3737; + margin-bottom: 50px; +} + +/* 角色档案区域 */ +.character-profiles { + flex: 1; + background-color: #fdf5ee; + overflow-y: auto; + padding: 10px; +} + +/* 聊天框 */ +.chat-section { + flex-grow: 1; + height: 100vh; + overflow: hidden; + display: flex; + justify-content: center; +} + +.chat-container { + width: 50%; + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; +} + +/* 顶部工具栏样式 */ +.toolbar { + background-color: #5c4545; + padding: 10px; + display: flex; + justify-content: space-between; + gap: 10px; + border-bottom: 1px solid #c4a983; +} + +.toolbar button { + background: none; + border: none; + color: #ebe3d7; + cursor: pointer; + padding: 5px 10px; +} + +.toolbar button:hover { + color: #fff; +} + +.control-btn { + display: flex; + align-items: center; + gap: 5px; + padding: 5px 10px; + border: none; + border-radius: 4px; + background-color: #5f3737; + color: white; + cursor: pointer; + transition: background-color 0.3s; +} + +.control-btn:hover { + background-color: #7a4747; +} + +.control-btn i { + font-size: 14px; +} + +.control-btn span { + font-size: 12px; +} + +#stopBtn { + background-color: #873434; +} + +#stopBtn:hover { + background-color: #a34141; +} + +.left-tools, .right-tools { + display: flex; + gap: 10px; +} + +.language-btn { + padding: 8px 15px; + border: 1px solid #ddd; + border-radius: 4px; + background-color: #fff; + cursor: pointer; + display: flex; + align-items: center; + gap: 5px; +} + +.language-btn:hover { + background-color: #f5f5f5; +} + +/* right-section */ +.right-section { + width: 24%; + height: 100vh; + display: flex; + flex-direction: column; + background-color: #fdf5ee; + border-left: 1px solid #5f3737; + overflow: hidden; +} + +.right-toolbar { + padding: 10px; + display: flex; + gap: 10px; + background-color: #5f3737; +} + +.tab-btn { + padding: 8px 16px; + border: none; + border-radius: 4px; + background-color: transparent; + color: #fdf5ee; + cursor: pointer; + transition: background-color 0.3s; +} + +.tab-btn:hover { + background-color: rgba(255, 255, 255, 0.1); +} + +.tab-btn.active { + background-color: #fdf5ee; + color: #5f3737; +} + +.right-content { + flex: 1; + overflow-y: auto; +} + +.tab-panel { + display: none; + padding: 20px; + height: calc(100% - 40px); + overflow-y: auto; +} + +.tab-panel.active { + display: block; +} + +/* 滚动条美化 */ +*::-webkit-scrollbar { + /*滚动条整体样式*/ + width: 6px; /*高宽分别对应横竖滚动条的尺寸*/ + height: 1px; + } +*::-webkit-scrollbar-thumb { + /*滚动条里面深色条*/ + border-radius: 10px; + box-shadow: inset 0 0 5px rgba(236, 236, 236, 0.1); + background: #ccc; +} +*::-webkit-scrollbar-track { + /*滚动条里面轨道*/ + box-shadow: inset 0 0 5px rgba(236, 236, 236, 0.1); + border-radius: 10px; + background: #ededed; +} \ No newline at end of file diff --git a/frontend/css/message.css b/frontend/css/message.css new file mode 100644 index 0000000000000000000000000000000000000000..4e7fabb1cf588f9c159198dbd47a41c6b3af4c3a --- /dev/null +++ b/frontend/css/message.css @@ -0,0 +1,199 @@ +/* message.css */ +/* 聊天消息区域样式 */ +.chat-messages { + flex-grow: 1; + overflow-y: auto; + padding: 20px; + background-color: #e8d6c5; +} + +.message { + display: flex; + margin-bottom: 20px; + gap: 10px; +} + +.message .icon { + width: 40px; + height: 40px; + border-radius: 50%; + overflow: hidden; + margin-right: 10px; + flex-shrink: 0; + flex-basis: 40px; + display: flex; + align-items: center; + justify-content: center; +} + +.message .icon img { + width: 100%; + height: 100%; + object-fit: cover; + min-width: 40px; + min-height: 40px; +} + +.message .content { + flex-grow: 1; + position: relative; +} + +.message .header { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 5px; +} + +.message .username { + color: #000000; + font-weight: bold; +} + +.message .timestamp { + color: #604d4c; + font-size: 0.8em; +} + +.message .text { + color: #000000; + line-height: 1.5; +} + +.message.system { + justify-content: center; + margin: 10px 0; +} + +.message.system .content { + background-color: rgba(255, 255, 255, 0.1); + padding: 5px 15px; + border-radius: 15px; +} + +.message.system .text { + color: #888; + font-size: 0.9em; + text-align: center; +} + +/* 底部输入区域样式 */ +.input-area { + background-color: #5f3d30; + padding: 10px; + display: flex; + gap: 10px; + border-top: 1px solid #3d3d3d; +} + +.input-area textarea { + flex-grow: 1; + background-color: #290000; + border: 1px solid #3a2626; + color: #e7e7e7; + padding: 10px; + resize: none; + border-radius: 4px; + min-height: 40px; +} + +.input-area button { + background: none; + border: none; + color: #e4d5ca; + cursor: pointer; + padding: 0 10px; +} + +.input-area button:hover { + color: #e7e7e7; +} + +.text-wrapper { + position: relative; +} + +.text { + padding: 5px; + border-radius: 4px; + transition: background-color 0.2s; +} + +.text.editing { + background-color: rgba(255, 255, 255, 0.9); + border: 1px solid #5f3737; + outline: none; + padding: 4px; + color: #000; +} + +.edit-buttons { + display: none; + gap: 8px; + margin-top: 8px; +} + +.edit-btn { + padding: 4px 12px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 0.9em; + transition: background-color 0.2s; +} + +.save-btn { + background-color: #5f3737; + color: white; +} + +.save-btn:hover { + background-color: #7a4747; +} + +.cancel-btn { + background-color: #ccc; + color: #333; +} + +.cancel-btn:hover { + background-color: #999; +} + +/* 确保系统消息不可编辑 */ +.message.system .text { + contenteditable: false; + pointer-events: none; +} + +.story-message { + background-color: #f5f5f5; + border-left: 4px solid #b44b43; + margin: 10px 0; + padding: 15px; +} + +.story-message .text { + white-space: pre-wrap; + line-height: 1.5; + color: #333; +} + +/* 添加编辑图标按钮样式 */ +.edit-icon { + position: absolute; + bottom: 5px; + right: 5px; + cursor: pointer; + opacity: 0; + transition: opacity 0.2s; + background: none; + border: none; + color: #5f3737; + padding: 5px; +} + +.message .content:hover .edit-icon { + opacity: 1; +} \ No newline at end of file diff --git a/frontend/css/right-section/api-panel.css b/frontend/css/right-section/api-panel.css new file mode 100644 index 0000000000000000000000000000000000000000..5a9874482cd5eda54acecc142532130dc8ddb84d --- /dev/null +++ b/frontend/css/right-section/api-panel.css @@ -0,0 +1,67 @@ +/* api-panel.css */ +.api-container { + display: flex; + flex-direction: column; + gap: 20px; + padding: 15px; +} + +.api-model-select, +.api-input-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.api-keys-container { + display: flex; + flex-direction: column; + gap: 15px; +} + +.api-key-input { + display: flex; + flex-direction: column; + gap: 8px; +} + +.api-key-input input { + padding: 8px; + border: 1px solid #5f3737; + border-radius: 4px; +} + +label { + color: #5f3737; + font-weight: bold; +} + +select { + padding: 8px; + border: 1px solid #5f3737; + border-radius: 4px; + background-color: white; +} + +.api-submit-btn { + padding: 10px; + background-color: #5f3737; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s; +} + +.api-submit-btn:hover { + background-color: #7a4747; +} + +.api-key-input .toggle-visibility { + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + cursor: pointer; + color: #5f3737; +} diff --git a/frontend/css/right-section/scene-panel.css b/frontend/css/right-section/scene-panel.css new file mode 100644 index 0000000000000000000000000000000000000000..6b1db0ce2abf73b6e68b6c5dffb81317ee8ed9da --- /dev/null +++ b/frontend/css/right-section/scene-panel.css @@ -0,0 +1,58 @@ +.scenes-container { + display: flex; + flex-direction: column; + gap: 15px; + padding: 15px; +} + +.scenes-header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.scenes-header h3 { + color: #5f3737; + margin: 0; +} + +.clear-selection-btn { + padding: 5px 10px; + background-color: #5f3737; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 0.9em; +} + +.clear-selection-btn:hover { + background-color: #7a4747; +} + +.scene-buttons { + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +.scene-btn { + padding: 8px 15px; + background-color: #fdf5ee; + border: 1px solid #5f3737; + border-radius: 4px; + color: #5f3737; + cursor: pointer; + transition: all 0.2s; +} + +.scene-btn:hover { + background-color: #5f3737; + color: white; +} + +.scene-btn.active { + background-color: #5f3737; + color: white; +} + diff --git a/frontend/css/right-section/settings-panel.css b/frontend/css/right-section/settings-panel.css new file mode 100644 index 0000000000000000000000000000000000000000..01fb6954179b44d7eb144e66e0001213b2d650ae --- /dev/null +++ b/frontend/css/right-section/settings-panel.css @@ -0,0 +1,30 @@ +/* settings-panel.css */ +.settings-container { + display: flex; + flex-direction: column; + gap: 15px; +} + +.setting-item { + padding: 15px; + background-color: white; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.setting-term { + font-weight: bold; + color: #5f3737; + margin-bottom: 5px; +} + +.setting-nature { + color: #666; + font-size: 0.9em; + margin-bottom: 8px; +} + +.setting-detail { + color: #333; + line-height: 1.4; +} diff --git a/frontend/css/right-section/status-panel.css b/frontend/css/right-section/status-panel.css new file mode 100644 index 0000000000000000000000000000000000000000..9d3b578f7e86f50c5bb8bfa777f289f59629cda7 --- /dev/null +++ b/frontend/css/right-section/status-panel.css @@ -0,0 +1,82 @@ +/* status-panel.css */ +.status-container { + display: flex; + flex-direction: column; + gap: 20px; +} + +.status-module { + background-color: white; + border-radius: 8px; + padding: 15px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.status-module h3 { + color: #5f3737; + margin: 0 0 10px 0; + font-size: 1.1em; + padding-bottom: 8px; + border-bottom: 2px solid #fdf5ee; +} + +.module-content { + font-size: 0.9em; +} + +/* 事件模块样式 */ +.event-text { + color: #5f3737; + line-height: 1.4; + display: flex; + align-items: center; +} + +/* 地点模块样式 */ +.location-name { + font-weight: bold; + color: #5f3737; + margin-bottom: 5px; +} + +.location-description { + color: #666; + line-height: 1.4; +} + +/* 分组模块样式 */ +.group-members { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.group-member { + background-color: #fdf5ee; + padding: 5px 10px; + border-radius: 15px; + font-size: 0.9em; + color: #5f3737; +} + +.no-members { + color: #666; + font-style: italic; +} + +/* 状态指示器 */ +.status-indicator { + width: 8px; + height: 8px; + border-radius: 50%; + margin-right: 8px; + display: inline-block; +} + +.status-active { + background-color: #4CAF50; +} + +.status-inactive { + background-color: #999; +} diff --git a/frontend/js/i18n.js b/frontend/js/i18n.js new file mode 100644 index 0000000000000000000000000000000000000000..e724f8a103c995d850d43fc23e16d0ca6c3b8303 --- /dev/null +++ b/frontend/js/i18n.js @@ -0,0 +1,97 @@ +const translations = { + en: { + start: "Start", + pause: "Pause", + stop: "Stop", + exportStory: "Export Story", + switchLang: "中/EN", + inputPlaceholder: "Enter your message", + status: "Status", + settings: "Settings", + scenes: "Scenes", + scenesList: "Scenes", + currentEvent: "Current Event", + currentLocation: "Current Location", + currentGroup: "Current Group", + map: "Map", + characterProfiles: "Character Profiles", + apiProvider: "API Provider:", + model: "Model:", + saveSettings: "Save Settings" + }, + zh: { + start: "开始", + pause: "暂停", + stop: "停止", + exportStory: "输出故事", + switchLang: "中/EN", + inputPlaceholder: "输入你的消息", + status: "状态", + settings: "设定", + scenes: "场景", + scenesList: "场景列表", + currentEvent: "当前事件", + currentLocation: "当前地点", + currentGroup: "当前分组", + map: "地图", + characterProfiles: "角色档案", + apiProvider: "API提供商:", + model: "模型:", + saveSettings: "保存设置" + } +}; + +class I18nManager { + constructor() { + this.currentLang = 'zh'; + this.init(); + } + + init() { + this.bindLanguageButton(); + this.updateTexts(); + } + + bindLanguageButton() { + const langBtn = document.getElementById('languageBtn'); + langBtn.addEventListener('click', () => { + this.currentLang = this.currentLang === 'zh' ? 'en' : 'zh'; + this.updateTexts(); + this.saveLanguagePreference(); + }); + } + + updateTexts() { + const elements = document.querySelectorAll('[data-i18n]'); + elements.forEach(element => { + const key = element.getAttribute('data-i18n'); + if (translations[this.currentLang][key]) { + element.textContent = translations[this.currentLang][key]; + } + }); + // 更新输入框占位符 + const textarea = document.querySelector('.input-area textarea'); + textarea.placeholder = translations[this.currentLang].inputPlaceholder; + + // 触发语言变更事件 + window.dispatchEvent(new CustomEvent('language-changed')); + } + + saveLanguagePreference() { + localStorage.setItem('preferredLanguage', this.currentLang); + } + + loadLanguagePreference() { + const savedLang = localStorage.getItem('preferredLanguage'); + if (savedLang) { + this.currentLang = savedLang; + this.updateTexts(); + } + } +} + +// 初始化语言管理器 +document.addEventListener('DOMContentLoaded', () => { + window.i18n = new I18nManager(); + window.i18n.loadLanguagePreference(); +}); \ No newline at end of file diff --git a/frontend/js/left-section/map-panel.js b/frontend/js/left-section/map-panel.js new file mode 100644 index 0000000000000000000000000000000000000000..659694c1a8b62377dc8ee6dad4f2707d2273e9ef --- /dev/null +++ b/frontend/js/left-section/map-panel.js @@ -0,0 +1,324 @@ +// map-script.js +class WorldMap { + constructor() { + // 示例地图数据 + this.defaultMapData = { + places: ["Unknown"], + distances: [ + ] + }; + + this.mapData = null; + this.selectedNode = null; + this.svg = null; + this.simulation = null; + this.container = null; + this.width = 0; + this.height = 0; + + this.init(); + } + + init() { + document.addEventListener('DOMContentLoaded', () => { + // 初始化地图容器 + this.initMapContainer(); + + // 监听窗口调整 + window.addEventListener('resize', () => this.handleResize()); + + // 先使用默认数据 + this.updateMap(this.defaultMapData); + + // 监听WebSocket消息 + window.addEventListener('websocket-message', (event) => { + const message = event.detail; + if (message.type === 'initial_data' && message.data.map) { + this.updateMap(message.data.map); + } + }); + }); + } + + initMapContainer() { + const container = document.getElementById('map-container'); + this.width = container.clientWidth; + this.height = container.clientHeight; + + // 创建缩放行为 + const zoom = d3.zoom() + .scaleExtent([0.8, 2]) + .on("zoom", (event) => this.zoomed(event)); + + // 创建SVG画布 + this.svg = d3.select("#map") + .append("svg") + .attr("width", this.width) + .attr("height", this.height) + .call(zoom); + + // 创建背景层 + const backgroundLayer = this.svg.append("g") + .attr("class", "background-layer"); + + // 加载背景图片 + this.loadBackgroundImage("./frontend/assets/images/fantasy-map.png", backgroundLayer); + + // 创建容器 + this.container = this.svg.append("g") + .attr("class", "nodes-container"); + } + + updateMap(mapData) { + this.mapData = mapData; + + // 准备数据 + const nodes = mapData.places.map(place => ({id: place})); + const links = mapData.distances.map(d => ({ + source: d.source, + target: d.target, + distance: d.distance + })); + + // 重置容器 + this.container.selectAll("*").remove(); + + // 创建力导向图 + this.simulation = d3.forceSimulation() + .force("link", d3.forceLink().id(d => d.id).distance(d => d.distance * 5)) + .force("charge", d3.forceManyBody().strength(-2000)) + .force("center", d3.forceCenter(this.width / 2, this.height / 2)) + .force("collision", d3.forceCollide().radius(40)); + + // 创建连线和节点 + this.createLinks(links); + this.createNodes(nodes); + + // 更新力导向图 + this.simulation + .nodes(nodes) + .on("tick", () => this.ticked()); + + this.simulation.force("link") + .links(links); + } + + zoomed(event) { + this.container.attr("transform", event.transform); + } + + createLinks(links) { + // 创建连线 + this.link = this.container.append("g") + .selectAll("line") + .data(links) + .enter() + .append("line") + .attr("class", "link"); + + // 创建距离标签 + this.distanceLabels = this.container.append("g") + .selectAll("text") + .data(links) + .enter() + .append("text") + .attr("class", "distance-label") + .text(d => d.distance) + .attr("stroke", "white") + .attr("stroke-width", "2px") + .attr("paint-order", "stroke"); + } + + createNodes(nodes) { + // 创建节点组 + this.node = this.container.append("g") + .selectAll(".node") + .data(nodes) + .enter() + .append("g") + .attr("class", "node") + .call(d3.drag() + .on("start", (event, d) => this.dragstarted(event, d)) + .on("drag", (event, d) => this.dragged(event, d)) + .on("end", (event, d) => this.dragended(event, d))) + .on("click", (event, d) => this.handleNodeClick(event, d)); + + // 添加节点圆形 + this.node.append("circle") + .attr("r", 20); + + // 添加节点文本 + this.node.append("text") + .attr("text-anchor", "middle") + .attr("dominant-baseline", "middle") + .text(d => this.formatNodeName(d.id)); + + this.node.append("title") + .text(d => d.id); + + // 创建弹出框 + if (!this.popup) { + this.popup = d3.select("body") + .append("div") + .attr("class", "popup") + .style("opacity", 0); + } + + // 添加全局点击事件 + d3.select("body").on("click", () => { + if (this.selectedNode) { + this.deselectNode(); + } + }); + } + + ticked() { + this.link + .attr("x1", d => d.source.x) + .attr("y1", d => d.source.y) + .attr("x2", d => d.target.x) + .attr("y2", d => d.target.y); + + this.distanceLabels + .attr("x", d => (d.source.x + d.target.x) / 2) + .attr("y", d => (d.source.y + d.target.y) / 2); + + this.node + .attr("transform", d => `translate(${d.x},${d.y})`); + } + + dragstarted(event, d) { + if (!event.active) this.simulation.alphaTarget(0.3).restart(); + d.fx = d.x; + d.fy = d.y; + } + + dragged(event, d) { + const transform = d3.zoomTransform(this.svg.node()); + d.fx = (event.x - transform.x) / transform.k; + d.fy = (event.y - transform.y) / transform.k; + } + + dragended(event, d) { + if (!event.active) this.simulation.alphaTarget(0); + d.fx = null; + d.fy = null; + } + + handleNodeClick(event, d) { + event.stopPropagation(); + + if (this.selectedNode === event.currentTarget) { + this.deselectNode(); + } else { + if (this.selectedNode) { + this.deselectNode(); + } + + this.selectedNode = event.currentTarget; + + d3.select(this.selectedNode) + .select("circle") + .classed("selected", true) + .transition() + .duration(200) + .attr("r", 30); + + this.link.transition() + .duration(200) + .style("stroke-opacity", l => + (l.source.id === d.id || l.target.id === d.id) ? 1 : 0.2 + ) + .style("stroke", l => + (l.source.id === d.id || l.target.id === d.id) ? "#ff0000" : "#999" + ); + + this.popup.transition() + .duration(200) + .style("opacity", .9); + + this.popup.html(` +
连接数: ${this.getConnectedLinks(d.id).length}
+相邻节点: ${this.getConnectedNodes(d.id).join(", ")}
+ `) + .style("left", (event.pageX + 10) + "px") + .style("top", (event.pageY - 10) + "px"); + } + } + + deselectNode() { + d3.select(this.selectedNode) + .select("circle") + .classed("selected", false) + .transition() + .duration(200) + .attr("r", 20); + + this.link.transition() + .duration(200) + .style("stroke-opacity", 0.6) + .style("stroke", "#999"); + + this.popup.transition() + .duration(200) + .style("opacity", 0); + + this.selectedNode = null; + } + + formatNodeName(name, maxLength = 3) { + if (name.length <= maxLength) return name; + + if (/^[\u4e00-\u9fa5]+$/.test(name)) { + return name.substring(0, maxLength - 1) + '…'; + } else { + return name.substring(0, maxLength) + '...'; + } + } + + getConnectedNodes(nodeId) { + return this.mapData.distances + .filter(l => l.source === nodeId || l.target === nodeId) + .map(l => l.source === nodeId ? l.target : l.source); + } + + getConnectedLinks(nodeId) { + return this.mapData.distances + .filter(l => l.source === nodeId || l.target === nodeId); + } + + loadBackgroundImage(url, backgroundLayer) { + const img = new Image(); + img.onload = () => { + const background = this.svg.append("image") + .attr("class", "map-background") + .attr("xlink:href", url) + .attr("width", this.width) + .attr("height", this.height); + backgroundLayer.append(() => background.node()); + }; + img.onerror = () => { + backgroundLayer.append("rect") + .attr("width", this.width) + .attr("height", this.height) + .attr("fill", "#f0f0f0"); + }; + img.src = url; + } + + handleResize() { + const container = document.getElementById('map-container'); + this.width = container.clientWidth; + this.height = container.clientHeight; + + this.svg + .attr('width', this.width) + .attr('height', this.height); + + this.simulation.force('center', d3.forceCenter(this.width / 2, this.height / 2)); + this.simulation.alpha(0.3).restart(); + } +} + +const worldMap = new WorldMap(); diff --git a/frontend/js/left-section/profile-panel.js b/frontend/js/left-section/profile-panel.js new file mode 100644 index 0000000000000000000000000000000000000000..7a62b63a8cd15e17673a83ab35d94cd31d7db11c --- /dev/null +++ b/frontend/js/left-section/profile-panel.js @@ -0,0 +1,148 @@ +// profile-script.js +class CharacterProfiles { + constructor() { + this.defaultCharacters = [ + { + id: 1, + name: 'Undefined', + icon: './frontend/assets/images/default-icon.jpg', + description: 'Undefined' + } + ]; + this.characters = this.defaultCharacters; + this.allCharacters = []; // 存储所有角色信息 + this.init(); + } + init() { + document.addEventListener('DOMContentLoaded', () => { + const container = document.querySelector('.profiles-container'); + if (!container) { + console.error('找不到角色档案容器元素'); + return; + } + + // 先渲染默认数据 + this.updateCharacters(this.defaultCharacters); + + // WebSocket消息处理 + window.addEventListener('websocket-message', (event) => { + const message = event.detail; + if (message.type === 'initial_data' && message.data.characters) { + this.updateCharacters(message.data.characters); + } + + if (message.type === 'scene_characters') { + // 处理服务器返回的场景角色数据 + this.updateCharacters(message.data, true); + } + + if (message.type === 'status_update' && message.data.characters) { + this.updateCharacters(message.data.characters); + } + + window.addEventListener('websocket-message', (event) => { + const message = event.detail; + + if (message.type === 'status_update') { + this.updateAllStatus(message.data); + } + + if (message.type === 'initial_data' && message.data.status) { + this.updateAllStatus(message.data.status); + } + }); + }); + + // 绑定点击事件 + container.addEventListener('click', (e) => this.handleCardClick(e)); + }); + } + createCharacterCard(character) { + const maxLength = 20; // 设置折叠时显示的最大字符数 + const needsExpand = character.description.length > maxLength; + const shortDesc = needsExpand ? character.description.substring(0, maxLength) + '...' : character.description; + + return ` +