# Codex Past Work Experience Summary 日期:`2026-03-23` ## 1. 工作范围概览 这几轮工作主要集中在 4 个方向: 1. 编辑器体系整理 2. NPC 视觉编辑与素材接入 3. 玩家角色与怪物动画资源纠偏 4. 选项行为编辑器与预览链路升级 这些改动不是孤立的 UI 修补,而是横跨了: - 资源定义层 - 编辑器字段层 - 运行时预览层 - 游戏真实播放逻辑层 ## 2. 已完成的核心工作 ### 2.1 编辑器入口与页签整理 - 当时曾保留 `/preset-editor`、`/npc-editor`、`/function-editor` - 当时还新增过 `/behavior-editor` 作为“选项行为”编辑页别名 - 将原先单独的 `NPC 视觉` 标签并回 `NPC` 编辑页 - 将 `Function` 页签改名为 `选项行为` 结论: - 独立编辑器入口如果没有继续接入主流程,应及时物理删除,不要长期保留兼容壳 - 页签命名要贴近百梦主语言,而不是内部实现命名 ### 2.2 NPC 视觉模块并入 NPC 编辑 完成内容: - 当时曾将 `NpcVisualEditor` 嵌入 `PresetEditor` 的 NPC 编辑页 - 让 NPC 文本字段与视觉字段围绕同一个当前选中 NPC 联动 - 保留视觉覆盖保存与全局布局保存能力 经验: - NPC 文本编辑和 NPC 视觉编辑不应分裂成两个互不关联的工作流 - “当前选中的 NPC” 必须是两个模块共享的单一数据源 ### 2.3 Medieval NPC 素材定义重建 完成内容: - 在 [medievalNpcVisuals.ts](/E:/Repos/Genarrative/src/data/medievalNpcVisuals.ts) 中重建了 Medieval NPC 的资产定义 - 补齐了 cloth / leather / metal / melee / magic / ranged 六大类真实素材 - 为素材增加了: - 语义化名称 - 图块尺寸 - 列数 - 帧数 - 姿态选项 - 让编辑器不再直接使用文件名、序号名作为展示项 经验: - 编辑器下拉项如果来自手写数组,迟早会和真实素材目录脱节 - 素材定义最好具备“资产元数据”,而不是只有路径字符串 - 一旦资产存在大图块,就不能再默认所有图块都是 `32x32` ### 2.4 NPC 动画器支持大图块武器 完成内容: - 在 [MedievalNpcAnimator.tsx](/E:/Repos/Genarrative/src/components/MedievalNpcAnimator.tsx) 中为 `AtlasSprite` 增加: - `tileWidth` - `tileHeight` - 对齐偏移支持 效果: - 长柄武器 - 巨剑 - 64x32 远程武器 - 64x64 投石索类武器 都能正确显示,不再被按 `32x32` 裁坏。 经验: - 视觉编辑器一旦涉及装备 atlas,就必须把“资源尺寸”从数据层带到渲染层 ### 2.5 玩家角色动画映射纠偏 完成内容: - 在 [characterPresets.ts](/E:/Repos/Genarrative/src/data/characterPresets.ts) 中重新核对 5 个玩家角色的 Hero 动画目录 - 修正了错误帧数、错误前缀、遗漏动作 - 补齐了真实存在但之前未接入的动作: - `acquire` - `climb` - `dash` - `die` - `double jump` - `hurt` - `jump` - `jump attack` - `wall slide` - 给角色动画配置增加了 `file` 字段,支持单文件动画 相关文件: - [types.ts](/E:/Repos/Genarrative/src/types.ts) - [CharacterAnimator.tsx](/E:/Repos/Genarrative/src/components/CharacterAnimator.tsx) - [characterCombat.ts](/E:/Repos/Genarrative/src/data/characterCombat.ts) 经验: - 只要编辑器允许用户切“预览动作”,就不能让未映射动作静默 fallback 到 `idle` - 正确做法是: 1. 先补齐真实动作映射 2. 再让预览下拉只显示当前角色实际可用动作 ### 2.6 怪物动画空白帧修复 完成内容: - 在 [monsterPresets.ts](/E:/Repos/Genarrative/src/data/monsterPresets.ts) 中把怪物动画从“连续帧猜测”改成“按图集行起点取帧” - 补上缺失的 `die` 配置 - 清除了所有落进空白格的动画段 经验: - 像素怪物图集不一定按一个连续区段排完整套动作 - 如果动作配置只写 `start + frames`,但没结合图集行结构,就非常容易踩进空白帧 ### 2.7 选项行为编辑器重构 完成内容: - 将原 “Function 编辑器” 改造成 “选项行为编辑器” - 页面文案和入口统一为“选项行为” - 移除“基础场景 / 结果场景”双窗格预览 - 保留并强化: - 行为列表 - 覆盖保存 - 快速模板套用 经验: - 百梦主并不关心 “function” 这个技术词,更关心“这个选项会发生什么” - 同类编辑器如果只给字段表单而没有模板起稿能力,复用效率会很低 ### 2.8 选项行为预览升级到实机回放 完成内容: - 在 [StateFunctionEditor.tsx](/E:/Repos/Genarrative/src/components/StateFunctionEditor.tsx) 中新增 `BehaviorExecutionPreview` - 预览不再是静态推测,而是: 1. 构造本地 `GameState` 2. 调用真实 `resolveFunctionOption` 3. 再调用 [useCombatFlow.ts](/E:/Repos/Genarrative/src/hooks/useCombatFlow.ts) 的 - `buildResolvedChoiceState` - `playResolvedChoice` - 从而直接复用游戏真实逻辑 覆盖能力包括: - 战斗行为 - 恢复行为 - 脱离行为 - 探索前探 - 切场行为 经验: - 编辑器预览只要和运行时逻辑写成两套,就一定会越来越不一致 - 预览层最稳的做法是“调用真实业务逻辑”,而不是“模拟真实业务逻辑” ## 3. 关键踩坑记录 ### 3.1 图标组件名覆盖原生 `Map` 问题: - `lucide-react` 的 `Map` 图标直接命名为 `Map` - 在 NPC 页签里 `new Map()` 实际调用到了图标组件 - 导致页签内容直接渲染为空 经验: - 图标组件命名尽量使用 `MapIcon`、`UserIcon` 这类后缀 - 避免覆盖 JS/TS 原生对象名 ### 3.2 预览 effect 依赖不稳定导致回放反复重启 问题: - `BehaviorExecutionPreview` 里使用了 `useCombatFlow()` - 但 effect 依赖了返回对象本身 - 每次 `gameState` 更新,effect 都会被视为变更 - 导致预览回放速度异常、重复重启、动画像加速 经验: - 只要预览组件内部要“异步播放状态变化”,就要高度警惕 effect 依赖环 - 解决方式是: - 用 `ref` 保存稳定方法引用 - 让 effect 只依赖真正的输入配置,不依赖内部播放状态 ### 3.3 实时面板与回放阶段不同步 问题: - `LIVE PLAYER` 用的是实时 `gameState` - `BATTLE SNAPSHOT` 用的是预计算首回合快照 - 两者不是同一时间点的数据 - 导致面板看起来“都对,但互相对不上” 经验: - 预览面板要么都显示“实时状态” - 要么都显示“同一个阶段的快照” - 混用实时值和预测值会让百梦主误判 ## 4. 这类项目里沉淀下来的方法论 ### 4.1 先校验资源,再改编辑器 顺序建议: 1. 先扫真实目录 2. 再建资产定义 3. 再修编辑器字段 4. 最后修预览 ### 4.2 预览必须尽量复用游戏真实链路 优先级: 1. 复用真实函数 2. 复用真实状态结构 3. 复用真实渲染组件 4. 最后才是补充编辑器专用的辅助信息 ### 4.3 编辑器要区分“可编辑字段”和“会生效字段” 经验: - 不是所有字段都应该在所有行为类型下开放 - 如果某类行为最终不会直接读取某个字段,就应该禁用或弱化它 - 否则百梦主会错误地以为改动无效是 bug ### 4.4 模板比空白表单更重要 经验: - 当系统里已经有多种成熟行为时,最快的创作路径不是“从零填写” - 而是: - 选一个最像的 - 套结构 - 微调文案和数值 ## 5. 推荐的后续方向 如果继续打磨这套编辑器,建议下一步做: 1. 为选项行为预览增加“时间轴 / 阶段日志” 2. 为选项行为编辑器增加“新建行为向导” 3. 把更多系统状态引入预览上下文 - 同伴 - NPC 状态 - 背包 - 当前场景实体池 4. 把“可编辑字段”和“只读推导字段”视觉上再分开 ## 6. 一句话总结 过去这几轮最重要的经验不是“写了多少编辑器 UI”,而是: **编辑器一旦想可靠,就不能只编辑静态数据,必须逐步接管真实资源定义、真实运行时状态和真实播放逻辑。**