# 桌宠攻略系统 · 亲密度设计文档(专业版) > 为 DSH 桌宠·角色扮演插件新增的「亲密度」子系统设计文档。 > 供实现/维护/后续扩展参考。 > 关联:`亲密度攻略_通俗版.md`(玩家向)。 --- ## 1. 概述与目标 把现有**一维关系阶段**(`computeStage()`:事件计数 → 5 档)升级为**亲密度系统**: - 三根轴:**好感(favor)/ 信任(trust)/ 心动(heart)**,各 0-100,内分三段 - **男友力(boyfriend)**:玩家自身四方面(靠谱/感性/情绪稳/上进),0-100 - **里程碑(milestones)**:关系升级的"关键时刻"事件表 - 三者**闭环联动**(见 §4),不是并列数值 **实现路线**:混合式。 - **AI 判断加减**(设计提议的路线B,避免写死规则表、防摸表刷分) - **代码硬控制**缩放/门槛/反哺(防 AI 乱给、保证"事件>日常") - 与现有「生命体征+商城经济」(过日子)子系统**并存、互不干扰**;与记忆/日记/心跳/看桌面复用同一状态与注入链路。 **目标**:攻略真实核心是"你真的懂她",而非让数字涨得慢。行为驱动、边际递减、负向真实、事件重于日常。 --- ## 2. 数据模型 存入角色档案(`character.json` 的 `state`),随角色独立、持久化、多实例以文件为基准。 ```js state.relation = { favor: 50, // 好感 0-100 trust: 40, // 信任 0-100 heart: 20, // 心动 0-100 } state.boyfriend = { reliability: 50, // 靠谱 empathy: 50, // 感性 stability: 50, // 情绪稳 ambition: 50, // 上进 } state.milestones = [] // 已触发里程碑 id 列表(如 ['m1','m2']) state.recentActs = [] // 最近行为素材:[{ act, time }],最多 8 条(供 AI 评审) state.relationSince = null // 该亲密度开始统计的时间 ``` ### 初始值按当前档位映射(迁移) | 当前档位 | favor | trust | heart | |---------|-------|-------|-------| | stranger | 30 | 20 | 10 | | acquaintance | 45 | 35 | 20 | | friend | 60 | 55 | 35 | | close_friend | 78 | 72 | 55 | | special | 90 | 85 | 75 | - heart 最低("急不得"),初始值反映"从陌生到恋人"的自然爬升。 - `loadState()` 合并补默认:老存档缺 `relation/boyfriend/milestones/recentActs` 时按上述映射初始化;`relationEnabled === false` 时跳过亲密度逻辑,仅保留旧 `computeStage` 行为。 --- ## 3. 三轴三档(段位) ```js function axisTier(value) { if (value <= 33) return 1 if (value <= 66) return 2 return 3 } ``` | 轴 | 一段 0-33 | 二段 34-66 | 三段 67-100 | |----|----------|-----------|------------| | 好感 | 疏离(客气有距离) | 亲近(会主动靠近) | 倾慕(满眼都是你) | | 信任 | 戒备(保留、不交底) | 放心(敢说心里话) | 依赖(把后背交给你) | | 心动 | 无感(只当同伴) | 在意(偶尔走神想你) | 心动(忍不住想起你) | **段位的作用**: 1. **表现层**:系统提示注入各轴段位 + 对应描述("她信任已到依赖,你失信一次掉得更狠")。 2. **门槛层**:里程碑 `req` 用段位表达(§4.2)。 3. **AI 判断依据**:roleplay_relation 前,AI 看到每轴几档,判断更精准。 --- ## 4. 联动引擎(核心) ### 4.1 男友力放大因子 ```js function boyfriendFactor() { const b = (reliability+empathy+stability+ambition) / 4 // 均值 0-100 return 0.6 + 0.8 * (b / 100) // → 0.6 ~ 1.4 } ``` - AI 返回**基础分**;代码缩放:加分 ×factor;减分 ×(1.6 − 0.6×factor)。 - 效果:男友力高 → 同样关心涨得多、负面掉得轻;男友力低 → 加分打折、减分更狠("再哄也没用")。 - 男友力单项按对应方面调节对应轴(靠谱↔信任、感性↔好感/心动、情绪稳↔信任、上进↔好感),由 AI 在 `boyfriend` 字段给出后,代码把对应方面并入影响。 ### 4.2 里程碑表(内置常量,req 用段位,reward 反哺) ```js const MILESTONES = [ { id:'m1', name:'第一次成功搭话', req:{favorTier:1}, reward:{favor:6} }, { id:'m2', name:'第一次记住她的喜好', req:{favorTier:2}, reward:{favor:5, trust:3} }, { id:'m3', name:'她难受时你陪在身边', req:{trustTier:2}, reward:{trust:8, favor:4} }, { id:'m4', name:'第一次守约', req:{trustTier:2}, reward:{trust:7, boyfriendReliability:5} }, { id:'m5', name:'她主动跟你分享心事', req:{favorTier:3, trustTier:2}, reward:{trust:8, favor:6, heart:3} }, { id:'m6', name:'一起经历过重要的事', req:{favorTier:3, trustTier:3}, reward:{favor:7, heart:4} }, { id:'m7', name:'约定的日子一起去…', req:{trustTier:3, heartTier:2}, reward:{trust:5, heart:8, boyfriendReliability:4} }, { id:'m8', name:'确认关系(预留)', req:{favorTier:3, trustTier:3, heartTier:3}, reward:{heart:10} }, ] ``` **触发链路**(代码校验,非纯 AI): 1. AI 在 `roleplay_relation.milestone` 申请触发某 id。 2. 代码用 `axisTier(当前值)` 校验 `req` **全部达标**。 3. 达标 → 写入 `state.milestones`(幂等:已触发不重复)、应用 `reward`(大额亲密度/男友力)、`pushStage('里程碑:…')`。 4. 不达标 → 返回带原因的提示(如"她还没完全信任你(信任一段/三档)"),AI 转达,不强求。 ### 4.3 心动前置锁 `heart` 只有在 `favor` 与 `trust` 的段位 ≥ 2 时才允许**正增**(防硬刷)。系统提示明确"心动是前两样攒够才冒出来的"。 --- ## 5. AI 判断层 ### 5.1 工具 `roleplay_relation` 并入每轮 `roleplay_remember`(同一次调用,省 token)。Schema: ```js { favor: -8..8, // 基础分,代码再按男友力缩放 trust: -8..8, heart: -8..8, boyfriend: { reliability: -8..8, empathy: -8..8, stability: -8..8, ambition: -8..8 }, milestone: 'm1'|'m2'|..., // 触发里程碑请求(可空) note: '为什么' // 理由,进演出区 } ``` - 硬约束:每项 |≤8|;代码缩放后仍 `clamp(0,100)`;heart 受 §4.3 锁;里程碑受 §4.2 校验。 - 男友力各轴同样 clamp;"涨得越来越慢/设上限"由 AI 依据系统提示的"边际递减"判断 + 代码 clamp 兜底。 ### 5.2 系统提示注入模板(每轮,`systemPrompt.section`) ``` 【关系】当前亲密度:好感 X(疏离/亲近/倾慕)· 信任 Y(戒备/放心/依赖)· 心动 Z(无感/在意/心动) 男友力:靠谱 A · 感性 B · 情绪稳 C · 上进 D 已触发里程碑:m1、m2…(共 n/8) 最近他做了:{recentActs 尾巴} 【关系判断规则】按"行为而非频率、事件重于日常、负向要真实"判断加减; 同一行为重复加成递减;心动需好感+信任达标才动;男友力是放大器(高则你更受用、低则再哄没用)。 ``` --- ## 6. 档位推导 ```js function relationStage() { const n = state.milestones.length // 档位由里程碑数 + 各轴段位下限决定(不是单纯数值) if (n >= 7 && favorTier>=3 && trustTier>=3 && heartTier>=3) return 'special' // 恋人 if (n >= 5 && favorTier>=3 && trustTier>=2) return 'close_friend' if (n >= 3 && favorTier>=2 && trustTier>=2) return 'friend' if (n >= 1 && favorTier>=2) return 'acquaintance' return 'stranger' } ``` - 复用现有 `STAGE_LABELS/STAGE_STYLES` 文案;旧 `computeStage()`(事件计数)降级为行为参考,不再直接决定档位。 - 档位显示在侧栏与系统提示「当前关系:」行。 --- ## 7. 行为埋点(素材) 在现有行为点写 `state.recentActs`(代码**不直接改亲密度**,只作 AI 评审素材): - 投喂(food)、照顾(care)、看桌面(look)、纪念日设置(anniversary)、开演(start)、送礼(gift)、打工(work)、守约/失约(对话中由 AI 判断并记录)。 - `recentActs` 保留最近 8 条 `{act, time}`;系统提示注入其尾巴。 --- ## 8. 前端 UI 侧栏「关系」区(角色头下方、养成状态区旁,复用 `.rp-stat-*` 渐变条样式): - 三轴渐变条 + **段位标签**(如「好感 · 亲近」):好感暖橙 / 信任薄荷 / 心动淡紫 - 男友力四小条(靠谱/感性/情绪稳/上进) - 里程碑进度(`里程 n/8` + 最近一条里程碑) - 关系档位行(陌生人 → 恋人) - 数据来自 `getState` 新增字段(15s 轮询刷新,无需新 RPC 端点) --- ## 9. 兼容与迁移 - **`relationEnabled` 开关**(settings,默认开):关闭后不注入关系、不显示关系区,回退到旧 `computeStage` 行为。 - **老存档**:缺 `relation/boyfriend/milestones/recentActs` → 按 §2 映射初始化。 - **切角色**:亲密度/男友力/里程碑随角色档案独立。 - **多实例**:与现有防串一致(deskpet/roleplay 双预设共用,以文件为基准读写)。 - **与"过日子"系统**:亲密度(她心)与生命体征/商城(生活)独立;`recentActs` 与 `unspoken` 并存。 --- ## 10. 测试与验收 1. `node --check` 全部;同步 deskpet/roleplay 预设与 `roleplay-persist` 备份。 2. 重启后侧栏出现关系区(亲密度条+段位标签+男友力+里程+档位)。 3. 对话中"A 记住了她的喜好" → `roleplay_relation` 记 favor + 请求 m2 → 校验 favor 二档 → 命中:favor 变化(含男友力放大)、`state.milestones` +m2、演出区见里程碑、档位/表现更新。 4. 连续重复同一行为 → AI 递减(提示生效);心动的正增在 favor/trust 不足时被拦。 5. 里程碑前置不足 → 返回"还差什么"、不记录。 6. 关闭 `relationEnabled` → 回退现有行为;重开恢复。 7. 更新 README / CHECKLIST / 打包 zip。 --- ## 11. 后续 - **表白/接受表白的时机判断**(心轴攒够 + 恰当时机):可加 `roleplay_confession` 判断流程;m8 预留。 - **里程碑事件表按角色人设定制**(流萤可换成她的专属事件,如"一起看晚霞""带她看星空")。 - **男友力与三根轴的克制边界**:如数据反馈"滚雪球",用更陡的 `boyfriendFactor` 上限或男友力增速限制。