Skip to content

Latest commit

 

History

History
145 lines (113 loc) · 9.01 KB

AGENTS.md

File metadata and controls

145 lines (113 loc) · 9.01 KB

AGENTS.md — RimMind-Personality

人格系统,LLM评估小人状态 → 注入人格Thought(最多3槽位)影响心情与行为。

Start here

先读 Source/README.md。通常只需继续打开请求 Comp、请求构建器、响应映射器、Profile、目标 Policy 或 Provider 注册器中的一条路径,不要从所有 Harmony Patch 开始搜索。

项目定位

每日定时(含确定性抖动)或事件触发(受伤/技能/事件/死亡) → ContextEngine(RequestStructured, SchemaRegistry.PersonalityOutput) → AI评估 → PersonalityThoughtMapper.Apply 解析 → 写入 PersonalityProfile(narrative+identity) → 生成 Thought_AIPersonality(最多3槽位) → MoodOffsetCalculator 查表影响心情。含玩家塑造投票(强化/抑制/忽略)、AgentIdentity注册、Bio页人格按钮、WorldComponent定期清理无效Profile。

依赖: Core(编译期),Personality上下文被Advisor/Dialogue通过Core系统自动消费。翻译自包含(事件触发key已迁入自身语言文件)。

构建

项 值
Target net48, C#9.0, Nullable enable
Output ../1.6/Assemblies/
Assembly RimMindPersonality
Harmony ID mcocdaa.RimMindPersonality
依赖 RimMindCore.dll, Krafs.Rimworld.Ref, Lib.Harmony.Ref, Newtonsoft.Json 13.0

源码结构

Source/
├── README.md                              入口到测试的运行时阅读地图
├── RimMindPersonalityMod.cs              组合根与设置入口
├── Personality/
│   ├── PersonalityProviderRegistrar.cs   Context 与 Agent Identity 注册
│   ├── PersonalityThoughtMapper.cs       核心: AI响应→Thought映射+塑造投票+EvaluationSchema
│   ├── PersonalityResultDto.cs           JSON DTO(无RimWorld依赖)
│   ├── Thought_AIPersonality.cs          自定义Thought(重写Label/MoodOffset/DurationTicks)
│   ├── MoodOffsetCalculator.cs           强度→心情偏移查表(-3~+3)
│   ├── ShapingAction.cs                  塑造投票枚举(替代字符串魔法值)
│   ├── PersonalityRequestBuilder.cs      共享请求信封构建器
│   ├── PersonalityContextScenarioPolicy.cs  人格上下文消费场景策略
│   ├── PersonalityContextText.cs         人格上下文格式化与截取纯函数
│   └── PawnResolver.cs                   共享Pawn查找辅助(按thingIDNumber)
├── Settings/
│   ├── AIPersonalitySettings.cs          17项设置(含4项时间参数)
│   └── PersonalitySettingsDrawer.cs      原生/Core设置页共享绘制实现
├── Data/
│   ├── PersonalityProfile.cs             人格档案(IExposable) + AIPersonalityWorldComponent(含定期清理)
│   └── ShapingRecord.cs                  玩家塑造记录
├── Comps/CompAIPersonality.cs            ThingComp(Tick触发/事件触发/TriggerEventType枚举)
├── UI/BioTabPersonalityPatch.cs + Dialog_PersonalityProfile.cs
├── Patches/
│   ├── AddCompToHumanlikePatch.cs        ThingDef.ResolveReferences Postfix注入Comp
│   ├── Patch_PersonalityInjury.cs        HediffSet.AddDirect Postfix(isBad+Severity>=0.2f+IsFreeNonSlaveColonist过滤)
│   ├── Patch_PersonalityDeath.cs         Pawn.Kill Postfix(检查DirectRelations)
│   ├── Patch_PersonalityIncident.cs      IncidentWorker.TryExecuteWorker Postfix(ThreatBig/ThreatSmall过滤)
│   ├── Patch_PersonalitySkill.cs         SkillRecord.Learn Prefix+Postfix(Harmony out int __state 捕获升级前等级 + __instance.Pawn)
│   └── PersonalityTriggerHelper.cs       共享Patch触发辅助(TriggerForPawn/TriggerForColonists)
└── Debug/PersonalityDebugActions.cs      8个Debug动作

触发机制

CompAIPersonality.CompTick: 基于概率的状态跃迁触发(Sunrise/Recreation/Skygaze/MoodSwing) + DailyInterval/JitterRange(基于thingIDNumber确定性抖动兜底) + 事件触发(eventCooldownTicks冷却)。

TriggerEventType枚举: Injury / Skill / Incident / Death / Sunrise / Recreation / Skygaze / MoodSwing

请求参数: Scenario=Personality (ScenarioRegistry defaultExcludeKeys: "combat_status"), MaxTokens=600, Temperature=0.8f

事件触发Patch过滤逻辑

Patch 过滤条件
Injury hediff.def.isBad != false + hediff.Severity >= 0.2f + PersonalityTriggerPolicy.IsEligible(pawn)
Skill __instance.Level > __state(Harmony Prefix out int __state 捕获升级前等级,通过 __instance.Pawn 与 RimMindPawnLookup.IsActiveSpawnedColonist 校验)
Incident def.category.defName == "ThreatBig" || "ThreatSmall"
Death pawn.relations.DirectRelations 包含 killedPawn

心情偏移查表

intensity -3 -2 -1 0 +1 +2 +3
MoodOffset -10 -3 -1 0 +1 +3 +10

MoodOffsetCalculator.CalcMoodOffset 自动clamp到[-3,+3]后查表。

PersonalityResultDto

thoughts[]: {type, label, description, intensity(-3~+3), duration_hours?}
narrative: string
identity?: {motivations[], traits[], core_values[]}

上下文注入

Provider 层级 场景 内容
personality_profile L3_State(0.25) Personality / Decision / Dialogue 人格档案(描述+工作倾向+社交倾向+AI叙事)
personality_state L3_State(0.20) Personality / Decision / Dialogue 当前活跃Thought列表(Slot_0/1/2)
personality_shaping L3_State(0.15) Personality / Decision / Dialogue 玩家塑造历史记录
personality_task L0_Static(0.95) 仅 Personality TaskInstruction
AgentIdentity Core注册 身份消费方 identity→motivations/traits/core_values

personality_profile / personality_state / personality_shaping / personality_task 均通过 RimMindAPI.MainThreadSnapshot.GetAsync 在主线程读取 Verse 状态与翻译,并通过 AIPersonalityWorldComponent.TryGet 只读查询 Profile(不在后台线程调用 GetOrCreate)。公开 Pawn Provider(personality.description、personality.work_tendencies、personality.social_tendencies、personality.ai_narrative、personality.shaping_history)同样使用 TryGet 与 PersonalityContextText.FormatHeaderedLines。

Profile清理

AIPersonalityWorldComponent.WorldComponentTick() 读档首帧初始化 _lastCleanupTick = ticksGame,此后每60000 tick(1游戏日)通过 CollectRetainedPawnIds() 与 PruneProfiles(_profiles, retainedIds) 执行:

  1. 收集所有存活殖民者(地图/远行队/运输舱)、地图内本派系殖民者/囚犯/奴隶、地图内未复活尸体 Corpse.InnerPawn,以及各派系被绑架列表 KidnappedPawnsListForReading 中仍存活的 Pawn ID(严禁遍历 WorldPawns.AllPawnsAlive)
  2. 在 _sync 锁保护下移除 _profiles 中不在保留集合内的条目

代码约定

  • Mod 入口只组合和转发;Provider 注册集中在 PersonalityProviderRegistrar,设置控件集中在 PersonalitySettingsDrawer
  • Thought槽位最多3个(SlotDefNames[3])
  • aiDescription 存档key为 "aiDesc"(非 "aiDescription",修改需向后兼容)
  • AIDecides 模式: duration_hours clamp到[1,24]
  • 翻译键前缀: RimMind.Personality.*
  • CompAIPersonality 状态跃迁描述(AwakeningDay/AwakeningNight/Dusk/ContemplationIdle/ContemplationSkygaze/Recreation/MoodShift)与 TriggerReason 包装均使用 RimMind.Personality.* 翻译键,带 .CanTranslate() 守卫与英文回退
  • Injury Patch 与 ShapingVote 回调均校验 PersonalityTriggerPolicy.IsEligible / RimMindPawnLookup.IsActiveSpawnedColonist
  • Skill Patch 使用 Harmony out int __state 传递升级前等级并直接读取 __instance.Pawn,无需静态字典或全图扫描
  • _compat1 字段仅消费旧存档 rimTalkSynced key,值不使用
  • ShapingAction 枚举替代 "reinforce"/"suppress"/"ignored" 字符串魔法值
  • PersonalityRequestBuilder 统一 CompAIPersonality 和 DebugActions 的请求构建
  • PawnResolver 统一 3 个 ContextProvider 的 Pawn 查找逻辑
  • PersonalityContextScenarioPolicy 统一人格状态在 Personality / Decision / Dialogue 三类场景的注入边界
  • PersonalityTriggerHelper 统一 4 个 Patch 的 "查Comp→TriggerEvent" 模式

操作边界

✅ 必须做

  • 新触发类型在 TriggerEventType 添加值 + TriggerEnabledMap 添加映射条目
  • 新设置项在 ExposeData + UI + 翻译键三处同步

⚠️ 先询问

  • 修改 MoodTable 心情偏移值
  • 修改每日抖动算法
  • 修改Patch触发过滤(如Injury调整严重度阈值)
  • 修改 _compat1 序列化(影响旧存档兼容)

🚫 绝对禁止

  • 后台线程调用 ThoughtMaker.MakeThought/TryGainMemory
  • 修改 "aiDesc" 存档key(破坏向后兼容)
  • 向Core注册Provider用旧API(用 ContextKeyRegistry.Register)
  • Skill Patch 中维护静态字典或全图扫描找 Pawn(已改用 Harmony __state 与 __instance.Pawn)
  • Context Provider 在主线程快照外直接读取 Verse/Pawn 状态或调用 GetOrCreate