From 307ad405ac2ef9a192c031e2d6e34e5aa3935de7 Mon Sep 17 00:00:00 2001 From: bridge Date: Tue, 18 Nov 2025 00:39:06 +0800 Subject: [PATCH] add long time memory --- src/classes/action/action.py | 29 +++++++++- src/classes/action/battle.py | 10 ++-- src/classes/action/breakthrough.py | 38 +++++++------ src/classes/avatar.py | 21 ++++---- src/classes/event.py | 12 ++++- src/classes/event_manager.py | 54 ++++++++++++++++++- src/classes/fortune.py | 4 +- src/classes/mutual_action/attack.py | 2 + src/classes/mutual_action/conversation.py | 9 ++-- src/classes/mutual_action/dual_cultivation.py | 12 +++-- src/classes/mutual_action/mutual_action.py | 17 +++--- src/classes/story_teller.py | 13 +++-- static/config.yml | 7 +-- 13 files changed, 167 insertions(+), 61 deletions(-) diff --git a/src/classes/action/action.py b/src/classes/action/action.py index 80c5263..90a462b 100644 --- a/src/classes/action/action.py +++ b/src/classes/action/action.py @@ -126,7 +126,34 @@ class ActualActionMixin(): 不一定是多个step,也有可能就一个step。 新接口:子类必须实现 can_start/start/step/finish。 + + 类变量: + - IS_MAJOR: 是否为大事(长期记忆),默认False(小事/短期记忆) """ + + # 默认为小事(短期记忆) + IS_MAJOR: bool = False + + def create_event(self, content: str, related_avatars=None) -> Event: + """ + 创建事件的辅助方法,自动带上is_major属性 + + Args: + content: 事件内容 + related_avatars: 相关角色ID列表 + + Returns: + Event对象,is_major根据当前Action的IS_MAJOR类变量设置 + """ + from src.classes.action.action import Action + # 获取当前类的IS_MAJOR属性 + is_major = self.__class__.IS_MAJOR if hasattr(self.__class__, 'IS_MAJOR') else False + return Event( + month_stamp=self.world.month_stamp, + content=content, + related_avatars=related_avatars, + is_major=is_major + ) @abstractmethod def can_start(self, **params) -> tuple[bool, str]: @@ -164,7 +191,7 @@ class TimedAction(DefineAction, ActualActionMixin): duration_months: int = 1 def step(self, **params) -> ActionResult: - if getattr(self, 'start_monthstamp', None) is None: + if not hasattr(self, 'start_monthstamp') or self.start_monthstamp is None: self.start_monthstamp = self.world.month_stamp self._execute(**params) done = (self.world.month_stamp - self.start_monthstamp) >= (self.duration_months - 1) diff --git a/src/classes/action/battle.py b/src/classes/action/battle.py index cfb0148..9215c24 100644 --- a/src/classes/action/battle.py +++ b/src/classes/action/battle.py @@ -15,6 +15,8 @@ class Battle(InstantAction): STORY_PROMPT: str | None = ( "不要出现具体血量、伤害点数或任何数值表达。" ) + # 战斗是大事(长期记忆) + IS_MAJOR: bool = True def _get_target(self, avatar_name: str): """ @@ -62,7 +64,7 @@ class Battle(InstantAction): rel_ids.append(target.id) except Exception: pass - event = Event(self.world.month_stamp, f"{self.avatar.name} 对 {target_name} 发起战斗(战斗力:{self.avatar.name} {int(s_att)} vs {target_name} {int(s_def)})", related_avatars=rel_ids) + event = Event(self.world.month_stamp, f"{self.avatar.name} 对 {target_name} 发起战斗(战斗力:{self.avatar.name} {int(s_att)} vs {target_name} {int(s_def)})", related_avatars=rel_ids, is_major=True) # 记录开始事件内容,供故事生成使用 self._start_event_content = event.content return event @@ -83,13 +85,13 @@ class Battle(InstantAction): rel_ids.append(t.id) except Exception: pass - result_event = Event(self.world.month_stamp, result_text, related_avatars=rel_ids) + result_event = Event(self.world.month_stamp, result_text, related_avatars=rel_ids, is_major=True) # 生成战斗小故事(同步调用,与其他动作保持一致) target = self._get_target(avatar_name) - start_text = getattr(self, "_start_event_content", "") or result_event.content + start_text = self._start_event_content if hasattr(self, '_start_event_content') else result_event.content story = StoryTeller.tell_from_actors(start_text, result_event.content, self.avatar, target, prompt=self.STORY_PROMPT) - story_event = Event(self.world.month_stamp, story, related_avatars=rel_ids) + story_event = Event(self.world.month_stamp, story, related_avatars=rel_ids, is_story=True) return [result_event, story_event] diff --git a/src/classes/action/breakthrough.py b/src/classes/action/breakthrough.py index 0e5e311..f13a6f5 100644 --- a/src/classes/action/breakthrough.py +++ b/src/classes/action/breakthrough.py @@ -30,6 +30,8 @@ class Breakthrough(TimedAction): PARAMS = {} # 冷却:突破应当有CD,避免连刷 ACTION_CD_MONTHS: int = 3 + # 突破是大事(长期记忆) + IS_MAJOR: bool = True # 保留类级常量声明,实际读取模块级配置 def calc_success_rate(self) -> float: @@ -65,8 +67,8 @@ class Breakthrough(TimedAction): # 记录结果用于 finish 事件 self._last_result = ( "success", - getattr(old_realm, "value", str(old_realm)), - getattr(new_realm, "value", str(new_realm)), + old_realm.value, + new_realm.value, ) else: # 突破失败:减少最大寿元上限 @@ -100,12 +102,11 @@ class Breakthrough(TimedAction): return (ok, "" if ok else "当前不处于瓶颈,无法突破") def start(self) -> Event: - # 清理状态 + # 初始化状态 self._last_result = None self._success_rate_cached = None # 预判是否生成故事与选择劫难 old_realm = self.avatar.cultivation_progress.realm - # 仅基于出发境界判断是否生成故事 self._gen_story = old_realm in ALLOW_STORY_FROM_REALMS if self._gen_story: self._calamity = TribulationSelector.choose_tribulation(self.avatar) @@ -113,36 +114,33 @@ class Breakthrough(TimedAction): else: self._calamity = None self._calamity_other = None - return Event(self.world.month_stamp, f"{self.avatar.name} 开始尝试突破境界", related_avatars=[self.avatar.id]) + return Event(self.world.month_stamp, f"{self.avatar.name} 开始尝试突破境界", related_avatars=[self.avatar.id], is_major=True) # TimedAction 已统一 step 逻辑 def finish(self) -> list[Event]: - res = getattr(self, "_last_result", None) - if not (isinstance(res, tuple) and res): + if not self._last_result: return [] - result_ok = res[0] == "success" - if not getattr(self, "_gen_story", False): + result_ok = self._last_result[0] == "success" + if not self._gen_story: # 不生成故事:不出现劫难,仅简单结果 core_text = f"{self.avatar.name} 突破{'成功' if result_ok else '失败'}" - return [Event(self.world.month_stamp, core_text, related_avatars=[self.avatar.id])] + return [Event(self.world.month_stamp, core_text, related_avatars=[self.avatar.id], is_major=True)] - calamity = getattr(self, "_calamity", "劫难") + calamity = self._calamity core_text = f"{self.avatar.name} 遭遇了{calamity}劫难,突破{'成功' if result_ok else '失败'}" rel_ids = [self.avatar.id] - other = getattr(self, "_calamity_other", None) - if other is not None: + if self._calamity_other is not None: try: - rel_ids.append(other.id) + rel_ids.append(self._calamity_other.id) except Exception: pass - events: list[Event] = [Event(self.world.month_stamp, core_text, related_avatars=rel_ids)] + events: list[Event] = [Event(self.world.month_stamp, core_text, related_avatars=rel_ids, is_major=True)] - if True: - # 故事参与者:本体 +(可选)相关角色 - prompt = TribulationSelector.get_story_prompt(str(calamity)) - story = StoryTeller.tell_from_actors(core_text, ("突破成功" if result_ok else "突破失败"), self.avatar, getattr(self, "_calamity_other", None), prompt=prompt) - events.append(Event(self.world.month_stamp, story, related_avatars=rel_ids)) + # 故事参与者:本体 +(可选)相关角色 + prompt = TribulationSelector.get_story_prompt(str(calamity)) + story = StoryTeller.tell_from_actors(core_text, ("突破成功" if result_ok else "突破失败"), self.avatar, self._calamity_other, prompt=prompt) + events.append(Event(self.world.month_stamp, story, related_avatars=rel_ids, is_story=True)) return events diff --git a/src/classes/avatar.py b/src/classes/avatar.py index 253bc6b..cda016f 100644 --- a/src/classes/avatar.py +++ b/src/classes/avatar.py @@ -241,7 +241,6 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin): spirit_animal_info = self.spirit_animal.get_info() if self.spirit_animal is not None else "无" info_dict = { - "id": self.id, "名字": self.name, "性别": str(self.gender), "年龄": str(self.age), @@ -509,12 +508,11 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin): 添加事件: - to_sidebar: 是否进入全局侧边栏(通过 Avatar._pending_events 暂存) - to_history: 兼容参数,已废弃(统一改为通过 World.event_manager 查询历史) + + 注意:事件会先存入_pending_events,统一由Simulator写入event_manager,避免重复 """ if to_sidebar: self._pending_events.append(event) - # 侧边栏类事件通常不在 Simulator 的 events 列表里,直接记入全局事件管理器 - em = self.world.event_manager - em.add_event(event) def get_action_space_str(self) -> str: action_space = self.get_action_space() @@ -547,14 +545,19 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin): for other in co_region_avatars[:8]: observed.append(f"{other.name},境界:{other.cultivation_progress.get_info()}") - # 历史事件改为从全局事件管理器查询 - n = CONFIG.social.event_context_num + # 历史事件改为从全局事件管理器分类查询 em = self.world.event_manager - events = em.get_events_by_avatar(self.id, limit=n) - history_list = [str(e) for e in events] + major_limit = CONFIG.social.major_event_context_num + minor_limit = CONFIG.social.minor_event_context_num + major_events = em.get_major_events_by_avatar(self.id, limit=major_limit) + minor_events = em.get_minor_events_by_avatar(self.id, limit=minor_limit) + + major_list = [str(e) for e in major_events] + minor_list = [str(e) for e in minor_events] info["观察到的角色"] = observed - info["历史事件"] = history_list + info["长期记忆"] = major_list + info["短期记忆"] = minor_list return info def get_hover_info(self) -> list[str]: diff --git a/src/classes/event.py b/src/classes/event.py index a42f21e..ed4b49e 100644 --- a/src/classes/event.py +++ b/src/classes/event.py @@ -12,6 +12,10 @@ class Event: content: str # 相关角色ID列表;若与任何角色无关则为 None related_avatars: Optional[List[str]] = None + # 是否为大事(长期记忆),默认False(小事/短期记忆) + is_major: bool = False + # 是否为故事事件(不进入记忆索引),默认False + is_story: bool = False def __str__(self) -> str: year = self.month_stamp.get_year() @@ -23,7 +27,9 @@ class Event: return { "month_stamp": int(self.month_stamp), "content": self.content, - "related_avatars": self.related_avatars + "related_avatars": self.related_avatars, + "is_major": self.is_major, + "is_story": self.is_story } @classmethod @@ -32,7 +38,9 @@ class Event: return cls( month_stamp=MonthStamp(data["month_stamp"]), content=data["content"], - related_avatars=data.get("related_avatars") + related_avatars=data.get("related_avatars"), + is_major=data.get("is_major", False), + is_story=data.get("is_story", False) ) class NullEvent: diff --git a/src/classes/event_manager.py b/src/classes/event_manager.py index e5fed99..aba7ec4 100644 --- a/src/classes/event_manager.py +++ b/src/classes/event_manager.py @@ -20,6 +20,12 @@ class EventManager: self._by_id: Dict[str, Event] = {} self._by_avatar: Dict[str, deque[Event]] = defaultdict(deque) self._by_pair: Dict[frozenset[str], deque[Event]] = defaultdict(deque) + # 按角色分类的大事/小事索引 + self._by_avatar_major: Dict[str, deque[Event]] = defaultdict(deque) + self._by_avatar_minor: Dict[str, deque[Event]] = defaultdict(deque) + # 按角色对分类的大事/小事索引 + self._by_pair_major: Dict[frozenset[str], deque[Event]] = defaultdict(deque) + self._by_pair_minor: Dict[frozenset[str], deque[Event]] = defaultdict(deque) def _append_with_limit(self, dq: deque, item: Event) -> None: dq.append(item) @@ -39,15 +45,29 @@ class EventManager: self._events.popleft() # 分索引:按人/人对 - rel = getattr(event, "related_avatars", None) or [] + rel = event.related_avatars or [] rel_unique = list(dict.fromkeys(rel)) # 去重但保持顺序 for aid in rel_unique: self._append_with_limit(self._by_avatar[aid], event) - # 仅当且仅当“恰有两位参与者”时建立按人对索引 + # 故事事件进入小事索引,不进入大事索引 + if event.is_story: + self._append_with_limit(self._by_avatar_minor[aid], event) + elif event.is_major: + self._append_with_limit(self._by_avatar_major[aid], event) + else: + self._append_with_limit(self._by_avatar_minor[aid], event) + # 仅当且仅当"恰有两位参与者"时建立按人对索引 if len(rel_unique) == 2: a, b = rel_unique[0], rel_unique[1] pair_key = frozenset([a, b]) self._append_with_limit(self._by_pair[pair_key], event) + # 角色对也建立分类索引 + if event.is_story: + self._append_with_limit(self._by_pair_minor[pair_key], event) + elif event.is_major: + self._append_with_limit(self._by_pair_major[pair_key], event) + else: + self._append_with_limit(self._by_pair_minor[pair_key], event) # —— 查询接口 —— def get_recent_events(self, limit: int = 100) -> List[Event]: @@ -68,4 +88,34 @@ class EventManager: return [] return list(dq)[-limit:] + def get_major_events_by_avatar(self, avatar_id: str, *, limit: int = 10) -> List[Event]: + """获取角色的大事(长期记忆)""" + dq = self._by_avatar_major.get(avatar_id) + if not dq: + return [] + return list(dq)[-limit:] + + def get_minor_events_by_avatar(self, avatar_id: str, *, limit: int = 10) -> List[Event]: + """获取角色的小事(短期记忆)""" + dq = self._by_avatar_minor.get(avatar_id) + if not dq: + return [] + return list(dq)[-limit:] + + def get_major_events_between(self, avatar_id1: str, avatar_id2: str, *, limit: int = 10) -> List[Event]: + """获取两个角色之间的大事(长期记忆)""" + key = frozenset([avatar_id1, avatar_id2]) + dq = self._by_pair_major.get(key) + if not dq: + return [] + return list(dq)[-limit:] + + def get_minor_events_between(self, avatar_id1: str, avatar_id2: str, *, limit: int = 10) -> List[Event]: + """获取两个角色之间的小事(短期记忆)""" + key = frozenset([avatar_id1, avatar_id2]) + dq = self._by_pair_minor.get(key) + if not dq: + return [] + return list(dq)[-limit:] + diff --git a/src/classes/fortune.py b/src/classes/fortune.py index 03e8d42..b39bdc2 100644 --- a/src/classes/fortune.py +++ b/src/classes/fortune.py @@ -475,11 +475,11 @@ async def try_trigger_fortune(avatar: Avatar) -> list[Event]: story_prompt = "请据此写100~150字小故事。" month_at_finish = avatar.world.month_stamp - base_event = Event(month_at_finish, event_text, related_avatars=related_avatars) + base_event = Event(month_at_finish, event_text, related_avatars=related_avatars, is_major=True) # 生成故事事件 story = await StoryTeller.tell_from_actors_async(event_text, res_text, *actors_for_story, prompt=story_prompt) - story_event = Event(month_at_finish, story, related_avatars=related_avatars) + story_event = Event(month_at_finish, story, related_avatars=related_avatars, is_story=True) # 返回基础事件和故事事件 return [base_event, story_event] diff --git a/src/classes/mutual_action/attack.py b/src/classes/mutual_action/attack.py index 10af7ba..434fa56 100644 --- a/src/classes/mutual_action/attack.py +++ b/src/classes/mutual_action/attack.py @@ -20,6 +20,8 @@ class Attack(MutualAction): STORY_PROMPT: str = "" # 攻击冷却:避免同月连刷攻击 ACTION_CD_MONTHS: int = 3 + # 攻击是大事(长期记忆) + IS_MAJOR: bool = True def _can_start(self, target: "Avatar") -> tuple[bool, str]: """攻击无额外检查条件""" diff --git a/src/classes/mutual_action/conversation.py b/src/classes/mutual_action/conversation.py index cdf507e..b3b1752 100644 --- a/src/classes/mutual_action/conversation.py +++ b/src/classes/mutual_action/conversation.py @@ -54,10 +54,13 @@ class Conversation(MutualAction): # 可能取消的关系 possible_cancel_relations = [relation_display_names[r] for r in get_possible_cancel_relations(target_avatar, self.avatar)] - # 历史上下文:仅双方共同经历的最近事件 - n = CONFIG.social.event_context_num + # 历史上下文:仅双方共同经历的大事和小事 + major_limit = CONFIG.social.major_event_context_num + minor_limit = CONFIG.social.minor_event_context_num em = self.world.event_manager - pair_recent_events = [str(e) for e in em.get_events_between(self.avatar.id, target_avatar.id, limit=n)] + major_events = em.get_major_events_between(self.avatar.id, target_avatar.id, limit=major_limit) + minor_events = em.get_minor_events_between(self.avatar.id, target_avatar.id, limit=minor_limit) + pair_recent_events = [str(e) for e in major_events + minor_events] return { "avatar_infos": avatar_infos, "avatar_name_1": avatar_name_1, diff --git a/src/classes/mutual_action/dual_cultivation.py b/src/classes/mutual_action/dual_cultivation.py index 5bc7317..7d9b2b5 100644 --- a/src/classes/mutual_action/dual_cultivation.py +++ b/src/classes/mutual_action/dual_cultivation.py @@ -22,7 +22,7 @@ class DualCultivation(MutualAction): - 仅当目标在交互范围内 - 目标可以选择 接受 或 拒绝 - 若接受:发起者获得大量修为(约为修炼的 3~5 倍,随对方等级浮动),目标不获得修为 - - 成功进入后生成一段“恋爱/双修”的小故事 + - 成功进入后生成一段"恋爱/双修"的小故事 """ ACTION_NAME = "双修" @@ -34,6 +34,8 @@ class DualCultivation(MutualAction): STORY_PROMPT: str | None = "两位修士在双修过程中情愫暗生,以含蓄、雅致的文字描绘一段暧昧而不露骨的双修体验,体现彼此性格、境界差异与甜蜜的恋爱时光。不要体现经验的数值。" # 双修的社交冷却:避免频繁请求 ACTION_CD_MONTHS: int = 3 + # 双修是大事(长期记忆) + IS_MAJOR: bool = True def _get_template_path(self) -> Path: # 复用 mutual_action 模板,仅需返回 Accept/Reject @@ -53,7 +55,7 @@ class DualCultivation(MutualAction): rel_ids = [self.avatar.id] if target is not None: rel_ids.append(target.id) - event = Event(self.world.month_stamp, f"{self.avatar.name} 邀请 {target_name} 进行双修", related_avatars=rel_ids) + event = Event(self.world.month_stamp, f"{self.avatar.name} 邀请 {target_name} 进行双修", related_avatars=rel_ids, is_major=True) # 仅写入历史 self.avatar.add_event(event, to_sidebar=False) if target is not None: @@ -104,17 +106,17 @@ class DualCultivation(MutualAction): if success: gain = int(self._dual_exp_gain) result_text = f"{self.avatar.name} 与 {target.name} 成功双修,{self.avatar.name} 获得修为经验 +{gain} 点" - result_event = Event(self.world.month_stamp, result_text, related_avatars=[self.avatar.id, target.id]) + result_event = Event(self.world.month_stamp, result_text, related_avatars=[self.avatar.id, target.id], is_major=True) events.append(result_event) # 生成恋爱/双修小故事:使用 StoryTeller 便捷方法 start_text = self._start_event_content or result_event.content story = StoryTeller.tell_from_actors(start_text, result_event.content, self.avatar, target, prompt=self.STORY_PROMPT) - story_event = Event(self.world.month_stamp, story, related_avatars=[self.avatar.id, target.id]) + story_event = Event(self.world.month_stamp, story, related_avatars=[self.avatar.id, target.id], is_story=True) events.append(story_event) else: result_text = f"{target.name} 拒绝了与 {self.avatar.name} 的双修" - result_event = Event(self.world.month_stamp, result_text, related_avatars=[self.avatar.id, target.id]) + result_event = Event(self.world.month_stamp, result_text, related_avatars=[self.avatar.id, target.id], is_major=True) events.append(result_event) return events diff --git a/src/classes/mutual_action/mutual_action.py b/src/classes/mutual_action/mutual_action.py index 1019594..4b178b8 100644 --- a/src/classes/mutual_action/mutual_action.py +++ b/src/classes/mutual_action/mutual_action.py @@ -66,12 +66,13 @@ class MutualAction(DefineAction, LLMAction, TargetingMixin): avatar_name_1: self.avatar.get_info(detailed=False), avatar_name_2: target_avatar.get_info(detailed=False), } - # 历史上下文:仅双方共同经历的最近事件 - n = CONFIG.social.event_context_num - - pair_recent_events: list[str] = [] + # 历史上下文:仅双方共同经历的大事和小事 + major_limit = CONFIG.social.major_event_context_num + minor_limit = CONFIG.social.minor_event_context_num em = self.world.event_manager - pair_recent_events = [str(e) for e in em.get_events_between(self.avatar.id, target_avatar.id, limit=n)] + major_events = em.get_major_events_between(self.avatar.id, target_avatar.id, limit=major_limit) + minor_events = em.get_minor_events_between(self.avatar.id, target_avatar.id, limit=minor_limit) + pair_recent_events = [str(e) for e in major_events + minor_events] feedback_actions = self.FEEDBACK_ACTIONS comment = self.COMMENT action_name = self.ACTION_NAME @@ -189,11 +190,13 @@ class MutualAction(DefineAction, LLMAction, TargetingMixin): """ target = self._get_target_avatar(target_avatar) target_name = target.name if target is not None else str(target_avatar) - action_name = getattr(self, 'ACTION_NAME', self.name) + action_name = self.ACTION_NAME rel_ids = [self.avatar.id] if target is not None: rel_ids.append(target.id) - event = Event(self.world.month_stamp, f"{self.avatar.name} 对 {target_name} 发起 {action_name}", related_avatars=rel_ids) + # 根据IS_MAJOR类变量设置事件类型 + is_major = self.__class__.IS_MAJOR if hasattr(self.__class__, 'IS_MAJOR') else False + event = Event(self.world.month_stamp, f"{self.avatar.name} 对 {target_name} 发起 {action_name}", related_avatars=rel_ids, is_major=is_major) # 仅写入历史,避免与提交阶段重复推送到侧边栏 self.avatar.add_event(event, to_sidebar=False) if target is not None: diff --git a/src/classes/story_teller.py b/src/classes/story_teller.py index 390247a..4bb9987 100644 --- a/src/classes/story_teller.py +++ b/src/classes/story_teller.py @@ -47,7 +47,8 @@ class StoryTeller: @staticmethod def _collect_recent_events(*actors: "Avatar") -> list[str]: from src.utils.config import CONFIG as _CONFIG - n = _CONFIG.social.event_context_num + major_limit = _CONFIG.social.major_event_context_num + minor_limit = _CONFIG.social.minor_event_context_num world = None for av in actors: if av is not None: @@ -58,11 +59,17 @@ class StoryTeller: em = world.event_manager non_null = [a for a in actors if a is not None] if len(non_null) >= 2: + # 两人故事:获取两人的大事和小事 a1, a2 = non_null[0], non_null[1] - return [str(e) for e in em.get_events_between(a1.id, a2.id, limit=n)] + major_events = em.get_major_events_between(a1.id, a2.id, limit=major_limit) + minor_events = em.get_minor_events_between(a1.id, a2.id, limit=minor_limit) + return [str(e) for e in major_events + minor_events] if non_null: + # 单人故事:获取单人的大事和小事 a = non_null[0] - return [str(e) for e in em.get_events_by_avatar(a.id, limit=n)] + major_events = em.get_major_events_by_avatar(a.id, limit=major_limit) + minor_events = em.get_minor_events_by_avatar(a.id, limit=minor_limit) + return [str(e) for e in major_events + minor_events] return [] @staticmethod diff --git a/static/config.yml b/static/config.yml index b5dd8be..3511bf6 100644 --- a/static/config.yml +++ b/static/config.yml @@ -18,8 +18,8 @@ ai: max_parse_retries: 3 game: - init_npc_num: 12 - sect_num: 3 # init_npc_num大于sect_num时,会随机选择sect_num个宗门 + init_npc_num: 6 + sect_num: 2 # init_npc_num大于sect_num时,会随机选择sect_num个宗门 npc_birth_rate_per_month: 0.001 fortune_probability: 0.001 @@ -30,7 +30,8 @@ avatar: persona_num: 3 social: - event_context_num: 8 + major_event_context_num: 10 # 大事(长期记忆)展示数量 + minor_event_context_num: 10 # 小事(短期记忆)展示数量 save: max_events_to_save: 1000