# 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. 一句话总结 这个项目最重要的经验不是“多写了多少功能”,而是: **凡是会同时影响叙事、状态、演出和工具链的需求,都要先统一边界,再落实现。**