Rework story engine flow and reorganize project docs
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-06 23:19:00 +08:00
parent d678929064
commit ddcb5d5c8c
241 changed files with 19805 additions and 2478 deletions

View File

@@ -0,0 +1,437 @@
# 当前 Function 设计审计2026-04-03
## 审计范围
本次审计重点阅读并对照了这些位置:
- `docs/experience/ADVENTURE_RUNTIME_DEV_EXPERIENCE.md`
- `docs/experience/PROJECT_WORK_EXPERIENCE_PLAYBOOK.md`
- `docs/experience/PROJECT_DEVELOPMENT_EXPERIENCE.md`
- `docs/planning/CURRENT_GAME_ITERATION_PRIORITIES_2026-04-03.md`
- `src/data/stateFunctions.ts`
- `src/data/npcInteractions.ts`
- `src/data/treasureInteractions.ts`
- `src/hooks/useStoryGeneration.ts`
- `src/hooks/story/npcEncounterActions.ts`
- `src/hooks/story/npcInteraction.ts`
- `src/hooks/story/progressionActions.ts`
- `src/hooks/story/storyGenerationState.ts`
- `src/services/ai.ts`
- `src/services/prompt.ts`
- `src/components/AdventurePanel.tsx`
- `src/components/StateFunctionEditor.tsx`
## 先说结论
当前运行时的“function”不是单一体系而是至少分成了 4 层:
1. `stateFunctions.ts` 里的基础战斗 / 空闲 function。
2. `npcInteractions.ts` 里的 NPC 交互 function。
3. `treasureInteractions.ts` 里的宝藏交互 function。
4. `useStoryGeneration.ts` / `npcInteraction.ts` / 背包装备锻造里额外加出来的“流程控制型 functionId”。
“选完选项触发 function 后没有触发剧情推理”这类现象,当前主要有 3 种来源:
1. **按设计先走本地分流,不会在第一次点击时立刻推理。**
2. **剧情推理其实已经完成,但被“继续冒险”这道 UI 中转门挡住了。**
3. **真正的可见性 bug`story_continue_adventure` 的文案常量已经乱码,导致 UI 提示失效,用户很容易误判为没继续推理。**
---
## 1. 当前 function 体系分层
### 1.1 基础状态 function`src/data/stateFunctions.ts`
这一层才是严格意义上的“状态 function 注册表”,由 `resolveFunctionOption` 统一解析。
当前运行时实际启用 12 个:
- 战斗类 7 个:
- `battle_all_in_crush`
- `battle_guard_break`
- `battle_probe_pressure`
- `battle_feint_step`
- `battle_recover_breath`
- `battle_finisher_window`
- `battle_escape_breakout`
- 空闲类 5 个:
- `idle_explore_forward`
- `idle_travel_next_scene`
- `idle_rest_focus`
- `idle_observe_signs`
- `idle_call_out`
关键设计点:
- 定义源头是 `BATTLE_FUNCTIONS` / `IDLE_FUNCTIONS`
- 最终运行时集合由 `buildStateFunctionDefinitions` 产出。
- 可执行过滤走 `getExecutableFunctions`
- 文案和视觉包装走 `resolveFunctionOption`
- 默认选项池走 `getDefaultFunctionIdsForContext`
注意:
- `idle_follow_clue` 仍然留在源码和 prompt 描述里,但在 `applyRuntimeFunctionAdjustments` 中被直接过滤掉,不会进入运行时 function 集合。
- `src/components/game-shell/useSceneTransitionModel.ts` 里仍然保留了 `idle_follow_clue` 的转场映射,这说明当前 function 清单并不完全一致。
### 1.2 NPC 交互 function`src/data/npcInteractions.ts`
这一层不是通过 `resolveFunctionOption` 生成的,而是 `buildNpcEncounterStoryMoment` 直接拼出 `StoryOption`,并挂上 `interaction.kind = 'npc'`
按功能类型看,当前会出现这些 `functionId`
- `npc_preview_talk`
- `npc_trade`
- `npc_fight`
- `npc_spar`
- `npc_help`
- `npc_chat`(可重复出现 2 个以上,代表不同聊天话题)
- `npc_gift`
- `npc_recruit`
- `npc_quest_accept`
- `npc_quest_turn_in`
- `npc_leave`
关键设计点:
- 这一层的 function 是“眼前 NPC 交互目录”,不是基础状态机目录。
- 真正执行分流不在 `stateFunctions.ts`,而在 `handleNpcInteraction` / `resolveNpcInteractionDecision`
- prompt 层通过 `availableOptions` 把这些 function 当作“固定可选项列表”交给模型,要求模型保留数量和 `functionId`
### 1.3 宝藏交互 function`src/data/treasureInteractions.ts`
这一层同样不是 `resolveFunctionOption` 体系,而是直接构造带 `interaction.kind = 'treasure'` 的选项。
当前有 3 个:
- `treasure_secure`
- `treasure_inspect`
- `treasure_leave`
执行时由 `useTreasureFlow.ts` 接管,最终再回到 `commitGeneratedState` 继续剧情推理。
### 1.4 流程控制 / 面板动作 functionId
这类 `functionId` 会进入 `lastFunctionId``commitGeneratedState`,但不在 `stateFunctions.ts` 注册表里:
- 流程控制:
- `story_continue_adventure`
- `camp_travel_home_scene`
- `story_opening_camp_dialogue`
- 面板动作:
- `inventory_use`
- `equipment_equip`
- `equipment_unequip`
- `forge_craft`
- `forge_dismantle`
- `forge_reforge`
这说明当前项目里“functionId”已经同时承担了 3 个角色:
- 运行时基础状态动作 ID
- NPC / 宝藏交互动作 ID
- 流程 / 面板事件 ID
这能跑,但可追踪性已经开始分裂。
---
## 2. 当前剧情推理触发链路
### 2.1 会立刻触发剧情推理的主链
这类点击后会直接走 AI 续推:
- 普通战斗 / 空闲 function
- `handleChoice`
- `buildResolvedChoiceState`
- `playResolvedChoice`
- `generateNextStep`
- 这些 NPC 交互
- `npc_preview_talk`
- `npc_help`
- `npc_chat`
- `npc_fight`
- `npc_spar`
- `npc_quest_accept`
- `npc_quest_turn_in`
- `npc_leave`
- 宝藏交互确认后
- `treasure_secure`
- `treasure_inspect`
- `treasure_leave`
- 面板动作确认后
- `inventory_use`
- `equipment_equip`
- `equipment_unequip`
- `forge_*`
共性是:
- 要么直接在 `handleChoice` 里调用 `generateNextStep`
- 要么先走 `commitGeneratedState` / `commitGeneratedStateWithEncounterEntry`,再统一调用 `generateStoryForState`
### 2.2 第一次点击不会立刻触发剧情推理的分流
这类最容易被误判成“function 触发了,但剧情没继续”:
- `npc_trade`
- `npc_gift`
- `npc_recruit`(队伍满时必进 modal队伍未满时会先进招募对话流
原因不是漏调,而是当前设计明确先走:
- `resolveNpcInteractionDecision`
- `trade_modal`
- `gift_modal`
- `recruit_modal`
- `recruit_immediate`
也就是说:
- 第一次点击只是**打开模态框 / 进入招募流程**。
- 真正推进剧情推理,要等到:
- `confirmTrade`
- `confirmGift`
- `confirmRecruit`
- `executeRecruitment`
如果产品预期是“用户每点一次选项就必须立即看到剧情继续”,这一层现在不满足。
### 2.3 `npc_chat` 是“先推理,再延迟展示选项”
`npc_chat` 不是普通的“生成下一幕 + 立刻给选项”,而是单独走这条链:
1. `commitNpcChatState` 先流式生成聊天正文。
2. 聊天结束后,再调用一次 `generateNextStep`
3. 新一轮冒险选项不直接显示,而是塞进 `deferredOptions`
4. 当前界面只先显示一个 `story_continue_adventure`
5. 用户再点一次,才把 `deferredOptions` 放出来。
所以这里常见的误判是:
- **剧情推理其实已经做完了。**
- 只是 UI 先让用户“继续冒险”一次,才把新选项展示出来。
---
## 3. 本次排查发现的重点问题
### 3.1 真正最像“没触发剧情推理”的地方:模态框型 NPC function
定位:
- `src/hooks/story/npcEncounterActions.ts:427-449`
- `src/hooks/story/storyGenerationState.ts:41-80`
- `src/hooks/story/npcInteraction.ts:427-585`
现象:
- 点击 `npc_trade` / `npc_gift` / `npc_recruit` 后,故事文本区通常不会立刻变化。
- 当前故事也不会马上追加一段新的 `storyText`
原因:
- 这些 function 的第一次点击只做本地 UI 分流。
- 直到用户在 modal 里确认,才会真正调用 `commitGeneratedState` 继续推理。
判断:
- **这不是单纯 bug而是当前设计本身如此。**
- 但如果玩家从“选项即剧情推进”的心智出发,会非常像“点了没反应”。
建议优先级:高。
### 3.2 最关键的实际 bug`story_continue_adventure` 文案乱码,导致“已推理但未显式提示”
定位:
- `src/hooks/useStoryGeneration.ts:92-96`
- `src/hooks/story/npcEncounterActions.ts:281-400`
- `src/components/AdventurePanel.tsx:534`
- `src/components/AdventurePanel.tsx:860`
- `src/components/AdventurePanel.tsx:879`
现象:
- `npc_chat` 完成后,系统本应展示一个“继续冒险”按钮,提示“剧情推理完成,继续后显示新的冒险选项”。
- 但当前 `CONTINUE_ADVENTURE_ACTION_TEXT` 常量已经写成了乱码:`缁х画鍐掗櫓`
- `AdventurePanel` 又是靠 `option.actionText === '继续冒险'` 来识别这个特殊按钮。
直接后果:
- 特殊提示 UI 不会出现。
- 玩家只会看到一个普通且乱码的单选项。
- 实际上 `deferredOptions` 已经算好了,但用户极容易误会为“剧情没有继续推理”。
判断:
- **这是本次排查里最明确的实现级 bug。**
- 它不会阻止底层推理发生,但会严重破坏“推理已完成”的可见性。
建议优先级:最高。
### 3.3 `StateFunctionEditor` 覆盖不到真正最容易出问题的 function
定位:
- `src/components/StateFunctionEditor.tsx:13-21`
- `src/components/StateFunctionEditor.tsx:488`
- `src/components/StateFunctionEditor.tsx:772-838`
- `src/components/StateFunctionEditor.tsx:992-1211`
现象:
- 编辑器预览只接了 `buildStateFunctionDefinitions` / `getAllStateFunctionDefinitions` / `resolveFunctionOption`
- 也就是它只能预览 `stateFunctions.ts` 那 12 个基础 function。
覆盖不到的关键分支:
- `npc_*`
- `treasure_*`
- `npc_preview_talk`
- `story_continue_adventure`
- modal 分流
- `npc_chat``deferredOptions`
判断:
- 这不是运行时 bug但它解释了为什么这类问题很难在编辑器里提前暴露。
- 当前“Function 编辑器”并没有覆盖到最复杂、最容易让用户感知为异常的 function 链路。
建议优先级:高。
### 3.4 function 清单存在“源码有、运行时无、别处还在引用”的分裂
定位:
- `src/data/stateFunctions.ts:350`
- `src/data/stateFunctions.ts:429-441`
- `src/components/game-shell/useSceneTransitionModel.ts:19-25`
现象:
- `idle_follow_clue` 仍在定义表、提示词描述、若干 `switch` 分支中存在。
- 但最终在 `applyRuntimeFunctionAdjustments` 被过滤掉,不会进入运行时 function 集合。
- `useSceneTransitionModel` 里却还保留着它的转场模式映射。
判断:
- 这不是“没触发剧情推理”的直接原因。
- 但会让维护者误判当前真实 function 清单,也会增加后续继续扩 function 时的混乱。
建议优先级:中。
### 3.5 自动化测试几乎没有覆盖“最容易让人误会没推理”的链路
定位:
- 当前已有测试主要是 `src/hooks/story/storyGenerationState.test.ts`
已覆盖:
- `trade_modal`
- `recruit_modal`
- 地图切场景
未覆盖:
- `npc_chat``deferredOptions -> story_continue_adventure -> 真正显示新选项`
- `npc_trade` / `npc_gift` / `npc_recruit` 确认后是否一定调用 `commitGeneratedState`
- `story_continue_adventure` 文案与 UI 特判是否一致
- `npc_preview_talk -> enterNpcInteraction -> generateStoryForState`
- 宝藏分支确认后是否稳定续推
判断:
- 这类问题之所以能长期存在,一个核心原因就是**最关键的续推分支没有测试兜底**。
建议优先级:高。
---
## 4. 按“首次点击是否立即触发剧情推理”整理
### 4.1 首次点击就会继续推理
- `battle_*`
- `idle_*`
- `npc_preview_talk`
- `npc_help`
- `npc_chat`
- `npc_fight`
- `npc_spar`
- `npc_quest_accept`
- `npc_quest_turn_in`
- `npc_leave`
- `treasure_*`
- `inventory_use`
- `equipment_*`
- `forge_*`
### 4.2 首次点击不会立刻继续推理
- `npc_trade`
- `npc_gift`
- `npc_recruit`(至少会先进入确认 / 对话流)
- `story_continue_adventure`
这里要特别分清:
- `npc_trade` / `npc_gift` / `npc_recruit` 是**先分流,后确认,确认后再推理**。
- `story_continue_adventure` 是**推理已经完成,只是先把结果选项延后展示**。
---
## 5. 建议的修正顺序
### P0
- 修掉 `CONTINUE_ADVENTURE_ACTION_TEXT` 的乱码。
- `AdventurePanel` 不要再靠 `actionText === '继续冒险'` 判定特殊按钮,改成按 `functionId === 'story_continue_adventure'` 判定。
### P1
- 明确产品规则:
- `npc_trade` / `npc_gift` / `npc_recruit` 第一次点击是否就应该写入一条“进入交易 / 送礼 / 招募确认”的剧情反馈。
- 如果答案是“应该”,那这些 modal 型 function 需要补一层轻量 story feedback而不是只弹框。
### P1
-`npc_chat` 补自动化测试:
- 聊天后必须出现 `story_continue_adventure`
- 第二次点击后必须能展示 `deferredOptions`
### P1
-`npc_trade` / `npc_gift` / `npc_recruit` 补自动化测试:
- 第一次点击只分流
- 确认后一定触发 `commitGeneratedState`
- 后续一定能拿到新的 `StoryMoment`
### P2
- 扩展 `StateFunctionEditor` 或补新的“交互 function 预览器”,把 `npc_*` / `treasure_*` / `story_continue_adventure` 也纳入可预演范围。
### P2
- 清理 `idle_follow_clue` 这类“半退场”的 function保证
- 运行时集合
- prompt 描述
- 编辑器
- 转场映射
- 测试
保持一致。
---
## 最后结论
当前最值得优先处理的,不是再继续加新的 function而是先把这 3 个点收拢:
1. **把“首次点击只分流、不推理”的 function 明确标出来。**
2. **把 `npc_chat -> story_continue_adventure -> deferredOptions` 这条延迟展示链做清楚。**
3. **先修掉 `story_continue_adventure` 的乱码和基于文案的 UI 判断。**
如果不先处理这几个点,用户会持续把“按设计延迟”与“真实漏调剧情推理”混在一起感知,后面 function 越多,这类问题会越难排查。

View File

@@ -0,0 +1,133 @@
# 物品生成系统与 Build 标签系统 PRD 落地审计
审计时间2026-04-05
审计范围:
- `docs/prd/AI_NATIVE_RUNTIME_ITEM_GENERATION_DESIGN.md`
- `docs/prd/RUNTIME_ITEM_GENERATION_CURRENT_SYSTEM_DESIGN.md`
- `docs/prd/BUILD_SYSTEM_ATTRIBUTE_SIMILARITY_PRD_2026-04-02.md`
- `docs/design/EQUIPMENT_BUILD_AND_FORGE_LOOP_SYSTEM_DESIGN.md`
## 结论速览
### 1. 物品生成系统
当前状态可以判定为:**主链已补齐落地**。
已经落地的是:
- 有独立的运行时上下文层、导演层、本地编译层、叙事回写层。
- 宝藏、怪物掉落、通用 NPC 商店已经能走统一的 runtime item director。
- 永久 build 标签物品、限时 build buff 物品、少量数值物品三种骨架都已经能编译出来,并接进现有背包 / 装备 / build 结算。
本轮已补齐的是:
- 新增了 runtime item AI 意图导演与 prompt并接入 NPC 帮助奖励主链,失败时自动回退到本地导演。
- NPC 交易库存改成按玩家当前 build 生成,并通过 `tradeStockSignature` 只在 build 变化时刷新。
- NPC 帮助奖励、委托奖励已经统一接入 runtime item director。
- 怪物掉落已经改成“基础掉落 + 语义掉落”双层叠加。
### 2. Build 标签系统
当前状态可以判定为:**核心已按 PRD 落地,且实现范围比 PRD 更大**。
已经落地的是:
- `BuildTagDefinition.attributeAffinity` 已扩展。
- `buildDamage.ts` 已改成“标签分别匹配角色属性画像”的加法模型,不再做标签两两网络效应。
- Buff / 角色固有 / 武器 / 护甲 / 饰品 / 套装标签都能进入最终倍率。
- Character 面板已经切到“属性适配度”展示,并能拆出单标签的属性贡献明细。
- 有针对新公式的测试覆盖。
还存在的尾项主要是:
- 实现用的是“世界属性 schema 六轴模型”,不是 PRD 文字里的固定四维属性。
- 旧的标签相似度辅助能力没有完全清干净,重铸仍在用 `getSimilarBuildTags` 做候选标签替换。
## 物品生成系统审计
| PRD 项 | 当前实现 | 判定 | 代码证据 |
| --- | --- | --- | --- |
| 上下文采样层 | 已有 `buildRuntimeItemGenerationContext` / `buildQuestRuntimeItemGenerationContext`,会收集场景、遭遇、关联 NPC、最近剧情、玩家 build 标签与 build gap。 | 已落地 | `src/data/runtimeItemContext.ts:157-188``src/data/runtimeItemContext.ts:191-252` |
| AI 意图层 | 已新增 `runtimeItemAiDirector` / `runtimeItemAiPrompt``buildRuntimeItemAiPromptInput` 已进入真实 prompt 组装NPC 帮助奖励主链会先请求 AI 物品意图,再回落到本地意图导演。 | 已补齐 | `src/services/runtimeItemAiPrompt.ts``src/services/runtimeItemAiDirector.ts``src/data/runtimeItemDirector.ts``src/hooks/story/npcEncounterActions.ts` |
| 本地编译层 | 已按 channel / slot / permanence 做 rarity 与预算编译,并产出 `statProfile``useProfile.buildBuffs``buildProfile``runtimeMetadata`。 | 已落地 | `src/data/runtimeItemCompiler.ts:77-101``src/data/runtimeItemCompiler.ts:122-206``src/data/runtimeItemCompiler.ts:245-276` |
| 叙事回写层 | 会把锚点、来源理由、build 倾向回写进物品名和描述。 | 已落地 | `src/data/runtimeItemNarrative.ts:171-189` |
| 永久标签 / 限时标签 / 少量数值三类物品 | 永久物品走 `buildProfile`,限时物品走 `useProfile.buildBuffs`,并可附带少量数值。 | 已落地 | `src/data/runtimeItemCompiler.ts:104-155``src/data/runtimeItemCompiler.ts:157-206` |
| 宝藏入口 | 宝藏奖励已经走 `buildRuntimeItemGenerationContext + buildDirectedRuntimeReward`,并把结果写回 story hint。 | 已落地 | `src/data/treasureInteractions.ts:52-89``src/hooks/useTreasureFlow.ts:45-75` |
| NPC 交易入口 | 通用 NPC 商店已改成按玩家当前 build 生成;初始 NPC 状态、交易模态打开时刷新、场景预览读取都会带上完整 `GameState`,并用 `tradeStockSignature` 避免无意义重刷。角色型 NPC 仍保留既有角色装备/背包模板。 | 已补齐 | `src/data/npcInteractions.ts``src/hooks/story/npcInteraction.ts``src/hooks/useStoryGeneration.ts``src/components/NpcModals.tsx` |
| NPC 帮助 / 关系奖励 | `npc_reward` 已真正接入主链。帮助奖励现在会生成带 `runtimeMetadata` 的 runtime item并保留数值恢复、冷却缩减与 story hint。 | 已补齐 | `src/data/npcInteractions.ts``src/hooks/story/npcEncounterActions.ts` |
| 委托奖励入口 | Quest reward 已改为走 runtime director支持 `buildQuestRuntimeItemGenerationContext`,领取时发放的是 runtime item。主 NPC 接任务流程也已切到 `generateQuestForNpcEncounter`。 | 已补齐 | `src/data/questFlow.ts``src/hooks/story/npcEncounterActions.ts``src/services/questDirector.ts` |
| 怪物掉落双层设计 | 普通世界掉落已改成预设 `lootTable` 基础掉落与 `monster_drop` runtime 语义掉落并存,不再互相覆盖。 | 已补齐 | `src/data/hostileNpcPresets.ts``src/data/hostileNpcPresets.test.ts` |
### 物品系统的具体判断
#### 已经明显符合 PRD 的部分
1. 系统分层已经形成。
`runtimeItemContext -> runtimeItemDirector -> runtimeItemCompiler -> runtimeItemNarrative` 这条链已经非常接近 PRD 里“上下文采样 / AI 意图 / 本地编译 / 叙事回写”的结构。
2. build 导向优先于纯数值。
`buildRuntimeItemContext` 会先算 `playerBuildTags``playerBuildGaps`,导演层再优先把 gap tag 与现有 build tag 拼进 `targetBuildDirection`,编译层才决定数值预算。
3. 奖励已经进入真实玩法结算。
runtime item 生成出的 `buildProfile` 会进入装备 build 结算,`useProfile.buildBuffs` 会在使用物品时写入 `activeBuildBuffs`
#### 本轮补齐后的说明
1. 运行时物品意图已经进入真实主链。
当前至少在 NPC 帮助奖励链路中,已经先走 AI 意图导演,再走本地编译与叙事回写;如果模型不可用,会回退到既有启发式导演,保证玩法不断。
2. 交易库存已经真正读取玩家当前构筑。
通用交易 NPC 的库存会基于玩家当前 build、装备标签和 build gap 生成,而不是继续依赖 NPC 自身偏好标签。
3. 帮助奖励、委托奖励、怪物掉落都已并入统一 runtime director。
现在三条链路都能产出带 relation anchor / source reason / runtime metadata 的 runtime item。
## Build 标签系统审计
| PRD 项 | 当前实现 | 判定 | 代码证据 |
| --- | --- | --- | --- |
| `BuildTagDefinition.attributeAffinity` 扩展 | 类型已扩展,标签注册表也会为每个标签注入 affinity。 | 已落地 | `src/types/build.ts:6-13``src/data/buildTags.ts:66-69` |
| 静态标签亲和度表 | 已有 `buildTagAttributeAffinity.ts`,提供标签到属性轴的静态 affinity 表。 | 已落地 | `src/data/buildTagAttributeAffinity.ts:127-183` |
| 从“标签互相影响”改为“标签分别匹配角色属性” | `buildDamage.ts` 已按单标签计算 `fitScore``bonusDelta` 和属性贡献,最后做加法累积,不再做 pair/cluster 乘法网络。 | 已落地 | `src/data/buildDamage.ts:236-318` |
| 来源系数 | Buff / 角色 / 武器 / 护甲 / 饰品 / 套装都有独立 source coefficient和 PRD 基本一致。 | 已落地 | `src/data/buildDamage.ts:95-114` |
| 最终伤害接入 | `resolvePlayerOutgoingDamage` / `resolveCompanionOutgoingDamage` / `resolveMonsterOutgoingDamage` 都已接 `buildDamageMultiplier`。 | 已落地 | `src/data/buildDamage.ts:498-542` |
| 展示层从“标签协同”改成“属性适配度” | Character 面板已经按标签展示 bonus、来源、主导属性并能打开明细弹窗。 | 已落地 | `src/components/CharacterPanel.tsx:205-247``src/components/CharacterPanel.tsx:497-539` |
| 验收测试 | 已覆盖单标签可拆分、删一个标签不重算其余标签、不同属性角色用同一套装倍率不同、Buff/套装来源正常进入等场景。 | 已落地 | `src/data/buildDamage.test.ts:125-313` |
| 四维属性口径 | PRD 写的是四维固定属性;实现已经提升为 world schema 六轴模型。目标一致,但口径不再一一对应。 | 已落地,但实现已外延扩展 | `src/types/attributes.ts:3-15``src/data/worldAttributeSchemas.ts:4-155` |
| 旧标签相似度清理 | 核心伤害结算已不再依赖旧矩阵,但 `getSimilarBuildTags` 仍存在,重铸继续用它挑候选标签,`generate:build-tags` 脚本也还保留。 | 收尾未完成 | `src/data/buildTags.ts:183-215``src/data/forgeSystem.ts:371-399``package.json:21-24` |
### Build 系统的具体判断
#### 已经符合 PRD 核心目标的部分
1. 可解释性已经建立。
现在每个标签都有自己的 `fitScore``attributeContributions``attributeModifierDeltas`,玩家可以看到“这个标签为什么强、强在哪条属性轴上”。
2. 新增标签不会反向扰动旧标签贡献。
`buildDamage.test.ts` 已专门验证“删掉一个标签,只会移除它自己的 row不会重算其他 row”。
3. 套装标签、Buff 标签、装备标签都能统一进入同一公式。
这点和 PRD 的来源规则一致,且测试已经覆盖。
#### 需要注意但不构成核心未落地的问题
1. 实现已经超出 PRD 的四维设计。
现在不是固定 `strength / agility / intelligence / spirit` 四维,而是通过 `WorldAttributeSchema` 映射成武侠/仙侠/自定义世界都能共用的语义属性轴。这更适合当前仓库的世界化属性系统,但也意味着 PRD 文案需要同步。
2. 旧相似度能力没有完全退场。
核心伤害结算已经不用标签两两矩阵,但锻造重铸仍然会根据标签相似度挑换洗标签,所以“旧体系相关命名/脚本”还没彻底收尾。
## 综合判断
如果按“是否已经把 PRD 的主战场落到代码里”来判断:
- **Build 标签系统:可以认为已经落地。**
- **物品生成系统:可以认为主链已经落地,之前审计出的缺口已在本轮补齐。**
如果接下来继续做收尾,更建议做的是:
1. 把 runtime item AI 意图层继续扩到宝藏、怪物掉落、委托奖励以外的更多同步入口,减少启发式 fallback 的覆盖面。
2. 给 Build 系统补一版文档同步,明确当前实现已经从 PRD 四维模型升级为世界属性 schema 模型,并清理剩余旧相似度脚本/命名。
3. 评估 `origin: 'ai_compiled'` 的语义是否还要细分成“AI 意图 + 本地编译”与“纯本地 fallback”两档方便后续观测与埋点。

19
docs/audits/README.md Normal file
View File

@@ -0,0 +1,19 @@
# 审计与复盘
这一组文档聚焦“当前状态是否健康、问题在哪里、和目标设计差多少”。
## 系列总览
- [engineering/README.md](./engineering/README.md):工程优化审查三轮记录的融合入口。
- [text/README.md](./text/README.md):文本、英文残留、乱码审计系列的融合入口。
## 专项审计
- [FUNCTION_DESIGN_AUDIT_2026-04-03.md](./FUNCTION_DESIGN_AUDIT_2026-04-03.md)Function 体系分层、职责边界和当前结构问题。
- [ITEM_AND_BUILD_PRD_AUDIT_2026-04-05.md](./ITEM_AND_BUILD_PRD_AUDIT_2026-04-05.md):物品生成与 Build 标签系统对 PRD 的落地情况。
## 推荐使用方式
1. 先读系列总览,确认“最新结论在哪一份”。
2. 再按需要进入具体日期文档,查看当时的证据和上下文。
3. 做方案设计前,优先把对应审计文档看完,避免重复踩已知问题。

View File

@@ -0,0 +1,278 @@
# 工程优化审查报告2026-03-29
## 说明
- 扫描范围:`src/``scripts/``docs/``package.json``vite.config.ts``tsconfig.json`
- 已执行校验:`npm run lint``npm run build``npm run check:content`
- 本报告只从工程角度讨论结构、边界、质量门禁、可维护性与可扩展性
- 按仓库说明,暂不讨论中文乱码本身
## 当前结论
项目当前**可构建、可运行、内容校验可通过**,说明基础功能链路是通的;但从工程视角看,已经出现明显的“单点过重、边界混杂、质量门禁偏弱、编辑器与运行时耦合”问题。继续叠需求会越来越依赖人工记忆和局部经验,回归风险会持续上升。
当前最值得优先处理的不是单个 UI 细节,而是以下四个工程主题:
1. 运行时主链路的职责拆分还不够,核心 hook / 组件已经过载
2. 缺少真正的工程质量门禁,`lint` 目前本质上只是 `tsc`
3. 编辑器、运行时、类后端能力都混在同一个 Vite 配置里
4. 持久化、AI 调用、编辑器保存等基础设施仍然是“分散手写”
## 运行状态快照
- `npm run lint` 通过
- `npm run build` 通过
- `npm run check:content` 通过
- 应用代码下未发现测试文件:`src/``scripts/``docs/` 内没有 `*.test.*` / `*.spec.*`
- 构建产物已出现较大 chunk
- `dist/assets/App-*.js``407 KB`
- `dist/assets/itemCatalog-*.js``414 KB`
- `dist/assets/PresetEditor-*.js``109 KB`
## 代码体征
下列文件已经明显进入“超大模块”区间:
| 文件 | 行数 | 观察 |
| --- | ---: | --- |
| `src/hooks/useStoryGeneration.ts` | 3304 | 同时管理剧情、NPC 交互、交易、送礼、招募、任务、角色聊天、道具/锻造接入 |
| `src/components/PresetEditor.tsx` | 2244 | 多编辑器入口聚合在一个巨型组件中 |
| `src/hooks/useCombatFlow.ts` | 1791 | 同时承担战斗推演、动画时序、逃跑演出、状态落地 |
| `src/components/GameShell.tsx` | 1592 | 入口 UI、选角、世界选择、自定义世界、场景切换、浮层控制全部集中 |
| `src/types.ts` | 663 | 运行时、AI、编辑器、自定义世界、背包、任务类型集中在一个总文件 |
补充信号:
- `src/components/GameShell.tsx` 内有 16 个 `useState`、10 个 `useEffect`、13 个 `useMemo`
- `src/hooks/useStoryGeneration.ts` 虽然只有少量 React state但内部累计 40+ 个函数,已经是“巨型流程控制器”
- `src/hooks/useCombatFlow.ts` 内有大量时间常量、动画常量、`sleep + setGameState` 过程式循环,测试成本很高
## 优先级问题
## P0运行时主链路职责过度集中
证据:
- `src/hooks/useStoryGeneration.ts:868-930` 进入 hook 后立即开始定义交易、送礼、招募、角色聊天等子流程
- `src/hooks/useStoryGeneration.ts:3191-3303` 返回对象同时暴露剧情、任务、NPC UI、角色聊天 UI、背包/锻造 UI
- `src/components/GameShell.tsx:293-360` 组件 props 很多,内部 state 也很多,承担“壳层 + 流程 + 浮层 + 自定义世界生成 + 场景切换”
- `src/hooks/useCombatFlow.ts:559-1787` 将战斗计算和战斗演出揉在同一层里
影响:
- 任何一个新需求都容易同时碰到剧情、UI、战斗、背包、NPC 关系四五条链路
- 代码 review 很难聚焦,改动一处时往往需要脑内跟完整条大流程
- 单元测试难写,因为逻辑不是纯函数,而是大量闭包 + 过程式状态推进
- 长期会形成“只有熟悉历史上下文的人才能安全修改”的隐性门槛
建议:
-`useStoryGeneration` 拆为“剧情推进”“NPC 交互”“角色聊天”“任务结算”“模态框控制”几个子域
-`useCombatFlow` 拆成“纯战斗结算引擎”和“战斗播放适配层”
-`GameShell` 回到壳层职责,只负责路由态、页面态、模态挂载与 props 编排
- 以“领域职责”拆分,而不是按“文件太长了随便切一刀”拆分
## P0缺少真正的工程质量门禁
证据:
- `package.json:11``lint` 实际只有 `tsc --noEmit`
- `package.json` 中没有 `test``format``lint:fix` 等基础脚本
- 根目录未发现 `.eslintrc*``.prettierrc*``.editorconfig`
- 代码目录下没有测试文件
影响:
- 当前项目的“能过 lint”只代表类型没炸不代表风格一致、依赖正确、Hooks 规则正确、死代码已清理
- 大型 hook / 大型组件的重构几乎没有自动回归保护
- 运行时行为、编辑器行为、AI fallback 行为主要依赖人工回归
建议:
- 补齐 ESLint、Prettier、EditorConfig至少覆盖 React Hooks、import、unused code、复杂度基线
- 引入 Vitest先覆盖纯数据层与纯规则层
-`useCombatFlow``stateFunctions``npcInteractions``questFlow` 增加单元测试
- 为“开局 -> 选世界 -> 选角色 -> 进入剧情 -> 战斗 -> 存档恢复”补最小 E2E smoke
- CI 中至少串联:类型检查 + 单测 + build + 内容校验
## P1编辑器、运行时、类后端能力全部耦合在 Vite 配置里
证据:
- `vite.config.ts:151-203` 在 Vite 插件里实现了 LLM 代理
- `vite.config.ts:206-269` 在 Vite 插件里实现了通用 JSON 文件读写 API
- `vite.config.ts:253` 直接写回 `src/data/*.json`
- `vite.config.ts:265-266``vite.config.ts:400-401``preview` 阶段也挂了这些接口
- `vite.config.ts:425-434` 启动时默认把这些“编辑器后端能力”全部注册进去
影响:
- 本地编辑器能力与运行时能力没有清晰边界
- `preview` 环境仍可写源码文件,发布边界不清晰
- 未来如果要做独立部署、多人协作、远程编辑、权限控制,会非常难迁移
- Vite 配置同时扮演构建配置、代理层、文件服务层、编辑器后端,职责失衡
建议:
- 将编辑器读写 API 从 `vite.config.ts` 抽到独立的本地工具服务或独立脚本
- 至少区分 `dev-only write api``preview/prod read-only api`
- 对编辑器保存接口建立统一客户端 SDK避免组件直接散落 `fetch('/api/...')`
- LLM 代理也建议独立成 `server/``scripts/dev-server/`,不要继续长在构建配置里
## P1持久化策略分散且直接序列化大状态对象
证据:
- `src/hooks/useGamePersistence.ts:152-167` 会在状态变化时自动把完整快照写入 `localStorage`
- `src/hooks/useGamePersistence.ts:157-163` 快照包含 `gameState + bottomTab + currentStory`
- `src/hooks/useGamePersistence.ts:68-116` 恢复逻辑已经开始承担大量 schema 纠偏职责
- `src/data/customWorldLibrary.ts:1-282` 自定义世界库单独维护一套 `localStorage` 读写与 normalize
- `src/hooks/useGameSettings.ts` 也单独维护一套本地设置持久化
影响:
- 状态结构一旦继续膨胀,快照写入频率和反序列化成本都会增加
- schema 迁移会越来越依赖手工 normalize 补丁
- 不同持久化入口各写一套 parser / normalizer风格和鲁棒性难统一
- 当前保存的是“运行中大对象”,而不是“稳定领域快照”,长期会放大兼容成本
建议:
- 建立统一的 persistence 层,集中管理 key、version、migration、节流、序列化策略
-`GameState` 做“可持久化切片”和“运行时临时切片”分层
- 自动保存增加节流/去抖,避免每次状态波动都全量落盘
- 如果继续扩展角色聊天、自定义世界、编辑器草稿,建议评估 IndexedDB 替代 `localStorage`
## P1运行时与编辑器仍在同一个前端入口体系中包体继续膨胀
证据:
- `src/main.tsx:21-34` 通过 `window.location.pathname` 手写分发页面
- `src/main.tsx:60` 只有“游戏”和“PresetEditor”两个大入口
- `PresetEditor``ItemCatalogEditor``StateFunctionEditor` 都属于重型模块
- 构建产物已经出现 `App``407 KB``itemCatalog``414 KB` 的 chunk
影响:
- 游戏端与编辑器端的演进节奏被绑定在一个 SPA 入口上
- 编辑器相关数据和静态资源容易继续抬高构建体积
- 未来增加更多编辑器页、更多世界模板、更多资源目录后,冷启动成本会更明显
建议:
- 将编辑器拆成独立入口,至少做成独立 route module而不是单个 `PresetEditor`
- 继续下钻按 tab 做懒加载,尤其是 `items/functions/npcs`
- 将静态大数据、资源目录索引、编辑器专用预览逻辑做更细的 chunk 拆分
- 如果项目后续会长期保留编辑器,建议直接分成 game app / editor app 两个 entry
## P2编辑器基础设施重复实现较多
证据:
- `src/components/PresetEditor.tsx:111-181` 自己实现 `cloneValue``saveJsonObject`
- `src/components/StateFunctionEditor.tsx:113-130` 再次实现 `cloneValue``SectionCard`
- `src/components/ItemCatalogEditor.tsx:94` 再次实现保存请求
- `src/hooks/useInventoryFlow.ts:8``src/hooks/useEquipmentFlow.ts:10``src/hooks/useForgeFlow.ts:12``src/hooks/useTreasureFlow.ts:10` 重复声明 `CommitGeneratedState`
影响:
- 修改保存行为、错误处理、深拷贝策略时需要多处同步
- 编辑器 UI 风格与交互行为容易逐步漂移
- 公共契约没有收拢到共享层,维护成本会逐步抬高
建议:
-`editor/shared/` 层,集中放保存 SDK、表单字段、卡片容器、克隆工具、错误处理
- 抽通用的 `CommitGeneratedState` 类型定义
- 将编辑器请求和覆盖保存逻辑统一走一个 client
## P2类型系统已经出现“总文件过载”
证据:
- `src/types.ts` 共 663 行
- `src/types.ts:1-260` 同时包含世界、动画、技能、对话、自定义世界、物品等类型
- `src/types.ts:536-663` 又继续承接剧情、聊天、任务、`GameState`、AI 响应
影响:
- 任一领域类型变化都会增加总文件冲突概率
- 新人理解类型边界成本高
- 编辑器类型、运行时类型、AI 传输类型被放在一起,不利于演化
建议:
- 按领域拆分:`types/combat.ts``types/story.ts``types/item.ts``types/customWorld.ts``types/persistence.ts`
- `GameState` 相关类型与 editor override 类型分开
- AI request/response contract 单独收口,避免继续堆进总类型文件
## P2AI 客户端层过厚,且重复了多套请求与解析逻辑
证据:
- `src/services/ai.ts` 共 1153 行
- `src/services/ai.ts:540-605``608-678``745-790` 分别手写了 JSON completion、纯文本 completion、流式 completion
- `src/services/ai.ts:680-697` 手写了多段 JSON 解析兜底
- `src/services/ai.ts:76-78``591-594``662-666` 主要依赖 `console.*` 打日志
影响:
- LLM 行为扩展时容易继续复制请求模板、错误处理、超时逻辑
- 错误分类不够稳定,观测主要停留在 console 层
- prompt、transport、fallback、parse 被放在一起,后续测试和替换模型都不够轻
建议:
-`llmClient`,统一 transport、timeout、stream、error taxonomy
-`llmParsers`,将 JSON parse / plain text parse / suggestion parse 独立
- 为关键 prompt 输出建立 fixture 测试,至少覆盖 fallback 与异常响应
- 如果后续要接多个模型,尽早把 provider 层和 prompt 层解耦
## P2手写路由与死代码开始累积
证据:
- `src/main.tsx:21-34` 采用手写 `pathname.startsWith(...)`
- `src/components/GameShell.tsx:1511` 存在 `false && showTeamModal`
影响:
- 路由能力不具备可扩展性,也不利于后续加 404、重定向、权限判断、嵌套路由
- 死代码继续堆积后,会误导维护者对真实入口和真实 UI 状态的判断
建议:
- 引入正式路由层,哪怕只做轻量路由也比手写分发更清晰
- 清理已经废弃的 UI 分支和不可达逻辑
- 对“临时下线的功能”改为 feature flag 或明确注释,不要用 `false &&`
## 建议落地顺序
### 第一阶段:先补工程底座
- 增加 ESLint / Prettier / EditorConfig
- 增加 `test` 脚本与 Vitest
- 把 CI 最小闭环搭起来类型检查、单测、build、内容校验
### 第二阶段:先拆边界,再拆大文件
- 先把 Vite 中的编辑器写文件接口、LLM 代理抽走
- 再把 `GameShell``useStoryGeneration``useCombatFlow` 按职责拆域
- 拆分时优先保持外部接口稳定,避免一次性全仓大改
### 第三阶段:收敛基础设施
- 统一 persistence 层
- 统一 editor shared 层
- 统一 AI client 层
- 拆分 `types.ts`
### 第四阶段:降低发布成本
- 将 editor 与 game 做更明确的入口拆分
- 优化 chunk 边界
- 评估是否把编辑器做成独立 app
## 一句话结论
这个仓库当前最需要优化的不是“再补几个功能”,而是**把已经验证有效的玩法与工具链,从“靠大文件和经验串起来”升级为“靠清晰边界、统一基础设施和自动化门禁支撑起来”**。只要这一步不做,后续每次加内容、加编辑器能力、加 AI 流程,工程成本都会持续上升。

View File

@@ -0,0 +1,290 @@
# 工程优化审查报告2026-03-30
## 审查范围
- 扫描范围:`src/``scripts/``docs/``.github/``package.json``tsconfig.json``vite.config.ts`
- 实际执行:`npm run lint``npm run test``npm run build``npm run check:content`
- 说明:按仓库要求,本报告不讨论中文乱码问题,只讨论工程结构、边界、质量门禁、可维护性和后续扩展成本
## 先说结论
这轮代码库相较 `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md` 已经有明显进展,项目不再是“所有能力都糊在一个入口文件里”的状态了,但整体仍然处于“重构过渡期”。
已经落地的积极变化:
- 入口路由已经从手写 `pathname` 分发,收敛到 `src/main.tsx` + `src/routing/appRoutes.tsx`
- 持久化能力已经抽到 `src/persistence/`
- 编辑器公共能力已经出现 `src/editor/shared/`
- `CI + ESLint + Prettier + Vitest` 已经接入
- 本地 API 插件已经从 `vite.config.ts` 抽走,落到 `scripts/dev-server/localApiPlugins.ts`
- `preview` 环境里的 JSON 写入接口已经改成只读,这一点比上轮更安全
但当前仍然存在 5 个值得优先处理的工程问题:
1. 运行时主链仍然过于集中,`story/combat` 的真实边界还没有彻底拆开
2. `src/services/ai.ts` 仍处于迁移中间态,存在重复实现和旧逻辑残留
3. 编辑器主入口仍是大型聚合组件,迁移残留没有清干净
4. 质量门禁已经有框架但还不够“硬”warning 和测试覆盖缺口仍然明显
5. 运行时渲染层和构建体积仍偏重,重 UI 模块还没拆到合适粒度
## 当前运行状态
- `npm run test` 通过6 个测试文件共 18 个测试全部通过
- `npm run build` 通过
- `npm run check:content` 通过
- `npm run lint` 通过,但仍有 76 条 warning
当前构建产物里仍然存在较重 chunk
- `dist/assets/GameCanvas-*.js``346.58 kB`
- `dist/assets/App-*.js``326.89 kB`
- `dist/assets/index-*.js``197.80 kB`
- `dist/assets/index-*.css``117.37 kB`
## P0运行时主链仍然过于集中Story/Combat 边界还没有拆透
### 现状
虽然 `App.tsx` 已经明显瘦身,`GameShell` 也比之前更像壳层,但真正决定游戏推进的主逻辑仍然高度集中在两个大 hook 里:
- `src/hooks/useStoryGeneration.ts:824`
- `src/hooks/useCombatFlow.ts:382`
### 证据
`useStoryGeneration` 仍然同时编排了多个本应继续拆开的子领域:
- `src/hooks/useStoryGeneration.ts:852` 接入 `useCharacterChatFlow`
- `src/hooks/useStoryGeneration.ts:1583` 接入 `useTreasureFlow`
- `src/hooks/useStoryGeneration.ts:1588` 接入 `useInventoryFlow`
- `src/hooks/useStoryGeneration.ts:1593` 接入 `useEquipmentFlow`
- `src/hooks/useStoryGeneration.ts:1597` 接入 `useForgeFlow`
- 文件总长仍有约 `3240`
- 结尾返回对象同时暴露剧情推进、地图旅行、NPC 交易/送礼/招募、角色聊天、背包与锻造 UI 能力,典型位置在 `src/hooks/useStoryGeneration.ts:3171-3219`
`useCombatFlow` 也不是纯计算层,它仍然同时承担:
- 战斗前后状态推导
- 动画播放与时间推进
- `setGameState` 驱动的可视化编排
- 逃跑流程与 story 响应同步
关键位置:
- `src/hooks/useCombatFlow.ts:382` `useCombatFlow`
- `src/hooks/useCombatFlow.ts:1195` `playEscapeSequenceWithStorySync`
### 影响
- 任何一个“剧情选项新增”都很容易同时碰到 battle、npc、quest、inventory、chat 五条链路
- review 成本高,回归范围判断依赖人脑上下文
- 单测很难往 hook 级别补,因为副作用、异步节奏和 UI 状态混在一起
- 后续想继续做 camp、custom world、更多 companion 玩法时,改动会继续集中到这两个入口
### 建议
-`useStoryGeneration` 继续下钻成“剧情推进 orchestrator + 领域 action service”
- `useStoryGeneration` 自己只保留编排,不再直接维护 trade/gift/recruit/chat/inventory/forge 的全部细节
- `useCombatFlow` 继续向“纯战斗结算”和“播放适配层”分离
- 先稳定公开接口,再做内部拆分,避免一次性大改
## P1AI 服务迁移只完成了一半,`src/services/ai.ts` 仍然存在双轨实现
### 现状
仓库已经新增了:
- `src/services/llmClient.ts`
- `src/services/llmParsers.ts`
- `src/services/aiFallbacks.ts`
- `src/services/aiTypes.ts`
这说明拆层方向是对的。但 `src/services/ai.ts` 还没有真正变成“纯 orchestration 层”,里面仍然保留着一整套旧 transport / parse / fallback 逻辑。
### 证据
- `src/services/ai.ts:64-66` 已经开始导入 `llmClient`
- `src/services/ai.ts:89-95` 仍然保留本地 `resolveTimeoutMs` 和超时常量
- `src/services/ai.ts:647` 仍然保留 `_requestPlainTextCompletion`
- `src/services/ai.ts:719` 仍然保留 `_parseJsonResponseText`
- `src/services/ai.ts:739` 仍然保留 `_parseLineListContent`
- `src/services/ai.ts:784` 仍然保留 `_streamPlainTextCompletion`
- `src/services/ai.ts:885-904` 仍然保留一批旧的 `_buildOffline...` helper
与之对应,新的实现已经在下面这些文件里存在:
- `src/services/llmClient.ts`
- `src/services/llmParsers.ts`
### 影响
- 同一类能力现在有两套真相源后续改错误分类、超时策略、SSE 行为时容易漏改
- 新同学读代码时很难判断应该继续改 `ai.ts`,还是应该去改 `llmClient.ts`
- 迁移残留会拉高维护成本,也会让测试边界变得模糊
### 建议
-`src/services/ai.ts` 收敛成“业务 prompt 编排 + fallback 选择”层
- 彻底删掉未再需要的 `_requestPlainTextCompletion``_streamPlainTextCompletion``_parse*` 等旧 helper
- 所有 transport / timeout / connectivity error / SSE 解析都只保留在 `llmClient.ts``llmParsers.ts`
- 迁移完成后,给 `ai.ts` 增加一组 orchestration 级测试,防止 fallback 分支回归
## P1编辑器主入口仍然太重而且过渡态残留还在
### 现状
编辑器公共能力已经开始沉淀到 `src/editor/shared/`,这是好事;但主编辑器入口仍然比较重,且部分文件还保留着迁移过程里的死代码和注释块。
### 证据
`PresetEditor` 仍然是一个大型聚合组件:
- `src/components/PresetEditor.tsx:402` `CharacterPresetPanel`
- `src/components/PresetEditor.tsx:1174` `SceneNpcPresetPanel`
- `src/components/PresetEditor.tsx:1547` `ScenePresetPanel`
- `src/components/PresetEditor.tsx:1852` `MonsterPresetPanel`
- `src/components/PresetEditor.tsx:2218` `PresetEditor`
- 文件总长仍有约 `2279`
同时,文件里还留着明显的过渡态残留:
- `src/components/PresetEditor.tsx:227` 仍然保留未使用的 `_SectionCard`
- `src/components/NpcVisualEditor.tsx:684` 保留 `if (false)` 的旧保存路径
- `src/components/NpcVisualEditor.tsx:685` 明确写着 “Deprecated inline save path kept only until the shared client migration is cleaned up.”
- `src/components/NpcVisualEditor.tsx:724` 还有第二处 `if (false)` 残留
### 影响
- 编辑器后续继续扩展时,容易重新长回“大一统文件”
- 过渡代码会误导维护者,以为旧保存链路仍然有效
- 公共层虽然建起来了,但如果不清理旧代码,长期会形成“共享层 + 本地特例”并存
### 建议
- 以“一个 tab 一个容器”的方式,把 `PresetEditor` 再拆一层
- 清理 `NpcVisualEditor` 里的废弃代码块,不要再保留 `if (false)` 分支
- 对编辑器共享层设定明确规则保存请求、克隆、Section 容器、错误提示都必须走 shared
- 对编辑器做一次“小型迁移完成清扫”,优先删掉已经废弃但还挂在文件里的旧路径
## P1质量门禁已经接上但还不够硬
### 现状
基础设施已经比上轮完整很多,但当前门禁仍然偏“有检查,不够严格”。
### 证据
当前 lint 结果:
- 本次 `npm run lint` 实际输出 `76` 条 warning虽然命令返回成功
脚本和规则层面的原因也很明确:
- `package.json:12``lint` 仍然是 `eslint . ... && tsc --noEmit`,没有 `--max-warnings 0`
- `package.json:11``lint:guardrails` 虽然加了 `--max-warnings 0`,但它只覆盖一组显式 allowlist 文件
- `package.json:18``check` 会先跑 `lint:guardrails`,再跑宽松版 `lint`
- `.eslintrc.cjs:45-61` 里大量规则仍然是 `warn`
- `.github/workflows/ci.yml:28-40` 已经把 `lint / guardrails / test / build / check:content` 都接到 CI但 warning 仍能稳定进主干
测试覆盖也还是偏薄:
- `src/` 当前共有 `126` 个文件
- 其中测试文件只有 `6`
- 现有测试主要覆盖 `routing``persistence``jsonClient``llmParsers``battlePlan`
- 关键主链如 `useStoryGeneration``useCombatFlow` 播放层、`GameShell` 集成链路、编辑器保存流程仍然没有直接测试
### 影响
- 代码库会持续积累“已知 warning但先不处理”的债务
- 工程信号会逐渐失真lint 通过不代表代码足够干净
- 大 hook 和大组件的重构依然主要依赖人工回归
### 建议
- 先把 warning 收敛到一个可控范围,再把全仓 `lint` 切成 `--max-warnings 0`
- `lint:guardrails` 不要长期靠 allowlist应该逐步扩大到全仓
- 优先补三类测试:
- `useStoryGeneration` 的状态推进和 modal 决策
- `useCombatFlow` 播放层的关键分支
- 编辑器保存链路和覆盖数据回写
## P2运行时渲染层仍然偏重chunk 也还没有拆到理想粒度
### 现状
入口已经有了 route lazy load模态框也做了一部分懒加载但核心运行时渲染层仍然比较重。
### 证据
- `src/components/AdventurePanel.tsx:470` 导出主组件,文件总长约 `1538`
- `src/components/GameCanvas.tsx:472` 导出主组件,文件总长约 `1131`
- `src/components/GameCanvas.tsx:768` 仍然存在 `false && companions.map(...)` 的死分支
- 本次构建里 `GameCanvas``App` 仍然是最大 chunk 之一
### 影响
- 运行时页面的首屏与热区模块仍然偏重
- 渲染逻辑、场景动画逻辑、实体选中逻辑继续堆在同一层review 和测试都偏吃力
- 清理死分支前,维护者对“哪些渲染路径是真实生效的”判断成本更高
### 建议
- `GameCanvas` 继续拆成 scene layer、entity layer、effect layer、overlay layer
- `AdventurePanel` 继续下沉 quest/stats/settings/reward 子面板
- 清理 `false &&` 与未使用辅助组件,避免假分支继续留在主路径文件中
- 结合真实 chunk 数据做一次 route 内部分包,而不是只靠入口级 lazy
## P2TypeScript 安全基线仍然偏宽松
### 现状
当前类型拆分方向是好的,`src/types.ts` 已经退化成 barrel真实类型开始向 `src/types/` 下沉。但 TypeScript 编译配置还比较保守,类型系统还没有真正变成强约束。
### 证据
- `tsconfig.json:12` `skipLibCheck: true`
- `tsconfig.json:16` `allowJs: true`
- 当前没有启用 `strict`
- 当前没有启用 `noUncheckedIndexedAccess`
### 影响
- 对大对象和字典访问的保护仍然偏弱
- 新模块迁移到更细类型后,收益会被宽松编译选项部分抵消
- “代码能过类型检查”并不等于边界足够安全
### 建议
- 不建议一次性全仓开严格模式
- 可以先从 `src/services/``src/persistence/``src/hooks/combat/` 这些相对纯的目录启更严格约束
- 至少先评估开启 `noUncheckedIndexedAccess` 和减少 `allowJs` 的必要性
## 建议的落地顺序
### 第一阶段:先把过渡态清干净
- 清理 `ai.ts` 的旧 transport / parser / fallback 实现
- 清理 `NpcVisualEditor``GameCanvas``PresetEditor` 等文件里的 `if (false)`、未使用 helper、废弃注释块
- 把 lint warning 数量先打下来
### 第二阶段:拆主链,不再让大 hook 继续膨胀
- 继续拆 `useStoryGeneration`
- 继续拆 `useCombatFlow`
- 优先把“领域动作”和“播放/展示编排”分开
### 第三阶段:补门禁
- 给主链补单测和少量集成 smoke
- 让全仓 lint 朝 `--max-warnings 0` 收敛
- 把 warning 从“长期存在”变成“短周期清零”
### 第四阶段:优化运行时体积
- 细化 `GameCanvas``AdventurePanel` 的模块边界
- 按实际交互热区做 chunk 继续拆分
- 用真实构建产物持续追踪是否降重
## 一句话结论
这轮仓库已经从“完全依赖大文件硬扛”进步到“基础设施开始成形”,但当前最需要做的已经不是继续加功能,而是把这轮重构收尾做完整:继续拆主链、删掉迁移残留、把 lint/test 门禁变硬、再顺手压缩运行时大模块。只要这一步补上,后续加剧情、加编辑器能力、加自定义世界都会轻很多。

View File

@@ -0,0 +1,200 @@
# 工程优化审查报告2026-04-01
## 审查范围
- 扫描范围:`src/``scripts/``docs/``.github/``package.json``tsconfig*.json``vite.config.ts``vitest.config.ts`
- 审查方式:阅读当前工作区代码结构,抽查核心运行时、编辑器、服务层与开发脚本,并执行工程命令验证现状
- 当前快照说明:仓库存在大量未提交改动,本报告基于当前工作区状态,不假定这些改动都已经合入主分支
- 说明:按仓库要求,不把中文乱码本身当成本次审查重点;只讨论工程结构、门禁、可维护性、可测试性和扩展成本
## 已执行检查
- `npm run lint:eslint`
结果:失败。`src/components/ItemCatalogEditor.tsx:167` 存在未使用的 `isSearchPending``startTransition`
- `npm run typecheck`
结果:通过
- `npm run test`
结果:通过,默认套件实际执行 10 个测试文件、28 个测试
- `npm run build`
结果:通过,但 `src/services/customWorldPresentation.ts:163-169` 出现 duplicate key 警告
- `npm run check:content`
结果:通过
## 当前结论
这轮代码库已经明显比前几版更有工程骨架了,至少有这些积极变化:
- `src/main.tsx` + `src/routing/appRoutes.tsx` 已经承担了入口路由分发
- `src/App.tsx` 已经比过去瘦很多,主流程开始交给 hook 和壳组件
- `src/components/PresetEditor.tsx` 已经成为较薄的 lazy shell而不是继续堆成巨型入口
- `src/editor/shared/jsonClient.ts``src/persistence/``src/hooks/combat/``src/hooks/story/` 这些目录说明仓库已经开始做分层
- CI、Vitest、ESLint、内容校验脚本都已经接上不再是完全裸奔状态
但从工程角度看,当前最值得优先优化的,不是继续加功能,而是把“半完成的工程化”补齐。核心问题集中在 6 个方面。
## P0质量门禁和真实风险点仍然脱节
### 现状
仓库已经引入了 lint、typecheck、test、build 和 content checks但关键热区并没有真正纳入统一门禁。
### 证据
- `.eslintrc.cjs:47-63``ignorePatterns` 直接跳过了多个高复杂度核心文件:
`src/components/AdventurePanel.tsx``src/components/NpcVisualEditor.tsx``src/components/preset-editor/PresetEditorPanels.tsx``src/hooks/useStoryGeneration.ts``src/services/customWorldPresentation.ts`
- `tsconfig.typecheck-guardrails.json:6-15` 只对非常有限的一小组文件开启严格类型检查,远没有覆盖主运行时链路
- `vitest.config.ts:8-10``customWorldPresentation` 映射到 stub`vitest.config.ts:20` 还排除了真实存在的 `src/services/ai.test.ts`
- 当前 `src/` 下共有 161 个文件,测试文件共有 11 个,但默认套件只执行其中 10 个
- `npm run build` 已经能暴露 `src/services/customWorldPresentation.ts:163-169` 的 duplicate key 警告,但这块文件同时被 ESLint ignore、被 Vitest stub 掉,说明真实风险没有被完整看见
### 影响
- 工程信号不一致:`test` 绿、`build` 过,不代表关键模块真的健康
- 复杂模块越是难测,越容易被长期豁免,最后演变成“最关键的地方最不受控”
- 后续重构会缺乏可靠的回归保护review 只能更多依赖人工记忆
### 建议
- 先缩小 `.eslintrc.cjs` 的 ignore 范围,优先把 `useStoryGeneration.ts``customWorldPresentation.ts``PresetEditorPanels.tsx` 拉回 lint
-`src/services/ai.test.ts` 重新纳入默认测试套件,除非有明确且短期的阻塞原因
- 不要长期依赖 `tsconfig.typecheck-guardrails.json` 的 allowlist至少把 `src/hooks/``src/services/``src/components/game-shell/` 逐步纳入 strict 范围
- 对 build warning 建立明确策略:要么在 CI 中失败,要么把 warning 收敛到零
## P0当前工作区不在真正的绿色基线
### 现状
当前代码不是“纯优化空间”问题,而是已经存在直接可见的门禁破口。
### 证据
- `package.json:11-15``lint:eslint``typecheck` 定义成正式脚本,说明它们本来就属于项目基线
- 实际执行 `npm run lint:eslint` 时,`src/components/ItemCatalogEditor.tsx:167` 报出未使用变量错误
- `src/components/ItemCatalogEditor.tsx:167` 引入了 `useTransition()` 返回值,但当前组件没有消费它
- `npm run build` 虽然成功,但 `src/services/customWorldPresentation.ts:163-169` 仍然有重复 object key 警告
### 影响
- 团队会越来越难区分“可接受的技术债”和“已经破坏基线的问题”
- 继续叠加功能会把问题扩散到更多文件,后面补起来成本更高
### 建议
- 先恢复工作区绿色基线,再继续推进大功能
- 把“lint 零错误、build 零 warning”作为下一轮工程整理的硬目标
## P1运行时主链路仍然被少数超级模块吸住
### 现状
入口已经变薄,但主复杂度仍集中在少数大文件里,尤其是故事推进、战斗同步和界面编排三层。
### 证据
- `src/hooks/useStoryGeneration.ts` 当前约 2210 行
- `src/hooks/useStoryGeneration.ts:694` 导出主 hook`src/hooks/useStoryGeneration.ts:1416` 接入 `useTreasureFlow`,后面还继续承接 NPC 互动、库存、打字机、AI、历史推进和故事回写
- `src/hooks/useCombatFlow.ts:134` 是主战斗 hook`src/hooks/useCombatFlow.ts:796-832` 仍然负责逃跑流程与 story sync 的耦合
- `src/components/GameShell.tsx` 当前约 791 行,`src/components/GameShell.tsx:260-269` 管理一组本地 UI 状态,`src/components/GameShell.tsx:482` 继续处理场景切换时的选择编排
- 构建产物里 `dist/assets/App-*.js` 约 389 kB`dist/assets/index-*.js` 约 198 kB说明主运行时 chunk 仍然偏重
### 影响
- 任何一个功能变化都容易跨 story、combat、transition、panel 几条链一起改
- hook 单测越来越难写,因为副作用、异步和 UI 编排仍然混在一起
- App 主 chunk 偏重,会继续拖累首屏和回归速度
### 建议
- 继续把 `useStoryGeneration` 收敛成 orchestration 层,把 treasure、NPC、inventory、chat、typewriter、AI 回写拆成更纯的领域 action
-`useCombatFlow` 更明确地区分“战斗结算”和“播放同步”
-`GameShell` 进一步下沉为 scene transition、selection flow、overlay panel 三类 view-model
## P1编辑器共享层只迁移了一半重复基础设施还在
### 现状
编辑器入口已经做了 shell 化,但真正的复杂度仍然堆在大型面板组件里,而且共享层没有吃干净。
### 证据
- `src/components/PresetEditor.tsx:41` 的入口已经很薄,说明方向是对的
-`src/components/preset-editor/PresetEditorPanels.tsx` 仍然约 2163 行
- `src/components/preset-editor/PresetEditorPanels.tsx:55` 仍然自带 `cloneValue`
- `src/components/preset-editor/PresetEditorPanels.tsx:117` 仍然自带 `saveJsonObject`
- `src/components/preset-editor/PresetEditorPanels.tsx:189` 仍然自带 `SectionCard`
- 与之对应,`src/editor/shared/jsonClient.ts:29-40` 已经提供了共享版 `fetchJson` / `saveJsonObject`
- `src/components/preset-editor/PresetEditorPanels.tsx:364``:1128``:1500``:1806` 仍然把四个大型 panel 放在同一个文件里
### 影响
- 编辑器的保存、错误处理、基础 UI 容器会继续多处复制,后续很难统一行为
- 迁移看起来开始了,但没有真正收尾,维护者仍然需要在“大文件 + 共享层”之间来回切换
### 建议
- 继续把 `PresetEditorPanels.tsx` 拆成按 tab 或按领域分文件
- 统一复用 `src/editor/shared/` 下的保存客户端、基础容器、表单片段
- 对编辑器做一次“小型迁移收尾”,目标是消灭重复的基础 helper
## P1本地开发 API 层与构建工具耦合过深
### 现状
本地 API 插件已经把很多临时逻辑吸收进项目内部,这是好事;但它现在承担的职责太多,且全部挂在 Vite 插件层。
### 证据
- `vite.config.ts:7-18` 直接把 `createLocalApiPlugins(__dirname, env)` 注入到 Vite config
- `scripts/dev-server/localApiPlugins.ts` 当前约 394 行
- `scripts/dev-server/localApiPlugins.ts:150` 定义 LLM proxy 插件
- `scripts/dev-server/localApiPlugins.ts:216` 定义通用 JSON 文件编辑插件
- `scripts/dev-server/localApiPlugins.ts:265` 直接把编辑器保存结果写回 `src/data/*.json`
- `scripts/dev-server/localApiPlugins.ts:429` 再统一把所有插件拼到一起
### 影响
- dev server、preview server、编辑器持久化和 LLM 代理被绑在一个文件里,测试与替换成本都偏高
- 随着编辑器继续扩张,这个文件会继续演化成“隐形后端”
- 生产与开发环境的边界容易模糊,问题排查也更依赖熟悉 Vite 插件机制的人
### 建议
- 至少先按职责把 `localApiPlugins.ts` 拆成 `llm-proxy``json-editor-api``asset-catalog` 三块
- 下一阶段可以考虑把编辑器 API 抽成独立本地服务层,而不是继续塞在 Vite 插件里
- 给 JSON 写入接口补 schema 校验,而不只是“是 object 就写入”
## P2构建体积仍有继续优化空间
### 现状
路由 lazy load 和部分 modal lazy load 已经做了,但主游戏运行时包仍然偏大。
### 证据
- `dist/assets/App-*.js` 约 389 kB
- `dist/assets/index-*.js` 约 198 kB
- `dist/assets/index-*.css` 约 117 kB
- `src/components/GameShell.tsx``src/hooks/useStoryGeneration.ts``src/services/prompt.ts` 仍然是较大的主链路文件
### 影响
- 新人本地启动、构建和回归阅读成本仍然偏高
- 主运行时模块越重,越不利于后续继续做场景扩展和编辑器共存
### 建议
- 优先沿着“运行时 orchestration 拆分”去减主 chunk而不是单纯追求更多 lazy import
-`prompt`、自定义世界、编辑器预览等非首屏关键代码继续做边界拆分
- 每轮重构后用真实构建产物复测,而不是只凭代码体感判断
## 建议的落地顺序
1. 先恢复绿色基线:修掉 `ItemCatalogEditor` lint 错误,处理 `customWorldPresentation` 的 duplicate key warning
2. 再补齐门禁:缩小 ESLint ignore、把 `ai.test.ts` 拉回默认测试、扩大 strict typecheck 覆盖
3. 然后拆主链:优先处理 `useStoryGeneration``useCombatFlow``GameShell`
4. 再做编辑器迁移收尾:拆 `PresetEditorPanels.tsx`,统一共享层
5. 最后处理 dev API 分层和 bundle 体积
## 一句话结论
这个仓库已经从“功能堆叠期”进入“工程收尾期”了。当前最值得做的不是再加一层玩法,而是把门禁补齐、把超级模块拆开、把半迁移状态收尾;只要这一步做稳,后续继续扩展剧情、编辑器和自定义世界的成本都会明显下降。

View File

@@ -0,0 +1,173 @@
# 怪物-NPC 脚本统一整改审计
日期2026-04-06
## 核心结论
当前工程仍然没有真正落实“怪物就是初始好感度为负数的 NPC”这一原则。
现状不是“NPC 脚本里支持 hostile 状态”,而是同时存在两条并行链路:
1. `npc / encounter / npcStates / npcInteraction`
2. `monster / hostileNpc / sceneMonsters / sceneHostileNpcs / hostileNpcPresets`
这会直接导致:
- 同一个敌对实体同时拥有 NPC 身份和 monster 身份。
- 场景、战斗、渲染、提示词都在维护两套入口。
- 后续修 bug 时,任何位置、死亡、血条、入场、掉落问题都要同时查两条链路。
本次文档的目标不是立刻改代码,而是先把应该删除的分叉脚本、应该降级成素材层的文件、以及必须合并的字段全部列清楚,作为后续统一改造的依据。
## 当前违背原则的根因
### 1. 场景数据仍然把“怪物”和“NPC”当成两类实体
当前场景层同时维护:
- `ScenePreset.monsterIds`
- `SceneNpc[]`
- `ScenePresetInfo.hostileNpcIds`
- `SceneNpc.monsterPresetId / hostileNpcPresetId`
这意味着场景里一个敌对单位既可以来自 `monsterIds`,也可以来自 `npcs`,甚至会被脚本再生成为 hostile scene npc。
### 2. 运行时仍然存在“怪物专用实体状态”
当前运行时仍然同时维护:
- `GameState.sceneMonsters`
- `GameState.sceneHostileNpcs`
- `SceneHostileNpc / SceneMonster`
这和“怪物本质上只是 hostile NPC”是冲突的。真正统一后运行时只应该保留一套“场景 NPC / 战斗 NPC”状态。
### 3. 战斗脚本仍然把怪物当独立 actor
战斗层目前不是“NPC 战斗,只是 hostile 的那部分会出手”,而是显式写了:
- `TurnActor = 'player' | 'companion' | 'monster'`
- `getClosestMonster`
- `resetCombatPresentation(monsters, ...)`
- `sceneMonsters` 全链路结算
这会强制后面所有视觉、掉落、提示词、AI 上下文都跟着叫 monster。
### 4. 渲染层仍然有 monster 专属显示入口
画布层当前仍然依赖:
- `sceneMonsters`
- `sceneHostileNpcs`
- `monsterPresetId`
- `HostileNpcAnimator`
也就是“敌对 NPC 是否按 NPC 脚本渲染”这件事,到最终显示层仍然没有统一。
## 一级删除清单
下面这些文件属于“业务流程分叉脚本”,不是单纯资源适配层。后续统一时应优先删除或并入 NPC 主链路。
| 文件 | 当前分叉角色 | 处理建议 |
| --- | --- | --- |
| `src/data/monsters.ts` | 对 `hostileNpcs.ts` 的别名出口 | 直接删除,禁止继续保留 monster 专属入口名。 |
| `src/data/hostileNpcs.ts` | 负责 monster 创建、编队、距离、朝向、变化、落位 | 按 hostile NPC 运行时工具重写并并入 NPC 体系;原文件名不应继续保留。 |
| `src/data/sceneEncounterPreviews.ts` | 单独构造 hostile encounter group、auto battle、hostile preview | 删除 monster 专线逻辑,改为“负好感 NPC 预览/入场/转战斗”。 |
| `src/hooks/combat/battlePlan.ts` | 使用 `monster` actor、`sceneMonsters``getClosestMonster` | 改成统一的 hostile NPC combatant 规划脚本monster actor 概念应移除。 |
| `src/hooks/combat/playback.ts` | 使用 `sceneMonsters` 播放怪物战斗演出 | 改成统一 NPC 战斗回放;不再区分 monster 播放器。 |
| `src/components/game-canvas/GameCanvasRuntime.tsx` | 运行时按 `sceneMonsters / sceneHostileNpcs` 双数据源选敌方实体 | 删除双源兜底,统一成单一 hostile NPC 列表。 |
| `src/components/game-canvas/GameCanvasEntityLayer.tsx` | 敌方实体按 monsterPreset 分支渲染 | 改成同一套 NPC 实体渲染,视觉差异仅由 visual preset 决定。 |
| `src/components/game-canvas/GameCanvasShared.tsx` | 定义 `sceneMonsters / sceneHostileNpcs` props 与 monster 专属计算 | 删除这些字段与 helper改成统一 NPC 画布协议。 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | 独立怪物预设编辑面板 | 并回 NPC hostile visual preset 面板,或删除该独立编辑器入口。 |
| `src/components/preset-editor/MonsterPresetTab.tsx` | 独立怪物预设页签 | 与上面一并删除或并入 NPC preset 编辑器。 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | 仍然单独编辑 `monsterIds` | 删除 `monsterIds` 编辑项,只保留场景 NPC 列表。 |
## 二级归并清单
下面这些文件不一定需要物理删除,但它们当前仍然在放大 monster / NPC 分轨,必须在统一改造时一起收口。
| 文件 | 当前问题 | 处理建议 |
| --- | --- | --- |
| `src/data/scenePresets.ts` | 通过 `monsterIds` 再生 hostile scene npc并区分 `getSceneHostileNpcs / getSceneFriendlyNpcs` | 保留场景数据文件本身,但删除 `monsterIds` 体系,让敌对角色直接存在于 `npcs` 中。 |
| `src/data/customWorldNpcMonsters.ts` | 用单独脚本推导“怪物型 NPC”预设 | 可保留为 hostile visual preset 选择器,但不能再生成第二套实体语义。 |
| `src/data/hostileNpcPresets.ts` | 目前既是视觉预设库,也是独立 hostile 流程的数据源 | 降级为 hostile visual/combat preset 库;不再拥有独立实体生命周期。 |
| `src/components/HostileNpcAnimator.tsx` | 当前名字和调用语义都在暗示“独立怪物实体” | 可以保留为贴图播放器,但应改为 hostile NPC 的视觉适配组件,而不是独立物种脚本。 |
| `src/components/AdventureEntityModal.tsx` | 详情弹窗仍会优先查 monster preset / hostileNpcPreset | 统一读取 NPC 档案;视觉差异只通过 hostile preset 补充。 |
| `src/components/SkillEffectPreview.tsx` | 预览器直接使用 `sceneMonsters``createSceneMonstersFromIds` | 改成统一 hostile NPC 预览态。 |
| `src/components/StateFunctionEditor.tsx` | 编辑器里仍然直接造 monster battle preview | 改成 hostile NPC preview。 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | 仍然暴露 `monsterPresetId` 字段 | 改成更明确的 hostile visual preset 字段避免“怪物类型”和“NPC 类型”双语义。 |
| `src/hooks/story/npcEncounterActions.ts` | 虽然入口叫 npc但内部仍然写 `sceneMonsters / sceneHostileNpcs` | 改成统一 hostile NPC 战斗状态字段。 |
| `src/hooks/story/choiceActions.ts` | 仍然有 `buildHostileNpcBattleReward``getResolvedSceneHostileNpcs` 这一层额外概念 | 统一到 hostile NPC 结算工具,不再把“敌对 NPC”和“monster”混称。 |
| `src/hooks/useStoryGeneration.ts` | 给 AI/剧情层传入 `sceneMonsters``sceneHostileNpcs` | 改成统一的 hostile NPC 上下文切片。 |
| `src/services/prompt.ts` | 仍然从 `monsterIds``createSceneMonstersFromIds` 组 prompt | 改成从场景 NPC 列表中筛出 hostile NPC。 |
| `src/services/questDirector.ts` | 仍然依赖 `monsterPresetId` 推导当前敌对目标 | 统一改为基于负好感或 hostile 标记的 NPC。 |
| `src/services/ai.ts` | 仍然混用 `monsterIds`、sceneNpc 的 hostile 判定 | 与场景统一后改成只读 NPC 列表。 |
| `src/services/questTypes.ts` | 仍然把 `hostileNpcIds / monsterIds` 当作 scene 快照字段 | 删除 `monsterIds`,保留 hostile NPC 语义。 |
## 可保留但必须降级为“素材/配置层”的内容
下面这些内容不一定要消失,但不能继续作为独立业务链路存在:
| 文件/内容 | 可以保留的原因 | 必须收口的边界 |
| --- | --- | --- |
| `src/components/HostileNpcAnimator.tsx` | 怪物贴图是特殊资源,需要专门 sprite sheet 播放器 | 只负责画图,不再决定实体类型、战斗身份、交互入口。 |
| `src/data/hostileNpcPresets.ts` | hostile visual/combat preset 仍然有价值 | 只能作为 hostile NPC 的 visual/combat preset 库不再驱动另一套“monster 实体”。 |
| `src/data/hostileNpcOverrides.json` | 资源级 override 仍可继续用 | 不能再配套出独立 hostile 流程。 |
| `src/data/monsterOverrides.json` | 如果只是素材映射,可迁移到 hostile visual preset override | 不应继续以 monster 专属命名长期存在。 |
| `src/data/customWorldNpcMonsters.ts` | 自定义世界里确实需要从文本匹配 hostile visual preset | 只能产出“NPC 使用哪个 hostile visual preset”不能产出独立 monster 身份。 |
## 字段级必须合并的内容
后续改代码时,至少要把下面这些字段和类型一起收口:
| 当前字段/类型 | 问题 | 合并方向 |
| --- | --- | --- |
| `ScenePreset.monsterIds` | 场景里额外保存一份怪物池 | 删除,只保留 `npcs`。 |
| `ScenePresetInfo.hostileNpcIds` | 历史遗留双字段 | 直接由 `npcs.filter(initialAffinity < 0 或 hostile)` 推导。 |
| `Encounter.monsterPresetId` | 把 hostile NPC 再次物种化 | 改成 hostile visual preset 字段,或并入统一 visualRef。 |
| `Encounter.hostileNpcPresetId` | 与 `monsterPresetId` 语义重叠 | 与上面合并为一个字段。 |
| `GameState.sceneMonsters` | 把敌对 NPC 单独塞进 monster 容器 | 改成统一 `sceneNpcCombatants` 或等价单一列表。 |
| `GameState.sceneHostileNpcs` | 历史兼容层,导致双数据源 | 删除。 |
| `SceneHostileNpc / SceneMonster` | 类型名直接固化了分轨 | 改成统一的 hostile NPC / scene combat NPC 类型。 |
| `SceneHostileNpcChange / SceneMonsterChange` | 继续复制同一套变更结构 | 合并成统一 NPC scene change。 |
| `SceneNpc.monsterPresetId / hostileNpcPresetId` | 同一实体上挂两套 preset 入口 | 收敛为一个 hostile visual/combat preset 字段。 |
## 本轮最优先的删除顺序
建议后续真正改代码时,按下面顺序删并,风险最低:
1. 先删字段入口:`monsterIds / sceneHostileNpcs / hostileNpcPresetId`
2. 再删运行时双轨:`src/data/monsters.ts``src/data/hostileNpcs.ts``src/data/sceneEncounterPreviews.ts`
3. 再删战斗双轨:`battlePlan.ts``playback.ts` 里的 `monster` actor 与 `sceneMonsters`
4. 再删画布双轨:`GameCanvasRuntime.tsx``GameCanvasEntityLayer.tsx``GameCanvasShared.tsx`
5. 最后清编辑器和提示词:`MonsterPresetPanel.tsx``MonsterPresetTab.tsx``prompt.ts``questDirector.ts`
## 改造后的目标形态
统一后应只剩下这一套语义:
- 场景中所有可见角色都放在 `npcs`
- 怪物 = `initialAffinity < 0``hostile = true` 的 NPC
- hostile 的视觉差异只来自 hostile visual preset
- 战斗中所有敌方单位都属于 hostile NPC combatant
- AI、任务、渲染、详情、掉落都只读同一套 NPC 数据
如果后面代码里还出现下面这些关键词,基本都说明分轨没有删干净:
- `sceneMonsters`
- `sceneHostileNpcs`
- `monsterIds`
- `hostileNpcPresetId`
- `createSceneMonstersFromIds`
- `getClosestMonster`
- `TurnActor = 'monster'`
## 这份文档的使用方式
后续正式开始改造时,建议把文件分成三批执行:
1. “直接删掉”的入口脚本
2. “改名并并回 NPC 主链路”的桥接脚本
3. “仅保留素材职责”的 renderer / preset 文件
不要继续接受“名字叫 NPC但内部仍然先转成 monster 再跑”的中间态。

View File

@@ -0,0 +1,19 @@
# 工程优化审查总览
这一组是同主题的连续审查记录,建议不要把它们当作三份彼此独立的文档来看。
## 当前推荐入口
1. [ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md](./ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md)
这一版最适合作为当前工程基线,重点从“是否真正绿色”“门禁有没有覆盖真实风险”来判断仓库状态。
2. [ENGINEERING_OPTIMIZATION_REVIEW_2026-03-30.md](./ENGINEERING_OPTIMIZATION_REVIEW_2026-03-30.md)
适合回看运行时主链路、Story/Combat 边界、分层过渡期问题。
3. [ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md](./ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md)
适合看第一轮系统性工程扫描,了解最早的问题基线。
## 融合结论
- 三轮结论是一致收敛的:问题不在“有没有开始工程化”,而在“工程化是否真正覆盖了最危险的主链路”。
- 最新一轮已经把关注点集中到质量门禁、真实绿色基线、关键模块豁免和 build warning 上。
- 如果只是为了判断现在先做什么,直接从 `2026-04-01` 开始即可。
- 如果是要做长期重构方案,再按 `2026-03-29 -> 2026-03-30 -> 2026-04-01` 的顺序回看演进。

View File

@@ -0,0 +1,91 @@
# 中文乱码位置清单
更新时间:`2026-03-24`
## 说明
- 本文档用于记录仓库内已确认或高置信度疑似存在中文乱码的位置。
- 当前这份文档是重建版本;原有的 [`docs/audits/text/CHINESE_MOJIBAKE_INVENTORY.md`](/E:/Repos/Genarrative/docs/audits/text/CHINESE_MOJIBAKE_INVENTORY.md) 本身也已经乱码,因此已整体替换。
- 本次整理依据:
- 仓库内旧清单中的完整文件/行号信息
- 本轮人工复核时再次直接看到的明显乱码位置
- 由于仓库内同时存在“文件内容已写坏”和“终端/工具显示失真”两类情况,下面清单优先保留高置信位置,便于后续逐项修复。
## 扫描范围
- 已纳入:`src/``docs/`、根目录文档与元数据文件
- 已排除:`.git/``node_modules/``dist/`、纯图片资源目录
## 高置信位置
### 文档与元数据
- [`docs/experience/AGENT_UI_CHANGELOG.md`](/E:/Repos/Genarrative/docs/experience/AGENT_UI_CHANGELOG.md)1, 3, 7, 9, 11-18, 24, 26-28, 32-33, 37, 39, 41-43, 47, 49, 51, 53-66, 68, 72, 74, 77-79, 83, 87, 89-90, 94, 96, 98-100, 104, 106-112, 116
- [`UI_CODING_STANDARD.md`](/E:/Repos/Genarrative/UI_CODING_STANDARD.md)3, 91, 104, 108, 112, 156, 158, 160-166
- [`metadata.json`](/E:/Repos/Genarrative/metadata.json)2-3
### 组件层
- [`src/components/AdventurePanel.tsx`](/E:/Repos/Genarrative/src/components/AdventurePanel.tsx)57, 65
- [`src/components/CharacterPanel.tsx`](/E:/Repos/Genarrative/src/components/CharacterPanel.tsx)37, 65-66, 91-95, 102-103
- [`src/components/GameCanvas.tsx`](/E:/Repos/Genarrative/src/components/GameCanvas.tsx)240, 462
- [`src/components/GameShell.tsx`](/E:/Repos/Genarrative/src/components/GameShell.tsx)108, 116, 124, 138, 171, 181
- [`src/components/InventoryPanel.tsx`](/E:/Repos/Genarrative/src/components/InventoryPanel.tsx)55, 58, 82-83, 181-184, 189, 191
- [`src/components/MapModal.tsx`](/E:/Repos/Genarrative/src/components/MapModal.tsx)105, 108, 136
- [`src/components/MedievalNpcAnimator.tsx`](/E:/Repos/Genarrative/src/components/MedievalNpcAnimator.tsx)124
- [`src/components/NpcVisualEditor.tsx`](/E:/Repos/Genarrative/src/components/NpcVisualEditor.tsx)65, 69-71, 403, 440, 444, 446, 464, 467, 470, 482, 569, 571, 585, 610, 628, 662, 690, 694-695, 697, 722, 751, 759, 775, 777, 781, 824
- [`src/components/PresetEditor.tsx`](/E:/Repos/Genarrative/src/components/PresetEditor.tsx)34-37, 43-44, 94, 96, 349, 470, 472, 480, 482, 512, 516, 519, 525, 568, 612, 618, 637, 639, 643, 645, 652, 661, 677, 740, 769, 771, 779, 781, 806, 809, 820, 831, 835, 837, 840, 848, 871, 894, 916, 918, 930, 932, 950, 953, 956, 960, 962, 990, 1004, 1006, 1012, 1018, 1024, 1030, 1036, 1064, 1120, 1122, 1130, 1132, 1150, 1153, 1156, 1172-1175, 1180, 1182, 1186, 1188, 1199, 1203-1204, 1208, 1240, 1242
### 数据层
- [`src/data/characterPresets.ts`](/E:/Repos/Genarrative/src/data/characterPresets.ts)97, 102, 104, 107, 129, 132-133, 142, 144, 170, 276, 302, 470, 496, 531, 540, 566, 699-700, 729, 972
- [`src/data/medievalNpcVisuals.ts`](/E:/Repos/Genarrative/src/data/medievalNpcVisuals.ts)103, 115, 117, 119, 136, 154, 156, 161, 167, 174, 177, 189, 226, 235-236, 241, 244-245, 249-254, 256-257, 260, 262, 274, 278, 288, 451-453, 565, 568, 577, 592
- [`src/data/monsterPresets.ts`](/E:/Repos/Genarrative/src/data/monsterPresets.ts)41-42, 54, 60-61, 79-80, 92, 98-99, 117-118, 136-137, 155-156, 171-173, 185, 191-192, 204, 210-211, 229-230, 242, 248-249, 261, 267-268, 280, 286-287, 304-305, 323-324, 335
- [`src/data/monsters.ts`](/E:/Repos/Genarrative/src/data/monsters.ts)112
- [`src/data/npcInteractions.ts`](/E:/Repos/Genarrative/src/data/npcInteractions.ts)68-71, 80, 82-83, 161, 165, 173, 182, 188-190, 196, 198, 205, 231, 241, 245, 255-260, 272, 296, 319-320, 372, 444-445, 449, 451, 453, 507, 569-570, 578-579, 587-588, 597, 605-606, 615, 617-618, 626-627, 634, 641-643, 652, 661, 665, 670, 672, 676
- [`src/data/scenePresets.ts`](/E:/Repos/Genarrative/src/data/scenePresets.ts)115, 120, 122, 128, 133, 135, 141, 146, 148, 154, 159, 161, 167, 172, 174, 180, 185, 187, 192-193, 198, 200, 205-206, 211, 213, 219, 224, 226, 232, 237, 239, 245, 250, 252, 258, 263, 265, 274, 279, 281, 287, 292, 294, 299-300, 305, 307, 313, 318, 320, 326, 331, 333, 339, 344, 346, 352, 357, 359, 364-365, 370, 372, 377-378, 383, 385, 390-391, 396, 398, 404, 409, 411, 417, 422, 424, 509, 523, 525
- [`src/data/stateFunctions.ts`](/E:/Repos/Genarrative/src/data/stateFunctions.ts)72-73, 80, 95-96, 103, 117-118, 125, 139-140, 147, 161-162, 169, 186-187, 194, 209-210, 217, 237-238, 255-256, 273-274, 294, 311-312, 329-330, 420, 430-431, 433-435, 437-438, 440-442, 444-445, 447, 449, 451-452, 454-456, 458, 460-461, 464, 466, 468, 484-485, 487, 489, 491, 493, 601, 618
### Hooks 与服务层
- [`src/hooks/useCombatFlow.ts`](/E:/Repos/Genarrative/src/hooks/useCombatFlow.ts)54, 56-58, 566
- [`src/services/ai.ts`](/E:/Repos/Genarrative/src/services/ai.ts)200-201, 209-210, 234-235, 269-270, 309, 311, 317, 338, 341, 358, 382
- [`src/services/prompt.ts`](/E:/Repos/Genarrative/src/services/prompt.ts)7-8, 10, 13-15, 19-20, 25-40, 43, 55, 61-62, 64, 66, 74-76, 78-79, 83-84, 87-90, 96, 103-104, 112, 115, 157, 159, 161-162, 164-165, 167-168, 170, 172-173
### 其他源码
- [`src/uiAssets.ts`](/E:/Repos/Genarrative/src/uiAssets.ts)54, 115, 122, 129, 142, 173, 180
## 本轮人工复核补充
以下位置是在本轮实现过程中直接再次看到的明显乱码文本,建议优先复查:
- [`src/hooks/useCombatFlow.ts`](/E:/Repos/Genarrative/src/hooks/useCombatFlow.ts)1094, 1554, 1556-1557
## 处理优先级建议
### 第一批
- `src/components/GameShell.tsx`
- `src/components/InventoryPanel.tsx`
- `src/components/CharacterPanel.tsx`
- `src/data/characterPresets.ts`
- `src/data/npcInteractions.ts`
- `src/data/scenePresets.ts`
- `src/services/prompt.ts`
### 第二批
- `src/components/PresetEditor.tsx`
- `src/components/NpcVisualEditor.tsx`
- `src/data/monsterPresets.ts`
- `src/data/stateFunctions.ts`
- `docs/experience/AGENT_UI_CHANGELOG.md`
- `UI_CODING_STANDARD.md`
## 备注
- 当前文档的目标是“先把位置收拢清楚”,不是直接修复乱码。
- 如果你下一步要我继续,我可以基于这份清单继续做两件事之一:
- 逐文件修复中文乱码
- 先做一个“乱码修复优先级 + 替换建议”文档

View File

@@ -0,0 +1,228 @@
# 编辑器 UI / 游戏 UI / 预设内容英文与乱码审计
更新时间:`2026-03-25`
## 范围与方法
- 范围只覆盖当前源码里会直接进入编辑器 UI、游戏运行时 UI、预设内容预览的文案。
- 本轮直接按 `utf-8` 读取 `src/components``src/data` 复核,不把旧审计文档当最终事实来源。
- 不统计 `import`、类型名、变量名、接口字段名、资源路径等纯开发层英文。
## 结论摘要
- 当前目标范围内,确认到 **1 处直接写进源码的中文乱码**
- `src/components/PresetEditor.tsx:72``鐗╁搧`
- 当前更大的问题已经不是“大片中文乱码”,而是 **编辑器与部分游戏界面还残留成组英文 UI 文案**
- 预设内容层面的英文主要集中在 **原始枚举值 / 构筑字段**,例如 `common / rare / legendary``neutral``buildProfile.role``idle / move / attack / die``steady / burst / mobility / finisher / projectile`。这些值本身在数据层可以保留英文,但当前有一部分被界面直接原样显示出来了。
## 编辑器 UI
### 英文残留
- `src/components/PresetEditor.tsx:84-89`
- 编辑器标签仍是 `Characters / NPCs / Scenes / Monsters / Items / Functions`
- `src/components/PresetEditor.tsx:97-104`
- 预设编辑里仍直接使用 `idle / move / attack / die``steady / burst / mobility / finisher / projectile`
- `src/components/StateFunctionEditor.tsx:333-367`
- 预览实体与效果摘要仍是英文:
- `Preview NPC`
- `Fallback NPC preview for ...`
- `Preview Treasure`
- `Treasure preview for ...`
- `Damage x / Incoming x / Heal + / Mana + / Cooldown + / Turn x`
- `src/components/StateFunctionEditor.tsx:496-607`
- 预览阶段与提示说明仍有整段英文:
- `Player Turn Preview`
- `Escape Preview`
- `Travel Result Preview`
- `Explore Preview`
- `Call-Out Preview`
- `Idle Behavior Preview`
- `Predicted skill: ...`
- `Monster counter template uses ...`
- `Battle behaviors are driven by skill weights ...`
- `Escape behaviors always use the chase flow ...`
- `src/components/StateFunctionEditor.tsx:855-939`
- 预览面板头部与信息卡仍是英文:
- `Option`
- `Mode`
- `Replay Preview`
- `Preview Playing`
- `Preview Ready`
- `Live Player`
- `Live Scene`
- `No scene`
- `Resolved Plan`
- `Option kind`
- `Target scene`
- `Cooldowns`
- `Battle Snapshot`
- `Animation`
- `Delivery`
- `Damage`
- `Predicted kill`
- `Target survives`
- `Snapshot based on live playback`
- `src/components/ItemCatalogEditor.tsx:25`
- 稀有度选项仍是 `common / uncommon / rare / epic / legendary`
- `src/components/ItemCatalogEditor.tsx:486-560`
- 物品预览区仍直接显示英文键和值:
- `rarity`
- `value`
- `usable`
- `yes / no`
- `equip`
- `world`
- `neutral`
- `HP / MP / Damage / Guard`
- `HP Restore / MP Restore / CD Reduce`
- `Build / 套装`
- `Role / Set / Piece`
- `none / standalone`
- `src/components/NpcVisualEditor.tsx`
- 目前大部分文案已中文化,但 `NPC` 缩写仍在标题、字段、保存提示中大量保留,属于低优先级统一项,不是乱码问题。
### 确认的中文乱码
| 文件 | 位置 | 当前文本 | 判断 |
| --- | --- | --- | --- |
| `src/components/PresetEditor.tsx` | `72` | `鐗╁搧` | 明确乱码,语义应为“物品” |
### 编辑器 UI 小结
- **最高优先级乱码修复点**`PresetEditor.tsx:72`
- **最高优先级英文清理点**`StateFunctionEditor.tsx``ItemCatalogEditor.tsx`
## 游戏各界面 UI
### 英文残留
- `src/components/GameShell.tsx:414`
- 标题副标仍是 `TAVERNREALMS`
- `src/components/GameShell.tsx:1083-1094`
- 团队弹窗里仍保留 `TavernRealms`
- `src/components/CharacterChatModal.tsx:52,73,76`
- `CHARACTER CHAT`
- `HP`
- `MP`
- `src/components/CharacterDetailModal.tsx:24-40`
- 属性与技能风格映射仍为英文:
- `Strength / Agility / Intelligence / Spirit`
- `Burst / Steady / Mobility / Finisher / Projectile`
- `Female / Male / Unknown`
- `src/components/CharacterDetailModal.tsx:149,186,194-271`
- 详情弹窗区块标题与标签仍有整段英文:
- `INITIAL COMPANION`
- `Close character details`
- `Profile`
- `Candidate`
- `Gender`
- `Stats`
- `Max HP / Max MP`
- `Journey`
- `Reason / Goal`
- `Skills / Loadout / Pack / Backstory / Personality`
- `src/components/InventoryPanel.tsx:39-50`
- 稀有度标签仍是 `Legendary / Epic / Rare / Uncommon / Common`
- `src/components/InventoryPanel.tsx:179-196,215`
- 物品详情仍是英文:
- `Quantity`
- `Owner`
- `Usable`
- `Yes / No`
- `Equipable`
- `Value`
- `Type`
- `Tags`
- `no-tags`
- `src/components/AdventureEntityModal.tsx:206-217`
- 自动生成的物品描述仍是英文整句:
- `helps restore HP`
- `supports MP recovery`
- `fits offensive loadouts`
- `supports defensive gearing`
- `works as a rare trinket-grade pickup`
- `can be saved for crafting or trading`
- `${item.name} can be kept for trading, gifting, or future build planning.`
- `${item.name} is a ${item.category} item that ...`
- `src/components/AdventureEntityModal.tsx:226-235`
- 物品属性摘要仍是英文:
- `HP`
- `MP`
- `Damage`
- `Guard x...`
- `src/components/AdventureEntityModal.tsx:1271-1332`
- NPC 物品详情弹窗仍有一整块英文:
- `ITEM DETAIL`
- `NPC inventory`
- `Quantity`
- `Value`
- `Equip Slot`
- `Not equippable`
- `Usable item`
- `Story, trade, or gift resource`
- `Type`
- `Rarity`
- `Tags`
- `No tags`
- `src/components/CompanionCampModal.tsx:152,176-177,213,216`
- `Active`
- `HP`
- `MP`
- `待命 roster`
- `Reserve`
- `src/components/NpcModals.tsx:507`
- 招募替换提示里仍混入 `roster`
### 当前未确认到的乱码
- 本轮没有在游戏运行时 UI 组件里复核到新的、直接写死在源码中的中文乱码。
- 当前游戏 UI 的主要问题已经转为“英文标签 / 英文句子未汉化”,不是大面积中文乱码。
## 预设内容
### 直接会透到 UI 的英文源
- `src/data/itemDesign.ts:52-72`
- 材质主题里直接保存了英文原始值:
- `worldAffinity: "neutral"`
- `role: "fieldcraft" / "breaker" ...`
- `rarity: "common"`
- `tags: ["scout", "craft"]`
- `src/data/itemCatalog.ts:260-270`
- `designed.rarity / designed.worldAffinity / designed.buildProfile` 会原样流入物品目录数据
- `src/components/ItemCatalogEditor.tsx:486-560`
- 上述原始字段当前会在编辑器预览里被直接显示,因此形成了可见英文泄漏
- `src/data/questFlow.ts:24-30`
- 任务奖励物品稀有度仍是 `rare / uncommon`
- `src/data/npcInteractions.ts:71-82,102-103,166`
- 稀有度与标签推断仍使用 `common / uncommon / rare / epic / legendary`
- 物品标签仍使用 `weapon / armor`
- `src/components/PresetEditor.tsx:97-104`
- 预设编辑直接使用 `idle / move / attack / die`
- 技能风格直接使用 `steady / burst / mobility / finisher / projectile`
- `src/components/StateFunctionEditor.tsx:85-98`
- 行为编辑直接使用 `battle / idle`
- 朝向直接使用 `left / right`
- 怪物动画直接使用 `idle / move / attack`
- 风格直接使用 `steady / burst / mobility / finisher / projectile`
### 当前未确认到的乱码
- 本轮没有在 `src/data/*.ts` 的预设正文里复核到新的、直接写死的中文乱码。
- 当前预设内容层面的问题,主要是“英文字段值没有在显示层做 label 映射”,不是正文汉字被写坏。
## 建议处理顺序
1. 先修 `src/components/PresetEditor.tsx:72``鐗╁搧`
2. 再集中处理 `src/components/StateFunctionEditor.tsx` 的整组英文预览与提示文案。
3. 然后处理 `src/components/ItemCatalogEditor.tsx` 的物品预览英文键名与英文值。
4. 之后清理游戏运行时最明显的英文块:
- `src/components/CharacterDetailModal.tsx`
- `src/components/InventoryPanel.tsx`
- `src/components/AdventureEntityModal.tsx`
- `src/components/CompanionCampModal.tsx`
- `src/components/CharacterChatModal.tsx`
- `src/components/GameShell.tsx`
5. 最后为预设源字段补统一显示映射,把 `common / rare / legendary / neutral / idle / left / right ...` 全部收口到统一词典。

View File

@@ -0,0 +1,91 @@
# 游戏 UI / 预设 / 编辑器 UI 英文与乱码复查
日期:`2026-03-29`
## 结论摘要
- 当前分支里,**确认存在源码级中文乱码的文件只有 1 个**`src/components/CustomWorldEntityEditorModal.tsx`
- 历史上已经出现过的两处高风险乱码,本次**未复现**
- `src/components/GameShell.tsx` 角色选择页返回按钮
- `src/data/npcInteractions.ts` 切磋敌对动作文案
- 目前更主要的问题已经从“大面积乱码”转成了三类:
- 运行时 UI 里的英文缩写或英文句子
- 编辑器 UI 里的英文术语、原始枚举值和英文缩写
- 预设数据中的英文名称、分类、标签、世界倾向、构筑角色等原始值直接透到 UI
## 复查口径
- 只统计会直接进入游戏 UI、编辑器 UI、预设预览或运行时详情的文本。
- 不把纯内部实现名算进问题范围,比如接口路径、变量名、导入路径、素材文件夹名。
- 终端输出已切换到 UTF-8 后复查,避免把“控制台显示乱码”误判成“源码真实乱码”。
## 一、已确认的源码级乱码
### 1. 编辑器 UI
| 文件 | 行号 | 当前文本 | 说明 |
| --- | --- | --- | --- |
| `src/components/CustomWorldEntityEditorModal.tsx` | `360`, `381` | `褰撳墠浼氱洿鎺...``棰勮 #...` | 场景预设选择弹窗的说明文案和预设编号标签已写坏 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `551`, `559`, `569`, `572`, `578`, `581`, `584`, `587` | `褰撳墠澶栬妯℃澘``褰㈣薄妯℃澘``鍚嶇О``绉板彿 / 韬唤``鑳屾櫙``鎬ф牸``鎴樻枟椋庢牸``鏍囩` | 可扮演角色编辑表单的标题与字段标签存在真实乱码 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `663`, `666`, `669`, `672` | `鍚嶇О``韬唤 / 鑱岃兘``鎻忚堪``鍔ㄦ満` | 普通 NPC 编辑表单字段标签存在真实乱码,即“创建自定义世界 -> NPC 编辑页”这一段 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `721`, `732`, `736`, `739` | `鍦烘櫙``棰勮鍥句腑鐨勫垏纾...``鍚嶇О``鎻忚堪` | 场景编辑器默认回退文案、说明文案和字段标签存在真实乱码 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `771`, `791` | ``瑙掕壊-${...}``、`['绾跨储', '浜掑姩']` | 默认新建数据本身带乱码,会继续流入编辑器与结果页 |
## 二、游戏 UI 中的英文残留
| 文件 | 行号 | 当前文本/值 | 说明 |
| --- | --- | --- | --- |
| `src/components/AdventurePanel.tsx` | `179-187` | `restores HP during an adventure run`、`fits offensive loadouts` 等整句英文 | 奖励物品自动描述仍是英文句子,会直接进入运行时奖励详情 |
| `src/components/AdventureEntityModal.tsx` | `815-816`, `988`, `1124-1126`, `1497` | `HP`、`MP` | 玩家、怪物、NPC 状态条与效果预览仍使用英文缩写 |
| `src/components/AdventureEntityModal.tsx` | `1071`, `1109`, `1426` | `NPC 信息`、`敌对NPC` / `NPC`、`NPC 背包` | NPC 相关标题和标签仍是中英混排 |
| `src/components/CompanionCampModal.tsx` | `176-177`, `232-233`, `254` | `HP`、`MP`、`NPC` | 同行编队卡片和空态提示仍保留英文缩写 |
| `src/components/NpcModals.tsx` | `251`, `355`, `407` | `NPC 商品列表`、`NPC 商品`、`HP` / `MP` | 商店弹窗标题和物品效果预览仍是中英混排 |
| `src/components/CharacterDetailModal.tsx` | `117` | `数量 x{item.quantity}` | 数量前缀里仍保留英文乘号写法 |
## 三、编辑器 UI 中的英文残留
| 文件 | 行号 | 当前文本/值 | 说明 |
| --- | --- | --- | --- |
| `src/components/ItemCatalogEditor.tsx` | `601`, `617-623` | `neutral / wuxia / xianxia`、`tag` 原始值 | 世界倾向和标签直接显示原始英文值 |
| `src/components/ItemCatalogEditor.tsx` | `637-651`, `689` | `HP`、`MP`、`Build Buff`、`CD` | 属性预览、使用效果和背包卡片预览仍有英文缩写/术语 |
| `src/components/ItemCatalogEditor.tsx` | `662-665` | `buildProfile.role`、`synergy` 原始值 | 构筑角色和协同标签直接暴露英文角色定位值 |
| `src/components/ItemCatalogEditor.tsx` | `712`, `824`, `841` | `物品 ID`、`使用 Build Buff`、`套装 ID` | 字段标签里仍有 `ID` / `Build Buff` |
| `src/components/StateFunctionEditor.tsx` | `843-846`, `910` | `HP`、`No visible target` | 预览摘要和实时状态里仍有英文缩写与整句英文 |
| `src/components/StateFunctionEditor.tsx` | `1089-1091` | `Option behavior overrides saved.`、`Failed to save option behavior overrides` | 保存反馈文案仍是英文 |
| `src/components/StateFunctionEditor.tsx` | `1133`, `1212`, `1218` | `definition.state`、`AnimationState`、`idle/move/attack` | 原始状态值和动画值仍直接显示 |
| `src/components/PresetEditor.tsx` | `86-88`, `2212` | `NPC`、`敌对 NPC` | 页签和说明文案仍有 `NPC` 英文缩写 |
| `src/components/PresetEditor.tsx` | `893-910`, `1997-2000` | `AnimationState`、`steady/burst/...`、`idle/move/attack/die` | 技能动作、技能风格、怪物预览动作直接显示原始英文枚举值 |
| `src/components/PresetEditor.tsx` | `942`, `1015`, `1142`, `1456`, `1477`, `1483`, `1752`, `1788`, `1796`, `2037`, `2137`, `2174` | `Build Buff`、`ID`、`FPS` | 多个编辑字段和动画配置项仍保留英文术语 |
| `src/components/NpcVisualEditor.tsx` | `568-571`, `581`, `817` | `NPC 视觉编辑器`、`当前 NPC`、`x / y` | 标题、字段名和坐标显示仍有英文缩写 |
## 四、预设 / 数据层中的英文残留
这些内容虽然不一定直接在当前文件里渲染,但会进入运行时详情、掉落展示、物品编辑器、预设编辑器或交易界面。
| 文件 | 行号 | 当前文本/值 | 透出路径 |
| --- | --- | --- | --- |
| `src/data/monsterPresets.ts` | `438-456`, `479-499`, `535-540`, `647-650` | `Material`、`Relic`、`Armor`、`Consumable`、`Stone Shell Shard`、`Blood Lens`、英文描述句子、`rare/uncommon`、`material/relic/mana` | 会进入怪物掉落、物品详情、交易弹窗和编辑器预览 |
| `src/data/itemDesign.ts` | `56-72`, `123-149`, `602-604`, `761-762`, `832-834` | `worldAffinity` 的 `neutral/wuxia/xianxia``role` 的 `fieldcraft/breaker/caster/berserker/assassin``tags` 的 `breaker/burst/mana``pieceName` 的 `dust/crystal/gem`,以及 `build` 混排短语 | 会直接透到 `ItemCatalogEditor` 的世界、标签、构筑角色、协同标签和套装信息 |
| `src/data/characterPresets.ts` | `368-379`, `384-386`, `525-543`, `839-857`, `1024-1045` | `Double Jump`、`jump attack`、`Wall Slide`、`blunt/dry/direct`、`wary/fragmented` 等原始动作名和对话风格值 | 会被 `PresetEditor` 的动作/风格选择器直接显示 |
## 五、未复现的问题
- `src/components/GameShell.tsx` 角色选择页返回按钮旧乱码已修复,当前为“返回”。
- `src/data/npcInteractions.ts` 旧的切磋动作乱码已修复,当前为“敌对/切磋前蓄力,点击后转为原地闪避”。
- 本次扫描 `src/components`、`src/data` 未发现 `<EFBFBD>`replacement character类型的编码损坏。
- 除 `src/components/CustomWorldEntityEditorModal.tsx` 外,本次未再确认到新的源码级中文乱码文件。
- 自定义世界的 NPC 视觉编辑组件 `src/components/CustomWorldNpcVisualEditor.tsx` 本次未发现新的乱码。
## 六、建议处理顺序
1. 先修 `src/components/CustomWorldEntityEditorModal.tsx` 的真实乱码。
2. 再清理 `src/components/AdventurePanel.tsx` 和 `src/data/monsterPresets.ts` 的整句英文,因为它们最容易直接破坏玩家观感。
3. 为高频缩写和枚举值补统一映射层:
- `NPC`
- `HP` / `MP` / `CD`
- `worldAffinity`
- `role`
- `tags`
- `AnimationState`
- 技能风格 `steady/burst/mobility/finisher/projectile`
4. 最后统一编辑器里所有 `ID`、`FPS`、`Build Buff` 之类术语的显示策略。

View File

@@ -0,0 +1,87 @@
# 游戏 UI / 预设 / 编辑器 UI 英文与乱码复核
日期:`2026-03-30`
## 结论摘要
- 当前分支里,确认仍在真实渲染的源码级乱码主要集中在 2 个文件:
- `src/components/GameShell.tsx`
- `src/components/CustomWorldEntityEditorModal.tsx`
- `src/components/NpcVisualEditor.tsx` 中确实还留有旧乱码字符串,但位于 `/* ... */` 注释块里,本次不计入“当前 UI 问题”。
- 英文残留仍然较多,主要分为三类:
- 游戏运行时界面的英文标题、空态文案和缩写
- 编辑器界面的英文术语、英文保存反馈和原始枚举值
- 预设 / 数据层中的英文名称、标签、角色定位、动画目录和 build 相关原值直接透到 UI
## 复核口径
- 显式按 UTF-8 读取文件,避免把终端编码问题误判成源码乱码。
- 只统计会进入游戏 UI、编辑器 UI、预设预览或结果页的文本。
- 注释块、变量名、导入路径、接口路径等内部实现名不计入本次问题清单。
- 英文残留部分以下表中的“当前确实会显示或透传”的高优先级项为主。
## 一、已确认的真实乱码
| 范围 | 文件 | 行号 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| 游戏 UI | `src/components/GameShell.tsx` | `565` | `瑙掕壊` | 主界面底部“角色”页签已写坏 |
| 游戏 UI | `src/components/GameShell.tsx` | `578` | `鍐掗櫓` | 主界面底部“冒险”页签已写坏 |
| 游戏 UI | `src/components/GameShell.tsx` | `591` | `鑳屽寘` | 主界面底部“背包”页签已写坏 |
| 游戏 UI | `src/components/GameShell.tsx` | `710` | `闃熶紞` / `鑳屽寘` | 浮层标题根据面板切换时会显示乱码 |
| 编辑器 UI | `src/components/CustomWorldEntityEditorModal.tsx` | `386` | `宸查€?` | 场景预设选择弹窗中的“已选中”状态标签已写坏 |
| 编辑器 UI | `src/components/CustomWorldEntityEditorModal.tsx` | `432` | `鍙栨秷` | 统一保存栏的取消按钮已写坏 |
| 编辑器 UI | `src/components/CustomWorldEntityEditorModal.tsx` | `436` | `淇濆瓨淇敼` | 统一保存栏的主按钮文案已写坏 |
## 二、游戏 UI 中的英文残留
| 文件 | 行号 | 当前文本 / 值 | 说明 |
| --- | --- | --- | --- |
| `src/components/AdventurePanel.tsx` | `363` | `Currency` | 任务奖励卡的货币标题仍是英文 |
| `src/components/AdventurePanel.tsx` | `371` | `No item bounty attached to this quest.` | 任务奖励空态文案仍是英文 |
| `src/components/AdventurePanel.tsx` | `1424-1428` | `LOOT CACHE``Tap an item icon to inspect its details.``No usable loot dropped this time, but the battle is still settled.` | 战利品弹层标题和说明仍是整句英文 |
| `src/components/AdventurePanel.tsx` | `1442` | `No loot dropped this time.` | 战利品列表空态文案仍是英文 |
| `src/components/AdventurePanel.tsx` | `1352`, `1524` | `x{item.quantity}``HP` / `MP` | 数量展示与效果预览仍保留英文缩写 |
| `src/components/AdventureEntityModal.tsx` | `892-899` | `label="HP"``label="MP"` | 同行状态估计卡仍使用英文缩写 |
| `src/components/AdventureEntityModal.tsx` | `1073`, `1111`, `1428` | `NPC 信息``敌对NPC` / `NPC``NPC 背包` | NPC 详情区仍是中英混排 |
| `src/components/CompanionCampModal.tsx` | `177-178`, `233-234`, `255` | `HP``MP``NPC` | 营地卡片和空态提示仍保留英文缩写 |
| `src/components/NpcModals.tsx` | `79`, `252`, `273`, `356`, `408` | `x{item.quantity}``NPC 商品列表``这个 NPC 当前没有可售商品。``NPC 商品``HP` / `MP` | 交易弹窗、详情弹窗和数量角标存在中英混排 |
| `src/components/CharacterDetailModal.tsx` | `117` | `数量 x{item.quantity}` | 角色详情中的数量前缀仍保留英文 `x` |
## 三、编辑器 UI 中的英文残留
| 文件 | 行号 | 当前文本 / 值 | 说明 |
| --- | --- | --- | --- |
| `src/components/ItemCatalogEditor.tsx` | `576-581`, `621-624` | `fieldcraft``breaker``mana``boots``dust``crystal``gem` 等原值 | 物品标签、构筑角色、部件名和协同信息会直接显示英文原值 |
| `src/components/ItemCatalogEditor.tsx` | `648`, `671`, `729-783`, `800` | `HP` / `MP` / `CD``物品 ID``使用 Build Buff``套装 ID` | 物品编辑器预览与字段标签仍有英文缩写 / 术语 |
| `src/components/StateFunctionEditor.tsx` | `818-821`, `885`, `915` | `HP``No visible target``n/a` | 选项行为预览面板仍有英文缩写和英文空态 |
| `src/components/StateFunctionEditor.tsx` | `1060-1064` | `Failed to save option behavior overrides``Option behavior overrides saved.` | 保存反馈仍是英文 |
| `src/components/StateFunctionEditor.tsx` | `1106`, `1185`, `1191` | `battle/idle``AnimationState` 的原始动作值、`idle/move/attack` | 状态和动作枚举值直接显示为英文 |
| `src/components/PresetEditor.tsx` | `88`, `90`, `1474-1501`, `1806-1814` | `NPC``敌对 NPC``NPC ID``关联角色 ID``敌对资源 ID``连接场景 ID` | 多个标签和页签仍保留英文缩写 / `ID` |
| `src/components/PresetEditor.tsx` | `101-106`, `896-913`, `2008-2018` | `idle/move/attack/die``steady/burst/mobility/finisher/projectile` | 角色技能和敌对资源预览会直接显示英文枚举值 |
| `src/components/PresetEditor.tsx` | `945`, `2155`, `2192` | `Build Buff``FPS` | 技能编辑和动作图集配置仍有英文术语 |
| `src/components/NpcVisualEditor.tsx` | `416-461` | `Failed to load NPC visual overrides``Failed to load NPC layout config``using bundled defaults` | NPC 视觉编辑器的加载失败提示仍是英文 |
| `src/components/NpcVisualEditor.tsx` | `678`, `718` | `Saved NPC visual overrides to ...``Saved shared NPC layout config.` | 保存成功反馈仍是英文 |
| `src/components/NpcVisualEditor.tsx` | `903`, `906`, `919`, `1226` | `NPC 视觉编辑器``当前 NPC``x ... / y ...` | 标题、字段标签与坐标信息仍存在中英混排 |
## 四、预设 / 数据层中会透到 UI 的英文值
| 文件 | 行号 | 当前文本 / 值 | 透出路径 |
| --- | --- | --- | --- |
| `src/data/monsterPresets.ts` | `494-512`, `522-540`, `647-652`, `718-723` | `Armor``Relic``Material``Consumable``Carapace Plate``Guard Core``Spore Pouch``Burst Cap``Ashfire Feather`、英文描述句子、`rare/uncommon` | 会进入怪物掉落、战利品详情、交易弹窗和物品预览 |
| `src/data/itemDesign.ts` | `56-57`, `67-68`, `123-149` | `worldAffinity: neutral/wuxia/xianxia``role: fieldcraft/breaker/caster/berserker/assassin``tags` 中的 `caster/mana/burst/assassin` | 会透到 `ItemCatalogEditor` 的世界、角色定位、标签和协同信息 |
| `src/data/itemDesign.ts` | `213-219`, `538-545`, `589-604`, `731-762`, `820-834`, `906-918` | `pieceName: boots/chest/gloves/...``build``setId``role``dust/crystal/gem` 等 | 会透到物品编辑器、套装信息和部件信息展示 |
| `src/data/characterPresets.ts` | `54-69` | `blunt/wary/dry/direct/fragmented` | 对话风格与性格归类原值会被编辑器直接显示 |
| `src/data/characterPresets.ts` | `368-379`, `525-526`, `839-850`, `1024-1025` | `Double Jump``jump attack``Wall Slide` | 角色动作目录 / 前缀原值会被 `PresetEditor` 直接显示 |
| `src/data/characterPresets.ts` | `384-386`, `541-543`, `855-857`, `1045` | `guardStyle` / `warmStyle` / `truthStyle` 对应的英文原值 | 角色预设风格字段在编辑器中仍会显示英文 |
## 五、未计入项
- `src/components/NpcVisualEditor.tsx:681-683``721-722` 的乱码字符串位于块注释内,不会进入当前界面,因此未计入本次“活跃问题”。
- `docs/*.md` 里的历史审计文档和旧清单不在本次范围内,本次只统计游戏 UI、预设和编辑器 UI。
## 六、建议处理顺序
1. 先修 `src/components/GameShell.tsx``src/components/CustomWorldEntityEditorModal.tsx` 的真实乱码,因为它们已经直接出现在主流程界面。
2. 再清理 `src/components/AdventurePanel.tsx` 的英文空态、战利品标题和 `Currency`,这是玩家最容易直接看到的一批英文。
3. 然后统一编辑器术语映射,优先处理 `HP` / `MP` / `NPC` / `ID` / `FPS` / `Build Buff` / `AnimationState`
4. 最后为 `src/data/itemDesign.ts``src/data/monsterPresets.ts``src/data/characterPresets.ts` 增加显示层映射,避免原始英文值继续直接透到编辑器和运行时界面。

View File

@@ -0,0 +1,276 @@
# 游戏 UI / 预设 / 编辑器 / npcInteraction / prompt 文本深度审计
日期:`2026-04-02`
## 说明
- 本文档基于当前仓库源码再次深搜,不直接沿用旧审计结论。
- 审计目标:找出“可能出现在游戏 UI、预设、编辑器 UI、生成链路中的文本”里仍然存在的
- `中文乱码`
- `英文直出`
- `中英混用`
- 本轮重点加查:
- `src/data/npcInteractions.ts`
- `src/services/prompt.ts`
- `src/services/characterChatPrompt.ts`
- `src/services/questPrompt.ts`
- 说明口径:
- “会显示给玩家/编辑器使用者”的文本,按高优先级记录。
- “内部英文枚举/键名,但可能泄露到 prompt、编辑器或预览”的内容也单独记录。
- 已经转成中文且当前复查无明显问题的区域,会标记为“复查通过”。
## 结论摘要
- 当前最严重的文本污染源不是单一 UI而是两条链路同时存在问题
- 运行时弹窗 / 实体详情 / NPC 交易招募弹窗
- `prompt` 生成链路
- `src/services/prompt.ts` 是当前最重灾区,既有大面积中文乱码,也混有英文结构词,会直接影响 AI 生成质量。
- `src/data/npcInteractions.ts` 里“话题 actionText / detailText”大体已是正常中文但商人来源匹配、库存种子物品类别/名称仍有明显乱码,而且阶段枚举仍是英文值。
- 预设编辑器仍然是英文和乱码高密度区,尤其是:
- `CharacterPresetPanel.tsx`
- `MonsterPresetPanel.tsx`
- `SceneNpcPresetPanel.tsx`
- `ScenePresetPanel.tsx`
- `StateFunctionEditor.tsx`
- 自定义世界 NPC/场景编辑器、NPC 视觉编辑器大体已转中文,但还残留 `NPC``AI``Shift` 等中英混用。
## 一、游戏主流程 UI 与运行时面板
### 1.1 复查通过
| 文件 | 行号 | 当前状态 | 说明 |
| --- | --- | --- | --- |
| `src/components/game-shell/PreGameSelectionFlow.tsx` | `47-49` | 通过 | 开场联系方式已改成 `QQ群``微信` |
| `src/components/game-shell/GameShellRuntime.tsx` | `147` | 通过 | 场景名兜底已改成 `当前区域` |
| `src/components/adventure-panel/AdventurePanelOverlays.tsx` | `137-158` | 通过 | 任务目标眉标、宝藏踪迹、切磋会话等主文案已是中文 |
### 1.2 仍有问题
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/game-shell/PreGameSelectionFlow.tsx` | `81``89` | 中英混用 | `正在生成核心NPC...` | `NPC` 仍在中文进度文案里直出 |
| `src/components/game-shell/GameShellOverlays.tsx` | `151` | 中文乱码 | `闃熶紞` / `鑳屽寘` | 队伍/背包弹层标题已写坏 |
| `src/components/game-shell/GameShellRuntime.tsx` | `200-201` | 英文直出 | `GENARRATIVE` | 运行时头部品牌字样仍为英文 |
| `src/components/adventure-panel/AdventurePanelOverlays.tsx` | `140` | 中英混用 | `未知敌对 NPC` | 已非乱码,但仍混入 `NPC` |
## 二、实体详情、NPC 交互弹窗、交易/招募 UI
### 2.1 `AdventureEntityModal.tsx`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/AdventureEntityModal.tsx` | `111` | 中文乱码 | `鏁屽 NPC` | hostile badge 已坏,同时混入 `NPC` |
| `src/components/AdventureEntityModal.tsx` | `113``137-146` | 英文直出 | `NPC``Player``Companion` | 标题/副标题兜底值仍为英文 |
| `src/components/AdventureEntityModal.tsx` | `221``264``272``283``296``306` | 英文直出 | `Portrait``Status``Relation``Attributes``Encounter``Inventory` | 六个主区块标题都未本地化 |
| `src/components/AdventureEntityModal.tsx` | `266-267` | 英文直出 | `HP``MP` | 状态条标签未本地化 |
| `src/components/AdventureEntityModal.tsx` | `274-275` | 英文直出 | `Affinity``Recruited: Yes/No` | 关系区块仍是英文 |
| `src/components/AdventureEntityModal.tsx` | `298-301` | 英文直出 | `Name``Context``Type``Battle mode` | 遭遇信息区块仍是英文 |
### 2.2 `NpcModals.tsx`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/NpcModals.tsx` | `251-252` | 英文直出 | `NPC inventory` / `Your inventory` / `items` | 交易栏标题和数量单位仍是英文 |
| `src/components/NpcModals.tsx` | `272` | 英文直出 | `This NPC has nothing to sell right now.` / `You have nothing to sell right now.` | 空状态未本地化 |
| `src/components/NpcModals.tsx` | `290` | 英文直出 | `Purchase total` / `Sale total` | 交易总价标题未本地化 |
| `src/components/NpcModals.tsx` | `297` | 中文乱码 | 大段价格不足提示 | 购买资金不足提示整段已坏 |
| `src/components/NpcModals.tsx` | `303` | 中文乱码 | 大段默认说明 | 未选中物品时的说明区整段已坏 |
| `src/components/NpcModals.tsx` | `350-399` | 英文直出 | `Item details``NPC item``Stock``Value``Purchase price``Buyback price``Slot``Not equippable``Usable immediately``Tags``None` | 物品详情弹窗几乎整屏英文 |
| `src/components/NpcModals.tsx` | `404` | 中文乱码 + 中英混用 | 含 `MP` 的恢复说明 | 物品使用效果提示已坏 |
| `src/components/NpcModals.tsx` | `465` | 中文乱码 | 好感变动提示 | 交易结果反馈文案已坏 |
| `src/components/NpcModals.tsx` | `500-501` | 英文直出 | `Manage companion slot``Select a current companion to rotate out before recruiting this NPC.` | 招募替换同伴弹窗未本地化 |
## 三、预设编辑器与编辑器 UI
### 3.1 复查通过或基本通过
| 文件 | 行号 | 当前状态 | 说明 |
| --- | --- | --- | --- |
| `src/components/CustomWorldEntityEditorModal.tsx` | `242` | 通过 | 图片路径占位文案已中文化,不再暴露 `URL` |
| `src/components/NpcVisualEditor.tsx` | `463` | 基本通过 | 空状态是中文,但仍混入 `NPC` |
| `src/components/CustomWorldNpcVisualEditor.tsx` | `88-91``552-765` | 基本通过 | 主体编辑项、装备类型、素材、姿态等基本都为中文 |
### 3.2 标签、枚举、面板标题问题
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/shared.ts` | `43` | 英文直出 | `NPC` | 预设编辑器顶层页签仍用英文 |
| `src/components/preset-editor/shared.ts` | `62-67` | 英文枚举外露 | `idle``move``attack``die` | 怪物动画候选仍是英文值 |
| `src/components/preset-editor/shared.ts` | `69-74` | 英文枚举外露 | `steady``burst``mobility``finisher``projectile` | 技能风格候选仍是英文值 |
| `src/components/NpcVisualEditor.tsx` | `702-708` | 中英混用 | `NPC 视觉编辑器` | 中文标题中混入 `NPC` |
| `src/components/NpcVisualEditor.tsx` | `718` | 中英混用 | `当前 NPC` | 选择器标签混入 `NPC` |
| `src/components/NpcVisualEditor.tsx` | `976-977` | 中英混用 | `拖动标记微调 NPC 的预览布局。移动时按住 Shift...` | 混入 `NPC``Shift` |
| `src/components/CustomWorldEntityEditorModal.tsx` | `482-483` | 中英混用 | `AI生成NPC形象``NPC 形象 AI 生成功能仍在开发中。` | 模态标题与副标题仍大量混用英文术语 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `635-636` | 中英混用 | `新增 NPC``编辑 NPC` | 主标题和副标题混入 `NPC` |
| `src/components/CustomWorldEntityEditorModal.tsx` | `734``762-763` | 中英混用 | `AI生成``AI生成场景``场景图片 AI 生成功能仍在开发中。` | 场景生成入口仍混入 `AI` |
| `src/components/CustomWorldEntityEditorModal.tsx` | `792-793` | 中英混用 | `npc-...``自定义NPC...` | 新建 NPC 默认 ID/名称混有英文前缀与 `NPC` |
### 3.3 `CharacterPresetPanel.tsx`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `262``264``277` | 中文乱码 | `瑙掕壊``淇濆瓨瑙掕壊瑕嗙洊` | 选择卡标题、下拉标签、保存按钮均已坏 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `320``326` | 中文乱码 | `鍔ㄧ敾``闁煎啿...` | 动画/世界标签已坏 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `418``427` | 中文乱码 | `涓栫晫``棰勮鎬墿` | 技能预览区字段标签已坏 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `313-314``402-403` | 通过 | `角色详情``技能预览` | 主体段落标题已是正常中文 |
### 3.4 `MonsterPresetPanel.tsx`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `49-50` | 英文直出 | `Saved monster overrides...``Failed to save monster overrides.` | 保存反馈未本地化 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `58-59` | 中文乱码 | 空状态整段提示 | 无怪物时的空态文案已坏 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `124-126` | 英文直出 | `Section``Editor section.``Field` | 左侧选择卡是占位英文 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `135` | 中文乱码 | `闂?` | 世界与名字之间的分隔符已坏 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `139` | 英文直出 | `Save Monster Overrides` | 保存按钮未本地化 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `158-159` | 英文直出 | `Monster Override Preview``Editor section.` | 右侧预览卡标题/说明未本地化 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `165``218``223``228``240``248``256` | 英文直出 | `Field``Name``Intro Action` | 多个字段标签仍是英文或占位文案 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `335` | 中文乱码 | 一段动画配置标签乱码 | 帧数相关字段标题已坏 |
### 3.5 `SceneNpcPresetPanel.tsx`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `159` | 英文直出 | `No NPC presets are available.` | 空状态未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `177-193` | 英文直出 | `NPC Library``Browse and select an NPC preset.``NPC ID``Save NPC Overrides` | 选择区整块未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `221-238` | 英文直出 | `Skill Preview``Skill``World` | 技能预览区未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `258-259` | 中文乱码 | 空状态/说明整段乱码 | 预览区已有损坏文本 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `264-268` | 英文直出 | `Visual Preview``Hostile NPCs use monster presets...``Narrative NPCs can preview...` | 视觉预览说明未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `310-357` | 英文直出 | `NPC Details``NPC ID``Name``Role``Avatar``Linked Character ID``Monster Preset ID``Initial Affinity``Description` | 详情字段整体未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `363` | 中文乱码 | 预览说明大段乱码 | NPC 预览描述区已坏 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `371-375` | 英文直出 | `Visual Editor``Hostile NPCs cannot use the visual editor...` | 可视编辑器说明未本地化 |
### 3.6 `ScenePresetPanel.tsx`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `105-108` | 英文直出 | `Treasure Ahead``Treasure` | 宝藏预览实体名/头像仍是英文 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `132-133` | 英文直出 | `Scene Library``Browse and select a scene preset.` | 左侧选择区未本地化 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `162` | 英文直出 | `Save` | 保存按钮未本地化 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `170-181` | 英文直出 | `Scene Preview``Preview Mode``Monster Preview``NPC Preview``Treasure Preview``Empty` | 预览模式整组未本地化 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `207-226` | 英文直出 | `Hostile NPCs``NPCs``Treasure Hint``None` | 场景摘要卡未本地化 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `233-299` | 英文直出 | `Scene Details``Scene ID``World``Name``Description``Image Source``Forward Scene``Unset``Connected Scene IDs``Monster IDs``Treasure Hints``NPCs In Scene` | 详情编辑区整块未本地化 |
### 3.7 `StateFunctionEditor.tsx` 与共享请求层
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/StateFunctionEditor.tsx` | `1060-1064` | 英文直出 | `Failed to save option behavior overrides``Option behavior overrides saved.` | 保存结果提示未本地化 |
| `src/components/StateFunctionEditor.tsx` | `1138` | 中英混用 | `GameState` | 预览说明里仍混入英文类型名 |
| `src/components/StateFunctionEditor.tsx` | `1143` | 中英混用 | `敌对NPC资源` | `NPC` 混入字段标签 |
| `src/components/StateFunctionEditor.tsx` | `1185` | 英文枚举外露 | `AnimationState` 原始值 | 玩家动作下拉会直接显示英文枚举值 |
| `src/components/StateFunctionEditor.tsx` | `1190` | 英文占位符外露 | `{monster}` | 占位提示面向编辑器用户直接可见 |
| `src/components/StateFunctionEditor.tsx` | `1191` | 英文枚举外露 | `idle``move``attack` | 怪物动画下拉仍使用英文值 |
| `src/components/StateFunctionEditor.tsx` | `1213-1217` | 基本通过 | `稳扎稳打``爆发``机动` 等 | 技能权重显示标签已是中文,但底层 key 仍是英文 |
| `src/editor/shared/jsonClient.ts` | `29``43` | 英文直出 | `Request failed``Save failed` | 通用网络错误兜底未本地化,所有编辑器接口都可能透出 |
## 四、`npcInteractions.ts` 重点复查
### 4.1 复查通过
| 文件 | 行号 | 当前状态 | 说明 |
| --- | --- | --- | --- |
| `src/data/npcInteractions.ts` | `507-657` | 通过 | `actionText` / `detailText` 话题库主体已是中文,适合作为后续清理基线 |
### 4.2 仍有问题
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/data/npcInteractions.ts` | `299-343` | 中文乱码 | `绋€鏈夊搧``鏉愭枡``琛屽晢鎶ょ``绮剧偧閾?``闃叉按琛屽泭``娌抽浘缃楃洏``鍏界毊``鐚庨拱缇藉潬``鎷撴湰鏂囧唽``娈嬬己鍦板浘``姝﹀櫒``鍒跺紡浣╁垁``鎶ょ敳``鎶よ噦``鏃у竷鍗?``闅忚韩鏃х墿` | 商人来源匹配、商品分类、商品名存在明显乱码,会直接流入交易 UI |
| `src/data/npcInteractions.ts` | `401-424` | 英文枚举外露 | `deep``honest``partial``guarded``warm``cooperative``neutral``distant``candid``true_but_incomplete``half_truth``situational_only` | 阶段/回答模式仍使用英文值,虽不一定直接给玩家看,但已进入 prompt 上下文 |
| `src/data/npcInteractions.ts` | `428-500` | 基本通过 | `已经愿意逐步谈到真实来历...` 等 | 描述层已是中文,可作为未来替换英文枚举时的文案来源 |
| `src/data/npcInteractions.ts` | `1199``1209``1243` | 中英混用 | `向该NPC送礼``邀请该NPC加入队伍``离开当前 NPC重新回到探索状态。` | 选项和说明里仍混入 `NPC` |
| `src/data/npcInteractions.ts` | `1250` | 中英混用 | `当前好感为 ...` 同句包含 `NPC` | 遭遇总结文本仍有术语混入 |
## 五、`prompt` 链路重点复查
### 5.1 `src/services/prompt.ts`
这是当前最需要优先清理的文件。问题不是一两处,而是“结构性污染”:
- 前段中文描述已混入乱码。
- 中段人物/遭遇/场景/状态描述大面积乱码。
- 后段选项约束、战斗/观察/营地对话指令大面积乱码。
- 同时混有 `functionId``actionText``npc|treasure|none` 等英文结构词。
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/services/prompt.ts` | `145``151` | 中文乱码 | `锛堣嚜瀹氫箟...``鑷畾涔変笘鐣?...` | 自定义世界描述区已坏 |
| `src/services/prompt.ts` | `170-171``198-216` | 中文乱码 | 冒险开场理由、表层钩子、眼前顾虑、目标等整段乱码 | 角色开场信息会直接污染生成上下文 |
| `src/services/prompt.ts` | `226-233` | 中文乱码 + 英文枚举外露 | `NPC``deep``warm``answerMode` 等 | NPC 会话阶段控制段同时存在乱码和英文枚举 |
| `src/services/prompt.ts` | `378-451` | 中文乱码 + 中英混用 | 遭遇实体、敌对 `NPC`、玩家状态、场景说明等整段乱码 | 玩家、NPC、怪物、场景等核心提示都已受污染 |
| `src/services/prompt.ts` | `547-568` | 中文乱码 + 英文结构词外露 | `functionId``actionText``function` | 选项约束与动作重写规则段落已坏 |
| `src/services/prompt.ts` | `859-910` | 中文乱码 + 中英混用 | 空闲/遭遇函数说明、观察线索、开场营地跟进等整段乱码 | 后半段生成规则几乎不可维护 |
### 5.2 `src/services/characterChatPrompt.ts`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/services/characterChatPrompt.ts` | `42-54` | 英文直出 | `You are a companion character...``Generate exactly 3 player reply suggestions.``Summarize the evolving relationship...` | 系统 prompt 整段为英文 |
| `src/services/characterChatPrompt.ts` | `57-59` | 英文直出 | `Wuxia``Xianxia``Custom World` | 世界描述仍为英文 |
| `src/services/characterChatPrompt.ts` | `64``69-71``74-75` | 英文直出 | `Custom world reference``female``male``unknown``left``right` | 性别、朝向、扩展说明均为英文 |
| `src/services/characterChatPrompt.ts` | `99-112` | 英文直出 | `Recent story: none.``Earlier story summary``Most recent 3 story rounds` | 历史摘要模板为英文 |
| `src/services/characterChatPrompt.ts` | `123-155` | 英文直出 | `damage``mana``cooldown``arrival reason``current goal``world schema``top attributes` | 角色信息拼接模板整体为英文 |
### 5.3 `src/services/questPrompt.ts`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/services/questPrompt.ts` | `28-31` | 英文直出 | `issued by``No live quests` | 当前任务摘要模板为英文 |
| `src/services/questPrompt.ts` | `35-37` | 英文直出 | `Active companions``Roster companions` | 同伴摘要模板为英文 |
| `src/services/questPrompt.ts` | `41-52` | 英文直出 | `Player``HP``Mana``Inventory snapshot` | 玩家状态模板为英文 |
| `src/services/questPrompt.ts` | `67-95` | 英文直出 | `You are the quest director...` 等整段 | 任务意图系统 prompt 全英文 |
| `src/services/questPrompt.ts` | `107-123` | 英文直出 | `World``Issuer NPC``Encounter kind``Recent story moments` 等 | 最终拼接 prompt 仍是英文框架 |
### 5.4 `src/services/aiFallbacks.ts`
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/services/aiFallbacks.ts` | `5-17` | 英文直出 | `Player: ...``That question is not casual...``I accept...` | 离线 NPC 对话与招募兜底仍是英文 |
| `src/services/aiFallbacks.ts` | `28-35` | 英文直出 | `I will answer in my own way``I still remember...` | 离线角色私聊回复兜底为英文 |
| `src/services/aiFallbacks.ts` | `40-42` | 英文直出 | 三条候选回复 | 私聊建议兜底为英文 |
| `src/services/aiFallbacks.ts` | `52-57` | 英文直出 | `Player``Recent exchange``warmer toward the player` | 私聊摘要兜底为英文 |
## 六、其他会外溢到 UI / 预览 / 生成链路的文本源
| 文件 | 行号 | 类型 | 当前文本 | 说明 |
| --- | --- | --- | --- | --- |
| `src/hooks/useStoryGeneration.ts` | `578-580` | 通过 | `前往...``离开营地...` | 旅行选项已中文化 |
| `src/hooks/useStoryGeneration.ts` | `599``602` | 英文直出 | `approaches from a short distance away...``steps into view...` | 初始同伴结果文本仍是英文 |
| `src/hooks/useStoryGeneration.ts` | `814` | 英文直出 | `Continue the camp exchange and organize the most natural next actions.` | 营地跟进生成指令仍是英文 |
| `src/data/scenePresets.ts` | `195``297` | 英文枚举外露 | `trade``fight``spar``help``chat``recruit``gift` | 场景函数列表仍是英文 ID |
| `src/data/stateFunctions.ts` | `33` | 英文枚举外露 | `idle|move|attack` | 怪物动画枚举仍是英文 |
| `src/data/stateFunctions.ts` | `130``152``174``196``221``244` | 英文枚举外露 | `steady``burst``mobility``finisher``projectile` | 技能权重 key 仍为英文 |
| `src/data/characterPresets.ts` | `60-76` | 英文枚举外露 | `blunt``wary``evasive``measured``gentle``teasing``dry``steady``direct``fragmented``deflecting` | 对话风格推断值仍为英文,已进入 `npcInteractions` / `prompt` 描述链路 |
## 七、优先级建议
### P0先修否则会持续污染生成结果或直接破坏主界面
1. `src/services/prompt.ts`
2. `src/components/NpcModals.tsx`
3. `src/components/AdventureEntityModal.tsx`
4. `src/data/npcInteractions.ts` 的商店库存种子乱码段
5. `src/components/game-shell/GameShellOverlays.tsx` 的标题乱码
### P1紧接着修编辑器体验当前已经明显受损
1. `src/components/preset-editor/MonsterPresetPanel.tsx`
2. `src/components/preset-editor/SceneNpcPresetPanel.tsx`
3. `src/components/preset-editor/ScenePresetPanel.tsx`
4. `src/components/preset-editor/CharacterPresetPanel.tsx`
5. `src/components/StateFunctionEditor.tsx`
6. `src/editor/shared/jsonClient.ts`
### P2统一术语与风格减少中英混用
1. 全局统一 `NPC``HP``MP``AI``Shift` 是否保留英文缩写
2.`npcInteractions.ts` / `characterPresets.ts` / `stateFunctions.ts` 的英文枚举与键名整理为“内部值 + 中文展示层”
3. 补齐 `aiFallbacks.ts``characterChatPrompt.ts``questPrompt.ts` 的中文 prompt / fallback 版本
## 八、建议的修复顺序
1. 先修 `prompt``npcInteractions`,因为这两处会同时污染 AI 输出和运行时文本。
2. 再修 `NpcModals``AdventureEntityModal``GameShellOverlays`,优先恢复玩家可见界面。
3. 再批量处理四个预设编辑器面板和 `StateFunctionEditor`,最后统一共享请求层兜底文案。

View File

@@ -0,0 +1,280 @@
# 游戏 UI / 预设实体 / 编辑器 UI 英文与乱码复核(续)
日期:`2026-03-30`
## 说明
- 这份文档是对当前分支的重新复核,不直接沿用旧审计文档的正文,因为旧文档本身已经存在较明显乱码。
- 本轮重点覆盖三类范围:
- 游戏运行时 UI`src/components/` 下实际会进入主流程的界面,以及 `src/components/game-shell/`
- 编辑器 UI`src/components/*Editor*.tsx``src/components/preset-editor/``src/editor/shared/`
- 预设实体 / 数据层:`src/data/` 中会被编辑器、预览面板或游戏详情页直接透出的文本
- 复核方式:
- 直接按 UTF-8 读取源码,避免把终端显示问题误判成源码乱码
- 只记录会显示在玩家或编辑器使用者面前的文本
- `import`、类型名、变量名、接口字段名、纯内部注释默认不计入
- 但保存 / 加载提示这类虽然来自 helper 文件、最终会显示到 UI 的字符串,仍计入
## 结论摘要
- 当前分支里,真正“源码里已经写坏”的中文乱码,主要集中在 4 个位置:
- `src/components/GameShell.tsx`
- `src/components/preset-editor/shared.ts`
- `src/components/CustomWorldEntityEditorModal.tsx`
- `src/components/preset-editor/PresetEditorPanels.tsx`
- 其中最严重的是 `src/components/preset-editor/PresetEditorPanels.tsx`
- 角色/NPC/场景/敌对 NPC 资源四个子面板里都有残缺字符串
- 同时混有 `NPC``ID``FPS``Build Buff``Medieval NPC` 等英文术语
- 数据层 `src/data/` 本轮没有再扫到新的中文乱码;问题更多是英文预设值直接透到编辑器 / 预览 UI。
- 游戏运行时 UI 侧已经比旧清单干净很多,但仍有几块明显英文残留:
- `AdventurePanel`
- `AdventureEntityModal`
- `CompanionCampModal`
- `NpcModals`
- `game-shell/CharacterSelectionFlow`
## 一、已确认的真乱码
| 范围 | 文件 | 行号 | 当前文本示例 | 说明 |
| --- | --- | --- | --- | --- |
| 游戏 UI | `src/components/GameShell.tsx` | `565`, `578`, `591`, `710` | `瑙掕壊``鍐掗櫓``鑳屽寘``闃熶紞` | 主界面底部 tab 和浮层标题已写坏 |
| 编辑器 UI | `src/components/preset-editor/shared.ts` | `42-55` | `瑙掕壊``鍦烘櫙``鐗╁搧``鏁屽 NPC``姝︿緺``浠欎緺``鑷畾涔変笘鐣?` | 新版预设编辑器 tab 与世界标签已写坏 |
| 编辑器 UI | `src/components/CustomWorldEntityEditorModal.tsx` | `383`, `429`, `433` | `宸查€?``鍙栨秷``淇濆瓨淇敼` | 自定义世界实体编辑弹窗里的已选中/取消/保存文案乱码 |
| 编辑器 UI | `src/components/preset-editor/PresetEditorPanels.tsx` | `251`, `530`, `1383`, `1468`, `1478`, `1830` 等多处 | `鏂版妧鑳?``鏂板鎶€鑳?``绾満鏅?``鑳屾櫙鍥捐矾寰?``涓嶈缃?``... FPS銆?` | 新版预设编辑器存在大面积残缺字符串,部分已经带 `?` 结尾 |
### `PresetEditorPanels.tsx` 乱码分布
- 角色预设区:
- `251`, `310`, `323`, `379`, `467-688`, `719-802`
- 示例:`新技<E696B0>?``预览技<E8A788>?``法力消<E58A9B>?``属性面<E680A7>?``主场<E4B8BB>?`
- NPC 预设区:
- `1000-1208`
- 示例:`这里汇总了场景里的所<E79A84>?NPC 角色预设<E9A284>?``如果<E5A682>?NPC 绑定了角色技能...<2E>?``敌对 NPC 会沿用战斗资源预设展示...<2E>?`
- 场景预设区:
- `1244-1478`
- 示例:`没有可编辑的场景预设<E9A284>?``敌<>?NPC``纯场<E7BAAF>?``背景图路<E59BBE>?``不设<E4B88D>?`
- 敌对 NPC 资源区:
- `1551-1851`
- 示例:`没有可编辑的敌对 NPC 资源<E8B584>?``基础数<E7A180>?``最大生<E5A4A7>?``... 和 FPS<50>?``起始<E8B5B7>?`
## 二、游戏 UI 中仍会显示的英文
### 1. 主冒险面板
- `src/components/AdventurePanel.tsx:363`
- `Currency`
- `src/components/AdventurePanel.tsx:371`
- `No item bounty attached to this quest.`
- `src/components/AdventurePanel.tsx:1424`
- `LOOT CACHE`
- `src/components/AdventurePanel.tsx:1427-1428`
- `Tap an item icon to inspect its details.`
- `No usable loot dropped this time, but the battle is still settled.`
- `src/components/AdventurePanel.tsx:1442`
- `No loot dropped this time.`
- `src/components/AdventurePanel.tsx:1524`
- `HP` / `MP`
### 2. 实体详情与交互弹窗
- `src/components/AdventureEntityModal.tsx:1163-1165`
- `x{item.quantity}`
- `Inspect`
- `src/components/AdventureEntityModal.tsx:1428`
- `NPC 背包`
- `src/components/CompanionCampModal.tsx:177-178`, `233-234`, `255`
- `HP`
- `MP`
- `NPC`
- `src/components/NpcModals.tsx:252`, `273`, `356`, `408`
- `NPC 商品列表`
- `这个 NPC 当前没有可售商品。`
- `NPC 商品`
- `HP` / `MP`
### 3. 开场选角流
- `src/components/game-shell/CharacterSelectionFlow.tsx:28-32`
- `Sword Princess`
- `Royal Blade`
- `Vanguard`
- `Twin Blade Rogue`
- `Assassin`
- `Armored Spear`
- `src/components/game-shell/CharacterSelectionFlow.tsx:35-39`
- `STR`
- `AGI`
- `INT`
- `SPI`
- `src/components/game-shell/CharacterSelectionFlow.tsx:329-333`
- `Character Stats`
- `Gender:`
## 三、编辑器 UI 中仍会显示的英文
### 1. 旧预设编辑入口
- `src/components/PresetEditor.tsx:61-69`
- `Preset Workshop`
- `Unified Preset Preview And Editor`
- `Manage character, NPC, scene, monster, item, and behavior presets from one editor shell. Each tab now loads its own container so the entry component stays small and focused.`
### 2. 新预设编辑器共享配置
- `src/components/preset-editor/shared.ts:60-72`
- `idle`
- `move`
- `attack`
- `die`
- `steady`
- `burst`
- `mobility`
- `finisher`
- `projectile`
### 3. 新预设编辑器主面板
- `src/components/preset-editor/PresetEditorPanels.tsx:620`
- `Build Buff`
- `src/components/preset-editor/PresetEditorPanels.tsx:966`
- `No NPC presets available.`
- `src/components/preset-editor/PresetEditorPanels.tsx:1100-1202`
- `NPC`
- `NPC ID`
- `Medieval NPC`
- `src/components/preset-editor/PresetEditorPanels.tsx:1830`, `1867`
- `FPS`
### 4. 物品编辑器
- `src/components/ItemCatalogEditor.tsx:648`
- `HP`
- `MP`
- `CD`
- `src/components/ItemCatalogEditor.tsx:783`
- `Build Buff`
- `src/components/ItemCatalogEditor.tsx:800`
- `套装 ID`
- `src/components/ItemCatalogEditor.tsx:576-585`, `793-800`
- `selectedItem.tags``buildProfile.role``setId` 等原始英文值会直接显示在预览或输入框里
### 5. 选项行为编辑器
- `src/components/StateFunctionEditor.tsx:818`, `821`
- `HP`
- `No visible target`
- `src/components/StateFunctionEditor.tsx:885`, `915`
- `HP`
- `n/a`
- `src/components/StateFunctionEditor.tsx:1060-1064`
- `Failed to save option behavior overrides`
- `Option behavior overrides saved.`
- `src/components/StateFunctionEditor.tsx:1185`
- `AnimationState` 枚举值直接作为 label 显示
- `src/components/StateFunctionEditor.tsx:1191`
- `idle` / `move` / `attack`
- `src/components/StateFunctionEditor.tsx:1217`
- `steady` / `burst` / `mobility` / `finisher` / `projectile`
### 6. NPC 视觉编辑器与自定义世界编辑器
- `src/components/npcVisualEditorPersistence.ts:27-32`, `46-51`
- `Failed to save NPC visual overrides`
- `Saved NPC visual overrides to src/data/npcVisualOverrides.json.`
- `Failed to save NPC layout config`
- `Saved shared NPC layout config.`
- `src/components/CustomWorldEntityCatalog.tsx:345`
- `MedievalFantasyCharacters`
- `src/components/CustomWorldEntityEditorModal.tsx:457`
- `MedievalFantasyCharacters`
## 四、预设实体 / 数据层中会透到 UI 的英文值
### 1. 物品预设
- `src/data/itemDesign.ts:52-58`, `67-69`, `123-149`
- `worldAffinity: "neutral" / "wuxia" / "xianxia"`
- `role: "fieldcraft" / "breaker" / "caster" / "berserker" / "assassin"`
- `rarity: "common" / "rare" / "epic"`
- `tags: ["caster", "mana"]`
- `src/data/itemDesign.ts:213-219`
- `pieceName: "boots" / "chest" / "gloves" / "helm" / "leggings" / "shield" / "weapon"`
- `src/data/itemDesign.ts:538-545`, `588-606`, `730-766`, `818-836`, `904-919`
- 描述和 profile 中直接拼入 `build``role``dust``crystal``gem` 等英文值
- 这些字段会在 `ItemCatalogEditor` 预览和构筑信息里直出
### 2. 敌对资源 / 掉落预设
- `src/data/monsterPresets.ts:494-540`, `647-723`
- 掉落类别:`Armor``Relic``Material``Consumable`
- 掉落名称:`Carapace Plate``Guard Core``Spore Pouch``Burst Cap``Ashfire Feather``Serpent Eye``Tide Ink``Lake Pearl``Thorn Nectar`
- 掉落描述整句仍是英文
- 这些条目会直接进入掉落预览、NPC 交易与物品详情
### 3. 角色预设
- `src/data/characterPresets.ts:53-70`
- 对话风格值:`blunt``wary``evasive``measured``gentle``teasing``dry``steady``direct``fragmented``deflecting`
- `src/data/characterPresets.ts:368-379`, `525-536`, `839-850`, `1024-1038`
- 动画资源名:`Double Jump``jump attack``Wall Slide``skill1 bullet FX`
- `src/data/characterPresets.ts:384-386`, `541-543`, `855-857`, `1043-1045`
- `guardStyle` / `warmStyle` / `truthStyle` 的英文原值
- 这些值会在角色预设编辑器与动作 / 风格下拉中透出
### 4. Build / 标签词典
- `src/data/buildTags.ts:42`, `56`, `91`, `126-147`, `309-316`
- `assassin`
- `fieldcraft`
- `breaker`
- `caster`
- `armor`
- `relic`
- `material`
- `consumable`
- `rare`
- `wuxia`
- `xianxia`
- `neutral`
- 这些原始 tag 会通过物品标签、build profile 和编辑器预览进入显示层
## 五、本轮复核中未发现新增中文乱码的范围
### 游戏 UI
- `src/components/CharacterChatModal.tsx`
- `src/components/CharacterDetailModal.tsx`
- `src/components/CharacterPanel.tsx`
- `src/components/MapModal.tsx`
说明:
- 上述文件大体已中文化。
- 仍可能存在少量英文缩写、内部 ID 或技术词,但本轮没有再发现新的明显中文乱码。
### 数据层
- `src/data/scenePresets.ts`
- `src/data/npcInteractions.ts`
- `src/data/treasureInteractions.ts`
- `src/data/customWorldLibrary.ts`
- `src/data/customWorldRuntime.ts`
说明:
- 本轮在 `src/data/` 中没有扫到新的中文乱码。
- 当前数据层问题主要是英文 tag、role、rarity、pieceName 等原始值会被上层编辑器直接显示。
## 六、建议优先级
1. 先修 `src/components/preset-editor/PresetEditorPanels.tsx`
- 当前最集中的真乱码源
- 已经影响角色 / NPC / 场景 / 敌对资源四个主编辑子页
2. 再修 `src/components/preset-editor/shared.ts``src/components/GameShell.tsx`
- 一个影响预设编辑入口 tab 与世界标签
- 一个影响玩家主界面底部导航
3. 然后处理 `src/components/CustomWorldEntityEditorModal.tsx`
- 量不大,但按钮文案已经坏到影响操作判断
4. 最后统一清英文术语
- 游戏 UI`AdventurePanel``AdventureEntityModal``CompanionCampModal``NpcModals``CharacterSelectionFlow`
- 编辑器 UI`PresetEditor.tsx``ItemCatalogEditor.tsx``StateFunctionEditor.tsx``npcVisualEditorPersistence.ts`
- 数据层:`itemDesign.ts``monsterPresets.ts``characterPresets.ts``buildTags.ts`

View File

@@ -0,0 +1,194 @@
# 游戏 UI / 预设 / 编辑器 UI 文案排查
日期:`2026-03-31`
## 说明
- 本文档基于当前分支源码重新复核,直接按 UTF-8 读取,不沿用旧审计文档中的乱码文本。
- 只记录会出现在游戏 UI、预设编辑器 UI、结果页预览或保存反馈中的文本。
- `import`、变量名、注释、仅内部使用的路径名,不计入本次问题清单。
- 位图图片里的内嵌文本未做 OCR本次只看源码层可见文案。
## 结论摘要
- 当前问题可以分成 3 类:
- 真实中文乱码或截断。
- 英文或英文缩写直接暴露在中文界面。
- 预设数据中的英文原始值直接透出到编辑器或预览。
- 乱码最集中的文件:
- `src/components/preset-editor/PresetEditorPanels.tsx`
- `src/components/NpcVisualEditor.tsx`
- `src/components/CustomWorldEntityEditorModal.tsx`
- `src/components/GameShell.tsx`
- `src/editor/shared/FormFields.tsx`
- 英文最集中的文件:
- `src/components/adventure-panel/AdventurePanelOverlays.tsx`
- `src/components/game-shell/PreGameSelectionFlow.tsx`
- `src/components/game-shell/CharacterSelectionFlow.tsx`
- `src/components/PresetEditor.tsx`
- `src/components/ItemCatalogEditor.tsx`
- `src/components/StateFunctionEditor.tsx`
- 预设数据层仍有一批英文原始值会直接透出到 UI
- `src/data/itemDesign.ts`
- `src/data/monsterPresets.ts`
- `src/data/characterPresets.ts`
- `src/data/buildTags.ts`
## 一、已确认的中文乱码 / 截断
| 范围 | 文件 | 行号 | 当前文本示例 | 说明 |
| --- | --- | --- | --- | --- |
| 游戏 UI | `src/components/GameShell.tsx` | `598`, `611`, `624` | `瑙掕壊` / `鍐掗櫓` / `鑳屽寘` | 主流程底部三个 tab 标签已写坏 |
| 游戏 UI | `src/components/AdventurePanel.tsx` | `569-571` | `已完<E5B7B2>?` / `已交<E5B7B2>?` / `进行<E8BF9B>?` | 任务状态标签出现截断乱码 |
| 游戏 UI | `src/components/CharacterDetailModal.tsx` | `223` | `属<>?` | 角色详情分区标题截断 |
| 编辑器 UI | `src/components/CustomWorldEntityEditorModal.tsx` | `242`, `384`, `430`, `434` | `鏀寔...URL` / `宸查€?` / `鍙栨秷` / `淇濆瓨淇敼` | 自定义世界实体编辑弹窗的占位、选中态、取消和保存按钮已写坏 |
| 编辑器 UI | `src/components/preset-editor/shared.ts` | `42-55` | `瑙掕壊` / `鍦烘櫙` / `鏁屽 NPC` / `姝︿緺` / `浠欎緺` / `鑷畾涔変笘鐣?` | 预设编辑器主 tab 和世界标签存在乱码 |
| 编辑器 UI | `src/components/preset-editor/PresetEditorPanels.tsx` | `1269`, `1364`, `1371-1372`, `1467`, `1477-1486`, `1521`, `1654-1661`, `1689`, `1707` | 多处整句乱码 | 主编辑面板说明文案、预览模式、帮助文本、提示段落大面积损坏 |
| 编辑器 UI | `src/components/NpcVisualEditor.tsx` | `463`, `521`, `550`, `701-705`, `719`, `786-833` | 多处整句乱码 | NPC 视觉编辑器的空态、失败提示、回滚提示、页头说明和多组选项已写坏 |
| 编辑器 UI | `src/editor/shared/FormFields.tsx` | `156` | `淇濆瓨涓?..` | 通用保存按钮的“保存中...”状态显示乱码 |
## 二、游戏 UI 中的英文残留
### 1. 冒险主界面与奖励弹层
- `src/components/adventure-panel/AdventurePanelOverlays.tsx:114-125`
- 奖励物品描述 fallback 仍是整句英文,如 `restores HP during the run``works as a rare relic reward`
- `src/components/adventure-panel/AdventurePanelOverlays.tsx:136-157`
- 任务目标展示里仍有 `BOUNTY TARGET``CACHE TRACE``SPAR SESSION``Inspect the hidden reward site`
- `src/components/adventure-panel/AdventurePanelOverlays.tsx:262-291`
- 任务奖励卡里仍有 `REWARD CACHE``Tap an item icon to inspect its details.``Affinity``Currency``No item bounty attached to this quest.`
- `src/components/adventure-panel/AdventurePanelOverlays.tsx:351-358`
- 目标详情卡仍有 `Objective``Area`
- `src/components/adventure-panel/AdventurePanelOverlays.tsx:490`, `525`, `668`
- 统计说明、保存禁用提示、空任务提示仍是英文,如 `Inspect play time, kills, quests, and travel history.``Saving is temporarily disabled...``No active quests yet.`
- `src/components/adventure-panel/AdventurePanelOverlays.tsx:749`, `781-785`, `831`, `887-908`, `925-1016`
- 完成奖励与战斗奖励弹层仍有 `Claim reward``QUEST COMPLETE``Reward ready``Quest reward claimed``Battle reward``LOOT CACHE``No loot dropped this time.``Rarity``Quantity``Slot``Not equippable``Usable directly``Effect preview: HP + ... / MP + ...`
### 2. 实体详情与 NPC 交互
- `src/components/AdventureEntityModal.tsx:1073`, `1111`, `1163-1165`, `1252`, `1428`
- 仍有 `NPC 信息``NPC``x{item.quantity}``Inspect``Character``NPC 背包`
- `src/components/AdventureEntityModal.tsx:892`, `898`
- 同伴状态标签仍直接显示 `HP` / `MP`
- `src/components/CompanionCampModal.tsx:177-178`, `233-234`, `255`
- 同伴卡片和空态句子里仍有 `HP` / `MP` / `NPC`
- `src/components/NpcModals.tsx:79`, `252`, `273`, `356`, `408`
- 交易弹窗与详情弹窗里仍有 `x{item.quantity}``NPC 商品列表``这个 NPC 当前没有可售商品。``NPC 商品``效果预览HP + ... / MP + ...`
### 3. 开场流程与角色选择
- `src/components/game-shell/CharacterSelectionFlow.tsx:28-44`
- 角色名、称号、定位、标签全部是英文,如 `Sword Princess``Royal Blade``Vanguard``STR``AGI``Female``Male`
- `src/components/game-shell/CharacterSelectionFlow.tsx:329-391`
- 面板标题和按钮仍有 `Character Stats``Gender:``Backstory``Customize``Details``Enter Camp``Go`
- `src/components/game-shell/PreGameSelectionFlow.tsx:63-75`
- 自定义世界生成进度仍全是英文,如 `Finalizing world archive...``Generating core NPCs...``Parsing world setup...`
- `src/components/game-shell/PreGameSelectionFlow.tsx:252-308`
- 开场按钮和入口仍有 `New Game``Start Game``Developer Team``Go``CONTACTS``WORLD SELECT``Back`
- `src/components/game-shell/PreGameSelectionFlow.tsx:344-421`
- 世界卡片与自定义世界入口仍有 `Online``Featured``Saved``Playable``Landmarks``Custom``Create Custom World``Enter a world setup...`
- `src/components/GameShell.tsx:630`, `651`, `695`
- Suspense fallback 仍显示 `Loading party panel``Loading adventure panel``Loading inventory panel`
### 4. 其他游戏 UI
- `src/components/CharacterDetailModal.tsx:112`
- `数量 x{item.quantity}` 中的 `x` 仍保留英文数量前缀。
## 三、编辑器 UI 中的英文残留
### 1. 编辑器入口与共享配置
- `src/components/PresetEditor.tsx:65-73`
- 页头完整为英文:`Preset Workshop``Unified Preset Preview And Editor` 及其说明段。
- `src/components/preset-editor/shared.ts:43`, `60-72`
- 主 tab 仍有 `NPC`;动画和技能风格选项仍直接使用 `idle``move``attack``die``steady``burst``mobility``finisher``projectile`
### 2. 预设编辑器主面板
- `src/components/preset-editor/PresetEditorPanels.tsx:1267`, `1594`
- 保存反馈仍是 `Saved.`
- `src/components/preset-editor/PresetEditorPanels.tsx:1277-1279`, `1327-1328`, `1414-1415`, `1608-1609`, `1647-1648`
- 多个分区标题和描述仍是占位英文 `Section` / `Editor section.`
- `src/components/preset-editor/PresetEditorPanels.tsx:1283`, `1442`, `1448`
- 表单标签出现错误拼接,如 `Field"NPC"``Field"ID"`
- `src/components/preset-editor/PresetEditorPanels.tsx:1320`, `1640`
- 保存按钮文字仍是 `Save`
- `src/components/preset-editor/PresetEditorPanels.tsx:1421`, `1658-1661`, `1692`, `1698`, `1701`, `1710`, `2149`
- 仍有 `NPC ID``Monster Encounter``NPC Encounter``Empty Scene``None``NPC``FPS` 等英文或英文缩写。
### 3. 物品 / 行为 / NPC 视觉编辑器
- `src/components/ItemCatalogEditor.tsx:648`, `729`, `736`, `760`, `767`, `783`, `800`
- 仍有 `HP``MP``CD``Build Buff``ID`
- `src/components/ItemCatalogEditor.tsx:793-817`
- `buildProfile.role``setId``pieceName` 等原始英文值直接显示在输入框。
- `src/components/StateFunctionEditor.tsx:818-821`, `885`, `915`
- 预览信息里仍有 `HP``No visible target``n/a`
- `src/components/StateFunctionEditor.tsx:1060-1064`
- 保存失败/成功提示仍是英文:`Failed to save option behavior overrides``Option behavior overrides saved.`
- `src/components/StateFunctionEditor.tsx:1106`, `1185`, `1191`, `1217`
- 仍直接展示 `battle` / `idle``AnimationState` 原值、`idle` / `move` / `attack`,以及 `steady` / `burst` / `mobility` / `finisher` / `projectile`
- `src/components/NpcVisualEditor.tsx:538`, `714`, `781`, `798`
- 仍有 `Save failed``Current NPC``Custom Hair Color``Hide Facial Hair`
- `src/components/npcVisualEditorPersistence.ts:26`, `31`, `45`, `50`
- 保存提示仍为 `Failed to save NPC visual overrides``Saved NPC visual overrides to src/data/npcVisualOverrides.json.``Failed to save NPC layout config``Saved shared NPC layout config.`
### 4. 自定义世界结果页 / 编辑弹窗
- `src/components/CustomWorldEntityCatalog.tsx:346`
- 说明文案里直接暴露资产名 `MedievalFantasyCharacters`
- `src/components/CustomWorldEntityEditorModal.tsx:242`, `458`
- 图片路径占位里仍保留 `URL`NPC 形象编辑说明里直接出现 `MedievalFantasyCharacters`
## 四、预设 / 数据层中会透出 UI 的英文原始值
### 1. 物品预设
- `src/data/itemDesign.ts:56-58`, `67-69`, `123-149`
- `worldAffinity``role``rarity``tags` 中仍有 `neutral``wuxia``xianxia``fieldcraft``breaker``caster``berserker``assassin``common``rare``epic` 等原始值。
- `src/data/itemDesign.ts:213-219`
- `pieceName` 仍为 `boots``chest``gloves``helm``leggings``shield``weapon`
- `src/data/itemDesign.ts:538-545`, `581-598`, `731-748`, `906-913`
- 描述拼接和构筑信息里仍直接出现 `build``role``dust``crystal``gem` 等英文原始词。
- 这些值会直接透出到 `ItemCatalogEditor` 的标签、构筑字段和预览信息。
### 2. 怪物掉落预设
- `src/data/monsterPresets.ts:494-536`, `647-721`
- 掉落类别仍有 `Armor``Relic``Material``Consumable`
- 掉落名称仍有 `Carapace Plate``Guard Core``Spore Pouch``Burst Cap``Ashfire Feather``Serpent Eye``Tide Ink``Lake Pearl``Thorn Nectar`
- 掉落描述仍有整句英文,如 `A toxin sac prized by alchemists and assassins alike.`
- 这些值会进入战斗奖励、物品详情和交易 UI。
### 3. 角色预设
- `src/data/characterPresets.ts:54-70`
- 会话风格原始值仍为 `blunt``wary``evasive``measured``gentle``teasing``dry``steady``direct``fragmented``deflecting`
- `src/data/characterPresets.ts:368-386`, `525-543`, `839-857`, `1024-1045`
- 动画文件夹 / 前缀与风格原始值仍有 `Double Jump``jump attack``Wall Slide``guardStyle``warmStyle``truthStyle`
- 这些值会透出到角色预设编辑器、技能预览和部分选择器。
### 4. Build / 标签词典
- `src/data/buildTags.ts:42`, `56`, `91`, `126-147`, `308-316`
- 仍有 `assassin``fieldcraft``breaker``caster``weapon``armor``relic``material``consumable``rare``wuxia``xianxia``neutral` 等原始标签。
- 这些值会在物品编辑器标签、构筑画像和相似度映射结果中直接显示。
## 五、优先级建议
1. 先修 `src/components/preset-editor/PresetEditorPanels.tsx``src/components/NpcVisualEditor.tsx`
- 这两处是当前编辑器侧最严重的问题源,既有大面积乱码,也有大量英文占位词。
2. 再修游戏首屏与奖励相关 UI
- 优先处理 `src/components/adventure-panel/AdventurePanelOverlays.tsx`
- 优先处理 `src/components/game-shell/PreGameSelectionFlow.tsx`
- 优先处理 `src/components/game-shell/CharacterSelectionFlow.tsx`
3. 然后修直接影响主流程判断的乱码
- `src/components/GameShell.tsx`
- `src/components/AdventurePanel.tsx`
- `src/components/CharacterDetailModal.tsx`
- `src/components/CustomWorldEntityEditorModal.tsx`
- `src/editor/shared/FormFields.tsx`
4. 最后补“显示层映射”
-`itemDesign.ts``monsterPresets.ts``characterPresets.ts``buildTags.ts` 这类预设原始值统一增加中文显示映射,避免继续把内部英文值直接透给编辑器和游戏 UI。

View File

@@ -0,0 +1,325 @@
# 游戏 UI / 预设 / 编辑器文本审计
日期:`2026-04-01`
## 范围
- 扫描范围:`src/components/``src/editor/``src/routing/``src/hooks/``src/services/``src/data/`
- 聚焦对象:
- 游戏内实际可见 UI 文本
- 预设编辑器与自定义世界编辑器中的可见文本
- 会直接透出到游戏 UI / 编辑器 UI 的预设原始值
- 未覆盖:
- 图片资源内嵌文字的 OCR
- `docs/` 历史文档本身
- 单纯内部实现用的 import path、className、asset path、纯 id 常量
## 方法
- 先做一轮源码级 AST 扫描,抽取 JSX 可见文本、按钮文案、占位文案、标签文案和常见说明文案。
- 再做一轮“反向解码”复核:
- `瑙掕壊 -> 角色`
- `鍦烘櫙 -> 场景`
- `姝︿緺 -> 武侠`
- `鏈煡 AI 閿欒 -> 未知 AI 错误`
- 结论只保留当前源码里仍然存在的问题,不直接沿用旧审计文档。
## 结论摘要
- 当前仍然有 3 类问题:
1. 真实乱码:主要在 `appRoutes.tsx``AdventurePanel.tsx``CharacterDetailModal.tsx``useStoryGeneration.ts``preset-editor/shared.ts` 和 4 个拆分后的预设面板文件中。
2. 游戏 / 编辑器英文残留:主要在 `AdventurePanelOverlays.tsx``AdventureEntityModal.tsx``PreGameSelectionFlow.tsx``NpcVisualEditor.tsx``ItemCatalogEditor.tsx``StateFunctionEditor.tsx`、自定义世界编辑器几处。
3. 预设原始值直接透出:主要在 `characterPresets.ts``itemDesign.ts``monsterPresets.ts``buildTags.ts``scenePresets.ts``stateFunctions.ts`
- 编辑器侧当前最明显的重灾区不是旧的 `PresetEditorPanels.tsx` 大文件,而是已经拆分出的:
- `src/components/preset-editor/shared.ts`
- `src/components/preset-editor/CharacterPresetPanel.tsx`
- `src/components/preset-editor/SceneNpcPresetPanel.tsx`
- `src/components/preset-editor/ScenePresetPanel.tsx`
- `src/components/preset-editor/MonsterPresetPanel.tsx`
- 游戏主流程里影响最直观的点:
- 路由加载页文本乱码
- 冒险面板里的任务状态 / 对话状态 / NPC 交互短描述乱码
- AI 错误兜底文案乱码
## 一、游戏 UI已确认乱码
| 文件 | 行号 | 当前文本 / 范围 | 说明 |
| --- | --- | --- | --- |
| `src/routing/appRoutes.tsx` | `103-115` | `LOADING EDITOR``LOADING GAME``姝e湪杞藉叆缂栬緫鍣?..``姝e湪杞藉叆鍐掗櫓...` | 路由级加载屏文案。后两段是真乱码;结合反向解码可确定原意分别接近“正在载入编辑器...”和“正在载入冒险...”。 |
| `src/components/AdventurePanel.tsx` | `99``101``103``109``111``113` | `查看库存与价<E4B88E>?``聊聊并试探口<E68EA2>?``看看能得到什么帮<E4B988>?``离开并继续探<E7BBAD>?``战斗决胜<E586B3>?``切磋几招看身<E79C8B>?` | NPC 交互短描述里有多处截断 / 乱码。 |
| `src/components/AdventurePanel.tsx` | `200``203` | `可作为制作材<E4BD9C>?``任务奖励物品可用于后续路线、交易或构筑规划<E8A784>?` | 任务奖励物品说明文本被截断。 |
| `src/components/AdventurePanel.tsx` | `569-571` | `已完<E5B7B2>?``已交<E5B7B2>?``进行<E8BF9B>?` | 任务状态标签乱码。 |
| `src/components/AdventurePanel.tsx` | `771` | `<60>?` | 对话气泡里的屏幕阅读器标签损坏。 |
| `src/components/AdventurePanel.tsx` | `833``837``870` | `剧情推演<E68EA8>?..``对话进行<E8BF9B>?``剧情推理完成继续后显示新的冒险选项<E98089>?` | 加载态 / 流式对话态 / 继续冒险提示都有截断。 |
| `src/components/CharacterDetailModal.tsx` | `35-36``223` | `女<>?``男<>?``属<>?` | 性别标签与“属性”标题乱码。 |
| `src/hooks/useStoryGeneration.ts` | `1214``1266``1409``1549``1978``2325` | `鏈煡 AI 閿欒` | 游戏故事流里 AI 失败时的统一兜底提示乱码;可反解为“未知 AI 错误”。 |
## 二、游戏 UI英文残留
### 1. 冒险面板和奖励弹层
- `src/components/adventure-panel/AdventurePanelOverlays.tsx`
- `554-570``Adventure stats``Current area:``ADVENTURE SUMMARY``enemies defeated``items in inventory``scene transitions so far`
- `622-668``Quest log``Total quests:``No active quests yet.`
- `711-798``QUEST BRIEF``Claim reward``QUEST COMPLETE``Reward ready``Reward pickup is now available in the quest log.``Open quest log`
- `887-1016``Battle reward``Defeated enemies:``BATTLE END``LOOT CACHE``Tap an item icon to inspect its details.``No usable loot dropped this time.``No loot dropped this time.``Rarity:``Quantity:``Slot:``Not equippable``Usable directly``Passive / non-immediate item``Effect preview: HP +``MP +``Cooldown -``Tags:``none`
- `src/components/AdventurePanel.tsx`
- `359-388``REWARD CACHE``Tap an item icon to inspect its details.``Affinity``Currency``No item bounty attached to this quest.`
- `636-638``Current area`
- `803``824`:两个按钮都显示 `Refresh`
### 2. 实体详情、同伴、交易
- `src/components/AdventureEntityModal.tsx`
- `892``898``HP``MP`
- `1073``NPC 信息`
- `1111``敌对NPC``NPC`
- `1163`:数量前缀 `x{item.quantity}`
- `1165``Inspect`
- `1428``NPC 背包`
- `src/components/CompanionCampModal.tsx`
- `177-178``233-234``HP``MP`
- `255``NPC`
- `src/components/NpcModals.tsx`
- `252``273``356``NPC 商品列表``这个 NPC 当前没有可售商品。``NPC 商品`
- `408``效果预览HP +... / MP +... / 冷却 -...`
- `src/components/CharacterDetailModal.tsx`
- `112``数量 x{item.quantity}`
### 3. 开场流程与加载态
- `src/components/game-shell/PreGameSelectionFlow.tsx`
- `48-49``QQ Group``WeChat`
- `81``89``核心NPC`
- `471-473``Wuxia Base`
- `519-527``Custom``Create Custom World``Enter a world setup and let the system generate playable characters, NPCs, items, and landmarks.`
- `src/components/game-shell/CharacterSelectionFlow.tsx`
- `401``Character Details`
- `406``Current Character`
- `src/components/GameCanvas.tsx`
- `32``Loading scene`
- `src/components/GameShell.tsx`
- `859``正在加载 NPC 交互...`
### 4. 运行时文案源头
- `src/data/sceneObservation.ts`
- `9-36` 整段观察结果仍是英文:
- `You pause to listen...`
- `Possible NPCs: ...`
- `Possible hostile NPCs: ...`
- `Possible treasure clues: ...`
- `Boss clue: ...`
- `src/hooks/useStoryGeneration.ts`
- `216``219`:最近战斗 / 最近协作提示仍是英文
- `639-646`:营地聊天结果文本混用了英文句子
- `662-667`:预览对话选项里仍有 `Speak with ...``Focus on the person in front of you first...`
## 三、编辑器 UI已确认乱码
### 1. 共享标签与世界名
- `src/components/preset-editor/shared.ts`
- `42``瑙掕壊`,可反解为 `角色`
- `44``鍦烘櫙`,可反解为 `场景`
- `45``鏁屽 NPC`,可反解为 `敌对 NPC`
- `46``鐗╁搧`,可反解为 `物品`
- `47``鍔熻兘`,可反解为 `功能`
- `53``姝︿緺`,可反解为 `武侠`
- `54``浠欎緺`,可反解为 `仙侠`
- `55``鑷畾涔変笘鐣?`,基本可判定原意是“自定义世界”,但当前字符串已经不完整
### 2. 角色预设面板
- `src/components/preset-editor/CharacterPresetPanel.tsx`
- `79`:空状态 / 顶部说明整段乱码
- `372-373`:装备区标题乱码
- `395-397`:背包区标题乱码
- `446-447`:技能预览相关标签乱码
- `475-477`:技能区提示乱码
- `590-592`:底部说明大段乱码
### 3. 场景 NPC 预设面板
- `src/components/preset-editor/SceneNpcPresetPanel.tsx`
- `87`:空状态整段乱码
- `267`:技能预览空态说明乱码
- `346`:角色 ID 标签乱码
- `352`:怪物预设 ID 标签乱码
- `389`:视觉编辑器说明整段乱码
### 4. 场景预设面板
- `src/components/preset-editor/ScenePresetPanel.tsx`
- `52`:空状态整段乱码
- `220-221`:敌对 NPC 分区标题乱码
- `254-255`:场景 ID 标签乱码
- `298-299`:怪物 ID 列表标签乱码
- `316-317`:关联 NPC 分区标题乱码
### 5. 怪物预设面板
- `src/components/preset-editor/MonsterPresetPanel.tsx`
- `53`:顶部说明整段乱码
## 四、编辑器 UI英文残留
### 1. 预设编辑器主面板
- `src/components/preset-editor/CharacterPresetPanel.tsx`
- `278-279``Character List``Choose a player character, preview it live, and edit the preset fields.`
- `325``Save Character Overrides`
- 多处通用占位仍是 `Section``Editor section.``Field`
- `347``Inventory World`
- `468-484``Skill Loadout``Add Skill`
- `510``Skill ID`
- `651``Character ID`
- `682``Asset Variant`
- `698``Personality`
- `713``Attributes``Adjust the four core character attributes.`
- `772``Unset`
- `798``scene-id-1 / scene-id-2`
- `src/components/preset-editor/SceneNpcPresetPanel.tsx`
- `181-182``NPC Library``Browse and select an NPC preset.`
- `186``NPC ID`
- `223``Save NPC Overrides`
- `230-246``Skill Preview``Preview ranged skills from the linked character.``Skill``World`
- `275-276``Hostile NPCs use monster presets...``Narrative NPCs can preview linked visuals...`
- `318-382``NPC Details``Role``Avatar``Initial Affinity``Description``Visual Editor`
- `src/components/preset-editor/ScenePresetPanel.tsx`
- `145``Scene`
- `172``Save`
- `179-193``Scene Preview``Preview Mode``Monster Preview``NPC Preview``Treasure Preview``Empty`
- `223``230``233``242``None``NPC`
- `248-272``Scene Details``World``Name``Description`
- `288``Unset`
- `src/components/preset-editor/MonsterPresetPanel.tsx`
- `172``Save Monster Overrides`
- `179-180``Monster Override Preview``Editor section.`
- `213-222``Attack Range:``Speed:``HP:``Max HP:`
- `236``Monster ID`
- `242``Name`
- `258``Intro Action`
- `373``FPS`
### 2. 其他编辑器 / 自定义世界
- `src/components/ItemCatalogEditor.tsx`
- `654``HP``MP``CD`
- `677``806``ID`
- `789``Build Buff`
- `458``863``public/Icons``itemOverrides.json`
- `src/components/NpcVisualEditor.tsx`
- `463``702``708``718``NPC`
- `977``Shift`
- `1028-1052``Current loadout:``Unknown headgear``No headgear``Unknown main hand``No main hand``Unknown off hand``No off hand`
- `src/components/CustomWorldEntityCatalog.tsx`
- `139``268``276``349``NPC`
- `224``WORLD DOSSIER`
- `346``MedievalFantasyCharacters`
- `src/components/CustomWorldEntityEditorModal.tsx`
- `242``URL`
- `460``MedievalFantasyCharacters`
- `478-479``730``758-759``AI``AI生成NPC形象``AI生成场景`
- `631-653``NPC`
- `src/components/PresetEditor.tsx`
- `71`:介绍文案里仍然直接显示 `NPC`
- `src/components/StateFunctionEditor.tsx`
- `803``Failed to play preview`
- `818-821``HP``No visible target`
- `915``n/a`
- `1060-1064``Failed to save option behavior overrides``Option behavior overrides saved.`
- `1106`:直接显示原始 `state`
- `1185`:直接把 `AnimationState` 值作为 label
- `1191`:敌对 NPC 反应动画里仍直接显示 `idle` / `move` / `attack`
- `1217`:技能风格仍直接依赖 `steady` / `burst` / `mobility` / `finisher` / `projectile`
## 五、预设 / 数据层:会直接透出 UI 的英文原始值
这一部分不是“源码内部英文就算问题”,而是“当前编辑器或预览没有做显示映射,导致原始英文值直接露给用户”。
### 1. 角色预设
- `src/data/characterPresets.ts`
- 动作文件夹 / 前缀仍是英文:
- `363-379`
- `520-536`
- `739-755`
- `834-850`
- `1019-1038`
- 对话风格原始值仍是英文:
- `384-386``blunt` / `dry` / `direct`
- `541-543``wary` / `dry` / `fragmented`
- `760-762``blunt` / `teasing` / `deflecting`
- `855-857``blunt` / `steady` / `direct`
- `1043-1045``measured` / `steady` / `fragmented`
- 技能风格 / 投射方式仍是英文:
- `407-408``445``473-474`
- `572-573``604-605``636-637``668-669``700-701`
- `791-792``815-818`
- `886``906``926-927``958-959``990-991`
- `1066-1077``1109-1110``1133-1146``1178-1179`
- 这些值当前会在角色预设编辑器、技能预览和部分行为预览里直接露出。
### 2. 物品设计 / Build 标签
- `src/data/itemDesign.ts`
- `56-201``worldAffinity` / `role` / `rarity` 原始值仍是英文,如 `neutral``wuxia``xianxia``fieldcraft``breaker``berserker``legendary`
- `213-219``pieceName` 仍是 `boots``chest``gloves``helm``leggings``shield``weapon`
- `820`:说明文本里仍混入 `build`
- `src/data/buildTags.ts`
- `11-291`:整套 build tag id 都是英文,如 `quickblade``combo``dash``ranged``burst``caster``vanguard``paladin``starter`
- 这些值会进入物品编辑器、构筑标签和相关预览。
### 3. 怪物与掉落
- `src/data/monsterPresets.ts`
- `490-736`:掉落 id、稀有度、tag 原始值大量是英文,如 `rare``uncommon``armor``material``relic``healing`
- `718-736`:有两条掉落本身是完整英文可见值:
- `Consumable` / `Thorn Nectar` / `Sticky sap that can be refined into emergency recovery tonic.`
- `Relic` / `Devour Bloom` / `A predatory blossom that stores concentrated life force.`
### 4. 场景 / 行为 / 锻造 / NPC 交互
- `src/data/scenePresets.ts`
- `349-651`:场景 id 全部是英文连字符格式,如 `wuxia-bamboo-road``xianxia-cloud-gate`
- 当前在编辑器 ID 字段中会直接显示。
- `src/data/stateFunctions.ts`
- `113-372``category` 原始值仍是 `battle` / `recovery` / `escape` / `idle`
- 编辑器预览还会直接显示动画 / delivery 原始值。
- `src/data/forgeSystem.ts`
- `264`:描述里混入 `build`
- `274-281``relic``epic``setId``pieceName` 等原始值会进入物品编辑器链路
- `src/data/npcInteractions.ts`
- `207-209`:兜底对话风格仍是 `measured` / `steady` / `fragmented`
## 六、建议修复顺序
1. 先修最影响主流程观感的真实乱码。
- `src/routing/appRoutes.tsx`
- `src/components/AdventurePanel.tsx`
- `src/components/CharacterDetailModal.tsx`
- `src/hooks/useStoryGeneration.ts`
2. 再修预设编辑器的共享标签和 4 个拆分面板。
- `src/components/preset-editor/shared.ts`
- `src/components/preset-editor/CharacterPresetPanel.tsx`
- `src/components/preset-editor/SceneNpcPresetPanel.tsx`
- `src/components/preset-editor/ScenePresetPanel.tsx`
- `src/components/preset-editor/MonsterPresetPanel.tsx`
3. 再统一清理英文残留。
- 游戏端优先:`AdventurePanelOverlays.tsx``AdventureEntityModal.tsx``PreGameSelectionFlow.tsx`
- 编辑器端优先:`ItemCatalogEditor.tsx``NpcVisualEditor.tsx``StateFunctionEditor.tsx`、自定义世界编辑器
4. 最后做“显示层映射”,避免预设原始英文继续漏到 UI。
- `characterPresets.ts`
- `itemDesign.ts`
- `buildTags.ts`
- `monsterPresets.ts`
- `scenePresets.ts`
- `stateFunctions.ts`
## 七、备注
- 本次结论以当前源码为准,和旧审计文档相比,已有一部分旧问题已经被修掉。
- `src/components/preset-editor/PresetEditorPanels.tsx` 现在只是 re-export 壳文件,真正的问题已经分散到拆分后的 panel 文件里。
- `src/components/preset-editor/shared.ts` 里的几处乱码已经可以明确反解,适合优先直接修正。
- `src/data/` 中很多英文值本身可能是内部枚举,但只要当前编辑器 / 预览没有做中文映射,就仍应视为“会暴露到用户侧”的文本问题。

View File

@@ -0,0 +1,273 @@
# 游戏 UI / 预设 / 编辑器文本二次审计(扩展重查版)
日期:`2026-04-02`
说明:
- 本文档用于替换同名上一版审计。上一版确实漏掉了不少内容,尤其是:
- `AdventurePanel` 里的任务概览与奖励文案
- `npcInteractions.ts` 里的 `actionText` / `detailText`
- 自定义世界编辑器、NPC 视觉编辑器里的英文兜底和混合术语
- 预设编辑器里多组仍未本地化的标题、字段名、保存反馈
- 本次以当前仓库实际内容为准,不沿用旧结论;已经修掉的内容不再重复计入。
## 审计范围
- 扫描目录:
- `src/components/`
- `src/data/`
- `src/hooks/`
- `src/services/`
- `src/routing/`
- `src/editor/`
- 关注对象:
- 玩家在主流程、冒险面板、弹窗里会看到的文本
- 预设编辑器、自定义世界编辑器、NPC 视觉编辑器中会直接显示的文本
- 会透传到 UI、弹窗、编辑器预览中的数据层文本源
- 标记类型:
- `英文直出`:面向玩家 / 编辑器用户的英文文本仍直接显示
- `中英混用`:中文 UI 中混入 `NPC``HP``MP``AI``URL``Shift` 等术语
- `异常显示`:明显乱码、截断、异常问号替代、分隔符损坏
## 结论摘要
- 游戏主流程里仍有明显英文残留:`QQ Group``WeChat``GENARRATIVE``Current Area`
- 游戏内任务 / 冒险面板仍有一批英文任务眉标和按钮辅助文案:`BOUNTY TARGET``CACHE TRACE``SPAR SESSION``Inspect reward item ...``Unknown monster`
- `GameShellOverlays.tsx` 仍有整组 loading fallback 出现异常编码。
- 预设编辑器目前仍是问题最密集区域之一,`CharacterPresetPanel``MonsterPresetPanel``SceneNpcPresetPanel``ScenePresetPanel``StateFunctionEditor` 里都有明显英文直出或半成品占位。
- 数据层里仍有大量会透出到 UI / 编辑器的英文值,重点在:
- `npcInteractions.ts`
- `useStoryGeneration.ts`
- `storyGenerationState.ts`
- `npcEncounterActions.ts`
- `sceneObservation.ts`
- `characterPresets.ts`
- `stateFunctions.ts`
## 一、游戏主流程 UI
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/game-shell/PreGameSelectionFlow.tsx` | `48-49` | 英文直出 | `QQ Group``WeChat` | 开场页联系方式标签仍是英文 |
| `src/components/game-shell/PreGameSelectionFlow.tsx` | `351` | 中英混用 | `contact.label === 'QQ Group' ? 'QQ群' : '微信'` | 逻辑分支仍依赖英文标签 |
| `src/components/game-shell/GameShellOverlays.tsx` | `123` | 异常显示 | `姝e湪鍔犺浇鍐掗櫓璇︽儏...` | 冒险详情 loading fallback 乱码 |
| `src/components/game-shell/GameShellOverlays.tsx` | `162` | 异常显示 | `姝e湪鍔犺浇闃熶紞闈㈡澘` | 队伍面板 loading fallback 乱码 |
| `src/components/game-shell/GameShellOverlays.tsx` | `187` | 异常显示 | `姝e湪鍔犺浇鑳屽寘闈㈡澘` | 背包面板 loading fallback 乱码 |
| `src/components/game-shell/GameShellOverlays.tsx` | `214` | 异常显示 | `姝e湪鍔犺浇闃熶紞钀ュ湴...` | 营地弹窗 loading fallback 乱码 |
| `src/components/game-shell/GameShellOverlays.tsx` | `229` | 异常显示 | `姝e湪鍔犺浇鍦板浘...` | 地图 loading fallback 乱码 |
| `src/components/game-shell/GameShellOverlays.tsx` | `248` | 异常显示 | `姝e湪鍔犺浇瑙掕壊鑱婂ぉ...` | 角色聊天 loading fallback 乱码 |
| `src/components/game-shell/GameShellOverlays.tsx` | `261` | 异常显示 | `姝e湪鍔犺浇 NPC 浜や簰...` | NPC 交互 loading fallback 同时混入 `NPC` |
| `src/components/game-shell/GameShellRuntime.tsx` | `146` | 英文直出 | `Current Area` | 当前场景名缺失时的兜底文案仍是英文 |
| `src/components/game-shell/GameShellRuntime.tsx` | `200` | 英文直出 | `GENARRATIVE` | 顶部 logo 文案仍是英文 |
| `src/components/GameShell.tsx` | `311` | 英文直出 | `Current Area` | 旧壳组件里同样保留英文兜底 |
| `src/components/GameShell.tsx` | `365` | 英文直出 | `GENARRATIVE` | 旧壳组件里同样保留英文 logo |
| `src/components/DeveloperTeamModal.tsx` | `44` | 英文直出 | `aria-label="Close developer team modal"` | 开发团队弹窗关闭按钮辅助文案未本地化 |
## 二、游戏内面板 / 弹窗
### 2.1 冒险与任务面板
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/AdventurePanel.tsx` | `197-198` | 异常显示 | `适合进攻型构``适合防御型构` | 描述文本疑似被截断,正常语义应是“构筑” |
| `src/components/AdventurePanel.tsx` | `206` | 异常显示 | `item.name + ' 奖励物品<E789A9>?';` | 奖励物品描述兜底尾部异常 |
| `src/components/AdventurePanel.tsx` | `216` | 异常显示 | ``${hours}小时 ...<2E>?...秒`` | 时长格式字符串出现异常字符 |
| `src/components/AdventurePanel.tsx` | `219` | 异常显示 | ``${minutes}<7D>?...秒`` | 分钟格式字符串同样异常 |
| `src/components/AdventurePanel.tsx` | `248` | 英文直出 | ``aria-label={`Inspect reward item ${item.name}`}`` | 奖励物品按钮辅助文案是英文 |
| `src/components/AdventurePanel.tsx` | `279` | 英文直出 | `BOUNTY TARGET` | 任务眉标未本地化 |
| `src/components/AdventurePanel.tsx` | `283` | 英文直出 | `Unknown monster` | 目标怪物兜底文案是英文 |
| `src/components/AdventurePanel.tsx` | `290` | 英文直出 | `CACHE TRACE` | 宝藏任务眉标未本地化 |
| `src/components/AdventurePanel.tsx` | `295` | 英文直出 | `Inspect the hidden reward site` | 宝藏任务副文案未本地化 |
| `src/components/AdventurePanel.tsx` | `302` | 英文直出 | `SPAR SESSION` | 切磋任务眉标未本地化 |
### 2.2 NPC / 实体 / 交易相关弹窗
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/AdventureEntityModal.tsx` | `895` | 中英混用 | `label="HP"` | 实体状态估计面板直接显示 `HP` |
| `src/components/AdventureEntityModal.tsx` | `901` | 中英混用 | `label="MP"` | 实体状态估计面板直接显示 `MP` |
| `src/components/NpcModals.tsx` | `252` | 中英混用 | `NPC 商品列表` / `你的背包列表` | 交易列表标题混入 `NPC` |
| `src/components/NpcModals.tsx` | `273` | 中英混用 | `这个 NPC 当前没有可售商品。` | 空状态文案混入 `NPC` |
| `src/components/NpcModals.tsx` | `356` | 中英混用 | `NPC 商品` | 详情弹窗标题混入 `NPC` |
| `src/components/NpcModals.tsx` | `408` | 中英混用 | `效果预览HP +... / MP +... / 冷却 -...` | 数值预览里直接保留 `HP`、`MP` |
### 2.3 自定义世界结果页
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/CustomWorldResultView.tsx` | `58` | 中英混用 | `新增 NPC` | 结果页新增操作标签混入 `NPC` |
## 三、自定义世界 / NPC 视觉编辑
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/CustomWorldEntityEditorModal.tsx` | `242` | 英文直出 | `URL` | 图片地址输入提示词未本地化 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `464` | 英文直出 | `MedievalFantasyCharacters` | 形象编辑副标题里直接暴露素材包英文名 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `482-483` | 中英混用 | `AI生成NPC形象`、`NPC 形象 AI 生成功能仍在开发中。` | 同时混入 `AI`、`NPC` |
| `src/components/CustomWorldEntityEditorModal.tsx` | `635-636` | 中英混用 | `新增 NPC`、`编辑 NPC...` | NPC 档案编辑标题混入英文缩写 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `663` | 中英混用 | `修改形象` | 本行本身无问题,但上下文仍指向 `NPC` 视觉编辑入口 |
| `src/components/CustomWorldEntityEditorModal.tsx` | `734` | 中英混用 | `AI生成` | 按钮文案混入 `AI` |
| `src/components/CustomWorldEntityEditorModal.tsx` | `762-763` | 中英混用 | `AI生成场景`、`场景图片 AI 生成功能仍在开发中。` | 场景生成弹窗混入 `AI` |
| `src/components/CustomWorldNpcVisualEditor.tsx` | `393` | 中英混用 | `AI生成` | 自定义 NPC 视觉编辑器按钮混入 `AI` |
| `src/components/NpcVisualEditor.tsx` | `263-267` | 英文直出 | `Failed to load NPC visual overrides`、`Failed to load NPC layout config` | 编辑器首屏可见的加载失败兜底为英文 |
| `src/components/NpcVisualEditor.tsx` | `284-308` | 英文直出 | `response was invalid, using bundled defaults` 等 | 多组降级提示未本地化 |
| `src/components/NpcVisualEditor.tsx` | `463` | 中英混用 | `请先选择一个 NPC 进行编辑` | 空态文案混入 `NPC` |
| `src/components/NpcVisualEditor.tsx` | `539` | 英文直出 | `Save failed` | 保存失败提示仍是英文 |
| `src/components/NpcVisualEditor.tsx` | `702-708` | 中英混用 | `NPC 视觉编辑器`、`选择并编辑 NPC 的外观...` | 页面标题与简介多次混入 `NPC` |
| `src/components/NpcVisualEditor.tsx` | `718` | 中英混用 | `当前 NPC` | 当前对象字段名混入 `NPC` |
| `src/components/NpcVisualEditor.tsx` | `976-977` | 中英混用 | `拖动标记微调 NPC 的预览布局。移动时按住 Shift...` | 帮助提示同时混入 `NPC` 与 `Shift` |
| `src/components/NpcVisualEditor.tsx` | `1033-1052` | 英文直出 | `Unknown headgear`、`No headgear`、`Unknown main hand`、`No main hand`、`Unknown off hand`、`No off hand` | 预览状态说明仍是英文 |
## 四、预设编辑器
### 4.1 共享配置与选项枚举
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/shared.ts` | `43` | 中英混用 | `label: 'NPC'` | 预设编辑器顶部 tab 仍直接显示 `NPC` |
| `src/components/preset-editor/shared.ts` | `63-66` | 英文直出 | `idle`、`move`、`attack`、`die` | 怪物动画可选项是原始英文值 |
| `src/components/preset-editor/shared.ts` | `70-74` | 英文直出 | `steady`、`burst`、`mobility`、`finisher`、`projectile` | 技能风格可选项是原始英文值 |
### 4.2 角色预设面板
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `91-92` | 英文直出 | `Saved character preset overrides...`、`Failed to save character preset overrides.` | 保存反馈未本地化 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `264-279` | 英文直出 | `Characters`、`Browse the character roster...`、`Field`、`Save Character Overrides` | 左侧选择卡与保存栏均为英文 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `315-322` | 英文直出 | `Character Details`、`Field` | 详情卡标题和字段名未本地化 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `404-430` | 英文直出 | `Skill Preview`、`Preview ranged skills...`、`Preview Monster` | 技能预览区英文直出 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `450-467` | 英文直出 | `Skill Setup`、`Add Skill` | 技能配置区仍是英文 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `498-558` | 英文直出 | 大量 `label="Field"` | 多数字段仍显示占位词 `Field` |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `605` | 英文直出 | `Start Frame` | 动画字段未本地化 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `629`、`729` | 英文直出 | `Section`、`Editor section.` | 两个分区仍是半成品英文占位 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `697-698` | 英文直出 | `Attributes`、`Adjust the core character attributes.` | 属性面板未本地化 |
| `src/components/preset-editor/CharacterPresetPanel.tsx` | `755` | 英文直出 | `Unset` | 场景绑定下拉空值项为英文 |
### 4.3 怪物预设面板
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `49-50` | 英文直出 | `Saved monster overrides...`、`Failed to save monster overrides.` | 保存反馈未本地化 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `124-139` | 英文直出 | `Section`、`Editor section.`、`Field`、`Save Monster Overrides` | 左侧选择区和保存栏未本地化 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `135` | 异常显示 | ``${WORLD_LABELS[monster.worldType]} 闂?${optionMonster.name}`` | 选择列表分隔符损坏 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `158-159` | 英文直出 | `Monster Override Preview`、`Editor section.` | 预览区标题仍是英文 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `192-201` | 英文直出 | `Attack Range`、`Speed`、`HP`、`Max HP` | 预览摘要未本地化 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `212-234` | 英文直出 | `Monster ID`、`Name`、`Intro Action` | 核心字段名仍是英文 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `343` | 英文直出 | `FPS` | 动画字段未本地化 |
| `src/components/preset-editor/MonsterPresetPanel.tsx` | `207`、`275`、`307` | 英文直出 | `Section`、`Editor section.` | 多个分区标题仍为占位英文 |
### 4.4 场景 NPC 预设面板
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `127-128` | 英文直出 | `Saved NPC overrides.`、`Failed to save NPC overrides.` | 保存反馈未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `159` | 英文直出 | `No NPC presets are available.` | 空态文案未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `177-193` | 英文直出 | `NPC Library`、`Browse and select an NPC preset.`、`NPC ID`、`Save NPC Overrides` | 左侧选择区英文直出 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `221-237` | 英文直出 | `Skill Preview`、`Preview ranged skills from the linked character.`、`Skill`、`World` | 技能预览区未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `258` | 异常显示 | `闂?NPC` | 空态或提示文案已损坏 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `264-268` | 英文直出 | `Visual Preview`、`Hostile NPCs use monster presets...` | 视觉预览区标题与说明均未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `310-371` | 英文直出 | `NPC Details`、`Name`、`Role`、`Avatar`、`Linked Character ID`、`Monster Preset ID`、`Initial Affinity`、`Description`、`Visual Editor` | 详情区字段名大面积英文直出 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `374-375` | 英文直出 | `Hostile NPCs cannot use the visual editor...`、`Narrative NPC visual overrides can be previewed here.` | 视觉编辑区说明未本地化 |
| `src/components/preset-editor/SceneNpcPresetPanel.tsx` | `382-384` | 异常显示 | 三整段乱码说明 + `NPC` | 视觉编辑区空态说明已严重损坏 |
### 4.5 场景预设面板
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `52-53` | 英文直出 | `Saved scene overrides.`、`Failed to save scene overrides.` | 保存反馈未本地化 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `62` | 英文直出 | `No scene presets are available.` | 空态文案未本地化 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `105-107` | 英文直出 | `Treasure Ahead`、`Treasure` | 宝藏预览实体名仍是英文 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `132-171` | 英文直出 | `Scene Library`、`Browse and select a scene preset.`、`Save`、`Scene Preview`、`Preview monsters, NPCs, and treasure...` | 场景面板主框架仍多处英文 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `175-181` | 英文直出 | `Preview Mode`、`Monster Preview`、`NPC Preview`、`Treasure Preview` | 预览模式切换未本地化 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `207-226` | 英文直出 | `Hostile NPCs`、`NPCs`、`None` | 预览摘要区未本地化 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `233-290` | 英文直出 | `Scene Details`、`Edit the selected scene preset.`、`Scene ID`、`World`、`Name`、`Description`、`Image Source`、`Forward Scene`、`Connected Scene IDs`、`Monster IDs`、`Treasure Hints` | 详情编辑区字段名几乎全部英文 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `271` | 英文直出 | `Unset` | 下拉空值项为英文 |
| `src/components/preset-editor/ScenePresetPanel.tsx` | `299` | 英文直出 | `NPCs In Scene` | 分区标题未本地化 |
### 4.6 状态函数编辑器
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/components/StateFunctionEditor.tsx` | `310-325` | 英文直出 | `Preview`、`Treasure` | 预览 NPC / 宝藏 context 里保留英文 |
| `src/components/StateFunctionEditor.tsx` | `1062-1064` | 英文直出 | `Option behavior overrides saved.`、`Failed to save option behavior overrides` | 保存反馈未本地化 |
| `src/components/StateFunctionEditor.tsx` | `1128` | 英文直出 | `无模板` 之外的模板选择逻辑仍有英文结构 | 该区主体中文,但下游模板 ID / 类型依旧偏英文 |
| `src/components/StateFunctionEditor.tsx` | `1185` | 英文直出 | `AnimationState` 原始值直接作为选项标签 | 动画值会直接显示英文枚举 |
| `src/components/StateFunctionEditor.tsx` | `1190` | 英文直出 | `placeholder="可使用 {monster} 占位符"` | 占位符本身暴露英文 key |
| `src/components/StateFunctionEditor.tsx` | `1191` | 英文直出 | `idle`、`move`、`attack` | 怪物动画下拉仍使用英文值 |
## 五、数据层 / 运行时文本源
### 5.1 直接驱动交互按钮、详情文案、结果文本的源头
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/data/npcInteractions.ts` | `444-580` | 重点补录 | 大量 `actionText` / `detailText` | 这是本轮补录重点,属于 NPC 交互选项直接展示源,需要逐条审校 |
| `src/data/npcInteractions.ts` | `327-349` | 英文直出 | `deep`、`honest`、`partial`、`guarded`、`warm`、`cooperative`、`neutral`、`distant`、`candid`、`true_but_incomplete`、`half_truth`、`situational_only` | 这些关系 / 说话风格值虽然是逻辑枚举,但后续很容易在编辑器、调试面板、覆盖配置中直接暴露 |
| `src/hooks/useStoryGeneration.ts` | `576-578` | 英文直出 | `Travel to ...`、`Leave camp and head toward ...` | 旅行选项和详情文案未本地化 |
| `src/hooks/useStoryGeneration.ts` | `654-659` | 英文直出 | `Speak with ...`、`Focus on the person in front of you first...` | 开场对话选项未本地化 |
| `src/hooks/useStoryGeneration.ts` | `827`、`1297` | 英文直出 | `Exchange an opening judgment with ... at camp` | 营地开场交互 actionText 未本地化 |
| `src/hooks/useStoryGeneration.ts` | `1097` | 英文直出 | `Begin the adventure` | 初始 actionText 未本地化 |
| `src/hooks/useStoryGeneration.ts` | `1374`、`1794` | 英文直出 | `Unknown AI error` | AI 兜底错误提示仍是英文 |
| `src/hooks/story/storyGenerationState.ts` | `137-141` | 英文直出 | `You leave ...`、`Travel to ...` | 旅行结果与 actionText 未本地化 |
| `src/hooks/story/npcEncounterActions.ts` | `277` | 英文直出 | `Victory reward: ${lootText}.` | 战斗胜利奖励结算文本未本地化 |
| `src/hooks/story/npcEncounterActions.ts` | `389` | 英文直出 | `NPC dialogue AI is unavailable.` | NPC 对话 AI 失败兜底是英文 |
| `src/hooks/story/characterChat.ts` | `68` | 英文直出 | `Player` | 聊天摘要拼接里保留英文说话人名 |
| `src/hooks/story/characterChat.ts` | `84` | 英文直出 | `Tell me more clearly what you mean.` | 建议起句未本地化 |
| `src/hooks/story/characterChat.ts` | `283` | 英文直出 | `Unknown AI error` | 私聊错误兜底未本地化 |
| `src/data/sceneObservation.ts` | `9-34` | 英文直出 | `You pause to listen...`、`Possible NPCs...`、`Possible hostile NPCs...`、`Possible treasure clues...`、`Boss clue...` | 观察环境的整组文本源仍是英文 |
### 5.2 会透出到编辑器 / 预览 / 覆盖系统的预设值
| 文件 | 行号 | 类型 | 当前文本 / 字段 | 说明 |
| --- | --- | --- | --- | --- |
| `src/data/scenePresets.ts` | `141` | 中英混用 | `role: '敌对NPC'` | 场景 NPC 角色名混入 `NPC` |
| `src/data/scenePresets.ts` | `194`、`294` | 英文直出 | `['trade', 'fight', 'spar', 'help', 'chat', 'recruit', 'gift']` | 场景 NPC 功能数组是英文原始值,编辑器容易直出 |
| `src/data/stateFunctions.ts` | `33` | 英文直出 | `monsterAnimation?: 'idle' | 'move' | 'attack'` | 动画值原始英文会进入状态函数编辑器 |
| `src/data/stateFunctions.ts` | `130`、`152`、`174`、`196`、`221`、`244` | 英文直出 | `steady`、`burst`、`mobility`、`finisher`、`projectile` | 技能权重 key 为英文原始值 |
| `src/data/stateFunctions.ts` | `372`、`445`、`569`、`575-576` | 中英混用 | 描述里多次直接写 `NPC` | 虽然主体中文,但会透出到说明文字 |
| `src/data/characterPresets.ts` | `54-70` | 英文直出 | `blunt`、`wary`、`evasive`、`measured`、`gentle`、`teasing`、`dry`、`steady`、`direct`、`fragmented`、`deflecting` | 对话风格推断返回值全为英文 |
| `src/data/characterPresets.ts` | `362-382`、`519-539`、`738-758`、`833-853`、`1018-1041` | 英文直出 | `assetFolder`、`folder`、`prefix` 中大量英文,如 `Sword Princess`、`idle`、`Double Jump`、`Wall Slide`、`Attack` | 这些值会被预设编辑器动画区直接展示或编辑 |
| `src/data/characterPresets.ts` | `387-389`、`544-546`、`763-765`、`858-860`、`1046-1048` | 英文直出 | `guardStyle`、`warmStyle`、`truthStyle` 使用英文值 | 会透出到预设编辑器 / 调试视图 |
| `src/data/characterPresets.ts` | `410-501`、`575-720`、`794-1000`、`1069-1197` | 英文直出 | `style`、`delivery`、`phase`、`anchor`、`motion` 使用 `steady`、`mobility`、`ranged`、`travel`、`target`、`projectile` 等英文值 | 角色技能配置层大面积保留英文元数据 |
| `src/data/monsterPresets.ts` | `384-817` | 英文直出 | 多处 `common`、`uncommon`、`rare`、`epic` | 怪物稀有度原始值为英文,若编辑器未做映射会直接暴露 |
| `src/editor/shared/jsonClient.ts` | `29-43` | 英文直出 | `Request failed`、`Save failed` | 编辑器通用 JSON 客户端默认错误文案未本地化 |
## 六、本轮已复查、暂未记录明确问题的文件
以下文件本轮重新检查过,但当前内容里没有继续记录“英文直出 / 异常显示”的明确条目,暂可视为本轮通过:
- `src/routing/appRoutes.tsx`
- `src/components/game-shell/CharacterSelectionFlow.tsx`
- `src/components/game-shell/GameShellStoryPanels.tsx`
- `src/components/CharacterPanel.tsx`
- `src/components/InventoryPanel.tsx`
- `src/components/MapModal.tsx`
- `src/components/CharacterChatModal.tsx`
- `src/components/SelectionCustomizationModals.tsx`
- `src/components/adventure-panel/AdventurePanelOverlays.tsx`
- `src/data/sceneEncounterPreviews.ts`
- `src/data/customWorldVisuals.ts`
- `src/services/customWorldBuilder.ts`
## 建议修复顺序
1. 先修主流程直接暴露给玩家的文本:
- `PreGameSelectionFlow.tsx`
- `GameShellOverlays.tsx`
- `GameShellRuntime.tsx`
- `GameShell.tsx`
- `AdventurePanel.tsx`
2. 再修编辑器里最容易误导内容生产的面板:
- `CharacterPresetPanel.tsx`
- `MonsterPresetPanel.tsx`
- `SceneNpcPresetPanel.tsx`
- `ScenePresetPanel.tsx`
- `StateFunctionEditor.tsx`
3. 最后统一清理数据层文本源和枚举映射:
- `npcInteractions.ts`
- `useStoryGeneration.ts`
- `storyGenerationState.ts`
- `npcEncounterActions.ts`
- `sceneObservation.ts`
- `characterPresets.ts`
- `stateFunctions.ts`

View File

@@ -0,0 +1,27 @@
# 文本与乱码审计总览
这一组文档记录的是同一条清理链路的不同阶段:从“发现哪里有英文/乱码”到“扩展到 prompt、npcInteraction、编辑器深层文本”。
## 当前推荐入口
1. [CHINESE_MOJIBAKE_INVENTORY.md](./CHINESE_MOJIBAKE_INVENTORY.md)
偏全局库存清单,适合先确认问题分布范围。
2. [GAME_UI_PRESET_EDITOR_NPC_PROMPT_TEXT_AUDIT_2026-04-02_DEEP_SCAN.md](./GAME_UI_PRESET_EDITOR_NPC_PROMPT_TEXT_AUDIT_2026-04-02_DEEP_SCAN.md)
这是当前最完整的深度审计版本,已经扩到 `prompt``npcInteractions`、运行时弹窗与编辑器深层文本。
3. [GAME_UI_PRESET_EDITOR_TEXT_AUDIT_2026-04-02.md](./GAME_UI_PRESET_EDITOR_TEXT_AUDIT_2026-04-02.md)
适合看“扩展重查版”的 UI / 预设 / 编辑器问题面。
## 历史时间线
- [EDITOR_GAME_PRESET_TEXT_AUDIT_2026-03-25.md](./EDITOR_GAME_PRESET_TEXT_AUDIT_2026-03-25.md):较早期的整体首轮盘点。
- [GAME_EDITOR_PRESET_TEXT_AUDIT_2026-03-29.md](./GAME_EDITOR_PRESET_TEXT_AUDIT_2026-03-29.md):复查阶段,开始收紧范围和口径。
- [GAME_EDITOR_PRESET_TEXT_AUDIT_2026-03-30.md](./GAME_EDITOR_PRESET_TEXT_AUDIT_2026-03-30.md):继续复核真实乱码与英文残留。
- [GAME_UI_PRESET_EDITOR_TEXT_AUDIT_2026-03-30_CONTINUED.md](./GAME_UI_PRESET_EDITOR_TEXT_AUDIT_2026-03-30_CONTINUED.md):对上一轮的续扫补充。
- [GAME_UI_PRESET_EDITOR_TEXT_AUDIT_2026-03-31.md](./GAME_UI_PRESET_EDITOR_TEXT_AUDIT_2026-03-31.md):继续收敛 UI、预设与编辑器问题。
- [GAME_UI_PRESET_EDITOR_TEXT_AUDIT_2026-04-01.md](./GAME_UI_PRESET_EDITOR_TEXT_AUDIT_2026-04-01.md):进入更明确的审计范围与方法阶段。
## 融合结论
- 早期几份文档主要负责“摸清哪里有问题”。
- `2026-04-02` 两份文档开始把重点收敛到真正会影响玩家体验和 AI 生成质量的链路。
- 现在做文本修复时,不必从最早一份开始逐篇读;优先看 `CHINESE_MOJIBAKE_INVENTORY``2026-04-02` 两份即可。