263 lines
7.1 KiB
Markdown
263 lines
7.1 KiB
Markdown
# Codex 实战经验沉淀
|
||
|
||
日期:`2026-03-24`
|
||
|
||
## 1. 先判断需求属于哪条链路
|
||
|
||
这个项目几乎所有需求都不是单点 UI 改动,通常会同时影响几条链路:
|
||
|
||
- 叙事链路:AI 剧情、提示词、选项文案
|
||
- 状态链路:`GameState`、NPC 状态、背包、队伍、委托
|
||
- 演出链路:屏幕外进场、战斗播放、实体站位、动画与特效
|
||
- 工具链路:编辑器、校验脚本、存档兼容、smoke
|
||
|
||
经验:
|
||
|
||
- 每次动手前先判断“这次主要影响哪几条链路”,不要把需求误判成单纯的 UI 需求。
|
||
- 只改表现、不改状态,最终一定会返工。
|
||
- 只改状态、不补校验,后面也一定会返工。
|
||
|
||
## 2. 先补状态模型,再补交互
|
||
|
||
这类项目里,最稳定的顺序永远是:
|
||
|
||
1. 先补类型与状态字段
|
||
2. 再补规则函数
|
||
3. 再补 hook 流程
|
||
4. 最后接 UI
|
||
|
||
已经反复验证有效的例子:
|
||
|
||
- `quests`
|
||
- `playerEquipment`
|
||
- `playerCurrency`
|
||
- `roster`
|
||
- `companions`
|
||
- `currentNpcBattleMode`
|
||
- `sparReturnEncounter`
|
||
|
||
经验:
|
||
|
||
- 如果一个功能需要“长期留存”,就不要只存在于局部组件 state。
|
||
- 先建模后接按钮,比先堆按钮后补状态稳定得多。
|
||
|
||
## 3. AI 负责叙事,本地负责规则
|
||
|
||
项目里最稳的边界是:
|
||
|
||
- AI 负责:
|
||
- `storyText`
|
||
- 对话文本
|
||
- 选项的自然语言表达
|
||
- 本地规则负责:
|
||
- 交易是否合法
|
||
- 招募是否成立
|
||
- 装备是否生效
|
||
- 委托进度是否完成
|
||
- 掉落、货币、好感、队伍编成
|
||
|
||
经验:
|
||
|
||
- 只要涉及数值、资源、状态迁移,就尽量不要让大模型即兴决定。
|
||
- 给模型的提示词应该描述“局面”和“边界”,不要让它代替规则系统。
|
||
|
||
## 4. 固定选项提示不要写得太死
|
||
|
||
一个重要经验是:
|
||
|
||
- 模型需要知道每个 `functionId` 的核心含义
|
||
- 但不需要看到“当前默认文案 / 补充信息 / 实际行为”这种过于细碎、强绑定的结构
|
||
|
||
更好的方式是:
|
||
|
||
- 保留 `functionId`、数量、顺序
|
||
- 只提供“这个 function 的核心语义参考”
|
||
- 让模型重写更自然、连续的 `actionText`
|
||
|
||
经验:
|
||
|
||
- 提示词越像表单,模型越容易产出僵硬选项。
|
||
- 提示词越像“约束 + 语义边界”,剧情越自然。
|
||
|
||
## 5. 面前实体的提示词必须和主角对称
|
||
|
||
如果主角有:
|
||
|
||
- 描述
|
||
- 性格
|
||
- 状态
|
||
- 属性
|
||
|
||
那么“当前面前实体”也应该尽量有同样结构。
|
||
|
||
经验:
|
||
|
||
- 只给一句“某 NPC 在这里活动”太粗,会削弱模型对局面的把握。
|
||
- 面前实体和主角描述层级一致后,模型更容易写出有来回感、对称感的叙事。
|
||
- 对生命/灵力这类状态,离散分档文本比裸数字更利于模型理解。
|
||
|
||
## 6. 屏幕外进场一定要抽成统一工具
|
||
|
||
这类项目很容易在多个地方各写一套“从屏幕外进入”的逻辑,结果出现:
|
||
|
||
- 同一实体重复进场
|
||
- 先进入屏幕,又被拉回屏幕外再进一次
|
||
- 多怪时只动第一个,其他直接跳终点
|
||
|
||
这次稳定下来的方法是:
|
||
|
||
- 抽统一的过渡工具
|
||
- `buildEncounterEntryState`
|
||
- `buildEncounterTransitionState`
|
||
- `interpolateEncounterTransitionState`
|
||
- 所有进场逻辑都复用这一套
|
||
- 区分两种场景:
|
||
- 真正从屏幕外冲入
|
||
- 已经在屏内预览,只是收敛到正式位置
|
||
|
||
经验:
|
||
|
||
- “屏幕外进入”本质上不是动画问题,而是状态过渡问题。
|
||
- 一旦同时存在 preview / call_out / resolve / replay,就必须统一插值逻辑。
|
||
|
||
## 7. 多实体系统里,不要默认“只处理第一个”
|
||
|
||
这个坑非常常见:
|
||
|
||
- 场景配置里有多个怪
|
||
- 运行时逻辑却只用 `monsterIds[0]`
|
||
- 或者动画只插值 `sceneMonsters[0]`
|
||
|
||
经验:
|
||
|
||
- 只要数据结构已经允许数组,就尽量按“整组”处理。
|
||
- 即便最后 UI 只重点展示一个,也不要在底层逻辑里偷偷退化成单体。
|
||
|
||
## 8. 招募系统不要只做“当前队伍”
|
||
|
||
如果只有 `companions` 而没有 `roster`,后面一定会遇到这些问题:
|
||
|
||
- 队伍满员时必须强制覆盖旧同伴
|
||
- 已招募角色很难转成待命
|
||
- 营地/编队功能没法闭环
|
||
|
||
这次稳定下来的模型是:
|
||
|
||
- `companions`:当前上阵
|
||
- `roster`:已招募但待命
|
||
|
||
经验:
|
||
|
||
- 只要项目里有招募,迟早就要有 roster。
|
||
- roster 不只是 UI 功能,而是状态层能力。
|
||
|
||
## 9. 装备系统不要只做展示
|
||
|
||
装备真正形成闭环,至少要同时做到:
|
||
|
||
- 背包里可装备 / 卸下
|
||
- 装备改变真实属性
|
||
- 战斗行为读取装备加成
|
||
- 存档兼容旧存档
|
||
|
||
经验:
|
||
|
||
- “装备栏能显示”不算完成。
|
||
- 只有真正影响 `maxHp / maxMana / damage / incomingDamage`,它才是玩法系统。
|
||
|
||
## 10. 交易系统最好统一成货币价值模型
|
||
|
||
一开始按“品质交换”虽然简单,但很快会遇到问题:
|
||
|
||
- 不同类别物品难比较
|
||
- 直接购买不好接
|
||
- 后面加入售卖、任务赏金、宝藏货币时会冲突
|
||
|
||
更稳定的做法是:
|
||
|
||
- 所有物品都有统一价值
|
||
- NPC 商品有购买价
|
||
- 玩家物品有回收价
|
||
- 货币作为通用交换媒介
|
||
|
||
经验:
|
||
|
||
- 一旦出现货币,就尽量让交易系统全面切成“价值模型”。
|
||
- 不要同时长期维护“品质交换”和“货币购买”两套完全不同的判定逻辑。
|
||
|
||
## 11. 编辑器要先做保存前校验
|
||
|
||
编辑器进入“可持续生产内容”阶段后,最优先的不是视觉,而是:
|
||
|
||
- 保存前校验
|
||
- 非法引用提示
|
||
- 数值边界检查
|
||
|
||
经验:
|
||
|
||
- 编辑器最怕的不是“不够漂亮”,而是“保存成功但运行时报错”。
|
||
- 只要内容开始增多,校验脚本和保存前校验就必须尽早接入。
|
||
|
||
## 12. 每次大改后都要补 smoke
|
||
|
||
对这个项目来说,`lint + build` 不够。
|
||
|
||
至少要补 smoke 的场景包括:
|
||
|
||
- 委托接取 -> 推进 -> 交付
|
||
- 多怪遭遇
|
||
- 装备加成
|
||
- 队伍编成
|
||
- 交易价值与直接购买
|
||
- 进场插值
|
||
|
||
经验:
|
||
|
||
- 只靠人工点点看,很容易漏掉状态分支。
|
||
- smoke 不一定要重,但要覆盖关键闭环。
|
||
|
||
## 13. 兼容旧存档要同步做
|
||
|
||
每次给 `GameState` 新增字段时,都要同步考虑:
|
||
|
||
- 默认值
|
||
- 存档读取兼容
|
||
- 旧字段缺失时如何补全
|
||
|
||
经验:
|
||
|
||
- 旧存档兼容不是“最后再说”的工作。
|
||
- 新字段一旦进 `GameState`,就应当同一轮把持久化兼容补上。
|
||
|
||
## 14. 不要在坏文件上无限缝补
|
||
|
||
这次实际踩到过一个很明显的坑:
|
||
|
||
- 某些文件本身已经混入大量乱码或结构损坏
|
||
- 在原地做小 patch 会越来越难维护
|
||
|
||
更稳的做法是:
|
||
|
||
- 保留接口
|
||
- 整文件重写成干净版本
|
||
- 再接回现有调用
|
||
|
||
经验:
|
||
|
||
- 当一个文件已经进入“局部 patch 很难保证正确”的状态时,重写往往比继续缝补更省时间。
|
||
|
||
## 15. 后续继续迭代时的建议顺序
|
||
|
||
如果继续推进这个项目,建议优先顺序:
|
||
|
||
1. 先清理中文乱码高频文件
|
||
2. 再继续精英/Boss 层
|
||
3. 再补营地关系事件
|
||
4. 再做编辑器差异预览 / 导入导出
|
||
|
||
## 16. 一句话总结
|
||
|
||
这个项目最重要的经验不是“多写了多少功能”,而是:
|
||
|
||
**凡是会同时影响叙事、状态、演出和工具链的需求,都要先统一边界,再落实现。**
|