# 冒险运行时开发经验沉淀 日期:2026-03-24 ## 1. 这轮工作主要覆盖了什么 这轮迭代不是单点 UI 修改,而是同时改了 4 条链路: 1. 战斗演绎链路:近战突进、远程施法、投射物/特效、受击结算时机。 2. 探索链路:向前探索、呼喊、NPC 离队、切换场景时的新 encounter 生成与入场动画。 3. NPC function 链路:聊天、招募、观察征兆、交易、离队、上下文注入边界。 4. 面板链路:队伍页、角色详情、背包页、移动端空间分配、入口 icon 语义。 这类项目最重要的判断是: 很多需求表面看是“改个界面”或“改句文案”,实际同时影响状态机、动画时序、AI 提示词、实体生成规则和移动端布局。 ## 2. 这轮最值得沉淀的结论 ### 2.1 function 的职责边界必须先定死 后面事实证明,只有少数 function 应该负责生成新 encounter: - `idle_explore_forward` - `idle_call_out` - `npc_leave` - 进入新场景 其他 function 如果也偷偷新增 NPC、怪物、宝箱,后面一定会出现这些问题: - 剧情上下文越来越乱 - 场景上实体数量失控 - 玩家以为“聊天/招募/观察”也会强行推进世界 - AI 生成内容和本地规则互相打架 经验: 先定义“谁能创造世界实体”,再写文案和动画。 ### 2.2 动画完成点必须和数值结算点绑定 这轮一个关键修正是: 攻击特效播放完后,受击目标才扣血。 如果不这样做,玩家看到的就是: - 特效还没打到,血条先掉了 - 投射物还在飞,目标已经结算 - dash 还没到位,攻击已经命中 经验: 战斗系统里不能只写“播放动画”,必须写清楚: 1. 起手阶段是什么 2. 位移阶段是什么 3. 命中阶段是什么 4. 哪个阶段结束后才改数值 ### 2.3 视觉素材选择要按“语义 + 小尺寸可读性”来做 这轮做过两类视觉判断: - 战斗特效素材该怎么挂到角色/技能上 - 冒险页入口 icon 应该换成什么 经验不是“素材越花越好”,而是: - 先看素材本身表达的动作语义 - 再看缩小到按钮尺寸后是否还能一眼看懂 - 最后才考虑风格统一 例如: - 队伍入口用“盔甲”不如用“盾牌”更像角色/编队 - 背包入口用真正的包袋图,比木板式 HUD 图更直观 - 远程施法不移动时,特效就必须承担“动作已经发生”的视觉职责 ### 2.4 角色型 NPC 和普通 encounter 不能混着处理 这轮踩过的坑说明: - 可扮演但未入队的 NPC - 已入队同伴 - 普通场景 NPC 这三者虽然都可能显示为 NPC,但数据完整度、立绘来源、详情页能力并不一样。 经验: - 角色型 NPC 要按角色数据链路渲染 - 普通 NPC 要按 encounter/NPC state 渲染 - 详情弹窗必须对缺失字段做空值保护 否则就会出现点击小人直接报 `map` 相关错误这类问题。 ### 2.5 角色和同伴的朝向/位移必须彼此独立 `idle_observe_signs` 的修正说明了一件事: 如果主角和同伴在 transform、朝向、随机停顿上仍然存在隐含父子级关系,最后视觉表现一定不自然。 经验: - 主角随机转向和同伴随机转向要分别计算 - 位置、朝向、停留时长都要独立采样 - 不要让父容器顺手把子角色的朝向也带过去 这条经验同样适用于: - 招募入队时的新同伴 dash - 多角色待机观察 - 场景内多实体同步演绎 ### 2.6 大模型负责“推理与叙述”,本地规则负责“世界变更” 这轮对 `npc_chat`、`npc_recruit`、`idle_observe_signs` 的调整,本质上都指向同一个原则: - 大模型可以生成观察结果、聊天内容、氛围描述 - 大模型不应该偷偷新增实体、替玩家做决定、绕开本地规则结算 经验: 1. 聊天生成要明确禁止提及其他 function 行为。 2. 招募对话可以引导到成功入队,但最终入队仍应由本地流程触发。 3. `idle_observe_signs` 可以走大模型推理,但写入剧情上下文的内容要可控。 4. `npc_recruit` 这种流程不要顺手给下次推理塞一个“新 NPC”。 一句话总结: AI 可以解释世界,但不能私自改世界。 ### 2.7 移动端面板要优先保信息密度,不要保装饰 这轮背包和队伍页的调整很能说明问题: - 队伍页只保留成员列表 - 成员详情放到弹窗 - 背包页去掉多余标题、提示文案、厚重背景框 - 装备信息移到角色详情,不和背包抢空间 经验: - 主面板只放“高频扫读信息” - 低频详情放二级弹窗 - 任何重复信息都要尽量去重 在小屏上,空间不是拿来“显得完整”的,而是拿来“保证可操作”的。 ## 3. 这轮最典型的踩坑记录 ### 3.1 encounter 生成距离只改一处是不够的 一开始只是把某个函数里的怪物生成位置往后挪,但后来发现: - 其他会生成 encounter 的 function 仍然太近 - 新场景进入时也可能直接出现在屏幕里 经验: “从屏幕外进场、要走 4 秒距离”必须是统一约束,不是某个函数里的特判。 ### 3.2 详情文案改源头不一定等于改到了最终显示层 这轮“选项小字太长”的问题最后证明: 真正该改的是渲染层显示的 `detailText`,而不是只改某个上游数据源。 经验: 用户说“没有生效”时,要优先检查最终渲染层,而不是只检查中间数据。 ### 3.3 新同伴入队时,尺寸问题本质是缩放基准不统一 招募流程里位置正确但大小不对,说明问题不在路径,而在: - 新同伴使用的缩放基准 - 主角扮演角色使用的缩放基准 不一致。 经验: 只要角色加入到主队镜头体系里,尺寸基准必须复用主角/同伴那套规则,不能临时另开一套。 ### 3.4 背包和角色详情职责不清,会持续挤压移动端布局 这轮背包页一度同时承担: - 物品网格 - 装备总览 - 装备卸下 - 详情查看 最后结果就是移动端空间不够、信息层级混乱。 经验: - 背包负责“物品” - 角色详情负责“装备” 职责一旦分清,后面很多 UI 冲突会自然消失。 ## 4. 可复用的开发方法 ### 4.1 新增一个 function 前,先问 6 个问题 1. 它会不会生成新 encounter? 2. 它会不会写入后续推理上下文? 3. 它的动画分几段? 4. 哪一刻才算真正生效? 5. 哪些内容由 AI 生成,哪些必须本地决定? 6. 它是否需要从屏幕外入场? 这 6 个问题先答清,后面返工会少很多。 ### 4.2 配战斗动画时,至少明确 4 个时点 1. 起手 2. 位移/施法 3. 特效命中 4. 扣血/击退/结算 特别是: - 近战攻击前的 dash - 远程不移动但要挂特效 - 受击延后到命中特效之后 都属于这套时点设计。 ### 4.3 做素材替换时,不要只看资源名 正确顺序更接近: 1. 打开素材看实际形状 2. 判断它在当前语义里是不是“最像这个功能” 3. 缩到真实 UI 尺寸再看一遍 4. 再决定 active/inactive 怎么处理 ### 4.4 做聊天流式界面时,反馈一定要插到正在发生的流里 这轮加“好感度 +x”提示后,更明确了一件事: - 系统反馈不应该只藏在最终结果 - 要插进聊天进行中的体验里 - 文本流超出剧情框时要自动滚动 否则用户会错过真正重要的状态变化。 ## 5. 以后继续做这类需求时,建议坚持的原则 - 先收拢 function 边界,再改剧情文案。 - 先确定动画结算时序,再接特效素材。 - 先做本地规则兜底,再让大模型生成文本。 - 先保证移动端可扫读,再考虑装饰性面板。 - 先复用已有角色/场景坐标体系,再做个别修正。 - 先看最终显示层,再判断“改动是否生效”。 ## 6. 这轮最重要的一句话总结 这类 AI 冒险 RPG 的开发,最难的不是“把功能做出来”,而是: **让 function 边界、世界状态、视觉演绎、移动端面板和大模型文本在同一套规则下稳定协作。** ## 7. 聊天输入区布局补充经验 ### 7.1 聊天框变大时,要优先增加“消息展示区”而不是只放大输入框 - 玩家感知里的“聊天框高度”主要来自消息气泡和剧情滚动区,不是输入栏本身。 - 如果只把输入框做高,实际会压缩选项区和底部按钮区,移动端反而更挤。 - 更稳妥的做法是: 先让剧情/聊天滚动区在剩余空间里拿到更高的伸缩优先级,再微调输入条高度和底部留白。 - 移动端不要随意给聊天区写死过大的最小高度,否则很容易把选项按钮和自定义输入一起挤出首屏。 ### 7.2 底部输入区要向安全区贴近,但不能直接贴死 - 自定义输入要更贴近屏幕底部,应该缩小底部控制区的额外 padding,而不是去掉安全区。 - `env(safe-area-inset-bottom)` 仍然要保留,否则刘海屏、手势条机型会出现输入框被顶起或遮挡的问题。 - 正确方向是: 保留安全区补偿,只减少设计层自己额外加上的底部留白。 ### 7.3 底部操作区下沉时,要同步增加和聊天区之间的呼吸感 - 当“队伍 / 背包 / 换一换 / 退出聊天 / 自定义输入”整体下移后,上下区块更容易挤在一起。 - 这时要略微增加聊天区和操作区之间的垂直间距,保证视觉层级仍然清楚。 - 目标不是做出更厚的面板,而是让用户一眼分清: 上面是正在发生的对话,下面是马上可点的操作。 ## 8. 战斗态底部面板布局经验 ### 8.1 战斗态不应继续保留剧情框占位 - 战斗画面里玩家关注的是敌我状态与可执行动作,剧情文本框如果继续占据底部高度,会直接挤压操作按钮。 - 战斗态应隐藏剧情框组件,只保留操作区;战斗结果叙事可放到结算或下一次非战斗剧情里展示。 ### 8.2 战斗选项数量要由剩余高度决定 - 不要固定渲染全部战斗选项,否则移动端低高度屏幕会把按钮挤出可点击区域。 - 更稳妥的做法是测量底部操作区可用高度,用单个按钮的最小高度和间距计算本帧可显示数量。 - 至少保留 1 个操作,避免极端高度下玩家看不到任何战斗入口。