278 lines
8.0 KiB
Markdown
278 lines
8.0 KiB
Markdown
# 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](/E:/Repos/Genarrative/src/components/NpcVisualEditor.tsx) 嵌入 [PresetEditor](/E:/Repos/Genarrative/src/components/PresetEditor.tsx) 的 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”,而是:
|
||
|
||
**编辑器一旦想可靠,就不能只编辑静态数据,必须逐步接管真实资源定义、真实运行时状态和真实播放逻辑。**
|