293 lines
10 KiB
Markdown
293 lines
10 KiB
Markdown
# 冒险运行时开发经验沉淀
|
||
|
||
日期: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 个操作,避免极端高度下玩家看不到任何战斗入口。
|