Prune obsolete docs and update navigation
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 文档总览
|
||||
|
||||
`docs/` 现在按主题拆成了 6 类,`docs/prd/` 保持独立,不参与本次整理改写。
|
||||
`docs/` 现在按主题拆成了 6 类;旧后端路线文档开始聚合和删除,后续实现以 Rust / SpacetimeDB 当前基线为准。
|
||||
|
||||
## 快速入口
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
- [技术方案](./technical/README.md):动画、服务端、外部产品形态拆解。
|
||||
- [规划与优先级](./planning/README.md):当前阶段的迭代排序与落地优先级。
|
||||
- [参考目录](./reference/README.md):脚本/Function 速查入口。
|
||||
- [PRD](./prd/):产品需求与阶段计划,原样保留。
|
||||
- [PRD](./prd):产品需求与阶段计划。
|
||||
|
||||
## 推荐阅读顺序
|
||||
|
||||
1. 先看 [经验沉淀](./experience/README.md),快速建立这个项目的开发共识。
|
||||
2. 再看 [工程审查总览](./audits/engineering/README.md) 和 [文本审计总览](./audits/text/README.md),了解当前风险。
|
||||
3. 需要排期时看 [规划与优先级](./planning/README.md)。
|
||||
4. 需要补方案时进入 [系统设计](./design/README.md) / [技术方案](./technical/README.md)。
|
||||
5. 需要对齐目标边界时再进入 [PRD](./prd/)。
|
||||
4. 需要补方案时进入 [系统设计](./design/README.md) / [技术方案](./technical/README.md);涉及后端先看 [当前后端实现基线](./technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)。
|
||||
5. 需要对齐目标边界时再进入 [PRD](./prd)。
|
||||
|
||||
## 分类规则
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
- `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`
|
||||
- `docs/audits/engineering/README.md`
|
||||
- `src/data/stateFunctions.ts`
|
||||
- `src/data/npcInteractions.ts`
|
||||
- `src/data/treasureInteractions.ts`
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
- `docs/audits/FUNCTION_DESIGN_AUDIT_2026-04-03.md`
|
||||
- `docs/reference/FUNCTION_SCRIPT_CATALOG_2026-04-04.md`
|
||||
- `docs/experience/ADVENTURE_RUNTIME_DEV_EXPERIENCE.md`
|
||||
- `docs/planning/CURRENT_GAME_ITERATION_PRIORITIES_2026-04-03.md`
|
||||
- `docs/audits/engineering/README.md`
|
||||
|
||||
本次实际核对了这些实现入口:
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## 系列总览
|
||||
|
||||
- [engineering/README.md](./engineering/README.md):工程优化审查三轮记录的融合入口。
|
||||
- [engineering/README.md](./engineering/README.md):当前工程优化审查与历史结论聚合入口。
|
||||
- [text/README.md](./text/README.md):文本、英文残留、乱码审计系列的融合入口。
|
||||
|
||||
## 专项审计
|
||||
|
||||
@@ -349,7 +349,7 @@
|
||||
文档依据:
|
||||
|
||||
1. `docs/audits/engineering/README.md`
|
||||
2. `docs/audits/engineering/CURRENT_ENGINEERING_OPTIMIZATION_PRIORITIES_2026-04-10.md`
|
||||
2. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
3. `docs/audits/engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md`
|
||||
4. `docs/experience/PROJECT_WORK_EXPERIENCE_PLAYBOOK.md`
|
||||
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
# 当前工程优化优先级汇总(2026-04-10)
|
||||
|
||||
## 结论先说
|
||||
|
||||
和 `2026-04-01` 那轮工程审查相比,当前仓库的主问题已经发生了明显迁移:
|
||||
|
||||
- 运行时主链拆分已经有进展,`useStoryGeneration.ts` 不再是最高复杂度热点。
|
||||
- `typecheck`、前后端测试、内容校验、编码校验都已经回到可通过状态。
|
||||
- 当前真正卡住工程节奏的,已经变成:
|
||||
- 绿色门禁不可信
|
||||
- 构建 warning 仍然会直接打断发布门禁
|
||||
- 自定义世界 / 编辑器 / 资产链路出现了新的巨型模块热点
|
||||
- 生成产物与旧工具链残留开始反向污染 lint、watch 和本地开发信号
|
||||
|
||||
一句话判断:
|
||||
|
||||
**现在最该优先做的,不是继续扩功能,而是先把门禁重新拉回可信状态,再拆 editor / custom world / assets 这批新的复杂度中心。**
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-10 当前校验快照
|
||||
|
||||
本次汇总不是只复述旧文档,额外执行了当前仓库校验命令。
|
||||
|
||||
| 项目 | 结果 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `npm run check:encoding` | 通过 | 编码基线正常 |
|
||||
| `npm run typecheck` | 通过 | 当前严格类型门禁可通过 |
|
||||
| `npm run test` | 通过 | `92` 个测试文件、`228` 个测试通过 |
|
||||
| `npm run server-node:test:baseline` | 通过 | 观测基线正常 |
|
||||
| `npm run server-node:test` | 通过 | `72` 个后端测试通过 |
|
||||
| `npm run check:content` | 通过 | 内容与覆盖校验正常 |
|
||||
| `npm run lint:eslint` | 失败 | `330` 个 error、`4` 个 warning |
|
||||
| `npm run build` | 失败 | 构建完成,但因 warning 被 `build-gate` 拦截 |
|
||||
|
||||
当前状态说明:
|
||||
|
||||
- 仓库不是“完全不可用”,而是已经进入“测试绿,但门禁信号不一致”的阶段。
|
||||
- 这类状态比纯红线更危险,因为团队会误以为主链已经稳定。
|
||||
|
||||
---
|
||||
|
||||
## P0:先恢复可信的绿色门禁
|
||||
|
||||
### P0-1:修复 lint 失真,重新建立可信基线
|
||||
|
||||
这是当前第一优先级。
|
||||
|
||||
#### 证据
|
||||
|
||||
- `npm run lint:eslint` 当前失败,报出 `330` 个 error、`4` 个 warning。
|
||||
- 问题既有真实源码问题,也有明显的门禁污染:
|
||||
- `src/`、`server-node/`、`scripts/` 中存在 import 排序、未使用导入、少量 hook 规则问题。
|
||||
- `temp-build-goal-check/` 这类生成产物目录也被 ESLint 扫描进来,放大了噪音。
|
||||
- `.eslintrc.cjs` 当前忽略了 `dist`、`media` 等目录,但没有忽略 `temp-build-goal-check`。
|
||||
- `vite.config.ts` 的 `server.watch.ignored` 已经忽略了 `**/temp*build*/**`,说明当前 watch 口径和 lint 口径并不一致。
|
||||
|
||||
#### 影响
|
||||
|
||||
- 团队无法快速判断“现在是源码真问题,还是产物目录噪音”。
|
||||
- lint 失真会直接削弱 review、回归和集成效率。
|
||||
- 在这种状态下继续加功能,只会让真实错误被更多噪音淹没。
|
||||
|
||||
#### 当前建议
|
||||
|
||||
1. 先清理或迁出 `temp-build-goal-check/` 这类生成产物目录,至少不要再让它进入 lint 扫描范围。
|
||||
2. 统一 `watch / lint / build` 对临时目录和生成目录的忽略口径。
|
||||
3. 再集中清当前源码层 lint 问题,优先处理:
|
||||
- import 排序
|
||||
- 未使用导入
|
||||
- 少量真实规则错误,例如 hook 误用和 `ban-types`
|
||||
|
||||
---
|
||||
|
||||
### P0-2:修复构建 warning,恢复可发布构建
|
||||
|
||||
这是和 P0-1 同级的阻塞项。
|
||||
|
||||
#### 证据
|
||||
|
||||
- `npm run build` 当前会被 `scripts/build-gate.mjs` 拦截。
|
||||
- 当前构建输出里最关键的 warning 有两类:
|
||||
- `src/services/ai.ts` 虽然尝试走动态加载,但又被 `src/components/CustomWorldEntityEditorModal.tsx` 静态引入,导致拆包失效。
|
||||
- `AuthenticatedApp-*.js` 达到 `1078.61 kB`,超过当前 `750 kB` 的 chunk warning 门槛。
|
||||
- 同轮构建里,`index-*.css` 也已经达到 `157.56 kB`,说明不仅 JS 主块重,样式也在继续膨胀。
|
||||
|
||||
#### 影响
|
||||
|
||||
- 当前不是“构建有一点 warning 可以先带着走”,而是发布门禁已经被 warning 直接打断。
|
||||
- editor / custom world / asset 工具能力正在把非主链代码重新带回主包路径。
|
||||
- 后续如果继续叠加这条链路,首屏、缓存和回归都会继续变差。
|
||||
|
||||
#### 当前建议
|
||||
|
||||
1. 先切断 `CustomWorldEntityEditorModal.tsx -> ../services/ai` 的静态依赖,让 `ai.ts` 真正留在懒加载路径。
|
||||
2. 把自定义世界编辑器、资产工作台、非首屏工具能力继续从 `AuthenticatedApp` 主块中拆出。
|
||||
3. 保持 `build warning = 失败` 的策略,不建议通过放宽阈值掩盖问题。
|
||||
|
||||
---
|
||||
|
||||
## P1:拆掉新的复杂度中心
|
||||
|
||||
### P1-1:优先拆 editor / custom world / assets 新热点
|
||||
|
||||
旧的运行时主链热点已经有所缓解,但复杂度并没有消失,而是转移到了新的模块上。
|
||||
|
||||
#### 当前大文件热点
|
||||
|
||||
前端:
|
||||
|
||||
- `src/components/CustomWorldEntityEditorModal.tsx`:`2778` 行
|
||||
- `src/services/ai.ts`:`2454` 行
|
||||
- `src/services/customWorld.ts`:`2217` 行
|
||||
- `src/data/npcInteractions.ts`:`2103` 行
|
||||
- `src/data/characterPresets.ts`:`1953` 行
|
||||
- `src/services/prompt.ts`:`1725` 行
|
||||
|
||||
后端:
|
||||
|
||||
- `server-node/src/modules/assets/characterAssetRoutes.ts`:`2295` 行
|
||||
- `server-node/src/app.test.ts`:`1527` 行
|
||||
- `server-node/src/auth/authService.ts`:`1243` 行
|
||||
- `server-node/src/modules/quest/runtimeQuestModule.ts`:`1137` 行
|
||||
|
||||
工具链:
|
||||
|
||||
- `scripts/dev-server/*.ts`:已于 `2026-04-19` 删除,旧 Vite 本地 API 链路不再保留实现代码
|
||||
|
||||
#### 影响
|
||||
|
||||
- 复杂度并没有真正被消灭,而是从运行时 story hook 转移到了自定义世界、资产编辑、提示词和数据装配链。
|
||||
- 这些文件大多同时承载了:
|
||||
- 领域规则
|
||||
- API 调用
|
||||
- 文本拼装
|
||||
- UI 状态
|
||||
- 工具流程
|
||||
- 后续任何一个小改动,都容易牵动整条大链,回归成本会再次上升。
|
||||
|
||||
#### 当前建议
|
||||
|
||||
1. 前端优先拆 `CustomWorldEntityEditorModal.tsx`,按“世界锚点 / 角色 / 地点 / 资产 / 高级设置”分段。
|
||||
2. 后端优先拆 `characterAssetRoutes.ts`,把 route、job orchestration、文件发布、模板读取拆开。
|
||||
3. 把 `src/services/ai.ts` 和 `src/services/customWorld.ts` 继续按运行时 / 编辑器 / 资产工具三条职责分层。
|
||||
|
||||
---
|
||||
|
||||
### P1-2:继续收口 editor / assets 工具链边界(旧链路已删除)
|
||||
|
||||
这项的重要性正在上升。
|
||||
|
||||
#### 证据
|
||||
|
||||
- `docs/technical/EDITOR_ASSET_API_MIGRATION_2026-04-08.md` 已说明 editor/assets API 已经迁到 `server-node`,方向是对的。
|
||||
- `scripts/dev-server/*.ts` 旧 Vite 本地 API 实现代码已于 `2026-04-19` 删除,仓库里不再保留并行实现。
|
||||
- 目录 `temp-build-goal-check/` 当前包含 `15099` 个文件,已经开始干扰 lint 和本地开发信号。
|
||||
- 相关日志里还出现了大量指向 `temp-build-goal-check` 的页面 reload 与 `ENOENT` 噪音。
|
||||
|
||||
#### 影响
|
||||
|
||||
- editor/assets 正式入口已经收口到 `server-node`,这部分双链路问题已解除。
|
||||
- 当前更大的噪音来源已经转移到临时构建目录、检查目录和历史日志残留。
|
||||
|
||||
#### 当前建议
|
||||
|
||||
1. 保持 `scripts/dev-server/README.md` 作为迁移结果标记,不要恢复旧 Vite `/api/*` 本地插件链。
|
||||
2. 将临时构建目录、检查目录、导出目录统一移出主工程扫描面。
|
||||
3. 继续以 `server-node/src/modules/editor/**`、`server-node/src/modules/assets/**` 与 `src/editor/shared/editorApiClient.ts` 作为唯一推荐入口,减少后续回流。
|
||||
|
||||
---
|
||||
|
||||
## P2:继续做架构收口,但不必抢在 P0 前面
|
||||
|
||||
### P2-1:继续压缩前端遗留 AI / 自定义世界实现
|
||||
|
||||
这一项仍然值得做,但当前不再是最前面的阻塞。
|
||||
|
||||
#### 原因
|
||||
|
||||
- `docs/technical/EXPRESS_BACKEND_WORKSTREAM_AUDIT_2026-04-09.md` 显示正式运行时主链已经大幅回收到后端。
|
||||
- 当前更明显的遗留,已经集中到编辑器、自定义世界工作台和资产工具,而不是正式运行时 story 主链。
|
||||
|
||||
#### 当前建议
|
||||
|
||||
1. 继续让正式运行时保持“后端为真相源”。
|
||||
2. 对仍留在前端的大 AI / prompt / custom world 实现,优先做职责收缩,而不是继续在原文件上堆逻辑。
|
||||
|
||||
---
|
||||
|
||||
### P2-2:继续优化自定义世界工作台,但以“减负”和“分层”为主
|
||||
|
||||
这一项更适合作为 P0、P1 稳住后的下一轮重点。
|
||||
|
||||
#### 依据
|
||||
|
||||
- `docs/audits/CUSTOM_WORLD_CREATOR_TOOL_AUDIT_2026-04-08.md` 已经明确指出:
|
||||
- 自定义世界入口、澄清、锁定、局部重生成、结果工作台仍是半收口状态。
|
||||
- 当前最大的前端热点文件也集中在这条链路上,说明它已经不仅是产品问题,也是工程复杂度问题。
|
||||
|
||||
#### 当前建议
|
||||
|
||||
1. 优先减少“大一统编辑弹窗”的职责,把高杠杆编辑和高级编辑分层。
|
||||
2. 让自定义世界生成、锁定、局部重生成规则继续向后端收口。
|
||||
3. 移动端优先,避免长表单和重弹窗继续吞掉维护成本。
|
||||
|
||||
---
|
||||
|
||||
## 推荐执行顺序
|
||||
|
||||
### 第一阶段:先把门禁拉回可信
|
||||
|
||||
1. 修 lint 口径失真
|
||||
2. 清生成产物扫描污染
|
||||
3. 修 build warning
|
||||
|
||||
### 第二阶段:再拆新的复杂度中心
|
||||
|
||||
1. 拆 `CustomWorldEntityEditorModal.tsx`
|
||||
2. 拆 `characterAssetRoutes.ts`
|
||||
3. 收缩 `src/services/ai.ts` / `src/services/customWorld.ts`
|
||||
|
||||
### 第三阶段:最后收 editor / custom world 架构尾巴
|
||||
|
||||
1. 清理旧 Vite 工具链残留
|
||||
2. 继续把自定义世界和资产工具收回正式后端边界
|
||||
|
||||
---
|
||||
|
||||
## 当前不建议优先做的事
|
||||
|
||||
- 不建议在当前 lint 与 build 仍然是红线时继续横向扩 editor / custom world 功能。
|
||||
- 不建议通过放宽 chunk warning 阈值来“修复”构建。
|
||||
- 不建议继续在 `CustomWorldEntityEditorModal.tsx`、`src/services/ai.ts`、`characterAssetRoutes.ts` 这类巨型文件中直接堆新逻辑。
|
||||
|
||||
---
|
||||
|
||||
## 本文依据
|
||||
|
||||
文档依据:
|
||||
|
||||
- `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md`
|
||||
- `docs/technical/EXPRESS_BACKEND_WORKSTREAM_AUDIT_2026-04-09.md`
|
||||
- `docs/technical/EDITOR_ASSET_API_MIGRATION_2026-04-08.md`
|
||||
- `docs/audits/CUSTOM_WORLD_CREATOR_TOOL_AUDIT_2026-04-08.md`
|
||||
- `docs/planning/CURRENT_GAME_ITERATION_PRIORITIES_2026-04-03.md`
|
||||
|
||||
当前仓库校验依据:
|
||||
|
||||
- `npm run check:encoding`
|
||||
- `npm run typecheck`
|
||||
- `npm run test`
|
||||
- `npm run server-node:test:baseline`
|
||||
- `npm run server-node:test`
|
||||
- `npm run check:content`
|
||||
- `npm run lint:eslint`
|
||||
- `npm run build`
|
||||
@@ -124,9 +124,8 @@
|
||||
本次审计结合了四类证据:
|
||||
|
||||
1. 文档基线:
|
||||
- `docs/audits/engineering/CURRENT_ENGINEERING_OPTIMIZATION_PRIORITIES_2026-04-10.md`
|
||||
- `docs/planning/EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md`
|
||||
- `docs/planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md`
|
||||
- `docs/audits/engineering/README.md`
|
||||
- `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
- `scripts/dev-server/README.md`
|
||||
2. 当前入口核对:
|
||||
- `src/main.tsx`
|
||||
@@ -591,10 +590,9 @@
|
||||
|
||||
文档依据:
|
||||
|
||||
1. `docs/audits/engineering/CURRENT_ENGINEERING_OPTIMIZATION_PRIORITIES_2026-04-10.md`
|
||||
2. `docs/planning/EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md`
|
||||
3. `docs/planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md`
|
||||
4. `scripts/dev-server/README.md`
|
||||
1. `docs/audits/engineering/README.md`
|
||||
2. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
3. `scripts/dev-server/README.md`
|
||||
|
||||
当前仓库扫描依据:
|
||||
|
||||
|
||||
@@ -366,9 +366,8 @@
|
||||
文档依据:
|
||||
|
||||
1. `docs/audits/engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md`
|
||||
2. `docs/audits/engineering/CURRENT_ENGINEERING_OPTIMIZATION_PRIORITIES_2026-04-10.md`
|
||||
3. `docs/planning/EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md`
|
||||
4. `docs/planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md`
|
||||
2. `docs/audits/engineering/README.md`
|
||||
3. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
|
||||
当前仓库复核依据:
|
||||
|
||||
@@ -381,4 +380,3 @@
|
||||
7. `src/services/runtimeItemAiDirector.ts`
|
||||
8. `src/services/apiClient.ts`
|
||||
9. 当前依赖图扫描结果与当前大文件体量扫描结果
|
||||
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
# 工程优化审查报告(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 单独收口,避免继续堆进总类型文件
|
||||
|
||||
## P2:AI 客户端层过厚,且重复了多套请求与解析逻辑
|
||||
|
||||
证据:
|
||||
|
||||
- `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 流程,工程成本都会持续上升。
|
||||
@@ -1,290 +0,0 @@
|
||||
# 工程优化审查报告(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` 继续向“纯战斗结算”和“播放适配层”分离
|
||||
- 先稳定公开接口,再做内部拆分,避免一次性大改
|
||||
|
||||
## P1:AI 服务迁移只完成了一半,`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
|
||||
|
||||
## P2:TypeScript 安全基线仍然偏宽松
|
||||
|
||||
### 现状
|
||||
|
||||
当前类型拆分方向是好的,`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 门禁变硬、再顺手压缩运行时大模块。只要这一步补上,后续加剧情、加编辑器能力、加自定义世界都会轻很多。
|
||||
@@ -1,200 +0,0 @@
|
||||
# 工程优化审查报告(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 体积
|
||||
|
||||
## 一句话结论
|
||||
|
||||
这个仓库已经从“功能堆叠期”进入“工程收尾期”了。当前最值得做的不是再加一层玩法,而是把门禁补齐、把超级模块拆开、把半迁移状态收尾;只要这一步做稳,后续继续扩展剧情、编辑器和自定义世界的成本都会明显下降。
|
||||
@@ -40,7 +40,7 @@
|
||||
### 2.1 文档依据
|
||||
|
||||
1. `docs/experience/PROJECT_WORK_EXPERIENCE_PLAYBOOK.md`
|
||||
2. `docs/planning/EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md`
|
||||
2. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
3. `docs/technical/RUNTIME_STORY_BACKEND_BOUNDARY_MIGRATION_2026-04-19.md`
|
||||
4. `docs/audits/engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md`
|
||||
5. `docs/audits/engineering/CURRENT_ENGINEERING_OPTIMIZATION_OPPORTUNITIES_2026-04-20.md`
|
||||
|
||||
@@ -1,36 +1,31 @@
|
||||
# 工程优化审查总览
|
||||
|
||||
这一组是同主题的连续审查记录,建议不要把它们当作三份彼此独立的文档来看。
|
||||
这一组只保留仍能指导当前 Rust / SpacetimeDB 主线的工程审查入口。早期连续扫描的有效结论已经合并到本 README 的“融合结论”,不再保留逐日旧稿。
|
||||
|
||||
## 当前推荐入口
|
||||
|
||||
1. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_F_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_F_2026-04-21.md)
|
||||
1. [SERVER_NODE_FREEZE_AND_DEPRECATION_2026-04-24.md](./SERVER_NODE_FREEZE_AND_DEPRECATION_2026-04-24.md)
|
||||
这一版是旧 Node 后端冻结、第一批物理删除与后续批次边界记录,明确当前工程只保留 Rust / SpacetimeDB 主线入口。
|
||||
2. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_F_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_F_2026-04-21.md)
|
||||
这一版是第六批落地记录,聚焦删除无入口 `questDirector`、旧观察文案 helper、一次性硬编码同步脚本,并补齐后端运行时 function catalog 契约覆盖。
|
||||
2. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_E_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_E_2026-04-21.md)
|
||||
3. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_E_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_E_2026-04-21.md)
|
||||
这一版是第五批落地记录,聚焦旧命名 re-export、空路由骨架、旧发布服务、前端 prompt 镜像与无入口编辑器壳层的物理删除。
|
||||
3. [FRONTEND_LOGIC_BACKEND_MIGRATION_AUDIT_2026-04-21.md](./FRONTEND_LOGIC_BACKEND_MIGRATION_AUDIT_2026-04-21.md)
|
||||
这一版是本轮前端越界逻辑专项审计,专门汇总当前仍应继续迁到 Express 后端的运行时、鉴权、生成编排与本地真相残留。
|
||||
4. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_D_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_D_2026-04-21.md)
|
||||
4. [FRONTEND_LOGIC_BACKEND_MIGRATION_AUDIT_2026-04-21.md](./FRONTEND_LOGIC_BACKEND_MIGRATION_AUDIT_2026-04-21.md)
|
||||
这一版是本轮前端越界逻辑专项审计,专门汇总当前仍应继续迁到 `server-rs` 的运行时、鉴权、生成编排与本地真相残留。
|
||||
5. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_D_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_D_2026-04-21.md)
|
||||
这一版是第四批落地记录,聚焦未接入业务的数据生成产物、测试专用 stub 与对应配置残留出清。
|
||||
5. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_C_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_C_2026-04-21.md)
|
||||
6. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_C_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_C_2026-04-21.md)
|
||||
这一版是第三批落地记录,聚焦鉴权真相收口,先移除前端保存自动登录用户名/密码的本地真相,并明确运行时快照前置写入为什么当前还不能硬砍。
|
||||
6. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_B_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_B_2026-04-21.md)
|
||||
7. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_B_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_B_2026-04-21.md)
|
||||
这一版是第二批落地记录,聚焦旧主流程壳层、旧 bootstrap 和旧 inventory / forge / equipment flow Hook 的正式出清。
|
||||
7. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_A_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_A_2026-04-21.md)
|
||||
8. [ENGINEERING_DEAD_CODE_CLEANUP_BATCH_A_2026-04-21.md](./ENGINEERING_DEAD_CODE_CLEANUP_BATCH_A_2026-04-21.md)
|
||||
这一版是第一批落地记录,聚焦高置信度小型孤岛、prompt 壳子、stub 和无入口 modal 的首轮清理。
|
||||
8. [CURRENT_ENGINEERING_OPTIMIZATION_OPPORTUNITIES_2026-04-20.md](./CURRENT_ENGINEERING_OPTIMIZATION_OPPORTUNITIES_2026-04-20.md)
|
||||
9. [CURRENT_ENGINEERING_OPTIMIZATION_OPPORTUNITIES_2026-04-20.md](./CURRENT_ENGINEERING_OPTIMIZATION_OPPORTUNITIES_2026-04-20.md)
|
||||
这一版是面向当前仓库状态的优化点盘点,适合直接拿来排优先级和拆执行批次。
|
||||
9. [ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md](./ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md)
|
||||
10. [ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md](./ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md)
|
||||
这一版是对 `2026-04-19` 基线的当前仓库复核,明确哪些问题已经处理、哪些表述需要纠正、热点又迁移到了哪里。
|
||||
10. [ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md](./ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md)
|
||||
11. [ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md](./ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md)
|
||||
这一版保留原始问题快照和执行回填,适合回看“为什么会有这轮清理与边界收口”。
|
||||
11. [ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md](./ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md)
|
||||
这一版最适合作为当前工程基线,重点从“是否真正绿色”“门禁有没有覆盖真实风险”来判断仓库状态。
|
||||
12. [ENGINEERING_OPTIMIZATION_REVIEW_2026-03-30.md](./ENGINEERING_OPTIMIZATION_REVIEW_2026-03-30.md)
|
||||
适合回看运行时主链路、Story/Combat 边界、分层过渡期问题。
|
||||
13. [ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md](./ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md)
|
||||
适合看第一轮系统性工程扫描,了解最早的问题基线。
|
||||
|
||||
## 融合结论
|
||||
|
||||
- 最新专项审计已经把“前端哪些逻辑还该后移到后端”收敛到 6 类:运行时快照、本地 token、本地浏览历史、NPC 委托换单、quest/runtime item 混合编排、浏览器 AI orchestration。
|
||||
@@ -43,11 +38,9 @@
|
||||
- 当前仓库已经完成“旧 dev 插件链路删除、根目录噪音清理、`server-node -> src/**` 反向依赖切断”这批第一阶段任务。
|
||||
- 当前如果想直接判断“今天先优化什么”,优先看 `CURRENT_ENGINEERING_OPTIMIZATION_OPPORTUNITIES_2026-04-20.md`。
|
||||
- 当前的新重点已经进一步收敛到三类:未接线孤岛模块、前端残留的运行时/鉴权真相、热点向 prompt/runtime profile/平台入口壳层迁移。
|
||||
- 三轮结论是一致收敛的:问题不在“有没有开始工程化”,而在“工程化是否真正覆盖了最危险的主链路”。
|
||||
- 最新一轮已经把关注点集中到质量门禁、真实绿色基线、关键模块豁免和 build warning 上。
|
||||
- 早期三轮工程扫描的结论已经聚合为一条长期规则:工程化不能只看目录和拆分动作,必须覆盖真实主链、质量门禁、绿色基线、关键模块豁免和 build warning。
|
||||
- `2026-04-19` 这一轮把问题压实到了四类:仓库噪音、旧 dev 入口残留、前端越界运行时逻辑、巨型热点文件。
|
||||
- `2026-04-20` 这一轮进一步确认:前两类已经阶段性完成,当前真正剩下的是边界尾巴和新热点迁移。
|
||||
- 如果只是为了判断现在先做什么,直接从 `2026-04-01` 开始即可。
|
||||
- 如果是要看当前清理和边界收口的最新状态,优先看 `ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md`。
|
||||
- 如果是要看“当前可执行的优化点清单”,优先看 `CURRENT_ENGINEERING_OPTIMIZATION_OPPORTUNITIES_2026-04-20.md`。
|
||||
- 如果是要做长期重构方案,再按 `2026-03-29 -> 2026-03-30 -> 2026-04-01 -> 2026-04-19 -> 2026-04-20` 的顺序回看演进。
|
||||
- 如果是要做长期重构方案,从 `2026-04-19`、`2026-04-20` 与当前 dead-code batch 记录开始即可。
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
2. 禁止新增从前端、Rust 后端、脚本或配置主动调用 `server-node/` 的逻辑。
|
||||
3. 禁止在 `server-node/` 内继续新增业务能力;后续能力必须落到 `server-rs/` 对应 crate。
|
||||
4. 历史文档、审计文档、迁移基线中允许保留 `server-node/` 作为旧系统来源说明,但不得把它描述成当前推荐实现。
|
||||
5. 删除 `server-node/` 前,必须先完成提示词资产与提示词相关工作流的最终迁移确认。
|
||||
5. 第一批物理删除后,提示词资产与提示词相关工作流继续按迁移核对项追踪,不再恢复旧工程目录。
|
||||
|
||||
## 3. 删除前阻断项
|
||||
## 3. 删除前迁移核对项
|
||||
|
||||
以下资产仍需要在删除目录前逐项确认迁移或废弃:
|
||||
以下资产曾作为删除前核对项。第一批物理删除后,旧实现不再从工作区直接读取;如需继续核对能力缺口,只允许通过历史提交、迁移文档或 `server-rs/` 已迁移实现追溯:
|
||||
|
||||
1. `server-node/src/prompts/customWorldEntityPrompts.ts`:自定义世界实体生成 prompt。
|
||||
2. `server-node/src/prompts/customWorldSceneNpcPrompts.ts`:自定义世界场景 NPC prompt。
|
||||
@@ -27,17 +27,17 @@
|
||||
|
||||
## 4. 工程防线
|
||||
|
||||
1. 根目录 `package.json` 中的 `server-node:*` 脚本统一改为冻结失败入口。
|
||||
2. 新增 `npm run check:server-node-freeze`,用于阻止新增 `server-node` 引用。
|
||||
3. 新增 `scripts/server-node-frozen.mjs`,任何旧 `server-node:*` 入口被误执行时都会直接失败并提示迁移到 `server-rs/`。
|
||||
4. 新增 `scripts/server-node-freeze-baseline.json`,只允许冻结前已经存在的引用继续作为迁移基线存在。
|
||||
1. 第一批物理删除后,根目录 `package.json` 不再保留 `server-node:*`、`dev:node`、`check:server-node-freeze` 等旧入口。
|
||||
2. Vite、Caddy 与本地开发脚本默认只指向 Rust `api-server`,不再保留 Node/Rust 后端切换开关。
|
||||
3. 历史文档允许保留旧 `server-node` 字样,但新增工程入口、脚本、依赖、运行说明不得再指向旧 Node 后端。
|
||||
4. 若后续需要恢复旧能力,只能迁移到 `server-rs/` 对应 crate 或 Axum facade,不恢复 `server-node/` 工程目录。
|
||||
|
||||
## 5. 后续处理顺序
|
||||
|
||||
1. 优先迁移或废弃提示词资产与 prompt 工作流。
|
||||
2. 确认前端不再通过任何路径调用 Node 后端能力。
|
||||
3. 删除旧脚本、旧 smoke、旧 manifest 与 `server-node/` 目录。
|
||||
4. 删除冻结基线检查中对历史引用的豁免。
|
||||
1. 继续核对提示词资产与 prompt 工作流是否已完整落到 Rust 主线。
|
||||
2. 继续把前端残留业务编排迁入 `server-rs/`。
|
||||
3. 清理技术索引中容易误导当前入口的 Node / Express 文案。
|
||||
4. 保留历史审计材料,但不得把旧 Node 后端描述为当前推荐实现。
|
||||
|
||||
## 6. 已确认迁移项
|
||||
|
||||
@@ -50,3 +50,46 @@
|
||||
3. 使用位置:`generate_draft_foundation_act_backgrounds(...)` 收集 `sceneChapterBlueprints[].acts[]` 后,先构造幕背景图专用提示词,再调用 `generate_custom_world_scene_image_for_profile(...)`。
|
||||
4. 保留语义:世界名、场景名、幕标题、幕摘要、幕目标、过渡钩子、主角色、辅助角色、世界气质、背景描述,以及“只生成环境背景,不出现角色立绘、站位 UI、对白框、按钮或文字”的约束。
|
||||
5. 迁移边界:`server-node/` 仅作为历史来源说明,不再参与运行;后续调整统一修改 Rust 主源。
|
||||
|
||||
## 7. 第一批安全删除记录(2026-04-25)
|
||||
|
||||
本批次开始把冻结隔离升级为物理删除。执行依据是项目后端主线已固定为 `server-rs/` 的 Rust + SpacetimeDB 多 crate 方案,旧 `server-node/` 不再作为可运行、可扩展、可引用的工程目录保留。
|
||||
|
||||
### 7.1 删除范围
|
||||
|
||||
1. 删除 `server-node/` 目录本体,旧实现只允许通过历史提交、迁移文档和已迁移到 `server-rs/` 的代码追溯。
|
||||
2. 删除旧 Node 后端专用入口:`scripts/dev-node.mjs`、`scripts/server-node-frozen.mjs`、`scripts/check-server-node-freeze.mjs`、`scripts/server-node-freeze-baseline.json`、`scripts/smoke-server-node.ts`、`scripts/smoke-same-origin-stack.ts`、`scripts/m7-api-compare.ts`、`scripts/deploy.sh`、`scripts/update.sh`、`view-llm-logs.ps1`。
|
||||
3. 根目录 `package.json` 删除 `server-node:*`、`dev:node`、`m7:api-compare` 与 `check:server-node-freeze` 等旧入口,并移除 `express`、`@types/express` 依赖。
|
||||
4. `npm run dev` 改为启动 Rust 本地栈;Vite 和 Caddy 默认只代理到 Rust `api-server`,不再保留 `GENARRATIVE_BACKEND_STACK` 的 Node/Rust 双栈切换口。
|
||||
5. 清理 `.gitignore` 中只服务 `server-node/` 的忽略规则,并同步 `README.md`、`.env.example`、`server-rs/README.md` 与 `scripts/dev-server/README.md`。
|
||||
|
||||
### 7.2 暂不处理范围
|
||||
|
||||
1. 历史 PRD、审计、迁移基线中的 `server-node` 文案暂时保留为历史记录,不在第一批中大规模改写。
|
||||
2. `backend-rewrite-tasklist/` 中以旧 Node 后端为对照的迁移材料暂时保留,作为后续核对 Rust 主线能力缺口的历史审计输入。
|
||||
3. `src/services/ai.ts` 与 `src/prompts/customWorldPrompts.ts` 的前端残留编排不属于本批 Node 后端删除范围;后续继续按“前端只负责表现,业务逻辑进入 `server-rs/`”单独收口。
|
||||
|
||||
### 7.3 后续批次建议
|
||||
|
||||
1. 技术文档索引中的 Node / Express 后端条目只保留为历史资料,不再作为当前入口或推荐方案。
|
||||
2. 后续如继续整理历史文档,只把仍描述 `Express / PostgreSQL` 为当前目标架构的文字修正为“历史阶段口径”。
|
||||
3. 继续把前端残留业务逻辑迁入 `server-rs`;涉及 SpacetimeDB 的设计、实现、脚本和绑定继续显式使用相关 skill。
|
||||
|
||||
### 7.4 本轮安全核对结果
|
||||
|
||||
2026-04-25 本轮开始分批删除时,已确认第一批工程入口层面满足以下条件:
|
||||
|
||||
1. 工作区根目录下已不存在 `server-node/` 物理目录。
|
||||
2. `scripts/` 下已不存在旧 Node 后端专用运行、冻结、smoke、API 对比脚本。
|
||||
3. 根目录 `package.json` 不再包含 `server-node:*`、`dev:node`、`m7:api-compare` 与 `check:server-node-freeze` 入口。
|
||||
4. `package.json` 与 `package-lock.json` 不再包含 `express`、`@types/express`、`pg`、`postgres` 依赖包。
|
||||
5. `README.md`、`scripts/dev-server/README.md`、`server-rs/README.md`、`vite.config.ts`、`scripts/*.mjs`、`src/`、`packages/` 与 `server-rs/` 未发现仍主动启动或调用 `server-node` 的当前工程入口。
|
||||
|
||||
### 7.5 第二批删除边界
|
||||
|
||||
第二批不再删除可运行工程代码,而是清理“容易误导当前实现口径”的历史文档索引:
|
||||
|
||||
1. 只修正文档中仍把 `server-node`、Express 或 PostgreSQL 描述为当前推荐后端的句子。
|
||||
2. 保留审计、PRD、迁移基线中作为历史事实、旧实现来源、能力对照的 `server-node` 引用。
|
||||
3. 不大规模重写包含中文剧情、需求、审计结论的历史文档,避免把真实历史上下文抹平。
|
||||
4. 若发现某个历史文档仍指导新开发继续写 Node 后端,先把该文档改为“历史阶段口径”,再继续工程处理。
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
# 编辑器 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 ...` 全部收口到统一词典。
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
# 游戏 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` 之类术语的显示策略。
|
||||
@@ -1,87 +0,0 @@
|
||||
# 游戏 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` 增加显示层映射,避免原始英文值继续直接透到编辑器和运行时界面。
|
||||
@@ -1,280 +0,0 @@
|
||||
# 游戏 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`
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
# 游戏 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。
|
||||
|
||||
@@ -1,325 +0,0 @@
|
||||
# 游戏 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/` 中很多英文值本身可能是内部枚举,但只要当前编辑器 / 预览没有做中文映射,就仍应视为“会暴露到用户侧”的文本问题。
|
||||
@@ -1,6 +1,6 @@
|
||||
# 文本与乱码审计总览
|
||||
|
||||
这一组文档记录的是同一条清理链路的不同阶段:从“发现哪里有英文/乱码”到“扩展到 prompt、npcInteraction、编辑器深层文本”。
|
||||
这一组只保留当前仍需要执行的文本与乱码审计入口。早期逐日扫描已经聚合到当前结论,不再保留旧稿链路。
|
||||
|
||||
## 当前推荐入口
|
||||
|
||||
@@ -11,17 +11,8 @@
|
||||
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):进入更明确的审计范围与方法阶段。
|
||||
|
||||
## 融合结论
|
||||
|
||||
- 早期几份文档主要负责“摸清哪里有问题”。
|
||||
- 早期几轮扫描已经完成使命,核心结论是:不要把乱码当成普通文案改写,先确认真实编码;文本修复要优先处理会进入玩家体验和 AI 生成链路的内容。
|
||||
- `2026-04-02` 两份文档开始把重点收敛到真正会影响玩家体验和 AI 生成质量的链路。
|
||||
- 现在做文本修复时,不必从最早一份开始逐篇读;优先看 `CHINESE_MOJIBAKE_INVENTORY` 和 `2026-04-02` 两份即可。
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
可复用来源:
|
||||
|
||||
- `README.md`
|
||||
- `docs/technical/NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md`
|
||||
- `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
- `docs/experience/PROJECT_DEVELOPMENT_EXPERIENCE.md`
|
||||
|
||||
### 5.2 技术研发情况
|
||||
|
||||
@@ -101,8 +101,8 @@
|
||||
- `docs/prd/AI_NATIVE_CUSTOM_WORLD_CREATION_FLOW_OPTIMIZATION_PRD_2026-04-06.md`
|
||||
- `docs/prd/AI_NATIVE_STORY_ENGINE_PHASE1_IMPLEMENTATION_PLAN_2026-04-06.md`
|
||||
- `docs/prd/AI_NATIVE_STORY_ENGINE_PHASE2_IMPLEMENTATION_PLAN_2026-04-06.md`
|
||||
- `docs/technical/NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md`
|
||||
- `docs/planning/CURRENT_GAME_ITERATION_PRIORITIES_2026-04-03.md`
|
||||
- `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
- `docs/audits/engineering/README.md`
|
||||
- `docs/experience/PROJECT_DEVELOPMENT_EXPERIENCE.md`
|
||||
|
||||
## 5. 三个方向的共用材料包
|
||||
|
||||
@@ -1,293 +0,0 @@
|
||||
# 当前游戏优先迭代清单(2026-04-03)
|
||||
|
||||
## 结论先说
|
||||
|
||||
当前阶段最不该做的,是继续零散加玩法、加场景、加文案,却让主链路、规则底座和工程门禁继续处在半完成状态。
|
||||
|
||||
按现有文档和代码状态看,建议优先级顺序如下:
|
||||
|
||||
1. `P0`:先恢复工程绿色基线,并把运行时主链路继续拆开
|
||||
2. `P1`:再落统一角色属性底座,作为战斗 / 对话 / 招募 / Build / 掉落 / 任务的共同语义基础
|
||||
3. `P1`:在统一属性底座之上,重做 Build、运行时物品奖励、任务系统三条核心玩法链
|
||||
4. `P2`:最后收尾编辑器共享层、本地 API 分层、移动端体验与运行时包体优化
|
||||
|
||||
一句话判断:
|
||||
|
||||
**现在的优先级不是“继续扩玩法宽度”,而是“先把底层规则、主流程边界和工程可维护性补齐,再扩玩法深度”。**
|
||||
|
||||
补充更新(`2026-04-21`):
|
||||
|
||||
当前与“主流程边界补齐”直接对应的执行基线,已经从泛化的 `GameShell / useStoryGeneration / customWorld` 热点讨论,收口成两条正式技术方案:
|
||||
|
||||
1. [../technical/CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md](../technical/CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md):负责创作入口 -> Agent session -> result preview -> published profile 主链。
|
||||
2. [../technical/RPG_ENTRY_RUNTIME_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md](../technical/RPG_ENTRY_RUNTIME_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md):负责平台入口 -> 继续游戏/开始游戏 -> RPG runtime -> runtime story 主链。
|
||||
|
||||
因此本文里的 `P0-2`,当前应按这两条主线落地,而不是继续围绕旧 `GameShell` / `PreGameSelectionFlow` / `runtimeRoutes.ts` 命名做泛化式重构。
|
||||
|
||||
---
|
||||
|
||||
## 优先级清单
|
||||
|
||||
## P0-1:恢复绿色基线,收紧质量门禁
|
||||
|
||||
### 为什么必须排第一
|
||||
|
||||
- `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md` 已明确指出:当前最值得优先优化的不是继续加功能,而是把“半完成的工程化”补齐。
|
||||
- 文档中提到过 `lint` 失败、`build` warning、核心热区文件被 ESLint ignore、部分测试未进入默认套件,这意味着当前代码库还不在真正稳定的绿色基线。
|
||||
- 在这种状态下继续叠加新玩法,只会把问题扩散到更多运行时链路和编辑器链路。
|
||||
|
||||
### 本阶段要做什么
|
||||
|
||||
- 修复现有 `lint` / `build warning` / 明确可见的门禁破口
|
||||
- 缩小高风险核心文件的 ignore 范围
|
||||
- 让 `lint + typecheck + test + build + check:content` 成为可信的统一门禁
|
||||
- 对 warning 建立“尽快清零”策略,而不是长期带病开发
|
||||
|
||||
### 做到什么算完成
|
||||
|
||||
- 主开发分支长期保持 `npm run check` 可稳定通过
|
||||
- 核心运行时文件不再依赖长期 ignore 才能过门禁
|
||||
- 构建 warning 收敛到零或有非常明确的短期处理计划
|
||||
|
||||
### 为什么它比新功能更优先
|
||||
|
||||
- 没有绿色基线,后续所有大改都缺少可靠回归保护
|
||||
- 这一步是后面统一属性、任务重构、物品系统重构的前置条件
|
||||
|
||||
---
|
||||
|
||||
## P0-2:继续拆运行时主链路,防止核心 hook 和壳层继续膨胀
|
||||
|
||||
### 为什么必须紧跟在 P0-1 后面
|
||||
|
||||
- `docs/experience/PROJECT_DEVELOPMENT_EXPERIENCE.md`、`docs/experience/PROJECT_WORK_EXPERIENCE_PLAYBOOK.md`、`docs/experience/ADVENTURE_RUNTIME_DEV_EXPERIENCE.md` 都反复强调:这个项目是叙事、状态、演出、界面四条链路耦合的复合项目,不能靠大文件硬扛。
|
||||
- `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-03-30.md` 和 `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md` 一致指出,`useStoryGeneration`、`useCombatFlow`、`GameShell` 仍然是当前最大的复杂度集中点。
|
||||
- 如果不先拆主链,后面的统一属性系统、任务系统、物品导演层都会继续堆进现有巨型流程控制器,技术债只会翻倍。
|
||||
|
||||
### 本阶段要做什么
|
||||
|
||||
- 按 [../technical/CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md](../technical/CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md) 收口创作链,统一 `Agent session -> result preview -> published profile`
|
||||
- 按 [../technical/RPG_ENTRY_RUNTIME_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md](../technical/RPG_ENTRY_RUNTIME_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md) 收口 `rpgEntry -> rpgSession -> rpgRuntime -> rpgRuntimeStory -> rpgProfile`
|
||||
- 旧 `GameShell / PreGameSelectionFlow / runtimeRoutes.ts / storyActionService.ts` 只作为历史热区名或兼容 façade,不再作为当前新任务默认落点
|
||||
|
||||
### 做到什么算完成
|
||||
|
||||
- 新功能接入时,不需要再跨 `story + combat + panel + modal` 四五层一起改
|
||||
- 核心流程可以按领域补测试,而不是只能做人工回归
|
||||
- 后续玩法扩展能优先加领域模块,而不是继续往大 hook 里塞逻辑
|
||||
|
||||
### 这一项的实际意义
|
||||
|
||||
- 这是“后续还能继续做大”的结构前提
|
||||
- 不做这一步,任何系统升级都会越来越难落地
|
||||
|
||||
---
|
||||
|
||||
## P1-1:落地统一角色属性系统,作为全玩法共同底座
|
||||
|
||||
### 为什么它是最优先的玩法底座
|
||||
|
||||
- `docs/prd/AI_NATIVE_UNIFIED_ROLE_ATTRIBUTE_SYSTEM_PRD_2026-04-02.md` 已经把问题说得很清楚:当前玩家、NPC、怪物、Build、对话、掉落还没有共享同一套解释坐标。
|
||||
- 当前项目已经有 NPC 关系、怪物标签、Build 语义、自定义世界生成能力,但这些系统之间还缺一套统一的世界级属性 schema。
|
||||
- 如果先做任务、物品、Build 深化,而不先统一属性,后面很容易再次出现“每个系统各自解释角色”的分裂。
|
||||
|
||||
### 本阶段要做什么
|
||||
|
||||
- 为预设世界固化世界级属性 schema
|
||||
- 为玩家角色、怪物、关键 NPC 补 `attributeProfile`
|
||||
- 建立统一的属性解析与校验层
|
||||
- 先让对话 / 招募 / 送礼 / 详情面板开始读取这套新属性解释
|
||||
|
||||
### 做到什么算完成
|
||||
|
||||
- 玩家、NPC、怪物都能落到同一套属性语义里
|
||||
- 聊天、送礼、招募至少有一条链可以直接解释到属性层
|
||||
- 自定义世界也能生成并持久化自己的属性 schema
|
||||
|
||||
### 为什么这项优先于“多做内容”
|
||||
|
||||
- 这是后面 Build、物品、任务三条系统统一升级的共同前提
|
||||
- 没有这层底座,玩法会继续“能跑,但彼此不共语义”
|
||||
|
||||
---
|
||||
|
||||
## P1-2:把 Build 系统从“标签互相影响”改成“标签匹配角色属性”
|
||||
|
||||
### 为什么这里要尽快做
|
||||
|
||||
- `docs/prd/BUILD_SYSTEM_ATTRIBUTE_SIMILARITY_PRD_2026-04-02.md` 指出:当前 Build 更像标签网络效应,解释成本高、平衡成本高、角色差异感不够强。
|
||||
- 一旦统一角色属性系统先落地,Build 就是最适合第二个接入的玩法层,因为它最直接影响战斗反馈和角色成长感。
|
||||
|
||||
### 本阶段要做什么
|
||||
|
||||
- 为 Build 标签补属性亲和度向量
|
||||
- 改写 `buildDamage` 逻辑,让每个标签独立匹配当前角色属性画像
|
||||
- 调整 Build 面板文案,从“标签协同”转成“属性适配度”
|
||||
|
||||
### 做到什么算完成
|
||||
|
||||
- 玩家能理解“为什么这个标签适合当前角色”
|
||||
- 新增标签只影响自身贡献,不再扰动整张标签网络
|
||||
- Build 面板能解释收益来自哪些属性
|
||||
|
||||
### 实际收益
|
||||
|
||||
- 提高可解释性
|
||||
- 降低平衡难度
|
||||
- 让角色差异感真正进入 Build 体验
|
||||
|
||||
---
|
||||
|
||||
## P1-3:重做运行时物品奖励,让奖励真正贴合场景、NPC、最近事件和 Build 缺口
|
||||
|
||||
### 为什么它值得排在任务系统前面
|
||||
|
||||
- `docs/design/AI_NATIVE_RUNTIME_ITEM_SYSTEM_REDESIGN_2026-04-02.md` 明确指出:当前宝藏、NPC、任务、锻造等入口都有物品,但缺少统一导演层,奖励与场景/NPC/事件的贴合度不够高。
|
||||
- 相比任务系统,运行时物品奖励能更快提升“世界贴脸感”和“当下反馈质量”,且可以先从宝藏入口低风险落地。
|
||||
|
||||
### 本阶段要做什么
|
||||
|
||||
- 增加运行时物品上下文采样、导演层、编译器和叙事回写层
|
||||
- 统一宝藏、NPC 奖励、怪物掉落、任务奖励的物品生成入口
|
||||
- 让奖励优先围绕 Build 标签、限时 Build Buff、少量数值补足来设计
|
||||
|
||||
### 做到什么算完成
|
||||
|
||||
- 至少宝藏和 NPC 奖励接入统一导演层
|
||||
- 物品能解释“为什么在这里出现、和谁有关、补的是什么方向”
|
||||
- 物品来源可以进入背包、剧情、锻造与存档的同一套结构
|
||||
|
||||
### 实际收益
|
||||
|
||||
- 奖励不再像泛用掉落池
|
||||
- 世界、人物、最近剧情与成长反馈终于真正连起来
|
||||
|
||||
---
|
||||
|
||||
## P1-4:把任务系统从“单目标单阶段”升级成“意图 -> 合约 -> 信号推进”
|
||||
|
||||
### 为什么它仍然是高优先级
|
||||
|
||||
- `docs/prd/AI_NATIVE_QUEST_SYSTEM_PRD_2026-04-02.md` 已经指出:当前任务闭环是成立的,但任务来源偏静态、结构偏扁平、状态过粗、奖励和关系变化也不够贴语境。
|
||||
- 当前项目已经具备任务 UI、任务奖励、NPC 交互、剧情推进链,这说明任务系统适合做“升级”,而不是推倒重来。
|
||||
|
||||
### 本阶段要做什么
|
||||
|
||||
- 新增任务生成上下文、AI 任务意图层、本地任务编译层
|
||||
- 把任务推进改成统一 signal 驱动
|
||||
- 支持多 step、阶段揭示、完成后回报、后续钩子
|
||||
|
||||
### 做到什么算完成
|
||||
|
||||
- NPC 接任务不再只是静态模板,而是能根据当前局面生成任务意图
|
||||
- 运行时能用统一 signal 推进任务步骤
|
||||
- 奖励除了货币/道具,还能自然进入关系、情报、后续机会
|
||||
|
||||
### 为什么它排在物品系统之后
|
||||
|
||||
- 任务系统耦合更深,适合作为统一属性和统一奖励导演层之后的升级项
|
||||
- 先把属性和物品奖励理顺,任务系统落地时会更稳
|
||||
|
||||
---
|
||||
|
||||
## P2-1:收尾编辑器共享层与本地 API 分层,让内容扩张不再继续拖慢主项目
|
||||
|
||||
### 为什么它不是最前面,但也不能拖太久
|
||||
|
||||
- 最近几份工程审查都指出:编辑器共享层、本地 JSON 写入接口、LLM 代理、Vite 插件职责仍然处于迁移中间态。
|
||||
- 当前项目已经进入“内容工具很多、正式运行时也很重”的阶段,若不收尾这部分,后续每次扩内容都会重复踩基础设施问题。
|
||||
|
||||
### 本阶段要做什么
|
||||
|
||||
- 继续拆 editor shared 层
|
||||
- 清理迁移残留和死分支
|
||||
- 把本地 API 至少按 `llm proxy / json editor api / asset catalog` 分职责拆开
|
||||
|
||||
### 做到什么算完成
|
||||
|
||||
- 编辑器保存、共享组件、共享 client 不再重复实现
|
||||
- 本地 API 分工清晰,dev / preview 边界清楚
|
||||
- 编辑器扩展不再继续依赖大聚合组件
|
||||
|
||||
---
|
||||
|
||||
## P2-2:继续优化移动端冒险体验、首屏信息密度与运行时包体
|
||||
|
||||
### 为什么它放在 P2
|
||||
|
||||
- `docs/experience/PROJECT_DEVELOPMENT_EXPERIENCE.md` 和 `docs/experience/MOBILE_UI_DEV_EXPERIENCE.md` 都强调:冒险页必须优先保证上方演出、一屏选项和文本区自适应。
|
||||
- 但从当前文档判断,移动端体验和包体问题更像“持续治理项”,不是当前阶段最核心的系统阻塞点。
|
||||
|
||||
### 本阶段要做什么
|
||||
|
||||
- 继续优化冒险页一屏布局与文本滚动策略
|
||||
- 拆 `GameCanvas`、`AdventurePanel` 等高热区大模块
|
||||
- 按真实交互热区继续做 chunk 拆分
|
||||
|
||||
### 做到什么算完成
|
||||
|
||||
- 手机首屏稳定容纳画布、文本和关键选项
|
||||
- 核心页面热区模块更容易维护和测试
|
||||
- 构建产物中的主 chunk 有持续下降趋势
|
||||
|
||||
---
|
||||
|
||||
## 不建议当前优先做的事
|
||||
|
||||
以下内容不是不能做,而是不建议排在当前这轮前面:
|
||||
|
||||
- 大量新增世界、场景、角色 preset
|
||||
- 继续横向扩 NPC 交互种类,但不补统一规则底座
|
||||
- 继续堆宝藏、掉落、锻造分支,但不先做统一物品导演层
|
||||
- 继续增加任务模板数量,但不升级任务 contract
|
||||
- 继续往 `useStoryGeneration` / `useCombatFlow` / `GameShell` / `PreGameSelectionFlow` / `runtimeRoutes.ts` / `storyActionService.ts` 里直接塞新逻辑
|
||||
|
||||
原因很简单:
|
||||
|
||||
**这些工作会让表面内容变多,但不会让项目变得更稳,反而会放大当前已经存在的结构问题。**
|
||||
|
||||
---
|
||||
|
||||
## 推荐迭代顺序
|
||||
|
||||
### 第一阶段:先稳住工程与主流程
|
||||
|
||||
1. 绿色基线与门禁收紧
|
||||
2. 创作链按 `CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md` 收口
|
||||
3. RPG 进入游戏与运行时链按 `RPG_ENTRY_RUNTIME_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md` 收口
|
||||
|
||||
### 第二阶段:先补统一语义底座
|
||||
|
||||
1. 统一角色属性系统
|
||||
2. Build 改为属性适配
|
||||
|
||||
### 第三阶段:再深化 AI 原生玩法闭环
|
||||
|
||||
1. 运行时物品导演层
|
||||
2. 任务意图与 contract 系统
|
||||
|
||||
### 第四阶段:最后做工具与体验收尾
|
||||
|
||||
1. 编辑器共享层 / 本地 API 分层
|
||||
2. 移动端体验与包体优化
|
||||
|
||||
---
|
||||
|
||||
## 本清单的主要依据
|
||||
|
||||
- `docs/experience/PROJECT_DEVELOPMENT_EXPERIENCE.md`
|
||||
- `docs/experience/PROJECT_WORK_EXPERIENCE_PLAYBOOK.md`
|
||||
- `docs/experience/ADVENTURE_RUNTIME_DEV_EXPERIENCE.md`
|
||||
- `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md`
|
||||
- `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-03-30.md`
|
||||
- `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md`
|
||||
- `docs/design/AI_NATIVE_RUNTIME_ITEM_SYSTEM_REDESIGN_2026-04-02.md`
|
||||
- `docs/prd/AI_NATIVE_UNIFIED_ROLE_ATTRIBUTE_SYSTEM_PRD_2026-04-02.md`
|
||||
- `docs/prd/BUILD_SYSTEM_ATTRIBUTE_SIMILARITY_PRD_2026-04-02.md`
|
||||
- `docs/prd/AI_NATIVE_QUEST_SYSTEM_PRD_2026-04-02.md`
|
||||
|
||||
## 最后结论
|
||||
|
||||
如果只保留一句话,那就是:
|
||||
|
||||
**当前最优先的迭代方向,不是继续堆新内容,而是先把工程基线、主流程边界和统一规则底座补齐;只有这样,AI 原生任务、物品、Build 和后续内容扩展才会真正开始越做越顺。**
|
||||
@@ -139,10 +139,10 @@ Git 分支治理可以后置做,但不能和首轮工程清洗混在一起,
|
||||
|
||||
本计划基于现有文档已经确认的结论推进,重点参考:
|
||||
|
||||
1. `docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-04-01.md`
|
||||
1. `docs/audits/engineering/README.md`
|
||||
2. `docs/audits/engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md`
|
||||
3. `docs/audits/engineering/CURRENT_ENGINEERING_OPTIMIZATION_OPPORTUNITIES_2026-04-20.md`
|
||||
4. `docs/planning/EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md`
|
||||
4. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
5. `docs/experience/PROJECT_WORK_EXPERIENCE_PLAYBOOK.md`
|
||||
|
||||
按当前审计结果,首轮就应重点关注下面 3 组对象。
|
||||
|
||||
@@ -1,588 +0,0 @@
|
||||
# Express 后端化并行任务拆分规划(2026-04-08)
|
||||
|
||||
## 1. 目的
|
||||
|
||||
这份文档用于把 [EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md](./EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md) 进一步拆成可并行推进、尽量互不冲突的任务流。
|
||||
|
||||
目标不是把大重构拆成很多零碎 TODO,而是把它拆成:
|
||||
|
||||
- 可以同时开工
|
||||
- 写入边界清晰
|
||||
- 交付物明确
|
||||
- 依赖关系稳定
|
||||
- 最后容易集成
|
||||
|
||||
---
|
||||
|
||||
## 2. 并行拆分原则
|
||||
|
||||
## 2.1 基本原则
|
||||
|
||||
- 每条任务尽量拥有独占目录或独占模块,不去抢同一批热点文件。
|
||||
- 热点集成文件只由“集成岗”或最后一轮集成处理,不作为多个任务的日常编辑目标。
|
||||
- 先搭协议边界,再迁规则执行,再收缩前端。
|
||||
- 前端与后端可以并行推进,但前提是先冻结 contract。
|
||||
- 编辑器链路和正式运行时链路分开拆,避免互相阻塞。
|
||||
|
||||
## 2.2 当前最容易冲突的文件
|
||||
|
||||
以下文件建议默认只由集成岗或最后一轮联调处理:
|
||||
|
||||
- `server-node/src/context.ts`
|
||||
- `server-node/src/routes/runtimeRoutes.ts`
|
||||
- `server-node/src/app.ts`
|
||||
- `src/services/apiClient.ts`
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/hooks/useGameFlow.ts`
|
||||
- `src/components/GameShell.tsx`
|
||||
|
||||
其他任务如果必须影响这些文件,优先通过:
|
||||
|
||||
- 新增独立模块
|
||||
- 新增 adapter
|
||||
- 新增中间层入口
|
||||
|
||||
而不是直接在热点文件中大改。
|
||||
|
||||
---
|
||||
|
||||
## 3. 建议并行批次
|
||||
|
||||
## 批次 A:可立即并行开工
|
||||
|
||||
- 任务 0:集成岗与接口冻结
|
||||
- 任务 1:共享 contract 与目录抽离
|
||||
- 任务 2:PostgreSQL 持久化基线收口
|
||||
- 任务 3:服务端 HTTP 基础设施与统一响应壳层
|
||||
- 任务 8:编辑器 API 归口与工具链隔离
|
||||
- 任务 9:测试、观测与部署基线
|
||||
|
||||
## 批次 B:在 contract 初版落地后并行开工
|
||||
|
||||
- 任务 4:服务端 AI 编排收口
|
||||
- 任务 5:运行时领域模块 A,Story / Combat / NPC
|
||||
- 任务 6:运行时领域模块 B,Inventory / Quest / Build / Runtime Item
|
||||
- 任务 7:前端 SDK、鉴权、持久化瘦身
|
||||
|
||||
## 批次 C:在服务端 action 和 view model 稳定后开工
|
||||
|
||||
- 任务 10:前端主流程壳层与大 hook 瘦身
|
||||
|
||||
---
|
||||
|
||||
## 4. 任务拆分
|
||||
|
||||
## 任务 0:集成岗与接口冻结
|
||||
|
||||
### 目标
|
||||
|
||||
负责冻结边界、维护接口文档、控制热点文件的合并节奏,避免多人同时改核心入口。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `docs/planning/**`
|
||||
- `docs/technical/**`
|
||||
- 最终集成时的热点入口文件
|
||||
|
||||
### 主要输出
|
||||
|
||||
- 统一任务看板
|
||||
- contract 版本表
|
||||
- 热点文件编辑规则
|
||||
- 每日或每阶段集成清单
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 团队知道哪些文件不能多人同时改
|
||||
- 每条任务都有明确的上游 contract 与下游接入点
|
||||
|
||||
---
|
||||
|
||||
## 任务 1:共享 Contract 与目录抽离
|
||||
|
||||
### 目标
|
||||
|
||||
先把前后端共同识别的类型、schema、响应结构、错误结构抽出来,切断 `server-node -> src/**` 的长期反向依赖。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `packages/shared/**`
|
||||
- 新建的共享类型、schema、contract 目录
|
||||
|
||||
### 可改边界
|
||||
|
||||
- `server-node/src/**` 中的 import 替换入口
|
||||
- `src/**` 中的 import 替换入口
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 具体业务规则迁移
|
||||
- 前端页面行为调整
|
||||
- 数据库实现细节
|
||||
|
||||
### 主要输出
|
||||
|
||||
- 统一 API envelope
|
||||
- 统一错误对象
|
||||
- 统一 action / response contract
|
||||
- 统一领域类型和状态枚举
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 新增服务端模块不需要继续直接依赖前端目录里的实现细节
|
||||
- 前后端都以共享 contract 为边界协作
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 可与任务 2、任务 3、任务 8、任务 9 同时启动
|
||||
- 是任务 4、任务 5、任务 6、任务 7 的上游基础
|
||||
|
||||
---
|
||||
|
||||
## 任务 2:PostgreSQL 持久化基线收口
|
||||
|
||||
### 目标
|
||||
|
||||
把“已经切到 PostgreSQL”的状态收成真正稳定的后端基线,清掉 SQLite 残留口径与仓储层耦合问题。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `server-node/src/config.ts`
|
||||
- `server-node/src/db.ts`
|
||||
- `server-node/src/repositories/**`
|
||||
- `server-node/src/app.test.ts`
|
||||
- `.env.example`
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 剧情规则
|
||||
- 选项结算
|
||||
- 前端状态瘦身
|
||||
|
||||
### 主要输出
|
||||
|
||||
- PostgreSQL 连接配置
|
||||
- 仓储层接口统一
|
||||
- 数据表初始化/迁移方案
|
||||
- 运行时持久化测试基线
|
||||
- 文档中的数据库现状统一
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 后端运行时数据完全以后端数据库为准
|
||||
- 配置、日志、测试、文档里不再把 SQLite 写成当前正式现状
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 可与任务 1、任务 3、任务 8、任务 9 同时启动
|
||||
- 为任务 5、任务 6、任务 7 提供稳定持久化基础
|
||||
|
||||
---
|
||||
|
||||
## 任务 3:服务端 HTTP 基础设施与统一响应壳层
|
||||
|
||||
### 目标
|
||||
|
||||
建立统一的服务端响应结构、错误结构、请求链路日志、版本字段和中间件壳层。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `server-node/src/http.ts`
|
||||
- `server-node/src/errors.ts`
|
||||
- `server-node/src/middleware/**`
|
||||
- `server-node/src/app.ts`
|
||||
|
||||
### 可改边界
|
||||
|
||||
- 为 route 层提供新的响应 helper
|
||||
- 为后续 action 接口提供统一 envelope
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 具体 story / combat / quest 业务逻辑
|
||||
- 前端页面层接入
|
||||
|
||||
### 主要输出
|
||||
|
||||
- 统一 JSON 响应格式
|
||||
- 统一错误格式
|
||||
- `requestId`
|
||||
- `latency` 与关键日志字段
|
||||
- 路由级版本与元信息壳层
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 后端所有新接口都能套用同一层响应约定
|
||||
- 前端不需要为不同接口写多套错误解析逻辑
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 可与任务 1、任务 2、任务 8、任务 9 同时启动
|
||||
- 是任务 4、任务 5、任务 6、任务 7 的共同基础
|
||||
|
||||
---
|
||||
|
||||
## 任务 4:服务端 AI 编排收口
|
||||
|
||||
### 目标
|
||||
|
||||
把正式运行时的 prompt 组装、模型调用、容错、SSE 转发都收回后端,浏览器不再保留正式运行时 AI fallback。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `server-node/src/services/llmClient.ts`
|
||||
- `server-node/src/services/chatService.ts`
|
||||
- `server-node/src/services/storyService.ts`
|
||||
- `server-node/src/services/customWorldGenerationService.ts`
|
||||
- `server-node/src/services/questService.ts`
|
||||
- `server-node/src/services/runtimeItemService.ts`
|
||||
|
||||
### 可新增目录
|
||||
|
||||
- `server-node/src/modules/ai/**`
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 前端主流程组件
|
||||
- 数据库存储实现
|
||||
|
||||
### 主要输出
|
||||
|
||||
- 后端统一 AI orchestration 层
|
||||
- 流式接口统一适配
|
||||
- prompt 复用策略
|
||||
- 前端 fallback 清理清单
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 正式运行时不再依赖浏览器端大体量 AI 实现作为兜底
|
||||
- AI 失败、超时、流式中断都能在后端统一处理
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 建议在任务 1、任务 3 有初版后启动
|
||||
- 可与任务 5、任务 6、任务 7 并行
|
||||
|
||||
---
|
||||
|
||||
## 任务 5:运行时领域模块 A,Story / Combat / NPC
|
||||
|
||||
### 目标
|
||||
|
||||
把剧情推进、战斗结算、NPC 交互这些最核心的运行时状态迁移到后端领域模块。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `server-node/src/modules/story/**`
|
||||
- `server-node/src/modules/combat/**`
|
||||
- `server-node/src/modules/npc/**`
|
||||
|
||||
### 可改边界
|
||||
|
||||
- 为 route/action 层提供服务接口
|
||||
- 为前端提供 view model 所需聚合结果
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 背包、Build、任务奖励编排
|
||||
- 编辑器接口
|
||||
|
||||
### 主要输出
|
||||
|
||||
- story action resolver
|
||||
- combat resolution service
|
||||
- npc interaction service
|
||||
- 统一返回给 UI 的 presentation/view model 结构
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 前端不再本地决定 function 合法性、战斗结果、NPC 关键关系变化
|
||||
- 点击选项时,后端能返回完整下一步展示结果
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 依赖任务 1、任务 3
|
||||
- 可与任务 4、任务 6、任务 7 并行
|
||||
|
||||
---
|
||||
|
||||
## 任务 6:运行时领域模块 B,Inventory / Quest / Build / Runtime Item
|
||||
|
||||
### 目标
|
||||
|
||||
把任务推进、运行时物品、背包/装备、Build 收益等剩余核心规则迁到后端。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `server-node/src/modules/inventory/**`
|
||||
- `server-node/src/modules/quest/**`
|
||||
- `server-node/src/modules/build/**`
|
||||
- `server-node/src/modules/runtime-item/**`
|
||||
|
||||
### 可改边界
|
||||
|
||||
- 调用任务 2 的仓储层
|
||||
- 使用任务 1 的共享 contract
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 前端页面层改造
|
||||
- Story / Combat / NPC 主链路
|
||||
|
||||
### 主要输出
|
||||
|
||||
- inventory mutation service
|
||||
- quest signal progression service
|
||||
- build calculation service
|
||||
- runtime item resolution service
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 背包、任务、Build、运行时物品不再由前端保留正式结算逻辑
|
||||
- 这些领域能独立测试,不依赖 UI hook
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 依赖任务 1、任务 2、任务 3
|
||||
- 可与任务 4、任务 5、任务 7 并行
|
||||
|
||||
---
|
||||
|
||||
## 任务 7:前端 SDK、鉴权、持久化瘦身
|
||||
|
||||
### 目标
|
||||
|
||||
让前端从“业务执行层”退回“API 消费层 + 表现层状态协调层”。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `src/services/apiClient.ts`
|
||||
- `src/services/authService.ts`
|
||||
- `src/services/storageService.ts`
|
||||
- `src/services/aiService.ts`
|
||||
- `src/hooks/useGamePersistence.ts`
|
||||
- `src/hooks/useGameSettings.ts`
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 页面组件大范围重构
|
||||
- `useStoryGeneration.ts` 主流程瘦身
|
||||
|
||||
### 主要输出
|
||||
|
||||
- 轻量前端 SDK
|
||||
- 统一鉴权请求层
|
||||
- 统一错误态与重试策略
|
||||
- 远端快照/设置消费层
|
||||
- 正式运行时浏览器 fallback 下线方案
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 前端服务层不再保留完整正式规则或正式 AI 编排
|
||||
- 存档与设置以后端返回结果为准
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 依赖任务 1、任务 3
|
||||
- 可与任务 4、任务 5、任务 6 并行
|
||||
- 为任务 10 提供稳定的 API 消费层
|
||||
|
||||
---
|
||||
|
||||
## 任务 8:编辑器 API 归口与工具链隔离
|
||||
|
||||
### 目标
|
||||
|
||||
把编辑器的写盘、生成、任务查询能力从“散落接口”整理成清晰的编辑器后端模块,避免继续污染正式运行时。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `src/editor/shared/**`
|
||||
- `src/components/preset-editor/**`
|
||||
- `src/components/npcVisualEditorPersistence.ts`
|
||||
- `src/components/preset-editor/characterAssetStudioPersistence.ts`
|
||||
- `scripts/dev-server/**`
|
||||
- `server-node/src/modules/editor/**`
|
||||
- `server-node/src/modules/assets/**`
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 主游戏运行时 action 逻辑
|
||||
- 正式剧情流转
|
||||
|
||||
### 主要输出
|
||||
|
||||
- `/api/editor/*` 与 `/api/assets/*` 命名空间
|
||||
- 统一 editor client SDK
|
||||
- 写接口权限边界
|
||||
- 编辑器工具链迁移清单
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 编辑器组件不再散落直连多个写接口
|
||||
- 编辑器 API 与运行时 API 的职责边界清晰
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 可与任务 1、任务 2、任务 3、任务 9 同时启动
|
||||
- 与任务 5、任务 6、任务 10 基本不冲突
|
||||
|
||||
---
|
||||
|
||||
## 任务 9:测试、观测与部署基线
|
||||
|
||||
### 目标
|
||||
|
||||
为整个后端化改造提供自动回归、链路日志和部署基线,避免“功能迁过去了但不可验证”。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `server-node/src/**/*.test.ts`
|
||||
- `scripts/**`
|
||||
- 部署与运维相关文档
|
||||
- 反向代理与 smoke 测试脚本
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 具体业务模块实现
|
||||
|
||||
### 主要输出
|
||||
|
||||
- 后端接口测试
|
||||
- 关键主链路 smoke
|
||||
- request/response 日志校验
|
||||
- 同域部署基线
|
||||
- 回滚、备份、迁移检查清单
|
||||
|
||||
### 验收标准
|
||||
|
||||
- `web + server` 改造过程有最小自动回归保护
|
||||
- 关键接口失败时能追踪到请求链路
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 可与任务 1、任务 2、任务 3、任务 8 同时启动
|
||||
- 后续持续跟进任务 4、任务 5、任务 6、任务 7、任务 10 的交付
|
||||
|
||||
---
|
||||
|
||||
## 任务 10:前端主流程壳层与大 Hook 瘦身
|
||||
|
||||
### 目标
|
||||
|
||||
在服务端 action 和前端 SDK 稳定后,把 `GameShell`、`useStoryGeneration` 这一层改成真正的表现层协调器。
|
||||
|
||||
### 独占范围
|
||||
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/hooks/story/**`
|
||||
- `src/hooks/useGameFlow.ts`
|
||||
- `src/components/GameShell.tsx`
|
||||
- `src/components/AdventurePanel.tsx`
|
||||
- `src/components/NpcModals.tsx`
|
||||
- `src/components/auth/**`
|
||||
|
||||
### 暂不负责
|
||||
|
||||
- 数据库、服务端仓储
|
||||
- 编辑器 API
|
||||
|
||||
### 主要输出
|
||||
|
||||
- 面向 action/view model 的前端流程层
|
||||
- 页面表现态与业务态分离
|
||||
- 大 hook 拆分后的协调层
|
||||
- 更容易测试和替换的主流程壳层
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 前端主流程不再直接吞下完整运行时规则
|
||||
- 页面层主要消费后端 view model,而不是本地自算结果
|
||||
|
||||
### 并行关系
|
||||
|
||||
- 依赖任务 5、任务 6、任务 7 至少有一轮稳定输出
|
||||
- 是最后一批大规模前端接入任务
|
||||
|
||||
---
|
||||
|
||||
## 5. 推荐协作顺序
|
||||
|
||||
## 第一步:先定边界
|
||||
|
||||
先启动:
|
||||
|
||||
- 任务 0
|
||||
- 任务 1
|
||||
- 任务 2
|
||||
- 任务 3
|
||||
|
||||
这一轮完成后,团队会得到:
|
||||
|
||||
- 统一 contract
|
||||
- 稳定数据库基线
|
||||
- 稳定后端响应壳层
|
||||
- 稳定任务分工边界
|
||||
|
||||
## 第二步:领域层和工具层分头推进
|
||||
|
||||
在第一步基础上并行启动:
|
||||
|
||||
- 任务 4
|
||||
- 任务 5
|
||||
- 任务 6
|
||||
- 任务 7
|
||||
- 任务 8
|
||||
- 任务 9
|
||||
|
||||
这一轮是整个改造的主生产阶段。
|
||||
|
||||
## 第三步:最后收前端主流程
|
||||
|
||||
最后启动:
|
||||
|
||||
- 任务 10
|
||||
|
||||
原因很简单:
|
||||
|
||||
- 如果太早改 `useStoryGeneration` 和 `GameShell`,前端还没有稳定的 action contract 和 view model,会反复返工。
|
||||
|
||||
---
|
||||
|
||||
## 6. 建议的多人分工方式
|
||||
|
||||
如果是 4 人并行,建议:
|
||||
|
||||
- 1 人负责任务 1 + 任务 0 的 contract/集成
|
||||
- 1 人负责任务 2 + 任务 3 的后端基建
|
||||
- 1 人负责任务 4 + 任务 5 的运行时主链
|
||||
- 1 人负责任务 8 + 任务 9,之后转入任务 7 或任务 10
|
||||
|
||||
如果是 6 人并行,建议:
|
||||
|
||||
- 1 人负责任务 0 + 任务 1
|
||||
- 1 人负责任务 2
|
||||
- 1 人负责任务 3 + 任务 9
|
||||
- 1 人负责任务 4
|
||||
- 1 人负责任务 5
|
||||
- 1 人负责任务 6 + 任务 8
|
||||
|
||||
前端主流程任务 10 建议在第二轮由最熟悉当前 UI 壳层的人接手。
|
||||
|
||||
---
|
||||
|
||||
## 7. 合并规则建议
|
||||
|
||||
- 每条任务优先新增目录和新模块,少直接改热点文件。
|
||||
- 热点文件统一在集成窗口合并,不在多个任务里同步推进。
|
||||
- 任何任务如果需要改 `useStoryGeneration.ts`,默认先暂停并和任务 10 对齐。
|
||||
- 任何任务如果需要改 `server-node/src/routes/runtimeRoutes.ts`,默认先走任务 0 的接口冻结表。
|
||||
- 编辑器链路和正式运行时链路不要混在同一个 PR 里。
|
||||
|
||||
---
|
||||
|
||||
## 8. 一句话结论
|
||||
|
||||
这次重构最稳的并行方式不是“大家一起改前后端”,而是:
|
||||
|
||||
**先用 contract、数据库基线和 HTTP 壳层把边界钉死,再让服务端领域迁移、编辑器归口、前端瘦身分轨并行,最后由主流程壳层统一接入。**
|
||||
@@ -1,447 +0,0 @@
|
||||
# Express 后端化工程重构规划(2026-04-08)
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前项目已经引入 `Express` 后端,且 `server-node/` 已经承接了运行时鉴权、存档、设置、自定义世界、剧情生成、角色聊天、NPC 对话、运行时物品意图、任务生成等能力。
|
||||
|
||||
但从当前工程状态看,项目仍处于“后端已存在,但运行时领域层尚未完全脱前端”的过渡态,主要表现为:
|
||||
|
||||
- 前端 `src/hooks/useStoryGeneration.ts` 仍然承担了大量运行时编排、规则拼接与状态推进职责。
|
||||
- 前端 `src/services/ai.ts` 仍然保留了完整的 AI 调用、提示词拼装和本地兜底实现。
|
||||
- 前端 `src/hooks/useGamePersistence.ts` 仍在承担较重的存档恢复、schema 纠偏与归一化职责。
|
||||
- `server-node/src/**` 当前仍在直接引用 `src/types`、`src/data`、`src/services` 中的内容,分层尚未真正闭合。
|
||||
- 编辑器相关写接口仍然散落在前端组件与 `jsonClient` 中,运行时 API 与编辑器 API 还没有完全归口。
|
||||
|
||||
现在既然已经明确“前端只负责做表现,所有逻辑、数据都放到后端进行运算和存储”,就需要把这个原则升级成整个工程的硬边界,而不是只停留在一部分接口迁移完成的状态。
|
||||
|
||||
---
|
||||
|
||||
## 2. 重构总原则
|
||||
|
||||
本轮重构只坚持一个核心原则:
|
||||
|
||||
**前端不是业务执行层,而是表现层;后端才是唯一的运行时真相来源。**
|
||||
|
||||
进一步展开为:
|
||||
|
||||
- 前端只负责页面结构、动画演出、输入采集、局部交互态、加载态和错误态展示。
|
||||
- 后端负责鉴权、会话、规则计算、剧情推进、AI 编排、任务推进、道具结算、Build 结算、存档读写与持久化。
|
||||
- 浏览器内不再保留“正式运行时业务规则”的第二套实现。
|
||||
- 浏览器内允许存在少量纯表现计算,但不允许成为游戏状态真相来源。
|
||||
- 编辑器能力与正式运行时能力分离,避免 dev 工具链继续污染正式运行时边界。
|
||||
|
||||
---
|
||||
|
||||
## 3. 重构目标
|
||||
|
||||
## 3.1 目标状态
|
||||
|
||||
- 浏览器只发送“玩家意图”和必要的展示参数,不直接提交完整运行时真相。
|
||||
- `Express` 后端成为唯一的运行时状态源、规则执行源和 AI 调度源。
|
||||
- 运行时快照、任务状态、NPC 状态、背包、属性、Build、剧情历史全部以后端持久化结果为准。
|
||||
- 前端不再直接 import 正式运行时 AI 逻辑、提示词逻辑和关键规则逻辑。
|
||||
- `server-node` 不再依赖 `src/**` 中的前端实现细节,而是依赖独立共享层。
|
||||
- 编辑器 API、运行时 API、资产生成 API 形成清晰命名空间和权限边界。
|
||||
|
||||
## 3.2 非目标
|
||||
|
||||
- 本轮不追求一次性重写所有玩法系统。
|
||||
- 本轮不再讨论关系型数据库选型切换,当前后端以 `PostgreSQL` 为准。
|
||||
- 本轮不改动已有中文剧情、设定和文案方向。
|
||||
- 本轮不为了“前后端分离”牺牲移动端体验与当前主流程可玩性。
|
||||
|
||||
---
|
||||
|
||||
## 4. 职责边界
|
||||
|
||||
| 领域 | 前端职责 | 后端职责 |
|
||||
| --- | --- | --- |
|
||||
| 页面与流程壳层 | 页面切换、面板开关、布局、自适应、动效、加载态 | 不负责页面 UI |
|
||||
| 用户输入 | 收集点击、拖拽、表单输入、选项选择 | 校验输入是否合法,解释输入对应的运行时动作 |
|
||||
| 游戏状态 | 仅持有当前展示所需 view model 和局部 UI state | 持有完整游戏状态、快照、事件日志、版本号 |
|
||||
| 剧情推进 | 展示文本流、选项、动画时间线 | 生成剧情、决定选项集合、推进故事状态 |
|
||||
| 战斗与数值 | 播放攻击、受击、死亡、位移 | 计算伤害、蓝耗、CD、死亡、掉落、逃跑结果 |
|
||||
| NPC/同伴交互 | 展示面板、聊天输入框、关系反馈演出 | 计算关系变化、招募条件、交易合法性、对话结果 |
|
||||
| 背包/装备/Build | 展示背包、装备栏、Build 面板 | 计算背包变化、装备结果、Build 收益与约束 |
|
||||
| 任务系统 | 展示任务卡片、任务进度、奖励动画 | 生成任务、推进 signal、发放奖励 |
|
||||
| AI 调用 | 不直接请求正式运行时模型 | 统一做 prompt 组装、模型调用、超时重试、日志 |
|
||||
| 持久化 | 最多保留极少量表现态缓存 | 负责存档、设置、用户数据、迁移、恢复 |
|
||||
| 编辑器 | 调用 SDK、展示工具面板 | 负责写盘、生成任务、队列、权限与审计 |
|
||||
|
||||
## 4.1 前端允许保留的状态
|
||||
|
||||
- 当前面板是否打开
|
||||
- 当前动画是否播放中
|
||||
- 当前流式文本已经显示到哪一段
|
||||
- 表单草稿、搜索词、临时筛选条件
|
||||
- 与展示相关的 viewport / media / motion 状态
|
||||
|
||||
## 4.2 前端禁止继续承载的职责
|
||||
|
||||
- function 合法性判定
|
||||
- 怪物/NPC/任务/物品结算
|
||||
- 正式运行时 prompt 组装
|
||||
- 正式运行时 AI fallback
|
||||
- 存档 schema 迁移主逻辑
|
||||
- 以 `localStorage` 作为正式运行时主存储
|
||||
- 编辑器组件直接散落 `fetch('/api/...')` 访问写接口
|
||||
|
||||
---
|
||||
|
||||
## 5. 当前工程问题归纳
|
||||
|
||||
## 5.1 运行时领域逻辑仍然偏前端中心
|
||||
|
||||
- `useStoryGeneration` 仍然是大体量编排热区,承接了剧情、NPC、战斗后续、任务和部分故事引擎逻辑。
|
||||
- `src/services/ai.ts` 体量很大,说明正式运行时 AI 编排尚未完全移出浏览器。
|
||||
- 当前“后端接口 + 前端兜底”的过渡模式,容易让正式逻辑继续双份存在。
|
||||
|
||||
## 5.2 服务端分层还没真正闭合
|
||||
|
||||
- `server-node` 当前仍直接引用 `src/types`、`src/data`、`src/services`。
|
||||
- 这意味着后端虽然有了入口,但核心领域模型仍然绑在前端目录结构上。
|
||||
- 继续沿着这条路开发,会让后端无法独立测试、独立构建和独立演进。
|
||||
|
||||
## 5.3 运行时持久化边界还不够干净
|
||||
|
||||
- 虽然正式存档已经走远端接口,但前端仍承担较重的恢复、归一化、迁移纠偏逻辑。
|
||||
- 这会导致“存档解释权”同时存在于前后端两边,后续迭代容易失配。
|
||||
|
||||
## 5.4 编辑器与运行时 API 仍然混杂
|
||||
|
||||
- 编辑器读写接口目前仍然有散落访问点。
|
||||
- 资产生成、JSON 写盘、运行时 API 还没有形成清晰的接口分域。
|
||||
- 继续混用会让权限控制、生产部署和后续多人协作变得困难。
|
||||
|
||||
## 5.5 当前协议更像“接口迁移”,还不是“后端驱动运行时”
|
||||
|
||||
- 目前很多接口是把已有前端逻辑搬成了远端调用入口。
|
||||
- 但真正理想状态应该是:玩家点击后,后端完成规则结算、状态推进、AI 调用和持久化,再把展示模型返回给前端。
|
||||
|
||||
---
|
||||
|
||||
## 6. 目标架构
|
||||
|
||||
```text
|
||||
Browser
|
||||
├─ 页面 / 动画 / 交互 / ViewModel 渲染
|
||||
├─ 轻量前端 SDK(只负责请求与状态绑定)
|
||||
└─ 局部 UI State
|
||||
|
||||
packages/shared
|
||||
├─ contracts
|
||||
├─ schemas
|
||||
├─ domain-types
|
||||
└─ api-client-types
|
||||
|
||||
server-node
|
||||
├─ src/modules/auth
|
||||
├─ src/modules/runtime-session
|
||||
├─ src/modules/story
|
||||
├─ src/modules/combat
|
||||
├─ src/modules/npc
|
||||
├─ src/modules/inventory
|
||||
├─ src/modules/build
|
||||
├─ src/modules/quest
|
||||
├─ src/modules/custom-world
|
||||
├─ src/modules/editor
|
||||
├─ src/shared/http
|
||||
├─ src/shared/infra
|
||||
└─ src/shared/llm
|
||||
|
||||
storage
|
||||
├─ postgres
|
||||
├─ uploads
|
||||
└─ generated
|
||||
```
|
||||
|
||||
## 6.1 共享层原则
|
||||
|
||||
- `packages/shared` 只放类型、schema、协议、纯函数和序列化约定。
|
||||
- 共享层不放浏览器专属实现,也不放 Node 专属 IO。
|
||||
- 所有可执行运行时规则默认放后端,不放共享层。
|
||||
|
||||
## 6.2 前端目录目标
|
||||
|
||||
前端建议逐步收敛成下面的职责结构:
|
||||
|
||||
```text
|
||||
src/
|
||||
├─ app
|
||||
├─ pages
|
||||
├─ widgets
|
||||
├─ features
|
||||
├─ entities
|
||||
├─ shared/api
|
||||
├─ shared/ui
|
||||
└─ shared/lib
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- `shared/api` 只保留面向后端 contract 的 SDK。
|
||||
- `features` 只组织交互流程和 UI 组合,不再承载正式运行时规则。
|
||||
- 超大 hook 逐步拆成“页面状态协调层 + 远端 action 调用层 + 表现层状态”。
|
||||
|
||||
---
|
||||
|
||||
## 7. 关键协议重构方向
|
||||
|
||||
当前最值得尽快统一的,不是继续加接口数量,而是把协议升级成“意图驱动”。
|
||||
|
||||
推荐核心动作协议:
|
||||
|
||||
```json
|
||||
{
|
||||
"sessionId": "runtime-session-id",
|
||||
"clientVersion": 12,
|
||||
"action": {
|
||||
"type": "story_choice",
|
||||
"functionId": "fight_attack",
|
||||
"targetId": "npc_merchant_01",
|
||||
"payload": {
|
||||
"optionId": "opt_02"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
后端统一返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"sessionId": "runtime-session-id",
|
||||
"serverVersion": 13,
|
||||
"viewModel": {},
|
||||
"presentation": {
|
||||
"storyText": "",
|
||||
"options": [],
|
||||
"battlePlayback": null,
|
||||
"toast": null
|
||||
},
|
||||
"patches": [],
|
||||
"meta": {
|
||||
"requestId": "req_xxx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
协议约束:
|
||||
|
||||
- 前端不再提交完整 `gameState` 作为后端运算依据。
|
||||
- 前端提交的是“玩家意图”,不是“玩家已经算好的结果”。
|
||||
- 后端返回的是“下一帧该怎么演”的展示模型,而不是只回一个零散字段。
|
||||
|
||||
---
|
||||
|
||||
## 8. 分阶段重构路线
|
||||
|
||||
## P0:先冻结边界,建立共享协议层
|
||||
|
||||
### 本阶段目标
|
||||
|
||||
把“前端只做表现,后端负责运行时真相”从口头原则变成工程边界。
|
||||
|
||||
### 主要任务
|
||||
|
||||
- 提取 `shared contracts`,把 `server-node` 对 `src/**` 的依赖逐步迁出。
|
||||
- 固化统一的 API 响应结构、错误结构、`requestId`、版本字段。
|
||||
- 明确运行时 API 命名空间与编辑器 API 命名空间。
|
||||
- 新功能一律禁止再把正式运行时规则写回前端。
|
||||
- 为关键运行时入口补健康检查、日志字段、耗时统计。
|
||||
|
||||
### 交付物
|
||||
|
||||
- 共享类型与 schema 目录
|
||||
- 统一 API 约定文档
|
||||
- 服务端模块边界草图
|
||||
- 前端 SDK 基础层
|
||||
|
||||
### 验收标准
|
||||
|
||||
- `server-node` 可以不依赖 `src/**` 中的前端运行时实现继续编译。
|
||||
- 新增运行时需求不再允许“前端先写一版、后端再补一版”。
|
||||
|
||||
## P1:把运行时状态与持久化解释权收回后端
|
||||
|
||||
### 本阶段目标
|
||||
|
||||
让后端成为运行时状态、快照、恢复和迁移的唯一解释者。
|
||||
|
||||
### 主要任务
|
||||
|
||||
- 建立 `runtime session` / `snapshot aggregate`。
|
||||
- 将存档恢复、版本迁移、默认值补齐、schema 纠偏迁到后端。
|
||||
- 把前端 `useGamePersistence` 收敛为“拉取快照 + 触发保存 + 接收 view model”。
|
||||
- 设置、快照、自定义世界库统一归入运行时仓储接口。
|
||||
- 明确哪些内容允许本地缓存,哪些必须以后端结果为准。
|
||||
|
||||
### 交付物
|
||||
|
||||
- 统一的运行时 session API
|
||||
- 快照版本迁移服务
|
||||
- 服务端持久化 schema 文档
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 前端不再承担正式存档恢复迁移的主逻辑。
|
||||
- 同一份存档的解释权只存在于后端。
|
||||
|
||||
## P2:把核心规则结算从前端迁到后端
|
||||
|
||||
### 本阶段目标
|
||||
|
||||
把“剧情推进、战斗、NPC、任务、物品、Build”这些真正影响状态的领域结算全部后端化。
|
||||
|
||||
### 主要任务
|
||||
|
||||
- 把 function 合法性过滤迁入后端。
|
||||
- 把战斗结算、蓝耗、伤害、死亡、掉落、逃跑结果迁入后端。
|
||||
- 把 NPC 交互决策、招募条件、关系变化、交易合法性迁入后端。
|
||||
- 把任务推进 signal、奖励结算、运行时物品结果、Build 结果迁入后端。
|
||||
- 前端收到的只是一份下一步展示所需的聚合 view model 与演出计划。
|
||||
|
||||
### 交付物
|
||||
|
||||
- 运行时 action resolver
|
||||
- 统一领域服务接口
|
||||
- 面向 UI 的 view model assembler
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 前端点击一个选项时,发送的是 action,不是本地先算完再上传结果。
|
||||
- 正式运行时的数值、资源、状态迁移不再依赖浏览器逻辑。
|
||||
|
||||
## P3:把 AI 编排彻底收口到后端
|
||||
|
||||
### 本阶段目标
|
||||
|
||||
让浏览器彻底退出正式运行时 AI 调用与 prompt 组装。
|
||||
|
||||
### 主要任务
|
||||
|
||||
- 把剧情生成、角色聊天、NPC 对话、自定义世界生成、任务生成、物品意图生成等统一后端执行。
|
||||
- 清理前端正式运行时代码中的 AI fallback。
|
||||
- 将 prompt 构造、模型容错、超时、重试、日志、SSE 转发统一收口到后端。
|
||||
- 对需要复用的 prompt 纯函数进行共享层抽取,但执行权只留在后端。
|
||||
|
||||
### 交付物
|
||||
|
||||
- 后端 AI orchestration 模块
|
||||
- 统一 SSE/streaming 适配层
|
||||
- 精简后的前端 AI SDK
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 浏览器正式运行时代码不再直接 import 大体量 AI 编排模块。
|
||||
- 无后端时,正式运行时不再默默回退到另一套浏览器逻辑。
|
||||
|
||||
## P4:把编辑器与资产流程独立成正式后端模块
|
||||
|
||||
### 本阶段目标
|
||||
|
||||
让编辑器能力不再作为运行时副产物存在,而是成为有边界的工具后端模块。
|
||||
|
||||
### 主要任务
|
||||
|
||||
- 建立 `/api/editor/*`、`/api/assets/*` 等明确命名空间。
|
||||
- 给编辑器写接口补权限、环境门禁、审计日志。
|
||||
- 统一编辑器 JSON 读写、资产生成、任务查询接口。
|
||||
- 前端编辑器组件全部改走统一 SDK,不再散落直连接口。
|
||||
|
||||
### 交付物
|
||||
|
||||
- editor API contract
|
||||
- 统一 editor client SDK
|
||||
- 生成任务与写盘适配器
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 编辑器写接口不再散落在多个组件内部。
|
||||
- 运行时 API 与编辑器 API 的职责边界清晰。
|
||||
|
||||
## P5:补齐质量门禁、部署路径和观测能力
|
||||
|
||||
### 本阶段目标
|
||||
|
||||
让这次后端化重构可以稳定上线,而不是只在本地联调成立。
|
||||
|
||||
### 主要任务
|
||||
|
||||
- 为后端补单测、接口测试和关键链路 smoke。
|
||||
- 为前端补 contract 测试,确保 UI 不依赖本地规则。
|
||||
- 建立 `Nginx/Caddy -> dist + /api` 的同域部署路径。
|
||||
- 为流式接口补代理配置、超时、取消和日志。
|
||||
- 为数据库迁移、备份、回滚预留脚本。
|
||||
|
||||
### 验收标准
|
||||
|
||||
- `web + server` 可以独立构建、独立测试、联合部署。
|
||||
- 关键主流程至少具备一条可自动验证的 smoke path。
|
||||
|
||||
---
|
||||
|
||||
## 9. 具体迁移清单
|
||||
|
||||
## 9.1 优先迁移对象
|
||||
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/hooks/useGamePersistence.ts`
|
||||
- `src/services/ai.ts`
|
||||
- `src/services/aiService.ts`
|
||||
- `src/services/storageService.ts`
|
||||
- `src/services/authService.ts`
|
||||
- 编辑器持久化模块与 `src/editor/shared/jsonClient.ts`
|
||||
|
||||
## 9.2 优先抽离到共享层的内容
|
||||
|
||||
- 领域类型定义
|
||||
- zod schema 或等价校验协议
|
||||
- API 请求与响应 contract
|
||||
- 纯序列化函数
|
||||
- 前后端都要认识的 enum / id / status 常量
|
||||
|
||||
## 9.3 不建议抽到共享层的内容
|
||||
|
||||
- 依赖数据库、文件系统、LLM、日志的服务
|
||||
- 正式运行时规则执行器
|
||||
- 存档迁移执行器
|
||||
- 资产生成任务调度器
|
||||
|
||||
---
|
||||
|
||||
## 10. 实施顺序建议
|
||||
|
||||
推荐顺序如下:
|
||||
|
||||
1. 先抽共享类型与协议,切断 `server-node -> src/**` 的反向依赖。
|
||||
2. 再把运行时 session、快照解释权、存档迁移收回后端。
|
||||
3. 再迁核心规则结算,让前端从“业务执行层”退回“表现协调层”。
|
||||
4. 然后彻底收口 AI 编排,移除正式运行时浏览器 fallback。
|
||||
5. 最后归整编辑器 API、部署路径、测试门禁和观测能力。
|
||||
|
||||
不建议的顺序:
|
||||
|
||||
1. 先零散把几个接口改成后端。
|
||||
2. 继续保留前端完整 fallback。
|
||||
3. 最后再补共享层和协议。
|
||||
|
||||
这个顺序会把“双份逻辑并存”的过渡期拖得很长,后面会越来越难收口。
|
||||
|
||||
---
|
||||
|
||||
## 11. 风险与控制点
|
||||
|
||||
- 最大风险不是“迁不动”,而是长期维持双份规则。
|
||||
- 后端化期间必须避免再往前端加新的正式运行时规则。
|
||||
- 协议演进要带版本号,否则快照和 UI 很容易错位。
|
||||
- 前端瘦身不能牺牲移动端一屏体验,表现层拆分仍要遵守移动端优先。
|
||||
- 编辑器 API 必须和正式运行时隔离,不要为了方便继续走混用路径。
|
||||
|
||||
---
|
||||
|
||||
## 12. 一句话结论
|
||||
|
||||
这次重构的核心不是“把几个请求改成走 Express”,而是:
|
||||
|
||||
**把项目从“前端主导运行时、后端承接部分接口”的过渡架构,升级成“Express 后端统一持有运行时真相,前端只负责表现和交互”的正式工程架构。**
|
||||
@@ -3,12 +3,10 @@
|
||||
## 当前入口
|
||||
|
||||
- [ENGINEERING_DEAD_CODE_AND_HIDDEN_BRANCH_CLEANUP_PLAN_2026-04-21.md](./ENGINEERING_DEAD_CODE_AND_HIDDEN_BRANCH_CLEANUP_PLAN_2026-04-21.md):面向无用历史代码、隐形多数据链路和半成品实现的一轮工程大清洗执行计划,强调先建台账、再删重收口、最后恢复主工程可读性。
|
||||
- [CURRENT_GAME_ITERATION_PRIORITIES_2026-04-03.md](./CURRENT_GAME_ITERATION_PRIORITIES_2026-04-03.md):当前阶段最值得优先做什么、为什么,以及它和审计/PRD 的对应关系。
|
||||
- [../technical/CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md](../technical/CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md):当前创作入口、Agent session、结果页自动保存、作品库与进入世界主链的正式文件级重构基线;涉及目录落位、命名规范、阶段验收与工作包拆分时优先看这一份。
|
||||
- [../technical/RPG_ENTRY_RUNTIME_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md](../technical/RPG_ENTRY_RUNTIME_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md):当前平台入口、继续游戏、角色选择、RPG runtime 与 runtime story 主链的正式文件级重构基线;涉及入口壳层、session、runtime、story、route/service/repository 拆分时优先看这一份。
|
||||
- [CURRENT_AGENT_CREATION_FLOW_OPTIMIZATION_PLAN_2026-04-20.md](./CURRENT_AGENT_CREATION_FLOW_OPTIMIZATION_PLAN_2026-04-20.md):创作链高层目标、冻结边界与执行顺序说明;文件级拆分与阶段验收以创作链重构执行方案为准。
|
||||
- [EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md](./EXPRESS_BACKEND_REFACTOR_PLAN_2026-04-08.md):基于“前端只做表现、逻辑与数据全部后端化”的工程重构规划。
|
||||
- [EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md](./EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md):将后端化重构拆成可并行推进、尽量不冲突的任务流与协作顺序。
|
||||
- [../technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](../technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md):当前后端唯一落地口径,后续排期涉及服务端、数据真相或 SpacetimeDB 时优先按这一份判断方向。
|
||||
- [BEIJING_POLICY_APPLICATION_OVERVIEW_13_21_24_2026-04-14.md](./BEIJING_POLICY_APPLICATION_OVERVIEW_13_21_24_2026-04-14.md):北京市方向 13 / 21 / 24 的统一判断、共用材料框架和准备顺序。
|
||||
- [BEIJING_DIRECTION13_APPLICATION_MATERIALS_2026-04-14.md](./BEIJING_DIRECTION13_APPLICATION_MATERIALS_2026-04-14.md):方向 13 软件智能化提升奖励的硬门槛、必交材料、底稿建议和证据清单。
|
||||
- [BEIJING_DIRECTION21_APPLICATION_MATERIALS_2026-04-14.md](./BEIJING_DIRECTION21_APPLICATION_MATERIALS_2026-04-14.md):方向 21 “创赢未来”成长计划的报名表、BP、Demo 和融资规划整理。
|
||||
@@ -18,4 +16,5 @@
|
||||
|
||||
- 需要排期、拆阶段、判断先修基线还是先加功能时,先看这份。
|
||||
- 当前如果要推进创作链或 RPG 运行时主链重构,先看上面的两份 `2026-04-21` 执行方案,再回来看高层优先级和冻结边界。
|
||||
- 涉及后端方案时,不再参考已删除的 Express / Node 规划文档,统一回到 Rust / SpacetimeDB 当前基线。
|
||||
- 这份文档大量引用了经验文档、工程审查和 PRD,适合作为跨文档导航页使用。
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# api-server 本地 Rust 栈冷编译等待修复记录
|
||||
|
||||
日期:`2026-04-25`
|
||||
|
||||
## 1. 背景
|
||||
|
||||
本地执行 `npm run dev:rust` 时,日志出现:
|
||||
|
||||
```text
|
||||
[dev:rust] 等待 api-server 就绪
|
||||
Compiling api-server v0.1.0
|
||||
[dev:rust] 等待 api-server 就绪超时: http://127.0.0.1:8082/healthz
|
||||
[dev:rust] 停止 api-server
|
||||
error: linking with `link.exe` failed: exit code: 143
|
||||
```
|
||||
|
||||
这类失败发生在 `api-server` 仍处于 `cargo run` 的冷编译或链接阶段时,`/healthz` 还没有机会监听端口。
|
||||
|
||||
## 2. 根因
|
||||
|
||||
根目录 `scripts/dev-rust-stack.sh` 同时使用 `SPACETIME_TIMEOUT_SECONDS=60` 控制:
|
||||
|
||||
1. SpacetimeDB standalone 的启动等待。
|
||||
2. Rust `api-server` 的 `/healthz` 就绪等待。
|
||||
|
||||
SpacetimeDB 的本地启动通常较快,但 `api-server` 在 Windows MSVC 链接、依赖增量失效、首次构建或新增大依赖后可能超过 60 秒。脚本在超时后执行清理逻辑,主动杀掉仍在运行的 `cargo run` 子进程,因此 `link.exe exit code: 143` 是被本地栈脚本中断后的表现,不应优先判断为 Visual Studio Build Tools 损坏。
|
||||
|
||||
## 3. 修复口径
|
||||
|
||||
`scripts/dev-rust-stack.sh` 将 SpacetimeDB 与 `api-server` 的等待窗口拆开:
|
||||
|
||||
1. `SPACETIME_TIMEOUT_SECONDS` 继续只控制 SpacetimeDB 就绪等待,默认 `60` 秒。
|
||||
2. 新增 `API_SERVER_TIMEOUT_SECONDS` 控制 `api-server` `/healthz` 就绪等待,默认 `300` 秒。
|
||||
3. 新增命令行参数 `--api-timeout-seconds <seconds>` 便于本地低性能机器或全量重编译时临时放宽。
|
||||
4. `api-server` 进程如果在等待窗口内自行退出,仍立即报错,不吞掉真实编译错误。
|
||||
|
||||
## 4. 使用方式
|
||||
|
||||
常规本地启动继续使用:
|
||||
|
||||
```bash
|
||||
npm run dev:rust
|
||||
```
|
||||
|
||||
如本地需要更长冷编译窗口,可执行:
|
||||
|
||||
```bash
|
||||
npm run dev:rust -- --api-timeout-seconds 600
|
||||
```
|
||||
|
||||
## 5. 验收标准
|
||||
|
||||
1. 冷编译期间脚本不会在 60 秒时误杀 `cargo run -p api-server`。
|
||||
2. `/healthz` 真正可访问后,脚本继续启动 Vite。
|
||||
3. 如果 `api-server` 编译失败或运行时提前退出,脚本仍能快速停止并输出原始错误。
|
||||
4. SpacetimeDB 启动异常仍使用独立的 `--spacetime-timeout-seconds` 判断。
|
||||
@@ -112,7 +112,7 @@
|
||||
|
||||
1. 工程修改必须同步对应阶段任务清单。
|
||||
2. 新增或改变接口时,同步更新 [RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md](./RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md)。
|
||||
3. 仍存在 Node 旧能力差异时,同步更新 [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md) 的过期说明或新增 Rust 侧补充索引。
|
||||
3. 仍存在旧能力差异时,同步更新 [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md) 或新增 Rust 侧补充索引。
|
||||
4. M4 结构变更同步维护 RPG runtime 链路文档。
|
||||
5. M5 结构变更同步维护 creation flow 链路文档。
|
||||
6. M6 资产链路变更同步维护 OSS / asset_object / generated path 文档。
|
||||
@@ -135,4 +135,3 @@
|
||||
3. 关键 SSE 接口联调。
|
||||
4. SpacetimeDB publish / rollback 演练。
|
||||
5. 灰度环境双跑对比。
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# 当前后端实现基线(2026-04-25)
|
||||
|
||||
## 1. 当前唯一落地口径
|
||||
|
||||
后续正式后端实现统一以 `server-rs` 为准:
|
||||
|
||||
- HTTP 门面:Rust `api-server` / Axum。
|
||||
- 实时状态与业务真相:`crates/spacetime-module` / SpacetimeDB。
|
||||
- 共享领域与契约:`server-rs` 多 crate 分层维护。
|
||||
- 前端职责:只做表现、输入采集、临时 UI 状态与服务端结果渲染。
|
||||
|
||||
涉及 SpacetimeDB 的表、reducer、绑定生成、发布、本地联调,必须按仓库内 SpacetimeDB skills 执行。
|
||||
|
||||
## 2. 已替代的旧方向
|
||||
|
||||
以下旧方向不再作为新功能设计和编码依据:
|
||||
|
||||
- `server-node` / Express / PostgreSQL 正式后端路线。
|
||||
- Go 服务端试验路线。
|
||||
- 浏览器侧承担正式运行时逻辑、正式生成编排或正式数据真相的路线。
|
||||
|
||||
旧实现只允许作为迁移参考:可以阅读其 contract、提示词、测试用例和边界经验,但不得为了兼容旧服务端继续扩展新代码。
|
||||
|
||||
## 3. 新文档落点
|
||||
|
||||
后续补充后端方案时优先落到这些文档族:
|
||||
|
||||
- Rust / SpacetimeDB 架构与切流:`SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md`、`BACKEND_REWRITE_CROSS_CUTTING_GOVERNANCE_2026-04-22.md`、`M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md`。
|
||||
- SpacetimeDB 模块拆分:`SPACETIME_MODULE_LIB_RS_SPLIT_EXECUTION_2026-04-23.md`。
|
||||
- Rust API 路由索引:`RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md`。
|
||||
- 本地与远端部署:`RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md`、`JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md`。
|
||||
|
||||
如果旧文档与本基线冲突,以本基线和更新日期更近的 Rust / SpacetimeDB 文档为准。
|
||||
@@ -1,101 +0,0 @@
|
||||
# 编辑器与资产 API 迁移清单(2026-04-08)
|
||||
|
||||
## 1. 任务定位
|
||||
|
||||
对应 [EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md](../planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md) 中的任务 8:编辑器 API 归口与工具链隔离。
|
||||
|
||||
本轮目标是把编辑器写盘、资产生成、生成任务查询从旧的 Vite 本地 API 插件里收口到 `server-node`,并把前端编辑器组件改成通过统一 SDK 访问。
|
||||
|
||||
---
|
||||
|
||||
## 2. 新命名空间
|
||||
|
||||
编辑器写盘与读取:
|
||||
|
||||
- `GET /api/editor/catalog/items`
|
||||
- `GET /api/editor/json/:resourceId`
|
||||
- `POST /api/editor/json/:resourceId`
|
||||
|
||||
资产生成与任务查询:
|
||||
|
||||
- `POST /api/assets/character-visual/generate`
|
||||
- `POST /api/assets/character-visual/publish`
|
||||
- `GET /api/assets/character-visual/jobs/:taskId`
|
||||
- `POST /api/assets/character-animation/generate`
|
||||
- `POST /api/assets/character-animation/publish`
|
||||
- `GET /api/assets/character-animation/jobs/:taskId`
|
||||
- `POST /api/assets/character-animation/import-video`
|
||||
- `GET /api/assets/character-animation/templates`
|
||||
|
||||
---
|
||||
|
||||
## 3. 前端接入
|
||||
|
||||
统一入口:
|
||||
|
||||
- `src/editor/shared/editorApiClient.ts`
|
||||
|
||||
已切换的编辑器链路:
|
||||
|
||||
- 角色预设覆盖保存
|
||||
- 敌人预设覆盖保存
|
||||
- 场景预设覆盖保存
|
||||
- 场景角色覆盖保存
|
||||
- NPC 形象覆盖与布局配置保存
|
||||
- 物品目录读取与物品覆盖保存
|
||||
- 状态行为覆盖保存
|
||||
- 角色主形象生成、发布与任务查询
|
||||
- 角色动作生成、导入、发布、模板读取与任务查询
|
||||
|
||||
---
|
||||
|
||||
## 4. 权限与环境边界
|
||||
|
||||
`server-node` 通过环境变量控制工具接口:
|
||||
|
||||
- `EDITOR_API_ENABLED`:控制 `/api/editor/*`。
|
||||
- `ASSETS_API_ENABLED`:控制 `/api/assets/*`。
|
||||
|
||||
默认策略:
|
||||
|
||||
- 非 `production` 环境默认开启。
|
||||
- `production` 环境默认关闭。
|
||||
- `ASSETS_API_ENABLED` 未设置时跟随 `EDITOR_API_ENABLED`。
|
||||
|
||||
这批接口会读写 `src/data/*.json` 与 `public/generated-*`,不应作为正式运行时 API 使用。
|
||||
|
||||
---
|
||||
|
||||
## 5. 旧工具链隔离状态
|
||||
|
||||
自 `2026-04-19` 起,`scripts/dev-server/**` 中的旧 Vite 本地插件实现代码已经从仓库删除,也不再作为当前开发入口使用。
|
||||
|
||||
当前保留状态:
|
||||
|
||||
- `scripts/dev-server/` 目录只保留迁移说明 README。
|
||||
- 旧链路的历史背景由 `docs/audits/engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md` 等审计文档承接。
|
||||
|
||||
新增编辑器或资产能力时,应优先写入:
|
||||
|
||||
- `server-node/src/modules/editor/**`
|
||||
- `server-node/src/modules/assets/**`
|
||||
- `src/editor/shared/editorApiClient.ts`
|
||||
|
||||
不要再新增旧式散落接口:
|
||||
|
||||
- `/api/item-overrides`
|
||||
- `/api/npc-visual-overrides`
|
||||
- `/api/character-overrides`
|
||||
- `/api/character-visual/*`
|
||||
- `/api/animation/*`
|
||||
- `/api/qwen-sprite/*`
|
||||
|
||||
---
|
||||
|
||||
## 6. 当前验收状态
|
||||
|
||||
- `/api/editor/*` 与 `/api/assets/*` 命名空间已落地。
|
||||
- 前端编辑器组件已通过统一 SDK 或资源 ID 访问编辑器 API。
|
||||
- Vite 已代理 `/api/editor` 与 `/api/assets` 到 Node 后端。
|
||||
- 写接口已经有环境门禁。
|
||||
- 旧 Vite 本地插件代码已删除,不再保留并行实现。
|
||||
@@ -1,108 +0,0 @@
|
||||
# Express 后端接口冻结与集成清单(2026-04-09)
|
||||
|
||||
## 1. 目的
|
||||
|
||||
这份文档补齐 `docs/planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 中任务 0 缺失的仓库内产物,用来明确:
|
||||
|
||||
- 当前 contract 的冻结版本
|
||||
- 热点文件的编辑规则
|
||||
- 各类改动进入集成窗口前的最小检查清单
|
||||
|
||||
它不是新的重构计划,而是给当前并行改造提供一个统一落库的“不要互相踩”的边界表。
|
||||
|
||||
---
|
||||
|
||||
## 2. Contract 版本表
|
||||
|
||||
| 范围 | 当前版本 | 源头文件 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| 统一 API envelope | `2026-04-08 / v1` | `packages/shared/src/http.ts` | `ApiResponse`、错误结构、`meta` 字段、envelope 头约定的统一来源。 |
|
||||
| auth contract | `2026-04-08` | `packages/shared/src/contracts/auth.ts` | 前后端都以 shared auth contract 识别登录、用户信息与 token 响应。 |
|
||||
| runtime snapshot/settings contract | `2026-04-08` | `packages/shared/src/contracts/runtime.ts` | 存档、设置、自定义世界会话与库表相关请求/响应来源。 |
|
||||
| runtime story action contract | `2026-04-08` | `packages/shared/src/contracts/story.ts` | `RuntimeStoryActionRequest/Response`、Task5/Task6 function id 与 view model 来源。 |
|
||||
| Node HTTP route meta | `2026-04-08` | `server-node/src/app.ts` | `/api/auth`、`/api/runtime/story`、`/api/editor`、`/api/assets` 都以这一轮 route version 为当前冻结口径。 |
|
||||
| editor/assets route 命名空间 | `2026-04-08` | `server-node/src/modules/editor/editorRoutes.ts`、`server-node/src/modules/assets/**` | 编辑器与资产接口统一走 `/api/editor/*`、`/api/assets/*`。 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 热点文件编辑规则
|
||||
|
||||
以下文件继续视为高冲突入口,默认不要在多个任务里并行大改:
|
||||
|
||||
- `server-node/src/context.ts`
|
||||
- `server-node/src/routes/runtimeRoutes.ts`
|
||||
- `server-node/src/app.ts`
|
||||
- `src/services/apiClient.ts`
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/hooks/useGameFlow.ts`
|
||||
- `src/components/GameShell.tsx`
|
||||
|
||||
统一规则:
|
||||
|
||||
- 新需求优先新增独立模块,再通过桥接或小入口接入,不要直接把逻辑堆进热点文件。
|
||||
- 需要改 `server-node/src/routes/runtimeRoutes.ts` 时,先确认 shared contract 是否已落库,再补 route 接入。
|
||||
- 需要改 `src/hooks/useStoryGeneration.ts` 时,优先确认是否其实应该落到 `server-node/src/modules/**`、`src/services/runtimeStoryService.ts` 或 `src/hooks/story/**`。
|
||||
- 编辑器链路与正式运行时链路不要混在同一轮提交里。
|
||||
- 如果同一轮同时碰到后端 action 与前端 UI 壳层,先冻结 action/view model,再接 UI。
|
||||
|
||||
---
|
||||
|
||||
## 4. 集成窗口清单
|
||||
|
||||
### 4.1 shared contract 变更
|
||||
|
||||
- 只在 `packages/shared/**` 改类型、schema、纯序列化约定。
|
||||
- 同步检查 `server-node/src/**` 和 `src/**` 是否都已切到 shared contract。
|
||||
- 至少跑一次 `npm run server-node:test`。
|
||||
- 如果前端消费层也改了,再补 `npm run typecheck`。
|
||||
|
||||
### 4.2 runtime action / domain module 变更
|
||||
|
||||
- 业务规则优先写在 `server-node/src/modules/**`,不要直接写回前端 hook。
|
||||
- 如果影响 `RuntimeStoryActionResponse`,同步检查 `packages/shared/src/contracts/story.ts`。
|
||||
- 至少覆盖对应模块测试,或补到 `server-node/src/modules/story/storyActionRoutes.test.ts`。
|
||||
- 合并前至少跑一次 `npm run server-node:test`。
|
||||
|
||||
### 4.3 persistence / repository / config 变更
|
||||
|
||||
- 只把 PostgreSQL 视为正式基线。
|
||||
- 如果改到 `server-node/src/db.ts`、`repositories/**`、迁移脚本,优先确认 `pg-mem` 测试仍通过。
|
||||
- 合并前至少跑一次 `npm run server-node:test`。
|
||||
|
||||
### 4.4 editor / assets 变更
|
||||
|
||||
- 后端入口只放在 `/api/editor/*`、`/api/assets/*`。
|
||||
- 前端统一从 `src/editor/shared/editorApiClient.ts` 或对应 persistence 层进入。
|
||||
- 不要新增旧 Vite 本地插件式散落接口。
|
||||
|
||||
### 4.5 前端壳层接入变更
|
||||
|
||||
- 优先消费 `runtime story state / action response / shared contract`,不要把正式规则写回前端。
|
||||
- 如果恢复流程有改动,优先以后端 runtime state 为准。
|
||||
- 若影响主流程,至少补对应 hook / view model 测试并跑 `npm run typecheck`。
|
||||
|
||||
---
|
||||
|
||||
## 5. 当前剩余非冻结区
|
||||
|
||||
以下几块仍处于“可继续收口但尚未完全冻结”的状态,改动时要额外小心:
|
||||
|
||||
- `server-node/src/bridges/legacyBuildRuntimeBridge.ts`
|
||||
- `server-node/src/bridges/legacyInventoryRuntimeBridge.ts`
|
||||
- `server-node/src/modules/ai/storyOrchestrator.ts`
|
||||
- `server-node/src/modules/ai/chatOrchestrator.ts`
|
||||
- `server-node/src/modules/ai/customWorldOrchestrator.ts`
|
||||
|
||||
它们目前仍残留一部分对 `src/**` 历史实现的复用,不建议在没有额外测试兜底时顺手混改。
|
||||
|
||||
---
|
||||
|
||||
## 6. 本轮落库结论
|
||||
|
||||
从 2026-04-09 起,仓库内已经具备任务 0 要求的这几类最小产物:
|
||||
|
||||
- contract 版本表
|
||||
- 热点文件编辑规则
|
||||
- 集成窗口检查清单
|
||||
|
||||
后续如果 shared contract、runtime action 或热点入口发生明显演进,应优先更新这份文档,而不是让口径只停留在聊天记录里。
|
||||
@@ -1,109 +0,0 @@
|
||||
# Express 后端任务 4 AI 编排收口状态(2026-04-08)
|
||||
|
||||
## 1. 结论
|
||||
|
||||
按 `EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 的任务 4 定义,本轮已经把正式运行时的 `story / character chat / npc chat / custom world generation / quest intent / runtime item intent` 的主要 AI 编排入口收回到 Express 后端。
|
||||
|
||||
当前可以视为:
|
||||
|
||||
- 正式运行时主链已不再依赖浏览器端大体量 AI 实现作为兜底。
|
||||
- prompt 组装、上游模型请求、SSE 转发已以后端为主。
|
||||
- 前端保留的本地 AI 大模块只通过懒加载方式服务于非正式运行时遗留入口,不再作为正式运行时默认路径。
|
||||
|
||||
---
|
||||
|
||||
## 2. 已完成项
|
||||
|
||||
### 2.1 后端统一 orchestration 入口
|
||||
|
||||
- `server-node/src/modules/ai/storyOrchestrator.ts`
|
||||
- `server-node/src/modules/ai/chatOrchestrator.ts`
|
||||
- `server-node/src/modules/ai/customWorldOrchestrator.ts`
|
||||
|
||||
这些模块承接:
|
||||
|
||||
- story prompt 组装
|
||||
- character chat prompt 组装
|
||||
- npc chat / recruit prompt 组装
|
||||
- custom world generation 后端入口封装
|
||||
|
||||
### 2.2 服务层收口
|
||||
|
||||
已收口到后端服务或模块的文件:
|
||||
|
||||
- `server-node/src/services/llmClient.ts`
|
||||
- `server-node/src/services/storyService.ts`
|
||||
- `server-node/src/services/chatService.ts`
|
||||
- `server-node/src/services/customWorldGenerationService.ts`
|
||||
- `server-node/src/services/questService.ts`
|
||||
- `server-node/src/services/runtimeItemService.ts`
|
||||
|
||||
### 2.3 前端正式运行时 fallback 清理
|
||||
|
||||
`src/services/aiService.ts` 已完成以下收缩:
|
||||
|
||||
- story 正式路径不再 fallback 到浏览器本地 AI 编排
|
||||
- character suggestions / summary / reply stream 不再 fallback 到浏览器本地 AI 编排
|
||||
- npc dialogue / recruit stream 不再 fallback 到浏览器本地 AI 编排
|
||||
- 移除了正式运行时对 `VITE_ENABLE_BROWSER_RUNTIME_AI_FALLBACK` 的依赖
|
||||
- 移除了正式运行时对本地轻量离线文案 fallback 的默认依赖
|
||||
- 对 `./ai` 的引用改为懒加载,避免正式运行时默认把大体量 AI 模块打进主路径
|
||||
- 正式运行时主流程 hook 已统一改走 `aiService`,不再直接从 `src/services/ai.ts` 获取 story/chat 主链能力
|
||||
|
||||
### 2.4 旧 bridge 清理
|
||||
|
||||
已移除:
|
||||
|
||||
- `server-node/src/bridges/legacyAiRuntimeBridge.ts`
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前边界说明
|
||||
|
||||
以下项仍然存在于前端目录,但不再属于正式运行时默认 AI 执行路径:
|
||||
|
||||
- `src/services/ai.ts`
|
||||
- `src/services/aiFallbacks.ts`
|
||||
- `src/components/CustomWorldEntityEditorModal.tsx` 中的工具链直连调用
|
||||
|
||||
它们当前主要作为:
|
||||
|
||||
- 兼容性遗留实现
|
||||
- 懒加载的非主路径工具能力
|
||||
- 非本轮正式运行时链路的复用来源
|
||||
|
||||
这不再构成任务 4 的主阻塞,但后续仍应继续配合任务 1 / 任务 7 做彻底分层。
|
||||
|
||||
---
|
||||
|
||||
## 4. 非任务 4 主阻塞但需要记录的事项
|
||||
|
||||
### 4.1 仍属编辑器/工具链范畴的遗留调用
|
||||
|
||||
- `generateCustomWorldSceneImage` 仍通过懒加载复用旧实现。
|
||||
|
||||
原因:
|
||||
|
||||
- 该能力属于自定义世界工具链,不是正式运行时剧情 / 对话主链。
|
||||
- 当前不会再影响“浏览器正式运行时是否依赖本地大 AI 编排”这一任务 4 验收项。
|
||||
|
||||
### 4.2 分层彻底闭合仍需后续任务配合
|
||||
|
||||
尽管任务 4 已完成主链收口,但以下更深层收敛仍建议交由后续任务继续推进:
|
||||
|
||||
- 继续减少 `server-node` 对 `src/**` 纯提示词/纯规则模块的历史复用
|
||||
- 继续把共享 contract / schema 下沉到 `packages/shared`
|
||||
- 继续把工具链与正式运行时拆分
|
||||
|
||||
这些属于任务 1、任务 7、任务 8 的后续工作,不再阻塞任务 4 验收。
|
||||
|
||||
---
|
||||
|
||||
## 5. 本轮建议验收口径
|
||||
|
||||
任务 4 可按以下口径验收:
|
||||
|
||||
- 浏览器正式运行时不再默认兜底到本地大体量 AI 编排
|
||||
- story/chat/custom world generation 主链 prompt 组装与请求执行权在后端
|
||||
- SSE 主链以后端转发为准
|
||||
- upstream timeout / abort / error 统一走后端处理链
|
||||
@@ -1,425 +0,0 @@
|
||||
# Express 后端并行任务完成度审计(2026-04-09)
|
||||
|
||||
## 1. 审计范围
|
||||
|
||||
本次审计以 `docs/planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 为基准,只检查仓库内可直接验证的代码、测试、脚本和文档产物。
|
||||
|
||||
不能仅靠仓库静态内容确认的团队协作物,例如看板、口头冻结流程、每日集成节奏,只按“仓库内可见状态”记录,不把它们误判成完全验收。
|
||||
|
||||
---
|
||||
|
||||
## 2. 任务完成度总览
|
||||
|
||||
| 任务 | 状态 | 结论 |
|
||||
| --- | --- | --- |
|
||||
| 任务 0:集成岗与接口冻结 | 基本完成 | 已补齐接口冻结与集成清单文档,contract 版本表、热点文件编辑规则、集成窗口检查项都已落库;但团队执行节奏本身仍无法仅凭仓库静态确认。 |
|
||||
| 任务 1:共享 Contract 与目录抽离 | 部分完成 | `packages/shared` 已建立并承接 auth/runtime/story contract,且 NPC Task6 bridge 与 chat prompt builder 已进一步下沉到后端本地模块;但 AI 编排主链仍残留少量 `src/**` 反向依赖,分层尚未完全闭合。 |
|
||||
| 任务 2:PostgreSQL 持久化基线收口 | 已完成 | `server-node/src/config.ts`、`db.ts`、`repositories/**`、迁移脚本、`pg-mem` 测试与部署文档均已到位。 |
|
||||
| 任务 3:HTTP 基础设施与统一响应壳层 | 已完成 | 统一错误格式、`requestId`、route meta、响应壳层、观测测试已落地。 |
|
||||
| 任务 4:服务端 AI 编排收口 | 基本完成 | orchestration 模块、SSE 转发和主链调用已回到后端,但仍有少量 prompt/规则模块通过 `src/**` 复用,属于后续继续收敛项。 |
|
||||
| 任务 5:Story / Combat / NPC | 已完成 | 后端 story action route、session 组装、combat/npc 领域服务和对应回归测试已落地。 |
|
||||
| 任务 6:Inventory / Quest / Build / Runtime Item | 已完成 | 对应模块、服务与回归测试已经覆盖主要正式运行时结算。 |
|
||||
| 任务 7:前端 SDK、鉴权、持久化瘦身 | 部分完成 | `apiClient`、`authService`、`storageService` 已统一,但前端仍保留一部分存档归一化和主流程协调职责。 |
|
||||
| 任务 8:编辑器 API 归口与工具链隔离 | 基本完成 | editor/assets 模块、前端 editor client、迁移文档均已出现,职责边界基本清晰。 |
|
||||
| 任务 9:测试、观测与部署基线 | 已完成 | baseline test、smoke、proxy smoke、部署与回滚清单、日志链路均已具备。 |
|
||||
| 任务 10:前端主流程壳层与大 Hook 瘦身 | 部分完成 | `GameShellRuntime` / `useGameShellRuntimeViewModel` 以及新的 `storyRequestCoordinator` 已拆出,但 `useStoryGeneration.ts` 仍然过重,主流程尚未彻底退回“表现层协调器”。 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 本轮补齐项
|
||||
|
||||
本轮先补齐了任务 0 缺失的仓库内协作产物:
|
||||
|
||||
- 新增 `docs/technical/EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md`
|
||||
- 落库当前 contract 版本表
|
||||
- 明确热点文件编辑规则
|
||||
- 补齐 shared/runtime/editor/frontend 壳层各自的集成窗口清单
|
||||
|
||||
这让任务 0 不再只停留在规划文档里,而是有了一份可随版本一起更新的冻结口径。
|
||||
|
||||
随后补上了一段此前仍偏向前端快照解释的恢复链路:
|
||||
|
||||
- `src/hooks/story/runtimeStoryCoordinator.ts`
|
||||
- 新增 `resumeServerRuntimeStory`
|
||||
- 继续游戏时,若当前是正式运行时故事快照,会先请求 `/api/runtime/story/state/:sessionId`
|
||||
- 让当前 `storyText` 与可用 `options` 优先以后端 runtime state 为准
|
||||
|
||||
- `src/hooks/useGamePersistence.ts`
|
||||
- `continueSavedGame()` 现在会优先走后端 runtime story 恢复
|
||||
- 如果服务端恢复失败,再回退到本地快照归一化结果
|
||||
- 额外补了 `bottomTab` 归一化,避免恢复时吃到宽泛字符串
|
||||
|
||||
- `src/hooks/story/runtimeStoryCoordinator.test.ts`
|
||||
- 新增“继续游戏时优先从后端恢复 runtime story”的测试
|
||||
- 新增“非正式运行时快照不额外请求后端”的测试
|
||||
|
||||
这次补丁对应的是任务 7 与任务 10 之间的一段未完全闭合边界:前端在恢复流程里不应该只把远端存档当作“原始 JSON 缓存”,而应优先相信后端当前 runtime state。
|
||||
|
||||
此外,本轮还继续补了任务 1 的一段后端分层收口:
|
||||
|
||||
- 新增 `server-node/src/modules/runtime/runtimeStatePrimitives.ts`
|
||||
- 后端本地承接 `addInventoryItems`
|
||||
- 后端本地承接 `removeInventoryItem`
|
||||
- 后端本地承接 `incrementGameRuntimeStats`
|
||||
- 后端本地承接 `buildRelationState`
|
||||
- 新增 `server-node/src/modules/runtime/runtimeStatePrimitives.test.ts`
|
||||
- 校验背包合并、移除、运行时统计累加、关系阶段映射
|
||||
- 调整桥接层:
|
||||
- `server-node/src/bridges/legacyInventoryRuntimeBridge.ts`
|
||||
- `server-node/src/bridges/legacyNpcTask6Bridge.ts`
|
||||
- `server-node/src/modules/quest/questTask6Bridge.ts`
|
||||
|
||||
这意味着任务 5/6 主链里最基础的一批状态原语,已经不再依赖前端 `src/data/runtimeStats.ts`、`src/data/attributeResolver.ts`、`src/data/npcInteractions.ts` 的对应实现。
|
||||
|
||||
本轮又继续把 NPC Task6 bridge 里最后一批直接挂到前端 `npcInteractions.ts` 的函数下沉到了后端本地:
|
||||
|
||||
- 新增 `server-node/src/modules/npc/npcTask6Primitives.ts`
|
||||
- 后端本地承接 `applyStoryChoiceToStanceProfile`
|
||||
- 后端本地承接 `buildInitialNpcState`
|
||||
- 后端本地承接 `syncNpcTradeInventory`
|
||||
- 后端本地承接 `getGiftCandidates`
|
||||
- 后端本地承接 `buildNpcGiftCommitActionText`
|
||||
- 后端本地承接 `buildNpcGiftResultText`
|
||||
- 后端本地承接 `buildNpcTradeTransactionActionText`
|
||||
- 后端本地承接 `buildNpcTradeTransactionResultText`
|
||||
- 新增 `server-node/src/modules/npc/npcTask6Primitives.test.ts`
|
||||
- 覆盖 NPC 初始库存生成
|
||||
- 覆盖交易库存刷新时保留非交易物品
|
||||
- 覆盖赠礼偏好排序
|
||||
- 调整桥接层:
|
||||
- `server-node/src/bridges/legacyNpcTask6Bridge.ts`
|
||||
|
||||
这意味着 Task6 的 NPC 交易/赠礼/初始库存这条支链,已经不再直接依赖前端 `src/data/npcInteractions.ts`。
|
||||
|
||||
同时还把叙事语言检测工具下沉到了共享层:
|
||||
|
||||
- 新增 `packages/shared/src/llm/narrativeLanguage.ts`
|
||||
- `src/services/narrativeLanguage.ts` 改为复用共享实现
|
||||
- `server-node/src/modules/ai/storyOrchestrator.ts` 改为直接依赖共享层
|
||||
|
||||
这部分虽然不是大块业务迁移,但它属于任务 1 最稳定的一类收口:把纯函数共识从前端目录中抽离出来。
|
||||
|
||||
再补充一批已经完成的后端纯原语迁移:
|
||||
|
||||
- 新增 `server-node/src/modules/runtime/runtimeEconomyPrimitives.ts`
|
||||
- 后端本地承接 `formatCurrency`
|
||||
- 后端本地承接 `getInventoryItemValue`
|
||||
- 后端本地承接 `getNpcPurchasePrice`
|
||||
- 后端本地承接 `getNpcBuybackPrice`
|
||||
- 新增 `server-node/src/modules/runtime/runtimeTreasureTexts.ts`
|
||||
- 后端本地承接 `buildTreasureResultText`
|
||||
- 新增 `server-node/src/modules/runtime/runtimeEconomyPrimitives.test.ts`
|
||||
- 覆盖交易定价、货币文本、宝藏奖励文本
|
||||
|
||||
对应桥接层:
|
||||
|
||||
- `server-node/src/bridges/legacyNpcTask6Bridge.ts`
|
||||
- 不再依赖前端 `src/data/economy.ts`
|
||||
- `server-node/src/bridges/legacyTreasureRuntimeBridge.ts`
|
||||
- 不再从前端导出 `buildTreasureResultText`
|
||||
|
||||
这说明任务 5/6 主链中一部分交易、礼物、宝藏结算反馈文本,也已经从前端数据层抽离。
|
||||
|
||||
本轮又进一步补了 NPC 状态与叙事记忆的后端本地原语:
|
||||
|
||||
- 新增 `server-node/src/modules/runtime/runtimeNpcStatePrimitives.ts`
|
||||
- 后端本地承接 `normalizeNpcPersistentState`
|
||||
- 后端本地承接 `markNpcFirstMeaningfulContactResolved`
|
||||
- 新增 `server-node/src/modules/runtime/runtimeNarrativeMemory.ts`
|
||||
- 后端本地承接 `appendStoryEngineCarrierMemory`
|
||||
- 新增 `server-node/src/modules/runtime/runtimeNpcStatePrimitives.test.ts`
|
||||
- 覆盖 NPC 状态归一化、首次有效接触标记、叙事载体记忆写入
|
||||
|
||||
对应桥接层:
|
||||
|
||||
- `server-node/src/bridges/legacyNpcTask6Bridge.ts`
|
||||
- 不再依赖前端 `src/services/storyEngine/echoMemory.ts`
|
||||
- 不再依赖前端 `src/data/npcInteractions.ts` 中的 NPC 状态归一化与首次接触标记逻辑
|
||||
|
||||
这进一步缩小了后端在任务 5/6 主链上对前端 story-engine 服务目录的借用范围。
|
||||
|
||||
本轮还整块收口了 Quest 与 Runtime Item 两条桥接链:
|
||||
|
||||
- 新增 `server-node/src/modules/quest/runtimeQuestModule.ts`
|
||||
- 后端本地承接 `buildQuestForEncounter`
|
||||
- 后端本地承接 `evaluateQuestOpportunity`
|
||||
- 后端本地承接 `buildFallbackQuestIntent`
|
||||
- 后端本地承接 `compileQuestIntentToQuest`
|
||||
- 后端本地承接 `buildQuestGenerationContextFromState`
|
||||
- 后端本地承接 `buildQuestIntentPrompt`
|
||||
- 后端本地承接 Quest 进度归一化与 signal 推进
|
||||
- 更新桥接层:
|
||||
- `server-node/src/bridges/legacyQuestProgressBridge.ts`
|
||||
- `server-node/src/bridges/legacyQuestRuntimeBridge.ts`
|
||||
|
||||
这意味着 Quest 的“确定性委托构建 + AI 意图上下文 + 任务推进”已经不再依赖前端 `src/data/questFlow.ts`、`src/services/questDirector.ts`、`src/services/questPrompt.ts`。
|
||||
|
||||
同时,Runtime Item 也已经收回到后端本地:
|
||||
|
||||
- 新增 `server-node/src/modules/runtime-item/runtimeItemModule.ts`
|
||||
- 后端本地承接 `buildRuntimeItemAiIntent`
|
||||
- 后端本地承接 `buildRuntimeItemIntentPrompt`
|
||||
- 后端本地承接 `buildLooseRuntimeItemGenerationContext`
|
||||
- 后端本地承接 `buildQuestRuntimeItemGenerationContext`
|
||||
- 后端本地承接 `buildDirectedRuntimeReward`
|
||||
- 后端本地承接 `buildRuntimeInventoryStock`
|
||||
- 后端本地承接 `flattenDirectedRuntimeRewardItems`
|
||||
- 新增 `server-node/src/modules/runtime-item/runtimeTreasureModule.ts`
|
||||
- 后端本地承接 `resolveTreasureReward`
|
||||
- 更新桥接层:
|
||||
- `server-node/src/bridges/legacyRuntimeItemBridge.ts`
|
||||
- `server-node/src/bridges/legacyRuntimeItemResolutionBridge.ts`
|
||||
- `server-node/src/bridges/legacyTreasureRuntimeBridge.ts`
|
||||
|
||||
这说明 Runtime Item / Treasure 相关的 AI 意图、奖励生成和库存生成,也已经从前端目录中抽离。
|
||||
|
||||
本轮还继续整块收口了 Build / Inventory / Forge / Equipment 规则桥接:
|
||||
|
||||
- 新增 `server-node/src/modules/runtime/runtimeEquipmentModule.ts`
|
||||
- 后端本地承接 `getEquipmentSlotFromItem`
|
||||
- 后端本地承接 `getEquipmentSlotLabel`
|
||||
- 后端本地承接 `getEquipmentBonuses`
|
||||
- 后端本地承接 `applyEquipmentLoadoutToState`
|
||||
- 新增 `server-node/src/modules/runtime/runtimeInventoryEffectsModule.ts`
|
||||
- 后端本地承接 `isInventoryItemUsable`
|
||||
- 后端本地承接 `resolveInventoryItemUseEffect`
|
||||
- 后端本地承接 `buildInventoryUseResultText`
|
||||
- 新增 `server-node/src/modules/runtime/runtimeForgeModule.ts`
|
||||
- 后端本地承接 `getForgeRecipeViews`
|
||||
- 后端本地承接 `executeForgeRecipe`
|
||||
- 后端本地承接 `executeDismantleItem`
|
||||
- 后端本地承接 `executeReforgeItem`
|
||||
- 后端本地承接 `getReforgeCostView`
|
||||
- 后端本地承接 `buildForgeSuccessText`
|
||||
- 新增 `server-node/src/modules/runtime/runtimeBuildModule.ts`
|
||||
- 后端本地承接 `appendBuildBuffs`
|
||||
- 后端本地承接 `getPlayerBuildDamageBreakdown`
|
||||
- 后端本地承接 `resolvePlayerOutgoingDamageResult`
|
||||
|
||||
对应桥接层:
|
||||
|
||||
- `server-node/src/bridges/legacyBuildRuntimeBridge.ts`
|
||||
- `server-node/src/bridges/legacyInventoryRuntimeBridge.ts`
|
||||
|
||||
这意味着 Build / Inventory / Forge / Equipment 相关的后端主链结算,已经不再依赖前端 `src/data/buildDamage.ts`、`src/data/equipmentEffects.ts`、`src/data/forgeSystem.ts`、`src/data/inventoryEffects.ts`。
|
||||
|
||||
本轮又补了一段任务 1 的 AI 编排收口:
|
||||
|
||||
- 新增 `server-node/src/modules/ai/chatPromptBuilders.ts`
|
||||
- 后端本地承接 character chat reply / suggestions / summary prompt 组装
|
||||
- 后端本地承接 npc chat / recruit prompt 组装
|
||||
- 调整:
|
||||
- `server-node/src/modules/ai/chatOrchestrator.ts`
|
||||
- `server-node/src/modules/ai/orchestrator.test.ts`
|
||||
|
||||
这意味着 chat orchestration 已不再依赖前端 `src/services/characterChatPrompt.ts` 与 `src/services/prompt.ts`。
|
||||
|
||||
本轮继续把 story orchestration 主链也收回到了后端本地:
|
||||
|
||||
- 新增 `server-node/src/modules/ai/storyPromptBuilders.ts`
|
||||
- 后端本地承接 `SYSTEM_PROMPT`
|
||||
- 后端本地承接 `buildUserPrompt`
|
||||
- 重写 `server-node/src/modules/ai/storyOrchestrator.ts`
|
||||
- 正式生产链不再依赖前端 `src/services/prompt.ts`
|
||||
- 正式生产链不再依赖前端 `src/data/stateFunctions.ts`
|
||||
- 正式生产链不再依赖前端 `src/data/scenePresets.ts`
|
||||
- 正式生产链不再依赖前端 `src/data/hostileNpcs.ts`
|
||||
- 调整:
|
||||
- `server-node/src/modules/ai/orchestrator.test.ts`
|
||||
|
||||
到这里,`server-node` 正式生产代码路径里,Story / Chat / Quest / Runtime Item / Treasure / Build / Inventory / Forge / NPC Task6 主链都已经从前端 `src/**` 目录脱钩。
|
||||
|
||||
本轮也继续推进了任务 10 的主流程瘦身:
|
||||
|
||||
- 新增 `src/hooks/story/storyRequestCoordinator.ts`
|
||||
- 抽离运行时 option source 解析
|
||||
- 抽离服务端 option catalog 回退策略
|
||||
- 抽离 initial / next story 请求参数协调
|
||||
- 新增 `src/hooks/story/storyRequestCoordinator.test.ts`
|
||||
- 覆盖服务端 option catalog 切换
|
||||
- 覆盖显式 option catalog 短路
|
||||
- 覆盖服务端目录加载失败时回退本地可用项
|
||||
- 调整:
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
|
||||
这说明 `useStoryGeneration.ts` 虽然仍重,但“故事请求协调”已经不再和主流程 UI 状态、NPC/战斗/宝藏后续处理混在同一个大段里。
|
||||
|
||||
本轮又补了一段任务 10 的纯展示逻辑拆分:
|
||||
|
||||
- 新增 `src/hooks/story/storyPresentation.ts`
|
||||
- 抽离 story options 去重与补齐
|
||||
- 抽离对白 turn 解析
|
||||
- 抽离 dialogue story moment 组装
|
||||
- 抽离 typewriter delay
|
||||
- 新增 `src/hooks/story/storyPresentation.test.ts`
|
||||
- 覆盖对白解析与 dialogue story moment
|
||||
- 覆盖选项池去重与补齐
|
||||
- 调整:
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
|
||||
这意味着 `useStoryGeneration.ts` 又减少了一批与 React 状态本身无关的纯函数逻辑,任务 10 的主流程壳层拆分继续向前推进。
|
||||
|
||||
本轮还补上了任务 1 的最后一条后端反向依赖:
|
||||
|
||||
- 删除 `server-node/src/bridges/legacyCustomWorldAiBridge.ts`
|
||||
- 重写 `server-node/src/modules/ai/customWorldOrchestrator.ts`
|
||||
- 后端本地承接 custom world generation 的 deterministic 生成流程
|
||||
- 后端本地承接 generation progress 汇报
|
||||
|
||||
这意味着 `server-node/src/**` 的正式生产代码路径已经不再反向依赖前端 `src/**` 目录。
|
||||
|
||||
---
|
||||
|
||||
## 4. 仍需继续收口的重点
|
||||
|
||||
### 4.1 任务 1 的剩余问题
|
||||
|
||||
当前从仓库内直接扫描看,`server-node/src/**` 的正式生产代码路径已经不再存在对前端 `src/**` 的反向依赖。
|
||||
|
||||
其中 Story / Chat / Quest / Runtime Item / Treasure / Build / Inventory / Forge / Equipment / NPC Task6 / Custom World generation 相关正式生产链都已经从这个列表中退出。
|
||||
|
||||
同时,`server-node/src/modules/ai/orchestrator.test.ts` 已不再直接依赖前端 `src/services/prompt.ts` 与 `src/data/stateFunctions.ts`。
|
||||
|
||||
这说明任务 1 在“后端正式生产运行时不反向依赖前端目录”这一层面已经完成。
|
||||
|
||||
#### 4.1.1 当前残留依赖的真实形态
|
||||
|
||||
从当前状态看,任务 1 后续不再是“补洞”,而是“优化”:
|
||||
|
||||
- 继续提高 custom world generation 的质量与保真度
|
||||
- 继续把真正通用的 prompt / JSON repair / batch helper 整理进 `packages/shared` 或 `server-node/src/modules/ai/**`
|
||||
- 维持后端不再回流引用前端目录的约束
|
||||
|
||||
#### 4.1.2 更适合的继续收口顺序
|
||||
|
||||
结合当前状态,任务 1 后续更适合做的是能力优化:
|
||||
|
||||
1. 继续增强 custom world generation 的语义保真度与校验强度。
|
||||
2. 继续把 prompt builder、JSON repair、批处理工具整理到 `packages/shared` 或 `server-node/src/modules/ai/**`。
|
||||
3. 持续维持“后端正式生产代码不反向依赖前端目录”的约束,避免后续重新开洞。
|
||||
|
||||
### 4.2 任务 7 的剩余问题
|
||||
|
||||
前端虽然已经大量改成 SDK 消费层,但 `src/persistence/runtimeSnapshot.ts` 里仍保留较重的存档归一化与迁移修复逻辑。
|
||||
|
||||
这部分后续仍建议继续向后端迁移,避免前后端双边解释快照。
|
||||
|
||||
#### 4.2.1 `runtimeSnapshot.ts` 当前仍承担的职责
|
||||
|
||||
从文件本身看,`src/persistence/runtimeSnapshot.ts` 仍不是一个单纯的“读取后端结果并转成 UI 状态”的轻薄消费层。
|
||||
|
||||
它当前仍直接负责:
|
||||
|
||||
- 存档迁移 manifest 应用
|
||||
- roster 归一化
|
||||
- player currency 默认值补齐
|
||||
- equipment loadout 回填与属性重算
|
||||
- NPC persistent state 归一化
|
||||
- quest log 归一化
|
||||
- runtime stats 归一化
|
||||
- scene encounter preview 修复
|
||||
- story engine memory 缺省补齐
|
||||
|
||||
这说明任务 7 的剩余问题,不只是“前端还有一点 normalize 代码”,而是:
|
||||
|
||||
- 前端仍在解释正式存档的结构语义
|
||||
- 前端仍在决定若干正式运行时字段的缺省和修复策略
|
||||
- 后端与前端之间仍存在“双边都能定义快照有效形态”的空间
|
||||
|
||||
#### 4.2.2 下一步更合适的迁移方向
|
||||
|
||||
结合本轮已经补上的“继续游戏优先以后端 runtime story state 为准”这段恢复链路,任务 7 后续更适合继续向这个方向推进:
|
||||
|
||||
1. 把 `runtimeSnapshot.ts` 中的迁移、归一化、缺省补齐继续下沉到后端持久化层或专门的 runtime snapshot service。
|
||||
2. 让前端拿到的远端快照尽量已经是“可直接消费的正式形态”,而不是“仍需前端补算的半成品”。
|
||||
3. 把前端保留的本地 hydrate 逻辑收缩到纯 UI 恢复字段,例如当前页签、面板开合、局部显示态。
|
||||
|
||||
只有这样,任务 7 才算真正回到“前端只做消费层,后端才是正式状态解释者”的目标。
|
||||
|
||||
### 4.3 任务 10 的剩余问题
|
||||
|
||||
当前最大的未完成项仍然是:
|
||||
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
|
||||
它仍承担了大量:
|
||||
|
||||
- 正式运行时故事编排
|
||||
- 本地 fallback 组织
|
||||
- NPC / 宝藏 / 战斗后续协调
|
||||
- 主流程状态推进
|
||||
|
||||
现阶段虽然已经有:
|
||||
|
||||
- `src/hooks/useGameShellRuntime.ts`
|
||||
- `src/components/game-shell/useGameShellRuntimeViewModel.ts`
|
||||
- `src/hooks/story/runtimeStoryCoordinator.ts`
|
||||
- `src/hooks/story/storyRequestCoordinator.ts`
|
||||
|
||||
但主流程还没有彻底完成 action/view model 化,任务 10 仍应视为“进行中”。
|
||||
|
||||
#### 4.3.1 `useStoryGeneration.ts` 当前仍然为什么过重
|
||||
|
||||
从仓库现状看,`src/hooks/useStoryGeneration.ts` 目前仍有约 1700 行,且其过重问题已经不是单纯“文件太长”,而是它还保留着大量正式业务协调职责。
|
||||
|
||||
当前这个 hook 里仍集中着:
|
||||
|
||||
- `buildStoryContextFromState` 这一整块故事上下文拼装
|
||||
- AI 请求前的 option catalog / fallback 组织
|
||||
- NPC / 宝藏 / 战斗 / inventory / goal / session 多条子链的集中协调
|
||||
- 本地 fallback story 生成
|
||||
- 一部分运行时规则与 narrative context 的最终拼装入口
|
||||
|
||||
这意味着即使已经拆出了:
|
||||
|
||||
- `runtimeStoryCoordinator`
|
||||
- `storyRequestCoordinator`
|
||||
- `choiceActions`
|
||||
- `npcEncounterActions`
|
||||
- `sessionActions`
|
||||
|
||||
`useStoryGeneration.ts` 仍然不是“单纯的 UI 壳层 hook”,而更像前端侧的运行时总协调器。
|
||||
|
||||
#### 4.3.2 任务 10 后续更值得优先拆的部分
|
||||
|
||||
按当前文件结构看,后续最值得优先继续抽离的不是零散按钮逻辑,而是下面三类真正还握在主 hook 里的核心块:
|
||||
|
||||
1. `buildStoryContextFromState` 这一整块 story-engine 叙事上下文装配。
|
||||
2. `buildFallbackStoryForState` / `getAvailableOptionsForState` 这类“正式规则兜底与选项来源判断”。
|
||||
3. NPC / Treasure / Character Chat / Session 这些子流之间的最终总装协调。
|
||||
|
||||
如果只是继续把零散函数拆到 `src/hooks/story/**`,但上述三块还留在主 hook 里,那么任务 10 仍然不会真正完成。
|
||||
|
||||
### 4.4 建议的下一轮补齐顺序
|
||||
|
||||
结合任务 1、任务 7、任务 10 当前的剩余形态,后续更合适的补齐顺序建议是:
|
||||
|
||||
1. 先继续收任务 7 的 runtime snapshot 解释权,把正式快照的迁移、修复、归一化口径继续回收到后端。
|
||||
2. 再继续收任务 10,把 `useStoryGeneration.ts` 压回主流程协调壳层,而不是继续让它承担正式运行时总装职责。
|
||||
|
||||
这样排的原因是:
|
||||
|
||||
- 任务 1 已经完成后,新的主阻塞就变成了任务 7 和任务 10。
|
||||
- 如果任务 7 不继续收,前端仍会在恢复链路里保留正式状态解释权,任务 10 也很难真正变薄。
|
||||
- 等到 runtime state 与 snapshot 口径都更稳定后,再继续瘦 `useStoryGeneration.ts`,返工会更少。
|
||||
|
||||
---
|
||||
|
||||
## 5. 本轮验证
|
||||
|
||||
已通过:
|
||||
|
||||
- `npm run server-node:test`
|
||||
- `npx vitest run src/hooks/story/storyRequestCoordinator.test.ts src/hooks/story/runtimeStoryCoordinator.test.ts`
|
||||
- `npm run typecheck`
|
||||
- `npm run check:encoding`
|
||||
|
||||
---
|
||||
|
||||
## 6. 结论
|
||||
|
||||
从仓库可验证结果看,任务 2、3、5、6、9 已经达到“可认为完成”的状态;任务 0、4、8 基本完成;任务 1、7、10 仍有明显后续收口空间。
|
||||
|
||||
当前最主要的未完成中心已经不再是后端基建,而是:
|
||||
|
||||
**把前端主流程和存档恢复彻底收成“以后端 runtime state 和 view model 为唯一真相源”。**
|
||||
@@ -1,190 +0,0 @@
|
||||
# 前端逻辑后移实施方案(2026-04-21)
|
||||
|
||||
更新时间:`2026-04-21`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
本方案只回答一件事:
|
||||
|
||||
**怎样把当前仍残留在前端的正式运行时逻辑、正式会话真相与正式生成编排,继续收回到 Express 后端。**
|
||||
|
||||
这份文档不是泛泛而谈的方向说明,而是直接面向本轮与后续几轮编码落地的实施基线。
|
||||
|
||||
---
|
||||
|
||||
## 2. 本轮确定的硬边界
|
||||
|
||||
根据仓库约束与当前审计结果,本轮继续冻结以下边界:
|
||||
|
||||
1. 前端只负责表现、输入采集、临时 UI 状态与服务端结果渲染。
|
||||
2. 后端负责正式鉴权、正式会话、正式运行时快照、正式任务生成、正式运行时物品意图生成、正式自定义世界生成。
|
||||
3. `codex/backend-rewrite-spacetimedb` 目标分支的鉴权仍以服务端签发 JWT、前端 Bearer token 携带为准;本轮合入不采用 `codex/dev` 的 access cookie 会话方案。
|
||||
4. 浏览器内不再把浏览历史作为本地正式真相,不再保留正式 quest / runtime item / custom world 生成编排。
|
||||
5. 运行时主链必须继续向“前端提交意图,后端解释快照并返回展示模型”收敛。
|
||||
|
||||
---
|
||||
|
||||
## 3. 现状拆分
|
||||
|
||||
当前残留问题已经收敛为三批:
|
||||
|
||||
### 3.1 第一批:正式真相仍在前端
|
||||
|
||||
1. `src/services/apiClient.ts`
|
||||
- 浏览器当前仍保存 access token,并在请求层拼接 `Authorization: Bearer ...`
|
||||
- 该链路在 `codex/backend-rewrite-spacetimedb` 仍是既定正式实现,不再按 cookie access session 改写
|
||||
2. `src/services/authService.ts`
|
||||
- 登录、微信绑定、回调消费流程都要与 JWT/Bearer 方案保持一致,避免混入 access cookie 分支语义
|
||||
3. `src/components/game-shell/PreGameSelectionFlow.tsx`
|
||||
- 浏览历史仍是本地写入 + 后端回填的双真相
|
||||
4. `src/services/platformBrowseHistory.ts`
|
||||
- 维护浏览历史本地存储、迁移标记与同步状态
|
||||
|
||||
### 3.2 第二批:运行时主链仍依赖前端预写快照
|
||||
|
||||
1. `src/hooks/story/runtimeStoryCoordinator.ts`
|
||||
- 在请求 runtime state / runtime action 前,仍先 `PUT /runtime/save/snapshot`
|
||||
2. `src/hooks/story/npcEncounterActions.ts`
|
||||
- 待接委托的“更换任务”“放弃任务”仍由前端正式结算
|
||||
|
||||
### 3.3 第三批:正式生成编排仍残留在浏览器
|
||||
|
||||
1. `src/services/questDirector.ts`
|
||||
2. `src/services/runtimeItemAiDirector.ts`
|
||||
3. `src/services/aiService.ts` 的 custom world profile 生成入口
|
||||
4. `src/services/ai.ts` 中仍保留的浏览器侧 legacy AI orchestration
|
||||
|
||||
---
|
||||
|
||||
## 4. 分批实施策略
|
||||
|
||||
## 4.1 第一批:先收正式真相
|
||||
|
||||
### 鉴权
|
||||
|
||||
目标状态:
|
||||
|
||||
1. 后端继续通过 JWT 承载 access token,并只从 `Authorization: Bearer ...` 读取当前访问身份。
|
||||
2. 前端请求层继续负责保存、刷新和携带 access token;公开请求与静默探测不得误清正式 token。
|
||||
3. access cookie 会话方案不进入 `codex/backend-rewrite-spacetimedb`,避免和目标分支已有 JWT 方案并存。
|
||||
4. `AuthGate` 通过 refresh cookie / `/api/auth/me` 恢复出用户后,必须先确保本地 access token 可用,再把 `readyUser` 暴露给运行时、设置、作品列表等受保护业务 hook;业务 hook 不能只凭 `user.id` 在 token 尚未补齐时启动远端请求。
|
||||
|
||||
本批涉及:
|
||||
|
||||
1. `server-node/src/routes/authRoutes.ts`
|
||||
2. `server-node/src/middleware/auth.ts`
|
||||
3. `src/services/apiClient.ts`
|
||||
4. `src/services/authService.ts`
|
||||
5. `src/components/auth/AuthGate.tsx`
|
||||
|
||||
### 浏览历史
|
||||
|
||||
目标状态:
|
||||
|
||||
1. 浏览历史唯一真相在 `runtimeRepository`。
|
||||
2. 前端不再保留本地浏览历史、迁移标记、同步标记。
|
||||
3. 浏览历史只通过 `storageService` 读取和写入。
|
||||
|
||||
本批涉及:
|
||||
|
||||
1. `src/components/game-shell/PreGameSelectionFlow.tsx`
|
||||
2. `src/components/game-shell/PlatformHomeView.tsx`
|
||||
3. `src/services/storageService.ts`
|
||||
4. `src/services/platformBrowseHistory.ts`
|
||||
|
||||
## 4.2 第二批:把 runtime story 快照解释权收回后端
|
||||
|
||||
目标状态:
|
||||
|
||||
1. 前端不再通过单独的 `PUT /runtime/save/snapshot` 预写快照再触发动作。
|
||||
2. runtime state / runtime action 允许前端提交当前快照上下文,由后端内部决定是否写入、如何解释、何时持久化。
|
||||
3. NPC 待接委托的 replace / abandon / accept 全部走后端 runtime action。
|
||||
|
||||
建议实施方式:
|
||||
|
||||
1. 扩展 `packages/shared/src/contracts/story.ts`
|
||||
- `RuntimeStoryActionRequest` 增加可选 `snapshot`
|
||||
- 新增 `RuntimeStoryStateRequest`
|
||||
2. 新增 `POST /api/runtime/story/state/resolve`
|
||||
3. `storyActionService` 内部统一处理“请求携带快照上下文时的服务端同步”
|
||||
4. 把 `npc_chat_quest_offer_replace` / `npc_chat_quest_offer_abandon` 接到后端 runtime action
|
||||
|
||||
## 4.3 第三批:把正式生成编排收成后端唯一出口
|
||||
|
||||
目标状态:
|
||||
|
||||
1. `questDirector` 只保留轻量 SDK。
|
||||
2. `runtimeItemAiDirector` 只保留轻量 SDK。
|
||||
3. custom world profile 正式生成走后端 route。
|
||||
4. 浏览器侧 `src/services/ai.ts` 不再承担正式浏览器主链。
|
||||
|
||||
建议实施方式:
|
||||
|
||||
1. `server-node/src/routes/runtimeRoutes.ts`
|
||||
- 补 `custom-world/profile` 正式 route
|
||||
2. `src/services/aiService.ts`
|
||||
- custom world 入口改走后端
|
||||
3. `src/services/questDirector.ts`
|
||||
- 只请求 `/api/runtime/quests/generate`
|
||||
4. `src/services/runtimeItemAiDirector.ts`
|
||||
- 只请求 `/api/runtime/items/runtime-intent`
|
||||
|
||||
---
|
||||
|
||||
## 5. 本轮落地范围
|
||||
|
||||
本轮优先完成以下内容:
|
||||
|
||||
1. 鉴权维持 `codex/backend-rewrite-spacetimedb` 既有 JWT/Bearer 方案,不合入 `codex/dev` 的 access cookie 访问认证。
|
||||
2. 浏览历史从前端本地真相后移到后端唯一真相。
|
||||
3. custom world profile 正式生成入口补齐后端 route,并把前端收成 SDK。
|
||||
4. `questDirector` / `runtimeItemAiDirector` 收缩为前端 SDK。
|
||||
5. runtime story contract 开始补“随请求提交快照上下文”的后端承接能力,并把 NPC 待接委托 replace / abandon 接到后端。
|
||||
|
||||
### 5.1 已完成
|
||||
|
||||
1. `codex/backend-rewrite-spacetimedb` 本轮保留 JWT access token + refresh cookie 组合方案,不合入 access cookie 写入与读取链路。
|
||||
2. 浏览历史已收敛为后端唯一真相,前端不再维护正式本地 browse history 链。
|
||||
3. runtime story 已支持随请求提交 snapshot,由后端内部解释与持久化。
|
||||
4. NPC 待接委托 `replace / abandon / accept` 已以后端 runtime action 为准。
|
||||
5. custom world profile 浏览器正式入口已改走后端 route。
|
||||
6. `questDirector` / `runtimeItemAiDirector` 已收缩为前端 SDK,不再承担正式浏览器编排。
|
||||
7. NPC 招募正式结算已迁到后端:
|
||||
- 前端只负责招募对白展示与 release 目标选择
|
||||
- 后端负责 `npcStates / companions / roster / currentEncounter / storyHistory` 正式结算
|
||||
- 满员换队招募已由后端承接
|
||||
|
||||
### 5.2 剩余未完成
|
||||
|
||||
1. `src/services/ai.ts` 仍保留 legacy fallback / test 能力,尚未彻底压缩出正式浏览器主链。
|
||||
2. 仍需继续审视是否存在其他 NPC / 运行时分支,把正式状态裁决留在前端。
|
||||
|
||||
---
|
||||
|
||||
## 6. 验收标准
|
||||
|
||||
### 第一批验收
|
||||
|
||||
1. 浏览器继续保存 access token,并由 `fetchWithApiAuth` 稳定拼接 `Authorization: Bearer ...`。
|
||||
2. 401 刷新链只在已发送 Bearer token 时触发,并且刷新响应必须返回新的 JWT。
|
||||
3. 浏览历史仅通过远端接口读写。
|
||||
4. `src/services/platformBrowseHistory.ts` 不再是正式链路依赖。
|
||||
5. 手机验证码登录、微信回调或 refresh cookie 会话恢复完成后,首屏并发读取设置、存档、个人看板、浏览历史、作品列表前,必须已经完成 access token 写入,避免出现“用户已 ready 但请求缺少 Authorization Bearer Token”的竞态。
|
||||
|
||||
### 第二批验收
|
||||
|
||||
1. `runtimeStoryCoordinator.ts` 不再在动作前独立 `PUT /runtime/save/snapshot`。
|
||||
2. `NPC` 待接委托 replace / abandon / accept 都以后端返回结果为准。
|
||||
|
||||
### 第三批验收
|
||||
|
||||
1. `questDirector.ts` 与 `runtimeItemAiDirector.ts` 不再保留正式 fallback orchestration。
|
||||
2. custom world profile 的浏览器正式入口不再直接 import legacy `./ai`。
|
||||
|
||||
---
|
||||
|
||||
## 7. 一句话结论
|
||||
|
||||
这轮迁移的重点不是“把几个 helper 挪到 server-node 目录”,而是:
|
||||
|
||||
**把前端里仍然承担正式真相、正式运行时解释和正式生成编排的那一层职责,继续收回到 Express 后端。**
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
- [M3_RUNTIME_SETTINGS_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md](./M3_RUNTIME_SETTINGS_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md)
|
||||
- [M3_BROWSE_HISTORY_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md](./M3_BROWSE_HISTORY_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md)
|
||||
- [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md)
|
||||
- [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)
|
||||
- `server-node/src/routes/rpg-profile/rpgProfileRoutes.ts`
|
||||
- `server-node/src/repositories/runtimeRepository.ts`
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
关联现状:
|
||||
|
||||
- [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md)
|
||||
- [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md)
|
||||
- [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)
|
||||
- `server-node/src/routes/rpg-profile/rpgProfileRoutes.ts`
|
||||
- `server-node/src/repositories/runtimeRepository.ts`
|
||||
|
||||
|
||||
@@ -24,11 +24,8 @@
|
||||
本文以以下现有文档和代码为准:
|
||||
|
||||
1. [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md)
|
||||
2. [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md)
|
||||
3. [EXPRESS_BACKEND_TASK4_AI_ORCHESTRATION_STATUS_2026-04-08.md](./EXPRESS_BACKEND_TASK4_AI_ORCHESTRATION_STATUS_2026-04-08.md)
|
||||
4. `server-node/src/modules/ai/storyOrchestrator.ts`
|
||||
5. `server-node/src/modules/ai/chatOrchestrator.ts`
|
||||
6. `server-node/src/modules/ai/customWorldOrchestrator.ts`
|
||||
2. [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)
|
||||
3. 历史 Node AI 编排代码仅作为迁移背景,不再作为当前实现依据。
|
||||
|
||||
## 3. 现状问题
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ M7 的目标不是新增玩法功能,而是在 `M0 ~ M6` 已迁移的 Rust 后
|
||||
1. 固定本地、灰度、切流前的检查命令。
|
||||
2. 固定 `Axum + SpacetimeDB + OSS` 的部署与回滚口径。
|
||||
3. 固定观测字段、慢请求、上游失败日志与资产任务日志。
|
||||
4. 固定旧 `server-node` 与新 `server-rs` 的双跑和 API 对比方式。
|
||||
4. 固定旧 `server-node` 删除后的 Rust 主线回归与部署验证方式。
|
||||
5. 等价拆分 `server-rs/crates/spacetime-module/src/lib.rs`,避免 SpacetimeDB 主工程继续退化为单大文件。
|
||||
|
||||
## 2. 执行约束
|
||||
@@ -19,8 +19,8 @@ M7 的目标不是新增玩法功能,而是在 `M0 ~ M6` 已迁移的 Rust 后
|
||||
1. 不改变现有 HTTP contract、SSE contract、SpacetimeDB 表名、reducer 名、procedure 名和对象键前缀。
|
||||
2. 不把 LLM、OSS、短信、微信等外部副作用移入 SpacetimeDB reducer。
|
||||
3. `spacetime-module` 拆分只做物理结构收口,不做 schema 重命名、字段删除、字段重排或 reducer/procedure 改名。
|
||||
4. 迁移期保留 `server-node` 作为回退锚点,M7 不删除旧后端。
|
||||
5. 前端切换默认仍指向 Node;只有显式设置 `GENARRATIVE_BACKEND_STACK=rust` 或 `GENARRATIVE_RUNTIME_SERVER_TARGET` 时才切到 Rust。
|
||||
4. `server-node/` 已进入物理删除流程,M7 不再把旧 Node 后端作为运行时回退锚点。
|
||||
5. 前端默认指向 Rust `api-server`;如需临时覆盖目标,只允许使用 `RUST_SERVER_TARGET` 或 `GENARRATIVE_RUNTIME_SERVER_TARGET` 指向 Rust 兼容服务。
|
||||
|
||||
## 3. 测试体系
|
||||
|
||||
@@ -36,7 +36,6 @@ M7 固定四层测试入口:
|
||||
```powershell
|
||||
.\server-rs\scripts\m7-preflight.ps1
|
||||
.\server-rs\scripts\smoke.ps1
|
||||
node scripts\run-tsx.cjs scripts\m7-api-compare.ts
|
||||
```
|
||||
|
||||
## 4. 部署准备
|
||||
@@ -72,32 +71,32 @@ OSS / CDN / 域名方案:
|
||||
6. `DASHSCOPE_BASE_URL`、`DASHSCOPE_API_KEY`
|
||||
7. `SMS_AUTH_ENABLED` 与短信供应商变量
|
||||
8. `WECHAT_AUTH_ENABLED` 与微信 OAuth 变量
|
||||
9. `GENARRATIVE_BACKEND_STACK`、`NODE_SERVER_TARGET`、`RUST_SERVER_TARGET`、`GENARRATIVE_RUNTIME_SERVER_TARGET`
|
||||
9. `RUST_SERVER_TARGET`、`GENARRATIVE_RUNTIME_SERVER_TARGET`
|
||||
|
||||
## 5. 灰度与切流
|
||||
|
||||
灰度环境固定为三段:
|
||||
|
||||
1. `shadow`:Node 继续承接用户流量,Rust 只由脚本和内部账号请求。
|
||||
2. `dual-run`:同一组 smoke/API compare 同时打 Node 与 Rust,差异必须登记。
|
||||
3. `rust-primary`:反向代理或 Vite dev proxy 指向 Rust,Node 进程保留但不作为主入口。
|
||||
1. `preflight`:只跑 Rust 预检、smoke 与人工主链验证,不接正式用户流量。
|
||||
2. `limited-rust`:小范围账号或灰度域名访问 Rust `api-server`,差异必须登记到 M7 验收记录。
|
||||
3. `rust-primary`:反向代理或 Vite dev proxy 指向 Rust `api-server`,旧 Node 后端不作为运行时入口保留。
|
||||
|
||||
前端切换方式:
|
||||
|
||||
1. 默认 `GENARRATIVE_BACKEND_STACK=node`。
|
||||
2. 本地或灰度切 Rust 设置 `GENARRATIVE_BACKEND_STACK=rust`,并配置 `RUST_SERVER_TARGET`。
|
||||
3. 紧急回退设置 `GENARRATIVE_BACKEND_STACK=node` 或直接覆盖 `GENARRATIVE_RUNTIME_SERVER_TARGET` 指回 Node。
|
||||
1. 默认使用 `RUST_SERVER_TARGET` 或 `GENARRATIVE_API_TARGET` 指向 Rust `api-server`。
|
||||
2. 本地或灰度可覆盖 `GENARRATIVE_RUNTIME_SERVER_TARGET`,但目标仍必须是 Rust 兼容服务。
|
||||
3. 紧急回退优先回滚到上一个 Rust 发布包或反向代理配置,不恢复 `server-node/` 工程目录。
|
||||
|
||||
## 6. API 对比
|
||||
## 6. API 回归
|
||||
|
||||
`scripts/m7-api-compare.ts` 负责对比 Node 与 Rust 的基础 contract:
|
||||
第一批删除后不再保留 Node/Rust 对比脚本,M7 回归改为 Rust 主线 contract 验证:
|
||||
|
||||
1. 默认对比 `/healthz` 与 `/api/auth/login-options`。
|
||||
2. 可通过 `M7_COMPARE_PATHS` 扩展只读路径清单。
|
||||
3. 对比时会固定传入 `x-request-id`,并归一化 `requestId / timestamp / latencyMs` 等波动字段。
|
||||
4. 默认严格模式下发现差异直接返回非零退出码。
|
||||
1. `server-rs/scripts/m7-preflight.ps1` 覆盖 Rust 工作区构建、测试与关键脚本门禁。
|
||||
2. `server-rs/scripts/smoke.ps1` 覆盖 `/healthz`、envelope 与 request id 基础 contract。
|
||||
3. `server-rs/scripts/oss-smoke.ps1` 覆盖真实 OSS 链路。
|
||||
4. 新增只读 contract 时优先补进 Rust 侧 smoke 或 handler 测试,不恢复 Node 对比脚本。
|
||||
|
||||
该脚本只承担“无状态 GET contract”对比;带登录、写入、OSS 或 SSE 的主流程仍由专门 smoke 脚本负责。
|
||||
带登录、写入、OSS 或 SSE 的主流程仍由专门 smoke、handler 测试和人工验证清单负责。
|
||||
|
||||
## 7. 观测能力
|
||||
|
||||
@@ -113,10 +112,10 @@ M7 观测字段固定为:
|
||||
|
||||
## 8. 数据迁移与回滚
|
||||
|
||||
当前 M7 不做一次性“Node PostgreSQL 全量导入 SpacetimeDB”的危险迁移,采用双跑验证与按主链确认的渐进策略:
|
||||
当前 M7 不做一次性历史数据导入 SpacetimeDB 的危险迁移,采用按主链确认的渐进策略:
|
||||
|
||||
1. 已迁移主链以 SpacetimeDB 为真相源。
|
||||
2. 未迁移或灰度失败主链继续回退到 Node。
|
||||
2. 未迁移或灰度失败主链必须继续迁入 Rust 主线后再开放,不回退到旧 Node 工程。
|
||||
3. 资产二进制以 OSS 为真相,不回滚到本地 `public/generated-*` 写盘。
|
||||
4. 若 SpacetimeDB schema 需要清库重发,只允许在开发库或明确灰度库执行 `--clear-database`。
|
||||
5. 生产回滚优先切反向代理目标,不优先改代码。
|
||||
@@ -128,6 +127,6 @@ M7 完成时必须满足:
|
||||
1. M7 文档、脚本、任务清单均同步。
|
||||
2. `api-server` 和 `spacetime-module` 至少通过 `cargo check`。
|
||||
3. 基础 smoke 脚本可执行,并覆盖 `healthz + envelope + request id`。
|
||||
4. Node/Rust API 对比脚本可执行。
|
||||
5. Vite dev proxy 已具备 Node/Rust 切换与回退开关。
|
||||
4. Rust 主线预检和 smoke 脚本可执行。
|
||||
5. Vite dev proxy 默认指向 Rust `api-server`,仅保留 Rust 目标覆盖开关。
|
||||
6. `spacetime-module` 已从单 `lib.rs` 拆为按 `runtime / gameplay / custom_world / asset_metadata / ai` 组织的文件结构。
|
||||
|
||||
@@ -1,399 +0,0 @@
|
||||
# Node 后端模块与接口索引
|
||||
|
||||
> 该文档由 `server-node/src/manifest/backendCapabilityManifest.ts` 自动生成。
|
||||
> 生成命令:`npm run server-node:manifest:backend`
|
||||
> 生成时间:`2026-04-20T14:26:38.663Z`
|
||||
>
|
||||
> 过期说明:该索引生成于 `2026-04-20`,其中 `createQwenSpriteRoutes` 与 `/api/assets/qwen-sprite/*` 相关描述已在 `2026-04-21` 后失效。当前 Node 现役资产挂载面仅保留 `createCharacterAssetRoutes`;`Qwen` 仅剩 prompt 模板复用与 `/generated-qwen-sprites/*` 历史路径兼容,不再存在独立路由主链。
|
||||
|
||||
## 总览
|
||||
|
||||
- 对外挂载面:6 个
|
||||
- 已登记路由:96 条
|
||||
- 内部模块目录:12 个
|
||||
- 公开接口:10 条
|
||||
- JWT 接口:69 条
|
||||
- 受环境开关控制的接口:17 条
|
||||
- 流式接口:6 条
|
||||
|
||||
## 产物
|
||||
|
||||
- JSON 清单:`server-node/manifests/backend-capability-index.json`
|
||||
- Markdown 索引:`docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md`
|
||||
- Manifest 源:`server-node/src/manifest/backendCapabilityManifest.ts`
|
||||
|
||||
## 对外挂载面
|
||||
|
||||
### 资产生成工具面
|
||||
|
||||
- 标识:`assets`
|
||||
- 路由数:14
|
||||
- 入口:`server-node/src/app.ts -> /api/assets -> createCharacterAssetRoutes`;`server-node/src/app.ts -> /api/assets/qwen-sprite -> createQwenSpriteRoutes`
|
||||
- 关联模块:`assets`
|
||||
- 责任:
|
||||
- 生成角色主形象、动作、动作模板与工作流缓存。
|
||||
- 承接 Qwen 精灵表主图、整表、修帧与保存链路。
|
||||
- 把产物发布到 `public/generated-*` 目录并落地局部 manifest。
|
||||
- 主要服务边界:
|
||||
- 负责对接 DashScope、Ark 等外部媒体供应商,但不维护 runtime 快照与业务状态。
|
||||
- 统一受 `ASSETS_API_ENABLED` 开关控制,产物以文件与 JSON manifest 形式落在仓库工作区。
|
||||
|
||||
### 鉴权与会话面
|
||||
|
||||
- 标识:`auth`
|
||||
- 路由数:17
|
||||
- 入口:`server-node/src/app.ts -> /api/auth -> createAuthRoutes`
|
||||
- 关联模块:无
|
||||
- 责任:
|
||||
- 承接本地账号、短信验证码与微信登录流程。
|
||||
- 管理 refresh session、用户信息、会话吊销、审计日志与风险拦截。
|
||||
- 主要服务边界:
|
||||
- HTTP 层只做 schema 校验、请求上下文拼装与 Cookie 管理,核心鉴权逻辑统一收口到 `server-node/src/auth/*`。
|
||||
- 用户、身份、会话、风控与短信事件等持久化职责全部下沉到 repository 层,避免路由直接碰数据库细节。
|
||||
|
||||
### 编辑器工具面
|
||||
|
||||
- 标识:`editor`
|
||||
- 路由数:3
|
||||
- 入口:`server-node/src/app.ts -> /api/editor -> createEditorRoutes`
|
||||
- 关联模块:`editor`
|
||||
- 责任:
|
||||
- 读取编辑器资源 JSON。
|
||||
- 回写编辑器覆盖文件。
|
||||
- 枚举 `public/Icons` 下的物品图标资源。
|
||||
- 主要服务边界:
|
||||
- 只对工作区文件系统与 `public` 目录负责,不参与运行时数据库存储。
|
||||
- 统一受 `EDITOR_API_ENABLED` 开关控制,生产环境可按需关闭。
|
||||
|
||||
### 基础健康检查
|
||||
|
||||
- 标识:`health`
|
||||
- 路由数:1
|
||||
- 入口:`server-node/src/app.ts -> /healthz -> createApp`
|
||||
- 关联模块:无
|
||||
- 责任:
|
||||
- 提供 Node 后端进程级健康探针。
|
||||
- 给反向代理、部署平台和本地联调提供最小可用状态确认。
|
||||
- 主要服务边界:
|
||||
- 只返回服务静态信息,不触达数据库、鉴权或外部模型供应商。
|
||||
|
||||
### 运行时主能力面
|
||||
|
||||
- 标识:`runtime-main`
|
||||
- 路由数:59
|
||||
- 入口:`server-node/src/app.ts -> /api -> createRuntimeRoutes`;`server-node/src/routes/runtimeRoutes.ts -> /runtime/custom-world/agent -> createCustomWorldAgentRoutes`
|
||||
- 关联模块:`ai`、`custom-world`、`quest`、`runtime`、`runtime-item`、`story`
|
||||
- 责任:
|
||||
- 承接运行时资料库、公开画廊、存档、设置与个人档案接口。
|
||||
- 承接剧情生成、聊天流、任务生成、运行时物品意图与自定义世界链路。
|
||||
- 承接 Custom World Agent 会话、消息流和操作回放。
|
||||
- 主要服务边界:
|
||||
- HTTP contract 收口在 `runtimeRoutes.ts`,真正的世界生成、剧情、聊天、任务和资源逻辑继续下沉到 `services/*` 与 `src/modules/*`。
|
||||
- 除公开画廊外,运行时接口统一走 JWT 鉴权,并依赖 `runtimeRepository`、session store 与 LLM client 执行。
|
||||
|
||||
### 运行时 Story Action 面
|
||||
|
||||
- 标识:`runtime-story-action`
|
||||
- 路由数:2
|
||||
- 入口:`server-node/src/app.ts -> /api/runtime/story -> createStoryActionRoutes`
|
||||
- 关联模块:`story`、`quest`、`inventory`、`runtime-item`、`npc`、`progression`、`combat`、`runtime`
|
||||
- 责任:
|
||||
- 把前端 story choice 动作解析为新的运行时状态。
|
||||
- 查询指定 story session 的可恢复状态。
|
||||
- 主要服务边界:
|
||||
- 路由层只做鉴权与 schema 校验,真正的动作分发与跨模块协作集中在 `storyActionService.ts`。
|
||||
- Story Action 会联动 quest、inventory、runtime-item、npc 等内部模块,但对前端只暴露 story 这一条稳定入口。
|
||||
|
||||
## 接口索引
|
||||
|
||||
| 方法 | 路径 | 访问 | 响应 | 挂载面 | 内部模块 | 说明 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| POST | `/api/assets/character-animation/generate` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 生成角色动作草稿。 |
|
||||
| POST | `/api/assets/character-animation/import-video` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 导入动作参考视频并转为可消费素材。 |
|
||||
| GET | `/api/assets/character-animation/jobs/:taskId` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 查询角色动作生成任务状态。 |
|
||||
| POST | `/api/assets/character-animation/publish` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 发布角色动作帧集到 public 目录。 |
|
||||
| GET | `/api/assets/character-animation/templates` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 列出内置角色动作模板。 |
|
||||
| POST | `/api/assets/character-visual/generate` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 生成角色主形象候选图。 |
|
||||
| GET | `/api/assets/character-visual/jobs/:taskId` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 查询角色主形象生成任务状态。 |
|
||||
| POST | `/api/assets/character-visual/publish` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 发布选中的角色主形象到 public 目录。 |
|
||||
| POST | `/api/assets/character-workflow-cache` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 保存角色资产工作流缓存。 |
|
||||
| GET | `/api/assets/character-workflow-cache/:characterId` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 按角色读取角色资产工作流缓存。 |
|
||||
| POST | `/api/assets/qwen-sprite/frame-repair` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 对单帧做 Qwen 修复。 |
|
||||
| POST | `/api/assets/qwen-sprite/master` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 生成 Qwen 精灵主图。 |
|
||||
| POST | `/api/assets/qwen-sprite/save` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 保存 Qwen 精灵资产到 public 目录。 |
|
||||
| POST | `/api/assets/qwen-sprite/sheet` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 生成 Qwen 精灵表。 |
|
||||
| GET | `/api/auth/audit-logs` | JWT | json | `auth` | 无 | 查询当前账号的鉴权审计日志。 |
|
||||
| POST | `/api/auth/entry` | 公开 | json | `auth` | 无 | 用户名密码登录;不存在则创建本地账号。 |
|
||||
| GET | `/api/auth/login-options` | 公开 | json | `auth` | 无 | 返回当前启用的登录方式与入口配置。 |
|
||||
| POST | `/api/auth/logout` | JWT | json | `auth` | 无 | 退出当前会话并清理 refresh cookie。 |
|
||||
| POST | `/api/auth/logout-all` | JWT | json | `auth` | 无 | 退出当前账号的全部会话。 |
|
||||
| GET | `/api/auth/me` | JWT | json | `auth` | 无 | 读取当前登录用户的鉴权资料。 |
|
||||
| POST | `/api/auth/phone/change` | JWT | json | `auth` | 无 | 已登录用户更换绑定手机号。 |
|
||||
| POST | `/api/auth/phone/login` | 公开 | json | `auth` | 无 | 手机号验证码登录。 |
|
||||
| POST | `/api/auth/phone/send-code` | 公开 | json | `auth` | 无 | 发送手机号登录或绑定验证码。 |
|
||||
| POST | `/api/auth/refresh` | 公开 | json | `auth` | 无 | 使用 refresh session 刷新 JWT。 |
|
||||
| GET | `/api/auth/risk-blocks` | JWT | json | `auth` | 无 | 查询当前用户命中的风控封禁。 |
|
||||
| POST | `/api/auth/risk-blocks/:scopeType/lift` | JWT | json | `auth` | 无 | 请求解除指定维度的风控拦截。 |
|
||||
| GET | `/api/auth/sessions` | JWT | json | `auth` | 无 | 列出当前账号的活跃会话。 |
|
||||
| POST | `/api/auth/sessions/:sessionId/revoke` | JWT | json | `auth` | 无 | 吊销指定会话。 |
|
||||
| POST | `/api/auth/wechat/bind-phone` | JWT | json | `auth` | 无 | 为已登录微信账号绑定手机号。 |
|
||||
| GET | `/api/auth/wechat/callback` | 公开 | redirect | `auth` | 无 | 处理微信回调并重定向回前端。 |
|
||||
| GET | `/api/auth/wechat/start` | 公开 | json | `auth` | 无 | 发起微信登录并返回授权 URL。 |
|
||||
| POST | `/api/custom-world/cover-image` | JWT | json | `runtime-main` | `custom-world`、`assets` | 生成自定义世界封面图。 |
|
||||
| POST | `/api/custom-world/cover-upload` | JWT | json | `runtime-main` | `custom-world`、`assets` | 上传并落地自定义世界封面图。 |
|
||||
| POST | `/api/custom-world/entity` | JWT | json | `runtime-main` | `custom-world`、`ai` | 按世界 profile 生成单个角色或地标实体。 |
|
||||
| POST | `/api/custom-world/scene-image` | JWT | json | `runtime-main` | `custom-world`、`assets` | 生成自定义世界场景图。 |
|
||||
| POST | `/api/custom-world/scene-npc` | JWT | json | `runtime-main` | `custom-world`、`ai`、`npc` | 按地标生成场景 NPC。 |
|
||||
| GET | `/api/editor/catalog/items` | 开关: EDITOR_API_ENABLED | json | `editor` | `editor` | 列出 `public/Icons` 下的物品图标资源。 |
|
||||
| GET | `/api/editor/json/:resourceId` | 开关: EDITOR_API_ENABLED | json | `editor` | `editor` | 读取指定编辑器资源 JSON。 |
|
||||
| POST | `/api/editor/json/:resourceId` | 开关: EDITOR_API_ENABLED | json | `editor` | `editor` | 回写指定编辑器资源 JSON。 |
|
||||
| POST | `/api/llm/chat/completions` | JWT | proxy | `runtime-main` | `ai` | 把聊天补全请求透传到上游模型。 |
|
||||
| DELETE | `/api/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 清空平台浏览历史。 |
|
||||
| GET | `/api/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 读取平台浏览历史。 |
|
||||
| POST | `/api/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 写入或批量同步平台浏览历史。 |
|
||||
| GET | `/api/profile/dashboard` | JWT | json | `runtime-main` | `runtime` | 读取运行时个人主页汇总。 |
|
||||
| GET | `/api/profile/play-stats` | JWT | json | `runtime-main` | `runtime` | 读取个人游玩统计。 |
|
||||
| GET | `/api/profile/save-archives` | JWT | json | `runtime-main` | `runtime` | 列出个人存档摘要。 |
|
||||
| POST | `/api/profile/save-archives/:worldKey` | JWT | json | `runtime-main` | `runtime` | 恢复指定世界的最近存档。 |
|
||||
| GET | `/api/profile/wallet-ledger` | JWT | json | `runtime-main` | `runtime` | 列出个人资产流水。 |
|
||||
| POST | `/api/runtime/chat/character/reply/stream` | JWT | stream | `runtime-main` | `ai`、`story` | 流式生成角色回复。 |
|
||||
| POST | `/api/runtime/chat/character/suggestions` | JWT | json | `runtime-main` | `ai`、`story` | 生成角色聊天建议语。 |
|
||||
| POST | `/api/runtime/chat/character/summary` | JWT | json | `runtime-main` | `ai`、`story` | 生成角色聊天摘要。 |
|
||||
| POST | `/api/runtime/chat/npc/dialogue/stream` | JWT | stream | `runtime-main` | `ai`、`npc`、`story` | 流式生成 NPC 对话。 |
|
||||
| POST | `/api/runtime/chat/npc/recruit/stream` | JWT | stream | `runtime-main` | `ai`、`npc`、`story` | 流式生成招募 NPC 对话。 |
|
||||
| POST | `/api/runtime/chat/npc/turn/stream` | JWT | stream | `runtime-main` | `ai`、`npc`、`story` | 流式生成 NPC 单回合发言。 |
|
||||
| GET | `/api/runtime/custom-world-gallery` | 公开 | json | `runtime-main` | `custom-world`、`runtime` | 列出公开的自定义世界画廊。 |
|
||||
| GET | `/api/runtime/custom-world-gallery/:ownerUserId/:profileId` | 公开 | json | `runtime-main` | `custom-world`、`runtime` | 读取指定公开世界作品详情。 |
|
||||
| GET | `/api/runtime/custom-world-library` | JWT | json | `runtime-main` | `custom-world`、`runtime` | 列出当前账号的自定义世界资料库。 |
|
||||
| DELETE | `/api/runtime/custom-world-library/:profileId` | JWT | json | `runtime-main` | `custom-world`、`runtime` | 删除指定自定义世界 profile。 |
|
||||
| PUT | `/api/runtime/custom-world-library/:profileId` | JWT | json | `runtime-main` | `custom-world`、`runtime` | 写入或更新指定自定义世界 profile。 |
|
||||
| POST | `/api/runtime/custom-world-library/:profileId/publish` | JWT | json | `runtime-main` | `custom-world`、`runtime` | 发布指定世界到公开画廊。 |
|
||||
| POST | `/api/runtime/custom-world-library/:profileId/unpublish` | JWT | json | `runtime-main` | `custom-world`、`runtime` | 撤回指定世界的公开发布状态。 |
|
||||
| POST | `/api/runtime/custom-world/agent/sessions` | JWT | json | `runtime-main` | `custom-world`、`ai` | 创建 Custom World Agent 会话。 |
|
||||
| GET | `/api/runtime/custom-world/agent/sessions/:sessionId` | JWT | json | `runtime-main` | `custom-world`、`ai` | 读取 Agent 会话快照。 |
|
||||
| POST | `/api/runtime/custom-world/agent/sessions/:sessionId/actions` | JWT | json | `runtime-main` | `custom-world`、`ai`、`assets` | 执行 Agent 卡片生成、资产同步或发布动作。 |
|
||||
| GET | `/api/runtime/custom-world/agent/sessions/:sessionId/cards/:cardId` | JWT | json | `runtime-main` | `custom-world`、`ai` | 读取 Agent 卡片详情。 |
|
||||
| POST | `/api/runtime/custom-world/agent/sessions/:sessionId/messages` | JWT | json | `runtime-main` | `custom-world`、`ai` | 向 Agent 会话提交一条创作消息。 |
|
||||
| POST | `/api/runtime/custom-world/agent/sessions/:sessionId/messages/stream` | JWT | stream | `runtime-main` | `custom-world`、`ai` | 流式提交 Agent 消息并实时接收回执。 |
|
||||
| GET | `/api/runtime/custom-world/agent/sessions/:sessionId/operations/:operationId` | JWT | json | `runtime-main` | `custom-world`、`ai` | 查询 Agent 后台操作状态。 |
|
||||
| POST | `/api/runtime/custom-world/entity` | JWT | json | `runtime-main` | `custom-world`、`ai` | 按世界 profile 生成单个角色或地标实体(兼容路径)。 |
|
||||
| POST | `/api/runtime/custom-world/scene-npc` | JWT | json | `runtime-main` | `custom-world`、`ai`、`npc` | 按地标生成场景 NPC(兼容路径)。 |
|
||||
| POST | `/api/runtime/custom-world/sessions` | JWT | json | `runtime-main` | `custom-world` | 创建传统自定义世界问答会话。 |
|
||||
| GET | `/api/runtime/custom-world/sessions/:sessionId` | JWT | json | `runtime-main` | `custom-world` | 读取传统自定义世界问答会话。 |
|
||||
| POST | `/api/runtime/custom-world/sessions/:sessionId/answers` | JWT | json | `runtime-main` | `custom-world` | 回答传统自定义世界问答题目。 |
|
||||
| GET | `/api/runtime/custom-world/sessions/:sessionId/generate/stream` | JWT | stream | `runtime-main` | `custom-world`、`ai` | 流式编译传统自定义世界 profile。 |
|
||||
| GET | `/api/runtime/custom-world/works` | JWT | json | `runtime-main` | `custom-world`、`runtime` | 列出当前账号的自定义世界作品汇总。 |
|
||||
| POST | `/api/runtime/items/runtime-intent` | JWT | json | `runtime-main` | `runtime-item`、`ai` | 生成运行时物品意图。 |
|
||||
| DELETE | `/api/runtime/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 清空平台浏览历史。(兼容路径) |
|
||||
| GET | `/api/runtime/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 读取平台浏览历史。(兼容路径) |
|
||||
| POST | `/api/runtime/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 写入或批量同步平台浏览历史。(兼容路径) |
|
||||
| GET | `/api/runtime/profile/dashboard` | JWT | json | `runtime-main` | `runtime` | 读取运行时个人主页汇总。(兼容路径) |
|
||||
| GET | `/api/runtime/profile/play-stats` | JWT | json | `runtime-main` | `runtime` | 读取个人游玩统计。(兼容路径) |
|
||||
| GET | `/api/runtime/profile/save-archives` | JWT | json | `runtime-main` | `runtime` | 列出个人存档摘要。(兼容路径) |
|
||||
| POST | `/api/runtime/profile/save-archives/:worldKey` | JWT | json | `runtime-main` | `runtime` | 恢复指定世界的最近存档(兼容路径)。 |
|
||||
| GET | `/api/runtime/profile/wallet-ledger` | JWT | json | `runtime-main` | `runtime` | 列出个人资产流水。(兼容路径) |
|
||||
| POST | `/api/runtime/quests/generate` | JWT | json | `runtime-main` | `quest`、`ai` | 按当前遭遇生成任务候选。 |
|
||||
| DELETE | `/api/runtime/save/snapshot` | JWT | json | `runtime-main` | `runtime` | 删除当前用户的运行时存档。 |
|
||||
| GET | `/api/runtime/save/snapshot` | JWT | json | `runtime-main` | `runtime`、`progression`、`quest` | 读取当前用户的运行时存档。 |
|
||||
| PUT | `/api/runtime/save/snapshot` | JWT | json | `runtime-main` | `runtime`、`progression`、`quest` | 保存并归一化当前运行时存档。 |
|
||||
| GET | `/api/runtime/settings` | JWT | json | `runtime-main` | `runtime` | 读取运行时设置。 |
|
||||
| PUT | `/api/runtime/settings` | JWT | json | `runtime-main` | `runtime` | 更新运行时设置。 |
|
||||
| POST | `/api/runtime/story/actions/resolve` | JWT | json | `runtime-story-action` | `story`、`quest`、`inventory`、`runtime-item`、`npc`、`progression`、`combat`、`runtime` | 解析前端 story choice 动作为新的运行时结果。 |
|
||||
| POST | `/api/runtime/story/continue` | JWT | json | `runtime-main` | `story`、`ai` | 生成下一段故事内容。 |
|
||||
| POST | `/api/runtime/story/initial` | JWT | json | `runtime-main` | `story`、`ai` | 生成首段故事内容。 |
|
||||
| GET | `/api/runtime/story/state/:sessionId` | JWT | json | `runtime-story-action` | `story`、`runtime` | 读取指定 story session 的运行时状态。 |
|
||||
| GET | `/api/ws/health` | JWT | json | `runtime-main` | `runtime` | 保留给未来实时链路的占位健康检查。 |
|
||||
| GET | `/healthz` | 公开 | json | `health` | 无 | 返回 Node 后端进程健康状态。 |
|
||||
|
||||
## 内部模块边界
|
||||
|
||||
### AI 编排模块
|
||||
|
||||
- 标识:`ai`
|
||||
- 目录:`server-node/src/modules/ai`
|
||||
- 对外可见面:`runtime-main`
|
||||
- 关联路由数:23
|
||||
- 职责:
|
||||
- 统一剧情、多轮聊天与自定义世界编排器的 prompt 构造与输出归一化。
|
||||
- 屏蔽前端对不同 AI 链路的直接拼装细节。
|
||||
- 主要服务边界:
|
||||
- 专注提示词与编排,不负责持久化与 HTTP 传输。
|
||||
- 通过 `services/llmClient.ts` 与外部模型交互,由路由与 service 层决定何时调用。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/ai/chatOrchestrator.ts`
|
||||
- `server-node/src/modules/ai/customWorldOrchestrator.ts`
|
||||
- `server-node/src/modules/ai/storyOrchestrator.ts`
|
||||
|
||||
### 资产工具模块
|
||||
|
||||
- 标识:`assets`
|
||||
- 目录:`server-node/src/modules/assets`
|
||||
- 对外可见面:`assets`
|
||||
- 关联路由数:18
|
||||
- 职责:
|
||||
- 承接角色资产与 Qwen 精灵表的生成、查询、发布和保存。
|
||||
- 维护资产流程需要的缓存、草稿与产物 manifest。
|
||||
- 主要服务边界:
|
||||
- 以文件系统和外部媒体模型为主要边界,不碰 runtimeRepository。
|
||||
- 对外暴露稳定 HTTP 路径,对内通过私有 helper 处理媒体编码、任务轮询与写盘。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/assets/characterAssetRoutes.ts`
|
||||
- `server-node/src/modules/assets/qwenSpriteRoutes.ts`
|
||||
|
||||
### 战斗结算模块
|
||||
|
||||
- 标识:`combat`
|
||||
- 目录:`server-node/src/modules/combat`
|
||||
- 对外可见面:`runtime-story-action`
|
||||
- 关联路由数:1
|
||||
- 职责:
|
||||
- 提供运行时战斗结算与数值变更能力。
|
||||
- 为 story action 里的战斗型交互提供纯计算服务。
|
||||
- 主要服务边界:
|
||||
- 聚焦状态推导与结果计算,不负责 transport 与持久化。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/combat/combatResolutionService.ts`
|
||||
|
||||
### 自定义世界运行时模块
|
||||
|
||||
- 标识:`custom-world`
|
||||
- 目录:`server-node/src/modules/custom-world`
|
||||
- 对外可见面:`runtime-main`
|
||||
- 关联路由数:26
|
||||
- 职责:
|
||||
- 规范 creator intent、世界运行时类型与 profile compile。
|
||||
- 把世界创作输入整理成运行时可消费的数据结构。
|
||||
- 主要服务边界:
|
||||
- 偏纯领域建模与 compile,不直接做 HTTP、数据库查询或模型调用。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/custom-world/creatorIntentRuntime.ts`
|
||||
- `server-node/src/modules/custom-world/runtimeProfile.ts`
|
||||
- `server-node/src/modules/custom-world/runtimeTypes.ts`
|
||||
|
||||
### 编辑器资源模块
|
||||
|
||||
- 标识:`editor`
|
||||
- 目录:`server-node/src/modules/editor`
|
||||
- 对外可见面:`editor`
|
||||
- 关联路由数:3
|
||||
- 职责:
|
||||
- 提供编辑器资源目录枚举与 JSON 读写入口。
|
||||
- 主要服务边界:
|
||||
- 只负责工作区文件输入输出,不参与运行时业务计算。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/editor/editorRoutes.ts`
|
||||
|
||||
### 背包与物品变更模块
|
||||
|
||||
- 标识:`inventory`
|
||||
- 目录:`server-node/src/modules/inventory`
|
||||
- 对外可见面:`runtime-story-action`
|
||||
- 关联路由数:1
|
||||
- 职责:
|
||||
- 维护背包变更、NPC 背包交互与 story action 里的物品副作用。
|
||||
- 主要服务边界:
|
||||
- 对运行时状态做局部变更,不直接暴露 HTTP 路由。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/inventory/inventoryMutationService.ts`
|
||||
- `server-node/src/modules/inventory/inventoryStoryActionService.ts`
|
||||
- `server-node/src/modules/inventory/npcInventoryStoryActionService.ts`
|
||||
|
||||
### NPC 交互模块
|
||||
|
||||
- 标识:`npc`
|
||||
- 目录:`server-node/src/modules/npc`
|
||||
- 对外可见面:`runtime-story-action`、`runtime-main`
|
||||
- 关联路由数:6
|
||||
- 职责:
|
||||
- 维护 NPC 互动规则、任务 primitive 与关系变更逻辑。
|
||||
- 主要服务边界:
|
||||
- 专注 NPC 侧状态推导,供 story action 与聊天/任务链路复用。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/npc/npcInteractionService.ts`
|
||||
- `server-node/src/modules/npc/npcTask6Primitives.ts`
|
||||
|
||||
### 成长与关卡进程模块
|
||||
|
||||
- 标识:`progression`
|
||||
- 目录:`server-node/src/modules/progression`
|
||||
- 对外可见面:`runtime-story-action`、`runtime-main`
|
||||
- 关联路由数:3
|
||||
- 职责:
|
||||
- 提供角色成长、敌对等级、章节推进与 benchmark 逻辑。
|
||||
- 主要服务边界:
|
||||
- 只做成长数值与章节进度计算,由 runtime hydrate 与 story action 复用。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/progression/playerProgressionService.ts`
|
||||
- `server-node/src/modules/progression/hostileProgressionService.ts`
|
||||
- `server-node/src/modules/progression/chapterProgressionPlanner.ts`
|
||||
|
||||
### 任务运行时模块
|
||||
|
||||
- 标识:`quest`
|
||||
- 目录:`server-node/src/modules/quest`
|
||||
- 对外可见面:`runtime-main`、`runtime-story-action`
|
||||
- 关联路由数:4
|
||||
- 职责:
|
||||
- 生成任务意图、维护任务日志与处理任务进度信号。
|
||||
- 为运行时 quest 接口与 story action 提供统一任务语义。
|
||||
- 主要服务边界:
|
||||
- 领域逻辑以 quest module 为中心,AI 生成只是一种输入来源。
|
||||
- 不直接处理 HTTP 响应,统一由 routes/service 层调用。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/quest/runtimeQuestModule.ts`
|
||||
- `server-node/src/modules/quest/questProgressionService.ts`
|
||||
- `server-node/src/modules/quest/questStoryActionService.ts`
|
||||
|
||||
### 运行时状态基座模块
|
||||
|
||||
- 标识:`runtime`
|
||||
- 目录:`server-node/src/modules/runtime`
|
||||
- 对外可见面:`runtime-main`、`runtime-story-action`
|
||||
- 关联路由数:32
|
||||
- 职责:
|
||||
- 定义运行时状态 primitive、经济与装备规则。
|
||||
- 负责存档 hydration、兼容迁移与状态归一化。
|
||||
- 主要服务边界:
|
||||
- 是 runtimeRepository 与 story action 的共同状态基座,不承担 HTTP 入口职责。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/runtime/runtimeSnapshotHydration.ts`
|
||||
- `server-node/src/modules/runtime/runtimeStatePrimitives.ts`
|
||||
- `server-node/src/modules/runtime/runtimeEquipmentModule.ts`
|
||||
|
||||
### 运行时物品模块
|
||||
|
||||
- 标识:`runtime-item`
|
||||
- 目录:`server-node/src/modules/runtime-item`
|
||||
- 对外可见面:`runtime-main`、`runtime-story-action`
|
||||
- 关联路由数:2
|
||||
- 职责:
|
||||
- 生成运行时物品意图、物品奖励与剧情指纹。
|
||||
- 维护宝藏与物品解析逻辑。
|
||||
- 主要服务边界:
|
||||
- 聚焦物品领域编译与奖励拼装,由 route/service 选择具体触发时机。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/runtime-item/runtimeItemModule.ts`
|
||||
- `server-node/src/modules/runtime-item/runtimeItemResolutionService.ts`
|
||||
- `server-node/src/modules/runtime-item/treasureStoryActionService.ts`
|
||||
|
||||
### 故事会话模块
|
||||
|
||||
- 标识:`story`
|
||||
- 目录:`server-node/src/modules/story`
|
||||
- 对外可见面:`runtime-main`、`runtime-story-action`
|
||||
- 关联路由数:10
|
||||
- 职责:
|
||||
- 维护运行时故事会话状态与 action 分发。
|
||||
- 为 story resolve、story state 查询提供统一入口。
|
||||
- 主要服务边界:
|
||||
- story 模块是 runtime 主循环的编排层,必要时再向 quest、inventory、combat 等领域模块分发。
|
||||
- 关键文件:
|
||||
- `server-node/src/modules/story/runtimeSession.ts`
|
||||
- `server-node/src/modules/story/storyActionRoutes.ts`
|
||||
- `server-node/src/modules/story/storyActionService.ts`
|
||||
|
||||
## 维护规则
|
||||
|
||||
- 新增 `server-node/src/modules/*` 目录时,必须先补充 manifest 里的模块说明,再重新生成产物。
|
||||
- 新增或下线路由时,先更新 manifest 里的路由清单,再运行生成命令同步 JSON 与文档。
|
||||
- 如果路由来自兼容路径或中间件派生路径,`sourceHint` 需要指向源代码里的真实表达式,确保生成脚本能做最小校验。
|
||||
@@ -1,245 +0,0 @@
|
||||
# Node 后端知识图谱
|
||||
|
||||
日期:`2026-04-08`
|
||||
|
||||
## 1. 当前定位
|
||||
|
||||
当前运行时后端以 `server-node/` 为唯一有效服务端实现。
|
||||
|
||||
当前职责:
|
||||
|
||||
- 承接运行时鉴权
|
||||
- 承接运行时持久化
|
||||
- 承接运行时 AI 接口
|
||||
- 承接编辑器写盘与资产生成工具接口
|
||||
- 为 Vite 前端提供开发期代理目标
|
||||
|
||||
当前不再使用:
|
||||
|
||||
- 已删除的旧 Vite 本地 API 插件链路 `scripts/dev-server/*.ts`
|
||||
|
||||
## 2. 技术栈
|
||||
|
||||
- HTTP 框架:`Express`
|
||||
- 语言与构建:`TypeScript` + `tsx` + `esbuild`
|
||||
- 数据库:`PostgreSQL`
|
||||
- JWT:`jose`
|
||||
- 密码哈希:`@node-rs/argon2`
|
||||
- 日志:`pino` + `pino-http` + `pino-roll`
|
||||
|
||||
## 3. 运行入口
|
||||
|
||||
推荐命令:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
相关脚本:
|
||||
|
||||
- 根目录联调:`npm run dev` / `npm run dev:node`
|
||||
- 仅前端开发:`npm run dev:web`
|
||||
- 单独启动后端开发模式:`npm run server-node:dev`
|
||||
- 构建后端:`npm run server-node:build`
|
||||
- 运行后端测试:`npm run server-node:test`
|
||||
|
||||
默认监听:
|
||||
|
||||
- 前端:`3000`
|
||||
- Node 后端:`8081`
|
||||
|
||||
## 4. 目录与主入口
|
||||
|
||||
服务端主入口:
|
||||
|
||||
- `server-node/src/server.ts`
|
||||
- `server-node/src/app.ts`
|
||||
|
||||
路由入口:
|
||||
|
||||
- `server-node/src/routes/authRoutes.ts`
|
||||
- `server-node/src/routes/runtimeRoutes.ts`
|
||||
- `server-node/src/modules/editor/editorRoutes.ts`
|
||||
- `server-node/src/modules/assets/characterAssetRoutes.ts`
|
||||
- `server-node/src/modules/assets/qwenSpriteRoutes.ts`
|
||||
|
||||
基础设施:
|
||||
|
||||
- `server-node/src/config.ts`
|
||||
- `server-node/src/logging.ts`
|
||||
- `server-node/src/db.ts`
|
||||
- `server-node/src/context.ts`
|
||||
|
||||
数据访问:
|
||||
|
||||
- `server-node/src/repositories/userRepository.ts`
|
||||
- `server-node/src/repositories/runtimeRepository.ts`
|
||||
|
||||
鉴权相关:
|
||||
|
||||
- `server-node/src/auth/authService.ts`
|
||||
- `server-node/src/auth/token.ts`
|
||||
- `server-node/src/auth/password.ts`
|
||||
- `server-node/src/middleware/auth.ts`
|
||||
|
||||
## 5. 鉴权模型
|
||||
|
||||
当前采用:
|
||||
|
||||
- 前端本地保存 `JWT + 自动生成的用户名密码`
|
||||
- 请求头使用 `Authorization: Bearer <token>`
|
||||
- 后端 middleware 统一解析出 `UserID`
|
||||
- handler 不直接解析 token
|
||||
|
||||
当前账号策略:
|
||||
|
||||
- 默认自动匿名账号启动
|
||||
- 本地无 JWT 时,前端会自动生成随机用户名密码并调用 `POST /api/auth/entry`
|
||||
- 本地 JWT 失效但仍保留随机凭据时,前端自动重新调用 `auth/entry` 恢复同一账号
|
||||
|
||||
JWT 现状:
|
||||
|
||||
- 当前为永久签发
|
||||
- claim 仍保留:`sub`、`iat`、`iss`、`ver`
|
||||
- `logout` 通过递增 `token_version` 立即失效旧 token
|
||||
|
||||
## 6. 数据存储
|
||||
|
||||
当前数据库:
|
||||
|
||||
- 当前运行时持久化已切换到 `PostgreSQL`
|
||||
- 连接信息由后端 `DATABASE_URL` 环境变量注入
|
||||
- 不再以本地 `SQLite` 文件作为正式运行时数据库
|
||||
- 后端测试默认使用 `pg-mem` 作为内存级 PostgreSQL 兼容实现
|
||||
- 基础表初始化通过 `schema_migrations` 基线管理
|
||||
- 可通过 `npm run server-node:db:migrate` 主动校验并补齐数据库基线
|
||||
|
||||
当前核心表:
|
||||
|
||||
- `users`
|
||||
- `save_snapshots`
|
||||
- `runtime_settings`
|
||||
- `custom_world_profiles`
|
||||
|
||||
当前隔离原则:
|
||||
|
||||
- 所有运行时数据按用户隔离
|
||||
|
||||
## 7. 已承接接口
|
||||
|
||||
鉴权:
|
||||
|
||||
- `POST /api/auth/entry`
|
||||
- `GET /api/auth/me`
|
||||
- `POST /api/auth/logout`
|
||||
|
||||
运行时持久化:
|
||||
|
||||
- `GET /api/runtime/save/snapshot`
|
||||
- `PUT /api/runtime/save/snapshot`
|
||||
- `DELETE /api/runtime/save/snapshot`
|
||||
- `GET /api/runtime/settings`
|
||||
- `PUT /api/runtime/settings`
|
||||
- `GET /api/runtime/custom-world-library`
|
||||
- `PUT /api/runtime/custom-world-library/:profileId`
|
||||
- `DELETE /api/runtime/custom-world-library/:profileId`
|
||||
|
||||
运行时 AI:
|
||||
|
||||
- `POST /api/llm/chat/completions`
|
||||
- `POST /api/custom-world/scene-image`
|
||||
- `POST /api/runtime/story/initial`
|
||||
- `POST /api/runtime/story/continue`
|
||||
- `POST /api/runtime/custom-world/agent/sessions`
|
||||
- `GET /api/runtime/custom-world/agent/sessions/:sessionId`
|
||||
- `POST /api/runtime/custom-world/agent/sessions/:sessionId/messages`
|
||||
- `POST /api/runtime/custom-world/agent/sessions/:sessionId/actions`
|
||||
- `GET /api/runtime/custom-world/works`
|
||||
- `POST /api/runtime/chat/character/suggestions`
|
||||
- `POST /api/runtime/chat/character/summary`
|
||||
- `POST /api/runtime/chat/character/reply/stream`
|
||||
- `POST /api/runtime/chat/npc/dialogue/stream`
|
||||
- `POST /api/runtime/chat/npc/recruit/stream`
|
||||
- `POST /api/runtime/items/runtime-intent`
|
||||
- `POST /api/runtime/quests/generate`
|
||||
|
||||
补充说明(`2026-04-19`):
|
||||
|
||||
- `POST /api/custom-world/scene-image` 现在支持前端仅提交 `profile + landmark + userPrompt` 上下文,由后端统一补齐场景图 prompt 与默认 negative prompt。
|
||||
- runtime story option 的 `interaction` 元数据现在由后端随 option 一并返回,前端不再本地按 `functionId` 重建 NPC / treasure 交互语义。
|
||||
|
||||
编辑器工具:
|
||||
|
||||
- `GET /api/editor/catalog/items`
|
||||
- `GET /api/editor/json/:resourceId`
|
||||
- `POST /api/editor/json/:resourceId`
|
||||
|
||||
资产工具:
|
||||
|
||||
- `POST /api/assets/character-visual/generate`
|
||||
- `POST /api/assets/character-visual/publish`
|
||||
- `GET /api/assets/character-visual/jobs/:taskId`
|
||||
- `POST /api/assets/character-animation/generate`
|
||||
- `POST /api/assets/character-animation/publish`
|
||||
- `GET /api/assets/character-animation/jobs/:taskId`
|
||||
- `POST /api/assets/character-animation/import-video`
|
||||
- `GET /api/assets/character-animation/templates`
|
||||
|
||||
编辑器与资产接口门禁:
|
||||
|
||||
- `EDITOR_API_ENABLED` 控制 `/api/editor/*`
|
||||
- `ASSETS_API_ENABLED` 控制 `/api/assets/*`
|
||||
- 非生产环境默认开启,生产环境默认关闭
|
||||
|
||||
## 8. Story 与 Custom World 现状
|
||||
|
||||
Story:
|
||||
|
||||
- Node 后端直接复用前端成熟 prompt 与归一化逻辑
|
||||
- 服务端走 `src/services/ai.ts` 中的严格版 story 生成链
|
||||
|
||||
Custom World:
|
||||
|
||||
- Node 后端当前已自持 `server-node/src/modules/custom-world/**` 运行时模块
|
||||
- 已承接 `creator intent` 归一化、`anchorPack / lockState` 推导、framework normalize、runtime profile compile
|
||||
- `customWorldOrchestrator` 与 `customWorldAgentFoundationDraftService` 已不再运行时 import 前端 `src/services/customWorld*.ts` 与 `src/types.js`
|
||||
- `server-node/src/prompts/customWorldPrompts.ts` 已承接 foundation draft 与 scene image 使用的 custom world prompt source
|
||||
- 上述 prompt 迁移只改变源码归属位置,没有改动提示词正文
|
||||
- 当前保留 `session + answers + SSE progress/result/error` 协议
|
||||
- 前端已支持接收真实阶段进度对象
|
||||
|
||||
## 9. 前端接入点
|
||||
|
||||
鉴权与请求:
|
||||
|
||||
- `src/services/apiClient.ts`
|
||||
- `src/services/authService.ts`
|
||||
- `src/components/auth/AuthGate.tsx`
|
||||
|
||||
运行时服务层:
|
||||
|
||||
- `src/services/storageService.ts`
|
||||
- `src/services/aiService.ts`
|
||||
|
||||
编辑器与资产工具层:
|
||||
|
||||
- `src/editor/shared/editorApiClient.ts`
|
||||
- `src/components/preset-editor/characterAssetStudioPersistence.ts`
|
||||
|
||||
## 10. 当前 Vite 角色
|
||||
|
||||
Vite 当前只负责代理,不再提供本地 API 插件。
|
||||
|
||||
当前代理目标:
|
||||
|
||||
- `/api/auth`
|
||||
- `/api/runtime`
|
||||
- `/api/editor`
|
||||
- `/api/assets`
|
||||
- `/api/llm`
|
||||
- `/api/custom-world/scene-image`
|
||||
- `/api/ws`
|
||||
|
||||
全部转发到 Node 后端。
|
||||
|
||||
`scripts/dev-server/` 目录现仅保留 README 作为迁移说明,旧本地 API 实现代码已于 `2026-04-19` 删除。
|
||||
@@ -1,226 +0,0 @@
|
||||
# Node 后端测试、观测与部署基线
|
||||
|
||||
日期:`2026-04-08`
|
||||
|
||||
## 1. 文档目标
|
||||
|
||||
这份文档用于落实 `EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 中的任务 9:
|
||||
|
||||
- 给 Node 后端补最小自动回归
|
||||
- 给请求链路补最小可追踪基线
|
||||
- 给部署、回滚、迁移补最小操作清单
|
||||
|
||||
当前目标不是一次性把监控平台、CI/CD、容器编排全部做完,而是先确保:
|
||||
|
||||
- 后端改动后有脚本能快速验证主链路
|
||||
- 线上或联调失败时能快速定位到具体请求
|
||||
- 发布前后有统一检查口径
|
||||
|
||||
## 2. 当前基线命令
|
||||
|
||||
推荐在仓库根目录执行:
|
||||
|
||||
```bash
|
||||
npm run server-node:db:migrate
|
||||
npm run server-node:test:baseline
|
||||
npm run server-node:smoke
|
||||
npm run server-node:smoke:proxy
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `npm run server-node:db:migrate`
|
||||
- 用当前 `DATABASE_URL` 主动校验 PostgreSQL 基线是否可连接、可初始化
|
||||
- 会确保 `schema_migrations` 和运行时基础表已补齐
|
||||
- `npm run server-node:test:baseline`
|
||||
- 当前先固定为任务 9 自己维护的观测基线测试
|
||||
- 已覆盖 `requestId` 回传、访问日志字段、错误日志链路
|
||||
- `npm run server-node:smoke`
|
||||
- 启动一套基于 `pg-mem` 的临时 Express 服务
|
||||
- 不依赖本地 PostgreSQL
|
||||
- 走真实 HTTP 调用验证 `healthz -> auth -> runtime save/settings -> logout`
|
||||
- `npm run server-node:smoke:proxy`
|
||||
- 基于已构建的 `dist + server-node/dist`
|
||||
- 自动拉起 `server-node + 同域反向代理 harness`
|
||||
- 用 `pg-mem` 跑同域反向代理链路 smoke
|
||||
- 验证 `web -> reverse proxy -> /api/* -> server-node` 主链路
|
||||
|
||||
如果要一口气跑完整发布前基线,可执行:
|
||||
|
||||
```bash
|
||||
npm run server-node:check:deploy
|
||||
```
|
||||
|
||||
补充说明:
|
||||
|
||||
- `npm run server-node:test` 仍然可以继续作为更大范围的后端接口套件入口
|
||||
- 但它会跟随其他并行任务一起变化,不应替代任务 9 自己的稳定基线
|
||||
|
||||
## 2.1 任务 9 对照清单
|
||||
|
||||
当前按并行任务规划中的任务 9 逐项对照:
|
||||
|
||||
- 后端接口测试:`npm run server-node:test`
|
||||
- 关键主链路 smoke:`npm run server-node:smoke`
|
||||
- request/response 日志校验:`npm run server-node:test:baseline`
|
||||
- 同域部署基线:本文第 6 节与 `npm run server-node:smoke:proxy`
|
||||
- 反向代理 smoke 测试脚本:`scripts/smoke-same-origin-stack.ts`
|
||||
- 回滚、备份、迁移检查清单:本文第 8 节与 `npm run server-node:db:migrate`
|
||||
- 发布前一键检查:`npm run server-node:check:deploy`
|
||||
|
||||
## 3. 当前 smoke 覆盖范围
|
||||
|
||||
当前 smoke 脚本验证以下链路:
|
||||
|
||||
- `GET /healthz`
|
||||
- `POST /api/auth/entry`
|
||||
- `GET /api/auth/me`
|
||||
- `PUT /api/runtime/save/snapshot`
|
||||
- `GET /api/runtime/save/snapshot`
|
||||
- `PUT /api/runtime/settings`
|
||||
- `GET /api/runtime/settings`
|
||||
- `DELETE /api/runtime/save/snapshot`
|
||||
- `POST /api/auth/logout`
|
||||
|
||||
当前代理 smoke 额外验证:
|
||||
|
||||
- `GET /`
|
||||
- `GET /healthz`(本地反向代理健康探针)
|
||||
- `POST /api/auth/entry` 经反代可用
|
||||
- `GET /api/auth/me` 经反代可用
|
||||
- `PUT /api/runtime/save/snapshot` 经反代可用
|
||||
- `GET /api/runtime/save/snapshot` 经反代可用
|
||||
- `X-Request-Id` 能穿过反向代理返回给调用方
|
||||
|
||||
当前 smoke 的定位是:
|
||||
|
||||
- 优先覆盖后端化后最容易断的基础链路
|
||||
- 优先覆盖前端最依赖的鉴权和持久化能力
|
||||
- 不把 AI 上游依赖拉进最小回归集,避免把第三方波动误判成主链路回归
|
||||
|
||||
## 4. 当前观测基线
|
||||
|
||||
当前请求链路至少要满足以下约束:
|
||||
|
||||
- 支持读取外部传入的 `X-Request-Id`
|
||||
- 如果调用方没有传 `X-Request-Id`,后端自动生成
|
||||
- 响应头回写 `x-request-id`
|
||||
- 访问日志至少包含:
|
||||
- `request_id`
|
||||
- `user_id`
|
||||
- `method`
|
||||
- `path`
|
||||
- `status`
|
||||
- `latency_ms`
|
||||
- 错误日志至少包含:
|
||||
- `request_id`
|
||||
- `user_id`
|
||||
- `err`
|
||||
|
||||
当前目的很明确:
|
||||
|
||||
- 浏览器、反向代理、Node 后端至少有一个共同可追踪的请求标识
|
||||
- 接口失败后,能从日志里快速找到对应请求
|
||||
|
||||
## 5. 部署前检查清单
|
||||
|
||||
发布前至少执行一次:
|
||||
|
||||
- `npm run check:encoding`
|
||||
- `npm run server-node:db:migrate`
|
||||
- `npm run server-node:test:baseline`
|
||||
- `npm run server-node:smoke`
|
||||
- `npm run server-node:build`
|
||||
- `npm run build`
|
||||
- `npm run server-node:smoke:proxy`
|
||||
|
||||
环境变量至少确认:
|
||||
|
||||
- `DATABASE_URL`
|
||||
- `JWT_SECRET`
|
||||
- `NODE_SERVER_ADDR`
|
||||
- `LOG_LEVEL`
|
||||
- `LLM_API_KEY` 或 `ARK_API_KEY`
|
||||
- `DASHSCOPE_API_KEY`
|
||||
|
||||
部署前数据库检查:
|
||||
|
||||
- 确认目标 PostgreSQL 可连接
|
||||
- 确认发布账号具备建表或执行初始化所需权限
|
||||
- 确认已执行 `npm run server-node:db:migrate` 或等效迁移步骤
|
||||
- 确认现网数据已完成备份
|
||||
|
||||
## 6. 同域部署基线
|
||||
|
||||
当前推荐仍然是同域部署:
|
||||
|
||||
- Web 静态资源:`https://game.example.com/`
|
||||
- Node API:`https://game.example.com/api/*`
|
||||
|
||||
最小拓扑:
|
||||
|
||||
```text
|
||||
Browser
|
||||
-> Nginx / Caddy
|
||||
-> dist
|
||||
-> server-node
|
||||
```
|
||||
|
||||
反向代理至少要保留这些头:
|
||||
|
||||
- `Host`
|
||||
- `X-Forwarded-For`
|
||||
- `X-Forwarded-Proto`
|
||||
- `X-Request-Id`
|
||||
|
||||
流式接口还要确保:
|
||||
|
||||
- `proxy_buffering off`
|
||||
- `X-Accel-Buffering: no`
|
||||
|
||||
## 7. 发布后 smoke 清单
|
||||
|
||||
发布完成后至少人工或脚本确认一次:
|
||||
|
||||
1. `GET /healthz` 返回 `200`
|
||||
2. 响应头里能看到 `x-request-id`
|
||||
3. `POST /api/auth/entry` 可正常注册或恢复账号
|
||||
4. `GET /api/auth/me` 可正常识别 token
|
||||
5. `PUT /api/runtime/save/snapshot` 和 `GET /api/runtime/save/snapshot` 正常
|
||||
6. 日志中能用同一个 `request_id` 串起访问记录
|
||||
|
||||
如果线上使用反向代理生成请求 ID,还要额外确认:
|
||||
|
||||
- 代理传入的 `X-Request-Id` 没有在 Node 层丢失
|
||||
- 同域入口 `/` 与 `/api/*` 可以通过同一个站点域名访问
|
||||
|
||||
## 8. 回滚与备份清单
|
||||
|
||||
回滚前先确认:
|
||||
|
||||
- 当前发布包版本号或 commit 可定位
|
||||
- 当前数据库备份可恢复
|
||||
- 当前 `.env` 或 secret 版本可回退
|
||||
|
||||
需要回滚时按顺序执行:
|
||||
|
||||
1. 停止新版本 Node 进程
|
||||
2. 切回上一个稳定前端静态包和 Node 构建产物
|
||||
3. 恢复上一个稳定环境变量版本
|
||||
4. 如果本次发布包含数据库结构变更,先确认是否需要回滚数据
|
||||
5. 回滚后重新执行 `healthz + auth + runtime save` 最小 smoke
|
||||
|
||||
如果本次发布已经写入了不兼容数据结构:
|
||||
|
||||
- 不要只回滚代码不验证数据兼容性
|
||||
- 必须先确认旧版本代码是否还能读取当前数据
|
||||
|
||||
## 9. 后续扩展方向
|
||||
|
||||
任务 9 的下一轮可以继续补:
|
||||
|
||||
- 把 smoke 纳入 CI
|
||||
- 为关键 API 增加结构化 contract 测试
|
||||
- 给上游 AI 调用补 vendor/model/errorCode 维度日志
|
||||
- 增加数据库迁移前后的自动检查脚本
|
||||
- 增加反向代理与正式环境的联调 smoke
|
||||
@@ -1,185 +0,0 @@
|
||||
# Prompt 目录收口方案(2026-04-19)
|
||||
|
||||
## 1. 这次调整解决什么问题
|
||||
|
||||
此前提示词分散在多个后端、前端和工具文件里:
|
||||
|
||||
- `server-node/src/modules/ai/**`
|
||||
- `server-node/src/modules/quest/**`
|
||||
- `server-node/src/modules/runtime-item/**`
|
||||
- `server-node/src/services/customWorld*.ts`
|
||||
- `server-node/src/services/eightAnchorPromptBuilder.ts`
|
||||
- `server-node/src/modules/assets/characterAssetRoutes.ts`
|
||||
- `src/services/**`
|
||||
- `src/components/**`
|
||||
|
||||
问题主要有三类:
|
||||
|
||||
1. 业务逻辑和 prompt 文本混写,改提示词时容易顺手改坏运行时逻辑。
|
||||
2. 同一类 prompt 缺少集中入口,排查系统 prompt / user prompt / repair prompt 成本高。
|
||||
3. 老桥接层、测试和新业务链路同时依赖时,迁移成本高,容易出现导出断裂。
|
||||
|
||||
这次收口目标不是“重写全部 AI 链路”,而是把当前正式业务 prompt 主源收到独立目录,业务模块退化成“准备上下文 + 调用 prompt 脚本”。
|
||||
|
||||
## 2. 新目录
|
||||
|
||||
本轮落地后的目录:
|
||||
|
||||
```text
|
||||
packages/shared/src/prompts/
|
||||
└─ qwenSprite.ts
|
||||
|
||||
server-node/src/prompts/
|
||||
├─ characterAssetPrompts.ts
|
||||
├─ chatPromptBuilders.ts
|
||||
├─ customWorldAgentPrompts.ts
|
||||
├─ customWorldEntityPrompts.ts
|
||||
├─ customWorldOrchestratorPrompts.ts
|
||||
├─ customWorldSceneNpcPrompts.ts
|
||||
├─ eightAnchorPrompts.ts
|
||||
├─ questPrompts.ts
|
||||
├─ runtimeItemPrompts.ts
|
||||
├─ storyOrchestratorPrompts.ts
|
||||
└─ storyPromptBuilders.ts
|
||||
|
||||
src/prompts/
|
||||
├─ characterChatPrompts.ts
|
||||
├─ customWorldEntityActionPrompts.ts
|
||||
├─ customWorldOrchestratorPrompts.ts
|
||||
├─ customWorldPrompts.ts
|
||||
├─ customWorldRolePromptDefaults.ts
|
||||
├─ questPrompts.ts
|
||||
├─ runtimeItemPrompts.ts
|
||||
├─ storyOrchestratorPrompts.ts
|
||||
└─ storyPromptBuilders.ts
|
||||
```
|
||||
|
||||
当前职责划分:
|
||||
|
||||
- `chatPromptBuilders.ts`
|
||||
- 角色私聊 / NPC 聊天 / 招募对话 prompt
|
||||
- `storyPromptBuilders.ts`
|
||||
- 主剧情 system prompt 与 user prompt builder
|
||||
- `storyOrchestratorPrompts.ts`
|
||||
- 剧情语言修复 prompt
|
||||
- `questPrompts.ts`
|
||||
- 任务意图 system prompt 与 user prompt builder
|
||||
- `runtimeItemPrompts.ts`
|
||||
- 运行时物品意图 system prompt 与 user prompt 文本装配
|
||||
- `customWorldOrchestratorPrompts.ts`
|
||||
- 自定义世界主编排 JSON 生成与 repair prompt
|
||||
- `customWorldAgentPrompts.ts`
|
||||
- 世界草稿 JSON prompt、补角色 / 补地点 prompt
|
||||
- `customWorldEntityPrompts.ts`
|
||||
- 世界编辑器角色 / 场景实体生成 prompt
|
||||
- `customWorldSceneNpcPrompts.ts`
|
||||
- 世界编辑器场景 NPC 生成 prompt
|
||||
- `characterAssetPrompts.ts`
|
||||
- 角色主图 / 动作试片正式生成 prompt
|
||||
- `eightAnchorPrompts.ts`
|
||||
- 八锚点状态推断、模式规则与正式单轮共创 prompt
|
||||
- `src/prompts/customWorldPrompts.ts`
|
||||
- 自定义世界分阶段生成 prompt 与场景背景图 prompt
|
||||
- `src/prompts/customWorldRolePromptDefaults.ts`
|
||||
- 角色资产工作台默认 prompt 种子唯一主源
|
||||
- `src/prompts/customWorldEntityActionPrompts.ts`
|
||||
- 编辑器技能动作 prompt
|
||||
- `packages/shared/src/prompts/qwenSprite.ts`
|
||||
- 共享资产层的基础角色 prompt 模板
|
||||
|
||||
## 3. 落地规则
|
||||
|
||||
### 3.1 业务模块只做两件事
|
||||
|
||||
1. 整理运行时上下文
|
||||
2. 调用 `server-node/src/prompts/**` 下的脚本输出 prompt
|
||||
|
||||
不要在业务模块里继续直接内联大段 system prompt / repair prompt / user prompt 模板文本。
|
||||
|
||||
### 3.2 Prompt 文件只放文本相关职责
|
||||
|
||||
允许放:
|
||||
|
||||
- system prompt 常量
|
||||
- user prompt builder
|
||||
- repair prompt builder
|
||||
- prompt 专用的文本摘要函数
|
||||
|
||||
不建议放:
|
||||
|
||||
- 运行时状态 mutation
|
||||
- 仓储读写
|
||||
- HTTP 处理
|
||||
- 与 prompt 无关的领域推导
|
||||
|
||||
### 3.3 兼容层保留旧导出
|
||||
|
||||
本轮对已有纯 prompt builder 文件采取了兼容迁移,旧路径保留为薄 re-export:
|
||||
|
||||
- `server-node/src/modules/ai/chatPromptBuilders.ts`
|
||||
- `server-node/src/modules/ai/storyPromptBuilders.ts`
|
||||
- `server-node/src/services/eightAnchorPromptBuilder.ts`
|
||||
- `src/services/prompt.ts`
|
||||
- `src/services/characterChatPrompt.ts`
|
||||
- `src/services/questPrompt.ts`
|
||||
- `src/services/runtimeItemAiPrompt.ts`
|
||||
- `src/components/asset-studio/customWorldRolePromptDefaults.ts`
|
||||
- `packages/shared/src/assets/qwenSprite.ts`
|
||||
|
||||
对于 `runtimeQuestModule.ts`、`runtimeItemModule.ts` 这类被桥接层直接引用的模块,本轮保留原导出名,通过 re-export 指向新 prompt 文件,保证兼容性。
|
||||
|
||||
## 4. 后续新增 prompt 的写法
|
||||
|
||||
新增提示词时按下面顺序处理:
|
||||
|
||||
1. 先判断属于后端、前端/编辑器还是共享工具层。
|
||||
2. 后端正式业务优先补到 `server-node/src/prompts/*.ts`。
|
||||
3. 前端/编辑器 prompt 优先补到 `src/prompts/*.ts`。
|
||||
4. 可复用的共享资产 prompt 优先补到 `packages/shared/src/prompts/*.ts`。
|
||||
5. 业务模块只传入已经整理好的上下文字段,不在模块内部继续拼长文本。
|
||||
6. 至少补一条该 prompt 的调用链测试或现有测试断言。
|
||||
|
||||
建议命名:
|
||||
|
||||
- system prompt:`XXX_SYSTEM_PROMPT`
|
||||
- repair prompt:`buildXXXRepairPrompt`
|
||||
- user prompt:`buildXXXPrompt`
|
||||
- 纯文本装配:`buildXXXPromptText`
|
||||
|
||||
## 5. 本轮范围与当前状态
|
||||
|
||||
本轮已经收口:
|
||||
|
||||
- Story
|
||||
- Chat
|
||||
- Quest
|
||||
- Runtime Item
|
||||
- Custom World 主编排
|
||||
- Custom World Agent 草稿增补
|
||||
- Custom World 编辑器角色 / 场景 / 场景 NPC 生成
|
||||
- Character Asset
|
||||
- Eight Anchor
|
||||
- Scene Image
|
||||
- 前端剧情 / 私聊 / 任务 / 物品 prompt 兼容层
|
||||
- 编辑器与工具链 prompt 种子
|
||||
|
||||
当前状态:
|
||||
|
||||
- 正式业务 prompt 主源已经集中到 prompt 目录。
|
||||
- 旧 `services/`、`tools/`、`components/` 下保留的相关文件主要是兼容层或调用方。
|
||||
- 当前没有再发现需要优先继续抽离的大块业务 prompt 正文。
|
||||
|
||||
## 6. 验证方式
|
||||
|
||||
本轮调整后建议至少执行:
|
||||
|
||||
- `npm run check:encoding`
|
||||
- `npm run server-node:test`
|
||||
- `npm --prefix server-node run build`
|
||||
|
||||
本轮实测结果:
|
||||
|
||||
- `npm run check:encoding` 通过
|
||||
- `npm --prefix server-node run build` 通过
|
||||
- `npm run build` 通过
|
||||
- `npm run server-node:test` 143 项全部通过
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
## 文档列表
|
||||
|
||||
- [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md):冻结当前后端唯一落地口径,明确新功能以 `server-rs + Axum + SpacetimeDB` 为准,旧 `server-node` / Express / PostgreSQL 与 Go 方向只允许作为迁移参考。
|
||||
- [API_SERVER_DEV_STACK_COLD_BUILD_TIMEOUT_FIX_2026-04-25.md](./API_SERVER_DEV_STACK_COLD_BUILD_TIMEOUT_FIX_2026-04-25.md):记录 `npm run dev:rust` 在 Windows 冷编译/链接阶段误把 `api-server` `/healthz` 等待判定为超时并杀掉 `cargo run` 的根因,以及将 SpacetimeDB 与 api-server 等待窗口拆分的脚本口径。
|
||||
- [API_ERROR_DETAILS_MESSAGE_DISPLAY_FIX_2026-04-25.md](./API_ERROR_DETAILS_MESSAGE_DISPLAY_FIX_2026-04-25.md):记录统一 API envelope 错误展示优先读取 `error.details.message` 的修复口径,避免 Big Fish 发布校验等业务错误只显示通用“请求参数不合法”。
|
||||
- [BIG_FISH_DIRECTION_TOUCH_CONTROL_2026-04-24.md](./BIG_FISH_DIRECTION_TOUCH_CONTROL_2026-04-24.md):记录大鱼吃小鱼从固定摇杆改为屏幕首触点方向控制,并要求本地直达局在未操作时保持对象运动。
|
||||
- [RUST_WORKSPACE_DEFAULT_BUILD_SCOPE_FIX_2026-04-25.md](./RUST_WORKSPACE_DEFAULT_BUILD_SCOPE_FIX_2026-04-25.md):记录 `server-rs` 无参数 `cargo build` 链接 `spacetime-module` 失败的根因,并冻结默认只构建原生 `api-server`、模块产物继续走 `spacetime build` 的命令边界。
|
||||
@@ -70,7 +72,7 @@
|
||||
- [SPACETIMEDB_REFRESH_SESSION_TABLE_DESIGN_2026-04-21.md](./SPACETIMEDB_REFRESH_SESSION_TABLE_DESIGN_2026-04-21.md):`M2` 第三张会话表 `refresh_session` 的 cookie/hash 边界、轮换与吊销语义、索引与迁移规则。
|
||||
- [SPACETIMEDB_AUTH_IDENTITY_TABLE_DESIGN_2026-04-21.md](./SPACETIMEDB_AUTH_IDENTITY_TABLE_DESIGN_2026-04-21.md):`M2` 第二张身份表 `auth_identity` 的 provider 范围、唯一约束、手机号/微信身份写入规则与迁移策略。
|
||||
- [SPACETIMEDB_AUTH_USER_ACCOUNT_TABLE_DESIGN_2026-04-21.md](./SPACETIMEDB_AUTH_USER_ACCOUNT_TABLE_DESIGN_2026-04-21.md):`M2` 第一张身份主表 `user_account` 的职责边界、字段、唯一约束、状态迁移、旧 `users` 映射与落地约束。
|
||||
- [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md):基于当前 Node 后端能力清单,设计用 `SpacetimeDB + Axum + 阿里云 OSS` 重写后端的目标架构、模块映射、数据分层、迁移顺序与验收标准。
|
||||
- [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md):基于旧 Node 后端能力清单,设计用 `SpacetimeDB + Axum + 阿里云 OSS` 重写后端的目标架构、模块映射、数据分层、迁移顺序与验收标准。
|
||||
- [M6_OSS_SERVER_UPLOAD_AND_STS_POLICY_2026-04-21.md](./M6_OSS_SERVER_UPLOAD_AND_STS_POLICY_2026-04-21.md):冻结 M6 剩余的 STS 与服务端上传 helper 落地口径,明确当前上传主链为服务器上传 OSS,Web 端只负责签名读下载。
|
||||
- [M6_ASSET_METADATA_HASH_VERSION_AND_SPECIALIZED_TABLE_BOUNDARY_2026-04-22.md](./M6_ASSET_METADATA_HASH_VERSION_AND_SPECIALIZED_TABLE_BOUNDARY_2026-04-22.md):冻结 M6 第一批内容 hash、版本、manifest、asset job 与强业务资产表的 Stage 1 边界,明确当前使用 `asset_object + asset_entity_binding + OSS manifest + AiTaskService` 闭合,不重复新增表。
|
||||
- [M6_LEGACY_GENERATED_PATH_OSS_READ_COMPAT_2026-04-22.md](./M6_LEGACY_GENERATED_PATH_OSS_READ_COMPAT_2026-04-22.md):冻结 M6 旧 `/generated-*` 路径到 OSS 私有读同源代理的兼容口径,保证旧前端仍能直接消费图片、视频、动作帧与 manifest。
|
||||
@@ -93,13 +95,11 @@
|
||||
- [M6_CHARACTER_ANIMATION_IMPORT_AND_TEMPLATE_STAGE1_2026-04-22.md](./M6_CHARACTER_ANIMATION_IMPORT_AND_TEMPLATE_STAGE1_2026-04-22.md):冻结 `M6` 第一批角色动作模板查询与参考视频导入从旧 Node 本地草稿写盘切到 Rust `OSS` 草稿对象的接口 contract、对象键规划与暂不确认 `asset_object` 的边界。
|
||||
- [M6_CHARACTER_WORKFLOW_CACHE_OSS_STAGE1_2026-04-22.md](./M6_CHARACTER_WORKFLOW_CACHE_OSS_STAGE1_2026-04-22.md):冻结 `M6` 第一批角色资产工作流缓存从旧 Node 本地 `workflow-cache.json` 切到 Rust `OSS` JSON 草稿对象的读写 contract、字段归一化与暂不落正式资产表的边界。
|
||||
- [M6_CHARACTER_VISUAL_ASSET_OSS_INTEGRATION_STAGE1_2026-04-22.md](./M6_CHARACTER_VISUAL_ASSET_OSS_INTEGRATION_STAGE1_2026-04-22.md):冻结 `M6` 第一批角色主形象 `generate / jobs / publish` 接口从旧本地 `public/generated-*` 真相切到 `OSS + asset_object + asset_entity_binding + AI task` 的最小闭环与兼容 contract。
|
||||
- [M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md](./M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md):冻结 `M7` 联调、回归、部署、观测、双跑对比、灰度切流、回滚和 `spacetime-module` 结构收口的可执行方案。
|
||||
- [M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md](./M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md):冻结 `M7` 联调、回归、部署、观测、Rust 主线灰度、回滚和 `spacetime-module` 结构收口的可执行方案。
|
||||
- [M3_BROWSE_HISTORY_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md](./M3_BROWSE_HISTORY_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md):冻结 `M3` 第二批 `browse history` 纵向切片的 `user_browse_history` 表、双路径 facade、宽松归一化、去重排序规则与测试策略。
|
||||
- [ASSET_ENTITY_BINDING_REDUCER_DESIGN_2026-04-21.md](./ASSET_ENTITY_BINDING_REDUCER_DESIGN_2026-04-21.md):冻结已确认 `asset_object` 绑定到业务实体槽位的首版 reducer/procedure、通用 `asset_entity_binding` 表与 Axum facade。
|
||||
- [FRONTEND_TO_BACKEND_MIGRATION_EXECUTION_PLAN_2026-04-21.md](./FRONTEND_TO_BACKEND_MIGRATION_EXECUTION_PLAN_2026-04-21.md):把鉴权、浏览历史、runtime story 快照、NPC 待接委托与正式生成编排继续后移到 Express 后端的实施方案与验收口径。
|
||||
- [REPO_NOISE_CLEANUP_BASELINE_2026-04-19.md](./REPO_NOISE_CLEANUP_BASELINE_2026-04-19.md):落实工程清理审计第一阶段后的仓库噪音清理范围、忽略规则闭合点与后续约束。
|
||||
- [ENCODING_CHECK_TRANSIENT_WORKSPACE_FIX_2026-04-22.md](./ENCODING_CHECK_TRANSIENT_WORKSPACE_FIX_2026-04-22.md):冻结编码检查不扫描临时 Cargo / verify 工作区、同时把 Rust 源文件纳入 UTF-8 校验的修复口径。
|
||||
- [PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md](./PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md):后端提示词收口到 `server-node/src/prompts/` 的目录方案、兼容策略与后续新增规则。
|
||||
- [CUSTOM_WORLD_DRAFT_GENERATION_FAILURE_ANALYSIS_AND_FIX_2026-04-20.md](./CUSTOM_WORLD_DRAFT_GENERATION_FAILURE_ANALYSIS_AND_FIX_2026-04-20.md):世界草稿生成失败后等待页误显示为“卡在编译草稿卡”的根因拆解、主链与增强链路边界,以及本次修复策略。
|
||||
- [CUSTOM_WORLD_AUTO_ASSET_VISIBILITY_FIX_2026-04-20.md](./CUSTOM_WORLD_AUTO_ASSET_VISIBILITY_FIX_2026-04-20.md):世界草稿里“资产已生成但结果页看不到”的根因拆解,包含角色主形象展示、分幕背景露出和 fallback 资源格式修复。
|
||||
- [CUSTOM_WORLD_PHASE4_COUNT_SEMANTICS_ALIGNMENT_2026-04-20.md](./CUSTOM_WORLD_PHASE4_COUNT_SEMANTICS_ALIGNMENT_2026-04-20.md):Phase4 新增角色/地点后草稿作品卡数量统计与测试断言的语义对齐说明。
|
||||
@@ -149,13 +149,6 @@
|
||||
- [CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md#93-工作包-c前端结果页与编辑器拆分](./CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md#93-%E5%B7%A5%E4%BD%9C%E5%8C%85-c%E5%89%8D%E7%AB%AF%E7%BB%93%E6%9E%9C%E9%A1%B5%E4%B8%8E%E7%BC%96%E8%BE%91%E5%99%A8%E6%8B%86%E5%88%86):记录工作包 C 已完成的结果页壳层拆分、编辑器目标分发与 mapper 收口、角色资产工坊 section/workflow 拆分,以及仍保留的阶段性 shared 实现边界。
|
||||
- [CREATION_PAGE_MOBILE_UI_FIX_2026-04-21.md](./CREATION_PAGE_MOBILE_UI_FIX_2026-04-21.md):创作页移动端底部 Tab、亮色主题 token 与滚动权责修复记录。
|
||||
- [TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md](./TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md):把外部仓库 TXT 模式完整迁入当前项目的冻结边界、模块映射、分阶段计划与验收清单。
|
||||
- [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md):由 `server-node/src/manifest/backendCapabilityManifest.ts` 生成的 Node 后端模块职责、挂载面与接口索引,后续新增模块/接口时同步更新这一份。
|
||||
- [NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md](./NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md):当前 Node 运行时后端的技术栈、入口、鉴权、存储与接口知识图谱。
|
||||
- [EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md](./EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md):Express 后端当前 contract 冻结版本、热点文件编辑规则与集成窗口清单。
|
||||
- [EXPRESS_BACKEND_WORKSTREAM_AUDIT_2026-04-09.md](./EXPRESS_BACKEND_WORKSTREAM_AUDIT_2026-04-09.md):按并行工作流文档逐项核对后的完成度审计与剩余收口点。
|
||||
- [EDITOR_ASSET_API_MIGRATION_2026-04-08.md](./EDITOR_ASSET_API_MIGRATION_2026-04-08.md):编辑器写盘、资产生成、任务查询从 Vite 本地插件迁到 Node 后端的接口与工具链清单。
|
||||
- [GO_SERVER_RUNTIME_INTEGRATION_2026-04-07.md](./GO_SERVER_RUNTIME_INTEGRATION_2026-04-07.md):Go 服务端接入、运行时持久化迁移与当前进展记录。
|
||||
- [GO_SERVER_TASKLIST_2026-04-08.md](./GO_SERVER_TASKLIST_2026-04-08.md):Go 服务端已完成与未完成事项的执行清单。
|
||||
- [AI_CHARACTER_ANIMATION_TECHNICAL_SOLUTION_2026-04-04.md](./AI_CHARACTER_ANIMATION_TECHNICAL_SOLUTION_2026-04-04.md):AI 生成角色形象与角色动画的技术路线。
|
||||
- [ALIYUN_NPC_IMAGE_ANIMATION_EXPERIMENT_2026-04-07.md](./ALIYUN_NPC_IMAGE_ANIMATION_EXPERIMENT_2026-04-07.md):面向编辑器的阿里云 NPC 形象与动作实验方案,按 4 条生成链路对比。
|
||||
- [PIXELMOTION_TECHNICAL_BREAKDOWN_2026-04-04.md](./PIXELMOTION_TECHNICAL_BREAKDOWN_2026-04-04.md):PixelMotion 产品形态与能力拆解。
|
||||
@@ -164,6 +157,5 @@
|
||||
## 使用建议
|
||||
|
||||
- 做实现选型时,优先看这一组。
|
||||
- 做后端实现前,先看 `CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`,再进入具体 Rust / SpacetimeDB 方案。
|
||||
- 做阶段排期时,把这一组和 `docs/planning/`、`docs/prd/` 一起看,更容易判断先后顺序。
|
||||
|
||||
|
||||
|
||||
@@ -44,8 +44,7 @@
|
||||
2. `docs/design/SCENE_CHAPTER_LOOP_AND_FIRST_ENTRY_CHAPTER_QUEST_DESIGN_2026-04-08.md`
|
||||
3. `docs/experience/CURRENT_GAME_FULL_FLOW_PLAYTEST_REPORT_2026-04-07.md`
|
||||
4. `docs/technical/RUNTIME_STORY_BACKEND_BOUNDARY_MIGRATION_2026-04-19.md`
|
||||
5. `docs/technical/FRONTEND_TO_BACKEND_MIGRATION_EXECUTION_PLAN_2026-04-21.md`
|
||||
6. `docs/technical/NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md`
|
||||
5. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
|
||||
### 1.3 本文刻意不覆盖的链路
|
||||
|
||||
|
||||
56
docs/technical/RUNTIME_NPC_CHAT_LLM_MIGRATION_2026-04-25.md
Normal file
56
docs/technical/RUNTIME_NPC_CHAT_LLM_MIGRATION_2026-04-25.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Runtime NPC 聊天 LLM 迁移设计(2026-04-25)
|
||||
|
||||
## 背景
|
||||
|
||||
当前 `server-rs/crates/api-server/src/runtime_chat.rs` 已承接 `POST /api/runtime/chat/npc/turn/stream`,但只返回确定性兜底文本。实际游戏聊天里,NPC 回复、下一轮建议、好感变化和限轮收束都应该沿用旧 Node 服务器的 LLM 编排。
|
||||
|
||||
## 迁移源
|
||||
|
||||
本轮只参考旧 Node 已冻结实现,不恢复 `server-node` 服务,也不把前端切回 Express:
|
||||
|
||||
1. `server-node/src/prompts/chatPromptBuilders.ts`
|
||||
2. `server-node/src/modules/ai/chatOrchestrator.ts`
|
||||
3. `server-node/src/services/chatService.ts`
|
||||
4. `packages/shared/src/contracts/rpgRuntimeChat.ts`
|
||||
|
||||
提示词常量必须原样迁移,禁止改写:
|
||||
|
||||
1. `NPC_CHAT_TURN_REPLY_SYSTEM_PROMPT`
|
||||
2. `NPC_CHAT_TURN_SUGGESTION_SYSTEM_PROMPT`
|
||||
|
||||
## 本轮落地边界
|
||||
|
||||
1. Rust `api-server` 在同一路由内优先调用 `platform-llm`。
|
||||
2. LLM 回复使用旧 Node 的 `buildNpcChatTurnReplyPrompt(...)` 等价构造逻辑,保持输入字段和中文上下文组织一致。
|
||||
3. LLM 建议使用旧 Node 的 `buildNpcChatTurnSuggestionPrompt(...)` 等价构造逻辑,解析规则保持“最多 3 行、去掉编号/项目符号”。
|
||||
4. 好感变化沿用旧 Node 的关键词打分规则:
|
||||
- 正向与负向关键词计分。
|
||||
- 首聊无明显关键词时给 `+1`。
|
||||
- 单轮变化限制在 `[-3, 3]`。
|
||||
5. `chatDirective.forceExitAfterTurn / closingMode=foreshadow_close` 时不生成建议,返回空数组,并在 `complete.chatDirective.forceExit` 中显式告知前端退出。
|
||||
6. LLM 未配置或失败时继续返回后端兜底 SSE,保证相遇和点击聊天链路不断。
|
||||
|
||||
## 暂不落地
|
||||
|
||||
1. 暂不迁移 `maybeBuildPendingNpcQuestOffer(...)` 的完整 quest 生成链。
|
||||
2. 暂不新增 SpacetimeDB reducer;本路由属于 Axum 侧 LLM 编排,SpacetimeDB reducer 仍保持确定性。
|
||||
3. 暂不扩展前端 UI 文案。
|
||||
|
||||
## 工程落点
|
||||
|
||||
1. 新增 `server-rs/crates/api-server/src/runtime_chat_prompt.rs`
|
||||
- 承载旧 Node 提示词常量。
|
||||
- 承载 NPC 聊天 prompt builder 与轻量 JSON 读取 helper。
|
||||
2. 修改 `server-rs/crates/api-server/src/runtime_chat.rs`
|
||||
- 注入 `State<AppState>`。
|
||||
- 优先 `LlmClient.stream_text(...)` 生成 `reply_delta`。
|
||||
- 再调用 `request_text(...)` 生成建议。
|
||||
- 计算 `affinityDelta / affinityText / chatDirective` 后输出 `complete`。
|
||||
3. 修改 `server-rs/crates/api-server/src/main.rs`
|
||||
- 注册 `runtime_chat_prompt` 模块。
|
||||
|
||||
## 验收
|
||||
|
||||
1. `cargo fmt -p api-server`
|
||||
2. `cargo check -p api-server`
|
||||
3. `node scripts/check-encoding.mjs docs/technical/RUNTIME_NPC_CHAT_LLM_MIGRATION_2026-04-25.md server-rs/crates/api-server/src/runtime_chat.rs server-rs/crates/api-server/src/runtime_chat_prompt.rs server-rs/crates/api-server/src/main.rs`
|
||||
@@ -163,6 +163,6 @@
|
||||
## 4. 维护规则
|
||||
|
||||
1. 新增、删除或改名 Rust 路由时,必须同步更新本索引。
|
||||
2. 如果 Node 后端 `NODE_BACKEND_MODULE_AND_API_INDEX.md` 的现役能力面发生变化,必须同时更新本索引与对应阶段任务清单。
|
||||
2. 如果 Rust 后端公开能力面发生变化,必须同时更新本索引、当前后端实现基线与对应阶段任务清单。
|
||||
3. 任何 breaking route change 都必须先更新阶段设计文档,再改代码。
|
||||
4. 真实切流前,必须用本索引对照代理层、前端调用面和 smoke 清单,避免只完成编译而遗漏外部可访问路径。
|
||||
|
||||
@@ -38,7 +38,7 @@ npm run dev:rust
|
||||
5. 执行 `spacetime --root-dir=server-rs/.spacetimedb/local publish <本地数据库名> --server http://127.0.0.1:3101 --module-path server-rs/crates/spacetime-module -c=on-conflict --yes`,确保 publish 的签名身份与 standalone 的本地控制库一致,并在当前开发阶段允许新版模块表结构变化且发生 schema 冲突时清除旧模块数据。
|
||||
6. 注入 `GENARRATIVE_API_*` 与 `GENARRATIVE_SPACETIME_*` 后启动 `cargo run -p api-server`;直接运行 `api-server` 时,如未显式设置 `GENARRATIVE_SPACETIME_DATABASE`,服务端也会向上查找 `spacetime.local.json` 作为本地默认库名。
|
||||
7. 等待 `http://127.0.0.1:<api-port>/healthz` 返回 HTTP 响应后再启动 Vite,避免前端初始化请求早于 Rust `api-server` 监听完成并在终端刷出 `ECONNREFUSED 127.0.0.1:<api-port>`。
|
||||
8. 注入 `GENARRATIVE_BACKEND_STACK=rust`、`RUST_SERVER_TARGET`、`GENARRATIVE_RUNTIME_SERVER_TARGET` 后启动 Vite。
|
||||
8. 注入 `RUST_SERVER_TARGET`、`GENARRATIVE_RUNTIME_SERVER_TARGET` 后启动 Vite。
|
||||
9. 任一子进程退出时,脚本回收其余子进程。
|
||||
|
||||
Vite 代理覆盖范围:
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
### 3.1 启动前强制 publish
|
||||
|
||||
`scripts/dev-node.mjs` 在拉起 Rust `api-server` 前,必须先执行:
|
||||
`scripts/dev-rust-stack.sh` 在拉起 Rust `api-server` 前,必须先执行:
|
||||
|
||||
```bash
|
||||
spacetime publish xushi-p4wfr --server http://127.0.0.1:3101 --module-path D:\Genarrative\server-rs\crates\spacetime-module --yes
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
关联现状:
|
||||
|
||||
- [EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md](./EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md)
|
||||
- [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)
|
||||
- [AUTH_LOGIN_OPTIONS_DESIGN_2026-04-21.md](./AUTH_LOGIN_OPTIONS_DESIGN_2026-04-21.md)
|
||||
- [AUTH_ME_QUERY_DESIGN_2026-04-21.md](./AUTH_ME_QUERY_DESIGN_2026-04-21.md)
|
||||
- [AUTH_SESSIONS_QUERY_DESIGN_2026-04-21.md](./AUTH_SESSIONS_QUERY_DESIGN_2026-04-21.md)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
- 浏览器直连会遇到 CORS
|
||||
- 更稳的方案是开发服务器代理,再由前端请求 `/api/llm/...`
|
||||
|
||||
[docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md](/E:/Repos/Genarrative/docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md) 也明确指出:
|
||||
工程审计聚合结论也明确指出:
|
||||
|
||||
- 编辑器、运行时、类后端能力全部耦合在 Vite 配置里
|
||||
- 未来如果做独立部署、多人协作、远程编辑、权限控制,会非常难迁移
|
||||
|
||||
@@ -171,5 +171,5 @@
|
||||
|
||||
1. [SPACETIMEDB_ASSET_OBJECT_STORAGE_DESIGN_2026-04-21.md](./SPACETIMEDB_ASSET_OBJECT_STORAGE_DESIGN_2026-04-21.md)
|
||||
2. [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md)
|
||||
3. [../../../server-rs/crates/module-assets/README.md](../../../server-rs/crates/module-assets/README.md)
|
||||
4. [../../../server-rs/crates/spacetime-module/README.md](../../../server-rs/crates/spacetime-module/README.md)
|
||||
3. [../../server-rs/crates/module-assets/README.md](../../server-rs/crates/module-assets/README.md)
|
||||
4. [../../server-rs/crates/spacetime-module/README.md](../../server-rs/crates/spacetime-module/README.md)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
## 2. 当前工程必须继承的能力基线
|
||||
|
||||
以 `docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md` 当前生成结果为准,现有 Node 后端的能力基线是:
|
||||
以下能力清单来自 `2026-04-20` 迁移设计时对旧 Node 后端的快照整理,只作为迁移参考,不再作为新功能扩展依据。后续实现方向以 `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md` 为准。
|
||||
|
||||
- 对外挂载面:`6` 个
|
||||
- 已登记路由:`96` 条
|
||||
@@ -228,10 +228,10 @@ SpacetimeDB 官方文档对自动迁移的限制很强:
|
||||
|
||||
从当前版本开始,凡是涉及 `SpacetimeDB` 的设计、实现、脚本、调试与前端接入,统一要求显式使用以下 skill 作为执行依据:
|
||||
|
||||
1. [$spacetimedb-cli](.codex\\skills\\spacetimedb-cli\\SKILL.md)
|
||||
2. [$spacetimedb-rust](.codex\\skills\\spacetimedb-rust\\SKILL.md)
|
||||
3. [$spacetimedb-concepts](.codex\\skills\\spacetimedb-concepts\\SKILL.md)
|
||||
4. [$spacetimedb-typescript](.codex\\skills\\spacetimedb-typescript\\SKILL.md)
|
||||
1. [$spacetimedb-cli](../../.codex/skills/spacetimedb-cli/SKILL.md)
|
||||
2. [$spacetimedb-rust](../../.codex/skills/spacetimedb-rust/SKILL.md)
|
||||
3. [$spacetimedb-concepts](../../.codex/skills/spacetimedb-concepts/SKILL.md)
|
||||
4. [$spacetimedb-typescript](../../.codex/skills/spacetimedb-typescript/SKILL.md)
|
||||
|
||||
执行要求:
|
||||
|
||||
@@ -895,8 +895,8 @@ SpacetimeDB 自动迁移更适合“增量追加”,不适合高频改列结
|
||||
5. `server-node/src/modules/story/storyActionRoutes.ts`
|
||||
6. `server-node/src/repositories/runtimeRepository.ts`
|
||||
7. `server-node/src/services/customWorldAgentOrchestrator.ts`
|
||||
8. `docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md`
|
||||
9. `docs/technical/NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md`
|
||||
8. 本文第 2 节保留的旧 Node 能力快照
|
||||
9. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
|
||||
|
||||
## 17. 外部技术依据
|
||||
|
||||
|
||||
@@ -872,9 +872,9 @@ TXT 模式不得直接改坏当前 `runtime story` 主链。
|
||||
|
||||
## 10.3 与 prompt 管理规范兼容
|
||||
|
||||
必须遵守 [PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md](./PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md) 中已冻结的规则:
|
||||
必须遵守当前 Rust 后端提示词迁移口径:
|
||||
|
||||
1. prompt 主源收口到 `server-node/src/prompts/`
|
||||
1. prompt 主源收口到 `server-rs` 对应生成与编排模块
|
||||
2. 业务模块只装配上下文
|
||||
3. 兼容层按需保留,但不新增业务内联 prompt
|
||||
|
||||
|
||||
Reference in New Issue
Block a user