1
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
重点补充:RPG 创作与运行时脚本职责地图见 [RPG_CREATION_AND_RUNTIME_SCRIPT_RESPONSIBILITY_MAP_2026-04-28.md](./reference/RPG_CREATION_AND_RUNTIME_SCRIPT_RESPONSIBILITY_MAP_2026-04-28.md)。
|
||||
- [埋点查询](./tracking/README.md):埋点原始事件与聚合投影的本地 SQL 查询。
|
||||
- [运营查询](./operations/README.md):任务、领奖、钱包对账等后台核查查询。
|
||||
- [PRD](./prd):产品需求与阶段计划;后台管理独立前端工程见 [ADMIN_WEB_CONSOLE_PRD_2026-04-30.md](./prd/ADMIN_WEB_CONSOLE_PRD_2026-04-30.md),新增 RPG 开场动画方案见 [AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md](./prd/AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md),新增抓大鹅 Match3D 玩法方案见 [AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md](./prd/AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md),方洞挑战创作、发布与试玩闭环见 [AI_NATIVE_SQUARE_HOLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-04.md](./prd/AI_NATIVE_SQUARE_HOLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-04.md)。
|
||||
- [PRD](./prd/README.md):产品需求与阶段计划;参考 MOKU / 幕间类 AI 文游的百梦 `text-game` 模板口径见 [AI_NATIVE_TEXT_GAME_TEMPLATE_MOKU_REFERENCE_PRD_2026-05-05.md](./prd/AI_NATIVE_TEXT_GAME_TEMPLATE_MOKU_REFERENCE_PRD_2026-05-05.md),视觉小说模板 TXT 玩法平台化接入口径见 [AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md](./prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md),创意互动内容 Agent Phase 1 的 LangChain-Rust PoC、拼图闭环和并行任务拆分见 [CREATIVE_INTERACTIVE_AGENT_PHASE1_LANGCHAIN_RUST_PUZZLE_LOOP_PRD_2026-05-05.md](./prd/CREATIVE_INTERACTIVE_AGENT_PHASE1_LANGCHAIN_RUST_PUZZLE_LOOP_PRD_2026-05-05.md),幸存者类模板闭环见 [AI_NATIVE_SURVIVOR_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-05.md](./prd/AI_NATIVE_SURVIVOR_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-05.md),后台管理独立前端工程见 [ADMIN_WEB_CONSOLE_PRD_2026-04-30.md](./prd/ADMIN_WEB_CONSOLE_PRD_2026-04-30.md),新增 RPG 开场动画方案见 [AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md](./prd/AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md),新增抓大鹅 Match3D 玩法方案见 [AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md](./prd/AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md),方洞挑战创作、发布与试玩闭环见 [AI_NATIVE_SQUARE_HOLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-04.md](./prd/AI_NATIVE_SQUARE_HOLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-04.md)。
|
||||
|
||||
生产部署切换到 systemd + Nginx + SpacetimeDB 自托管的总方案见 [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./technical/PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md),该文档也是当前生产 Jenkinsfile 的唯一入口。SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段迁移流程见 [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md);private 表迁移 JSON 导入导出、HTTP 413 分片导入和旧数据库迁移流水线经验见 [SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md](./technical/SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md) 与 [JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md](./technical/JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md);后台管理独立前端工程技术方案见 [ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md](./technical/ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md)。
|
||||
|
||||
@@ -23,6 +23,14 @@ SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段
|
||||
|
||||
`maincloud` 相关脚本、环境变量、测试名和文档要求已统一判定为历史残留,后续禁止新增、运行或引用;当前后端 smoke 使用 `npm run api-server` 与 `/healthz`,详细规则见 [MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md](./technical/MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md)。
|
||||
|
||||
基于 LangChain-Rust,以“感知—思考—记忆—行动—反思—协作”闭环完成图文创意理解、拼图模板选择、积分范围确认、拼图草稿字段填充、立即试玩和自然语言修订草稿字段的 Agent 方案见 [CREATIVE_INTERACTIVE_CONTENT_AGENT_TECHNICAL_SOLUTION_2026-05-05.md](./technical/CREATIVE_INTERACTIVE_CONTENT_AGENT_TECHNICAL_SOLUTION_2026-05-05.md)。
|
||||
|
||||
创意互动内容 Agent Phase 1 的产品边界、实现细节、SpacetimeDB 落点、前端接入和可并行任务拆分见 [CREATIVE_INTERACTIVE_AGENT_PHASE1_LANGCHAIN_RUST_PUZZLE_LOOP_PRD_2026-05-05.md](./prd/CREATIVE_INTERACTIVE_AGENT_PHASE1_LANGCHAIN_RUST_PUZZLE_LOOP_PRD_2026-05-05.md)。
|
||||
|
||||
视觉小说模板接入以 [AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md](./prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md) 为最新口径:只吸收外部 TXT 玩法的模板创作与运行经验,禁止迁入外部平台功能,并删除回放。
|
||||
|
||||
AI 文字游戏模板接入以 [AI_NATIVE_TEXT_GAME_TEMPLATE_MOKU_REFERENCE_PRD_2026-05-05.md](./prd/AI_NATIVE_TEXT_GAME_TEMPLATE_MOKU_REFERENCE_PRD_2026-05-05.md) 为最新口径:只吸收 MOKU / 幕间类 AI 文游的剧本游乐场、自由行动、AI GM、记忆和模拟器强反馈经验,禁止迁入外部社区、支付、榜单、私有存档或回放。
|
||||
|
||||
## 推荐阅读顺序
|
||||
|
||||
1. 先看 [经验沉淀](./experience/README.md),快速建立这个项目的开发共识。
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
- [CHARACTER_ASSET_PROMPT_CHAIN_AUDIT_2026-04-20.md](./CHARACTER_ASSET_PROMPT_CHAIN_AUDIT_2026-04-20.md):角色资产默认描述文本、正式图像/动作 prompt、共享模板与保留接口的分层与冗余审计。
|
||||
- [RPG_RUNTIME_DIRECT_DRAFT_PROFILE_AUDIT_2026-04-25.md](./RPG_RUNTIME_DIRECT_DRAFT_PROFILE_AUDIT_2026-04-25.md):RPG 运行时进入世界时改为直读 Agent session 草稿 profile 的链路检查。
|
||||
- [RPG_WORLD_DRAFT_EDIT_AUTOSAVE_OVERRIDE_AUDIT_2026-04-28.md](./RPG_WORLD_DRAFT_EDIT_AUTOSAVE_OVERRIDE_AUDIT_2026-04-28.md):RPG 世界草稿结果页编辑后被旧设定覆盖的前端本地态、session 真相源与自动保存链路审计。
|
||||
- [VN11_NEGATIVE_SCAN_REPORT_2026-05-07.md](./VN11_NEGATIVE_SCAN_REPORT_2026-05-07.md):视觉小说 VN-11 回放删除与外部平台功能误入负向扫描报告。
|
||||
- [VN12_FULL_CHAIN_ACCEPTANCE_REPORT_2026-05-07.md](./VN12_FULL_CHAIN_ACCEPTANCE_REPORT_2026-05-07.md):视觉小说 VN-12 全链路联调与自动化验收报告。
|
||||
- [engineering/RPG_FRONTEND_SCRIPT_BACKEND_MIGRATION_AUDIT_2026-04-28.md](./engineering/RPG_FRONTEND_SCRIPT_BACKEND_MIGRATION_AUDIT_2026-04-28.md):RPG 前端脚本中仍应迁到 `server-rs` / SpacetimeDB 的开局、快照、story engine、战斗、NPC/背包规则与创作残留后门审计。
|
||||
- [engineering/RPG_FRONTEND_SCRIPT_BACKEND_MIGRATION_COMPLETION_CHECK_2026-04-28.md](./engineering/RPG_FRONTEND_SCRIPT_BACKEND_MIGRATION_COMPLETION_CHECK_2026-04-28.md):RPG 前端脚本后端迁移完成度复核,标明开局、快照、story engine / prompt context、`camp_travel_home_scene`、战斗、NPC、背包/锻造、结果页保存 normalize 与角色资产 prompt 主链均已收口。
|
||||
- [engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md](./engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md):对 `2026-04-19` 工程清理审计的当前仓库复核,区分已完成项、仍存边界问题和新的热点迁移。
|
||||
|
||||
32
docs/audits/VN11_NEGATIVE_SCAN_REPORT_2026-05-07.md
Normal file
32
docs/audits/VN11_NEGATIVE_SCAN_REPORT_2026-05-07.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# VN-11 负向扫描报告
|
||||
|
||||
生成日期:2026-05-07
|
||||
|
||||
## 扫描范围
|
||||
|
||||
- 工程代码:`src/`、`packages/shared/src/`、`server-rs/crates/`
|
||||
- 文档与共享记忆:`docs/`、`.hermes/shared-memory/`
|
||||
- 外部平台误入复核:视觉小说前端、service、shared contracts、Rust contracts、module、api-server、SpacetimeDB schema 与 facade 路径
|
||||
|
||||
## 扫描结论
|
||||
|
||||
- 工程代码回放类直出命中:0
|
||||
- 文档 / 共享记忆回放类命中:222
|
||||
- 视觉小说实现路径外部平台能力疑似误入命中:0
|
||||
|
||||
## 处理记录
|
||||
|
||||
- 已将 `storyEngine` 回归工具的命名从 replay 语义收口为 rerun / 复测语义。
|
||||
- 已将技能效果预览按钮的内部状态与文案从重播语义收口为重新预览语义。
|
||||
- 已确认视觉小说工程路径未新增回放路由、DTO、表、按钮、文案、外部平台账号 / 订单 / 会员 / 促销 / 后台 / 公开市场或私有存档能力。
|
||||
|
||||
## 文档命中说明
|
||||
|
||||
- 文档命中来自历史旧文档、设计复盘、禁止语境、负向验收或本报告记录。VN-11 工程门禁只阻断代码路径新增能力。
|
||||
|
||||
## 门禁命令
|
||||
|
||||
```bash
|
||||
npm run check:visual-novel-vn11
|
||||
```
|
||||
|
||||
92
docs/audits/VN12_FULL_CHAIN_ACCEPTANCE_REPORT_2026-05-07.md
Normal file
92
docs/audits/VN12_FULL_CHAIN_ACCEPTANCE_REPORT_2026-05-07.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# VN-12 全链路联调与自动化验收报告
|
||||
|
||||
生成日期:2026-05-07
|
||||
|
||||
## 结论
|
||||
|
||||
- 状态:通过
|
||||
- 失败项:0
|
||||
- 收口说明:VN-12 本次只补验收门禁、关键路径测试和报告记录,未扩展新玩法功能。
|
||||
|
||||
## 自动化验收清单
|
||||
|
||||
- docs/prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md
|
||||
- docs/audits/VN11_NEGATIVE_SCAN_REPORT_2026-05-07.md
|
||||
- src/components/visual-novel-creation/VisualNovelAgentWorkspace.test.tsx
|
||||
- src/components/visual-novel-result/VisualNovelResultView.test.tsx
|
||||
- src/components/visual-novel-runtime/VisualNovelRuntimeShell.test.tsx
|
||||
- src/services/visual-novel-runtime/visualNovelRuntimeClient.test.ts
|
||||
- src/services/visual-novel-runtime/visualNovelRuntimeSse.test.ts
|
||||
- server-rs/crates/api-server/src/visual_novel.rs
|
||||
- server-rs/crates/module-visual-novel/src/application.rs
|
||||
- server-rs/crates/shared-contracts/src/visual_novel.rs
|
||||
- package.json
|
||||
- server-rs/crates/api-server/src/app.rs
|
||||
- src/services/visual-novel-runtime/visualNovelRuntimeClient.ts
|
||||
- src/services/visual-novel-runtime/visualNovelRuntimeClient.test.ts
|
||||
- src/services/visual-novel-runtime/visualNovelRuntimeSse.test.ts
|
||||
- src/components/visual-novel-creation/VisualNovelAgentWorkspace.test.tsx
|
||||
- src/components/visual-novel-result/VisualNovelResultView.test.tsx
|
||||
- src/components/visual-novel-runtime/VisualNovelRuntimeShell.test.tsx
|
||||
|
||||
## API smoke
|
||||
|
||||
- `/api/creation/visual-novel/sessions`
|
||||
- `/api/creation/visual-novel/works`
|
||||
- `/api/runtime/visual-novel/gallery`
|
||||
- `/api/runtime/visual-novel/works/{profile_id}/runs`
|
||||
- `/api/runtime/visual-novel/runs/{run_id}/actions/stream`
|
||||
- `/api/runtime/visual-novel/runs/{run_id}/history`
|
||||
- `/api/runtime/visual-novel/runs/{run_id}/regenerate`
|
||||
- `/api/profile/save-archives`
|
||||
- `/api/profile/save-archives/{world_key}`
|
||||
- `/api/runtime/save/snapshot`
|
||||
|
||||
本次实测:
|
||||
|
||||
- `npm run api-server` 可启动 Rust `api-server`。
|
||||
- `GET http://127.0.0.1:3100/healthz` 返回 `200`,响应为 `{"ok":true,"service":"genarrative-api-server"}`。
|
||||
- `GET /api/runtime/visual-novel/gallery` 在当前本地环境返回超时 / `502`,日志显示 `api-server` 连接 `127.0.0.1:3101` SpacetimeDB 数据库 `xushi-p4wfr` 被拒绝;该项按本地 SpacetimeDB 未完整就绪记录为环境阻塞,不新增工程实现。
|
||||
|
||||
## 前端关键路径
|
||||
|
||||
- 创作工作台:`VisualNovelAgentWorkspace`
|
||||
- 结果页:`VisualNovelResultView`
|
||||
- 运行时:`VisualNovelRuntimeShell`
|
||||
- 运行时 SSE:`visualNovelRuntimeSse` / `visualNovelRuntimeClient`
|
||||
|
||||
## 桌面 / 移动端检查
|
||||
|
||||
- 桌面端:已用 Edge headless 截取 `/creation/visual-novel/agent`,文件为 `docs/audits/VN12_VISUAL_NOVEL_DESKTOP_2026-05-07.png`。
|
||||
- 移动端:已用 Edge headless 截取 `/creation/visual-novel/agent`,文件为 `docs/audits/VN12_VISUAL_NOVEL_MOBILE_2026-05-07.png`。
|
||||
- in-app browser 插件本次未发现可用 IAB backend,截图使用本机 Edge headless 兜底完成。
|
||||
|
||||
## 校验摘要
|
||||
|
||||
- package.json scripts: 通过
|
||||
- api-server visual novel routes: 通过
|
||||
- visual novel runtime client routes: 通过
|
||||
- visual novel runtime client tests: 通过
|
||||
- visual novel SSE tests: 通过
|
||||
- visual novel creation tests: 通过
|
||||
- visual novel result tests: 通过
|
||||
- visual novel runtime tests: 通过
|
||||
|
||||
## 执行命令
|
||||
|
||||
```bash
|
||||
npm run check:visual-novel-vn12 -- --write-report
|
||||
npm run test -- src/components/visual-novel-creation/VisualNovelAgentWorkspace.test.tsx src/components/visual-novel-result/VisualNovelResultView.test.tsx src/components/visual-novel-runtime/VisualNovelRuntimeShell.test.tsx src/services/visual-novel-runtime/visualNovelRuntimeClient.test.ts src/services/visual-novel-runtime/visualNovelRuntimeSse.test.ts
|
||||
npm run check:encoding
|
||||
npm run typecheck
|
||||
cd server-rs
|
||||
cargo test -p shared-contracts
|
||||
cargo test -p module-visual-novel
|
||||
cargo check -p api-server
|
||||
```
|
||||
|
||||
## 未覆盖风险
|
||||
|
||||
- 当前本地 SpacetimeDB 连接未完整就绪,公开 gallery API 的真实数据返回未在本次环境完成;`/healthz` 与编译 / 单测已通过。
|
||||
- 若接口路由或测试名称后续调整,需要同步更新本门禁脚本与报告模板。
|
||||
|
||||
BIN
docs/audits/VN12_VISUAL_NOVEL_DESKTOP_2026-05-07.png
Normal file
BIN
docs/audits/VN12_VISUAL_NOVEL_DESKTOP_2026-05-07.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 160 KiB |
BIN
docs/audits/VN12_VISUAL_NOVEL_MOBILE_2026-05-07.png
Normal file
BIN
docs/audits/VN12_VISUAL_NOVEL_MOBILE_2026-05-07.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
@@ -28,3 +28,12 @@
|
||||
- 锁定的模板卡统一以“敬请期待”作为状态标注,不再显示“锁定”。
|
||||
- RPG 入口展示为“角色扮演 / 剧情演绎,冒险成长”,拼图入口展示为“拼图 / 创意礼物,生活分享”。
|
||||
- 忙碌状态仅保留在模块标题行的轻量状态中,避免占用每张可用卡片的首要视觉层级。
|
||||
|
||||
## 2026-05-07 玩法参考图
|
||||
|
||||
1. 每个玩法入口都必须配置一张 `public/creation-type-references/` 下的参考图。
|
||||
2. 当前创作 Tab 顶部玩法卡带、旧创作中心卡带和玩法类型弹层都消费同一份 `PLATFORM_CREATION_TYPES.imageSrc`,避免多入口视觉漂移。
|
||||
3. 图片只承担玩法识别和氛围锚定,不在卡片上叠加规则说明文案。
|
||||
4. 移动端卡片仍以紧凑横滑为主,参考图使用暗色遮罩承接标题,文本不得溢出卡片。
|
||||
5. 当前创作 Tab 的可见玩法卡必须真实渲染 `img`,不能只在隐藏弹窗或旧入口中配置图片。
|
||||
6. 参考图卡片上的标题和副标题必须显式使用白色文字,并配合底部加深渐变与文字阴影;禁止依赖 `text-inherit`,避免黑字叠在暗蒙版上。
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
- 新增“分类” Tab,用作品标签聚合所有公开发布作品。
|
||||
- 强化“创作” Tab 的导航视觉权重,让它在底部导航中居中并更醒目。
|
||||
- 登录态底部导航顺序为:首页、分类、创作、存档、我的。
|
||||
- 未登录态底部导航只保留:首页、创作、分类,其中创作保持居中。
|
||||
- 登录态底部导航顺序为:推荐、发现、创作、草稿、我的。
|
||||
- 未登录态底部导航只保留:推荐、创作、发现,其中创作保持居中。
|
||||
|
||||
## 2. 数据边界
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
底部导航展示 5 个入口:
|
||||
|
||||
1. 首页
|
||||
2. 分类
|
||||
1. 推荐
|
||||
2. 发现
|
||||
3. 创作
|
||||
4. 存档
|
||||
4. 草稿
|
||||
5. 我的
|
||||
|
||||
创作入口位于第三位,视觉上使用更大的图标壳、轻微上浮、渐变高亮和阴影,保证它是主行动入口。
|
||||
@@ -36,11 +36,11 @@
|
||||
|
||||
底部导航展示 3 个入口:
|
||||
|
||||
1. 首页
|
||||
1. 推荐
|
||||
2. 创作
|
||||
3. 分类
|
||||
3. 发现
|
||||
|
||||
不展示“存档”和“我的”,避免未登录用户在底部导航看到必须登录后才有价值的入口。创作入口位于第二位,保持几何居中。
|
||||
不展示“草稿”和“我的”,避免未登录用户在底部导航看到必须登录后才有价值的入口。创作入口位于第二位,保持几何居中,并沿用原推荐 Tab 的星光图标;推荐 Tab 改用游戏手柄图标。
|
||||
|
||||
### 3.3 桌面端
|
||||
|
||||
@@ -59,6 +59,6 @@
|
||||
|
||||
- 登录态移动端底部导航顺序准确,创作在 5 个 Tab 中居中。
|
||||
- 未登录态移动端底部导航只显示 3 个 Tab,创作在中间。
|
||||
- 分类 Tab 能按标签切换并展示公开作品。
|
||||
- 发现 Tab 能按标签切换并展示公开作品。
|
||||
- 创作 Tab 在移动端和桌面端都比普通 Tab 更醒目。
|
||||
- 不修改 server-node,不新增后端逻辑。
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# 平台创作 Tab 模板入口设计
|
||||
|
||||
更新时间:`2026-05-07`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
创作 Tab 恢复为模板选择入口,但不回到旧的大卡片选择面板:
|
||||
|
||||
1. 首屏保留现有创作页布局骨架,顶部标题固定为“10分钟创作一个精品互动玩法”。
|
||||
2. 选择模板入口改为横向 Tab,数据来自 `src/config/newWorkEntryConfig.ts` 的可见玩法配置。
|
||||
3. 默认选中“拼图”模板,并在创作 Tab 内直接展示拼图创作表单。
|
||||
4. 智能创作入口从可见模板中隐藏,保留既有 `creative-agent` 运行链路用于后续内部恢复或草稿目标打开。
|
||||
5. 草稿、发现、我的等一级 Tab 职责不变,作品管理仍在草稿 Tab。
|
||||
|
||||
## 2. 页面结构
|
||||
|
||||
移动端和桌面端共用同一信息结构:
|
||||
|
||||
```text
|
||||
标题:10分钟创作一个精品互动玩法
|
||||
模板 Tab:拼图 / 方洞挑战 / 视觉小说 / AIRP
|
||||
默认内容:拼图创作表单
|
||||
```
|
||||
|
||||
拼图表单嵌入创作 Tab 时:
|
||||
|
||||
- 不展示工作台返回按钮。
|
||||
- 不重复展示“创建拼图”标题。
|
||||
- 保留表单内的拼图模板、参考图上传、画面描述和生图模型选择。
|
||||
- 生成草稿仍走登录保护,未登录时先触发登录流程。
|
||||
|
||||
## 3. 交互
|
||||
|
||||
1. 打开“创作”一级 Tab 时默认停留在拼图 Tab,不主动创建拼图 session。
|
||||
2. 点击拼图表单“生成草稿”后,才创建拼图 session 并执行 `compile_puzzle_draft`。
|
||||
3. 拼图表单内的模板按钮使用 `tablist / tab` 语义,点击后只填充画面描述。
|
||||
4. 点击非拼图且已开放的模板 Tab 时,进入该玩法既有工作台;未开放模板保持禁用。
|
||||
5. `creative-agent` 不出现在模板 Tab 和选择弹层中,不再作为创作 Tab 首屏入口。
|
||||
|
||||
## 4. 验收
|
||||
|
||||
1. 点击“创作”后首屏出现“10分钟创作一个精品互动玩法”。
|
||||
2. 顶部选择模板入口为 Tab,拼图 Tab 默认 `aria-selected=true`。
|
||||
3. 创作 Tab 默认显示拼图创作表单内容,且不显示旧“Hi, 朋友”、输入框或智能创作快捷按钮。
|
||||
4. 隐藏的智能创作类型不出现在模板 Tab、旧选择弹层和创作 Hub 卡片中。
|
||||
5. 草稿页返回创作页后仍回到同一模板入口,并可保留拼图表单草稿内容。
|
||||
@@ -0,0 +1,90 @@
|
||||
# 平台移动端推荐、发现与草稿 Tab 改版设计
|
||||
|
||||
更新时间:`2026-05-05`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
本次只调整平台入口的信息架构与移动端视觉,不新增后端接口:
|
||||
|
||||
1. 原“首页”一级 Tab 对用户改名为“推荐”,进入后直接展示原首页推荐榜单启动后的公开游戏内容流。
|
||||
2. 原“首页”中的搜索、今日游戏、游戏分类等探索内容移动到第二个一级 Tab;第二个 Tab 对用户命名为“发现”。
|
||||
3. 原“排行”页内容并入“发现”页的子 Tab 中,不再作为一级主 Tab 独立展示。
|
||||
4. 创作页只保留新建创作入口;原创作页作品列表拆到一级“草稿” Tab,替换原“存档” Tab。
|
||||
5. 原“存档”列表结构并入“我的”页面的“玩过”列表弹层,作为每个已玩作品的可继续存档入口。
|
||||
6. 移动端推荐页与底部 Tab 栏参考用户给定样式,使用大画面推荐流、顶部品牌/通知、悬浮胶囊底部导航;保留当前平台已有明暗两套主题色 token。
|
||||
|
||||
## 2. 状态映射
|
||||
|
||||
为降低迁移风险,前端内部 `PlatformHomeTab` 仍复用既有状态值:
|
||||
|
||||
- `home`:用户看到“推荐”。
|
||||
- `category`:用户看到“发现”,内容包含搜索、今日游戏、分类和排行子 Tab。
|
||||
- `create`:用户看到“创作”,只承担新建入口。
|
||||
- `saves`:用户看到“草稿”,承载原创作页作品列表。
|
||||
- `profile`:用户看到“我的”,其中“玩过”弹层合并存档入口。
|
||||
|
||||
旧 `category` 状态此前承载“排行”,本次不改状态名,只改用户文案和页面内容,避免详情页返回目标、测试辅助和历史路由状态大范围迁移。
|
||||
|
||||
## 3. 推荐页
|
||||
|
||||
移动端推荐页默认不展示搜索和频道横滑条,进入一级“推荐”后直接渲染公开作品流:
|
||||
|
||||
- 数据来源沿用 `featuredEntries + latestEntries` 去重后的公开作品列表。
|
||||
- 卡片保留现有作品读模型字段:封面、作者、游玩、改造、点赞、标签。
|
||||
- 移动端推荐卡使用近全屏大画面比例,底部展示互动指标、作者和主操作,不写规则说明类文案。
|
||||
- 无数据、加载中和错误态沿用短状态文案。
|
||||
|
||||
桌面端仍保持现有首页布局,只把一级导航文案从“首页”改为“推荐”。
|
||||
|
||||
## 4. 发现页
|
||||
|
||||
发现页承接原首页探索能力和原排行能力,子 Tab 为:
|
||||
|
||||
1. 推荐:原首页推荐内容流,可作为发现页内的快速回看。
|
||||
2. 今日:原首页“今日游戏”。
|
||||
3. 分类:原首页“游戏分类”。
|
||||
4. 排行:原一级“排行”页四榜切换。
|
||||
|
||||
移动端发现页顶部保留搜索框和子 Tab;分类内容继续使用纵向应用商店式列表;排行内容继续使用榜单行。
|
||||
|
||||
## 5. 创作与草稿
|
||||
|
||||
创作页只保留新建创作入口:
|
||||
|
||||
- 继续复用 `CustomWorldCreationStartCard` 和现有创作类型弹窗。
|
||||
- 不在创作页下方展示作品列表,避免“创作入口”和“作品管理”挤在同一首屏。
|
||||
|
||||
草稿页复用创作中心作品架:
|
||||
|
||||
- 默认显示全部作品列表,保留草稿/已发布筛选。
|
||||
- 入口、删除、分享、领取拼图激励等行为全部复用现有 `CustomWorldCreationHub` 的作品卡逻辑。
|
||||
- 一级底部 Tab 文案为“草稿”,内部仍可按草稿与已发布筛选。
|
||||
|
||||
## 6. 我的页玩过列表
|
||||
|
||||
“我的”页面的“玩过”列表弹层合并存档结构:
|
||||
|
||||
- 顶部仍展示总游戏时长。
|
||||
- 列表先展示可恢复存档,使用原 `SaveArchiveCard` 的字段结构和恢复行为。
|
||||
- 再展示已玩作品统计列表,保持作品号、最近时间和时长。
|
||||
- 若某个存档被点击,必须继续走既有后端恢复接口,不在前端拼接运行态。
|
||||
|
||||
## 7. 验收
|
||||
|
||||
1. 移动端底部导航显示“推荐 / 发现 / 创作 / 草稿 / 我的”,未登录时显示“推荐 / 创作 / 发现”。
|
||||
2. 点击“推荐”直接看到公开作品推荐流,不再先看到搜索框和频道 Tab。
|
||||
3. 点击“发现”可看到搜索、推荐、今日、分类、排行子 Tab。
|
||||
4. 点击“草稿”看到原创作页作品列表。
|
||||
5. 点击“创作”只看到新建创作入口。
|
||||
6. “我的”里的“玩过”弹层包含原存档列表入口,点击存档能继续恢复。
|
||||
7. 移动端底部导航为悬浮胶囊样式,保留当前明暗主题色变量,不新增第三套主题。
|
||||
|
||||
## 8. 2026-05-07 未登录三栏补充
|
||||
|
||||
未登录状态下底部导航只显示 3 个入口,顺序调整为:
|
||||
|
||||
1. 推荐
|
||||
2. 创作
|
||||
3. 发现
|
||||
|
||||
创作 Tab 必须位于中间,并使用原推荐 Tab 的星光图标,保持几何和视觉上的主行动入口。推荐 Tab 改用游戏手柄图标,避免与创作图标重复。
|
||||
@@ -12,6 +12,8 @@
|
||||
- [MOBILE_CREATION_NEW_WORK_COMPACT_LAYOUT_2026-04-24.md](./MOBILE_CREATION_NEW_WORK_COMPACT_LAYOUT_2026-04-24.md):移动端创作页新建作品模块最多占用首屏约 1/3 高度的紧凑布局设计。
|
||||
- [MOBILE_CREATION_WORK_LIST_TWO_COLUMN_LAYOUT_2026-04-29.md](./MOBILE_CREATION_WORK_LIST_TWO_COLUMN_LAYOUT_2026-04-29.md):移动端创作页作品列表至少 2 列的紧凑布局设计。
|
||||
- [PLATFORM_HOME_MOBILE_FEED_CARD_REDESIGN_2026-04-28.md](./PLATFORM_HOME_MOBILE_FEED_CARD_REDESIGN_2026-04-28.md):平台首页移动端参考图式信息流、双端公开作品卡 16:9 封面结构与点赞数读模型设计。
|
||||
- [PLATFORM_MOBILE_RECOMMEND_DISCOVER_DRAFT_TAB_REDESIGN_2026-05-05.md](./PLATFORM_MOBILE_RECOMMEND_DISCOVER_DRAFT_TAB_REDESIGN_2026-05-05.md):平台移动端推荐、发现、创作、草稿、我的 Tab 重新分工与推荐页/底部导航改版设计。
|
||||
- [PLATFORM_CREATE_TAB_CREATIVE_AGENT_HOME_2026-05-05.md](./PLATFORM_CREATE_TAB_CREATIVE_AGENT_HOME_2026-05-05.md):平台创作 Tab 恢复模板 Tab 入口、默认选中拼图并内嵌拼图创作表单的布局设计。
|
||||
- [PLATFORM_CATEGORY_AND_CREATE_TAB_DESIGN_2026-04-24.md](./PLATFORM_CATEGORY_AND_CREATE_TAB_DESIGN_2026-04-24.md):平台入口新增分类 Tab、登录态导航裁剪与创作 Tab 视觉强化设计。
|
||||
- [PLATFORM_BIG_FISH_ENTRY_HIDE_2026-04-28.md](./PLATFORM_BIG_FISH_ENTRY_HIDE_2026-04-28.md):平台入口暂时隐藏大鱼吃小鱼创作卡片,但保留现有玩法链路。
|
||||
- [UNIFIED_MODAL_WINDOW_DESIGN_2026-04-25.md](./UNIFIED_MODAL_WINDOW_DESIGN_2026-04-25.md):统一平台风与 RPG 像素风模态窗口外壳、交互边界和迁移顺序。
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 943 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 999 KiB |
@@ -221,3 +221,8 @@
|
||||
- 后续新增怪物资源时,先检查红圈标注的实际落点,再调整锚点分档或单怪物偏移,避免出现“悬在地面上方”的状态。
|
||||
- 自定义世界里敌对角色已经先作为场景 NPC 存在,即使它同时携带 `characterId` 和 `monsterPresetId`,画布也不能直接沿用模板角色的 `groundOffsetY`;只要 encounter 自身有 `imageSrc` 或 `visual`,就按场景 NPC 自定义形象锚点处理。
|
||||
- 幕预览运行时还会构造“无 `characterId`、但有 `visual` 的场景 NPC”,这类和平相遇分支同样必须套用场景 NPC 自定义形象锚点,否则会停在画面中上部。
|
||||
|
||||
### 10.3 移动端固定整页画布缩放
|
||||
- 主站移动端以固定游戏画布体验为准,入口 `viewport` 需要锁定 `minimum-scale=1.0`、`maximum-scale=1.0` 和 `user-scalable=no`,同时保留 `viewport-fit=cover` 适配安全区。
|
||||
- 浏览器仍可能通过 iOS `gesture*` 或多指 `touchmove` 触发整页缩放,因此主站启动入口应统一调用 `lockMobileViewportZoom()` 拦截页面级捏合与快速双击缩放。
|
||||
- 不要在每个画布组件里重复注册缩放拦截;单指滚动、点击、拖拽应继续留给具体页面和玩法处理。
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
- [RPG_DRAFT_IMAGE_PARALLEL_GENERATION_2026-04-24.md](./RPG_DRAFT_IMAGE_PARALLEL_GENERATION_2026-04-24.md):记录 RPG 底稿阶段角色主形象与场景背景图并行生成约束。
|
||||
- [PLATFORM_HOME_BANNER_IMAGE_SIZE_FIX_2026-04-25.md](./PLATFORM_HOME_BANNER_IMAGE_SIZE_FIX_2026-04-25.md):记录首页 banner 背景图不能进入普通布局流的修复经验。
|
||||
- [RPG_PUBLISH_GALLERY_REFRESH_FIX_2026-04-25.md](./RPG_PUBLISH_GALLERY_REFRESH_FIX_2026-04-25.md):记录 RPG 发布后首页 / 分类页公开作品列表刷新链路。
|
||||
- [VISUAL_NOVEL_HANDOFF_AND_MAINTENANCE_2026-05-07.md](./VISUAL_NOVEL_HANDOFF_AND_MAINTENANCE_2026-05-07.md):记录视觉小说模板交接时的阅读顺序、常见坑和维护检查口径。
|
||||
- [AGENT_EMPTY_SESSION_DRAFT_VISIBILITY_2026-04-26.md](./AGENT_EMPTY_SESSION_DRAFT_VISIBILITY_2026-04-26.md):记录 Agent 空会话不应进入作品草稿列表的后端判定规则。
|
||||
- [BIG_FISH_PUBLISH_FEEDBACK_FIX_2026-04-26.md](./BIG_FISH_PUBLISH_FEEDBACK_FIX_2026-04-26.md):记录大鱼吃小鱼发布成功后结果页反馈与作品列表刷新的修复口径。
|
||||
- [BIG_FISH_WORKS_JSON_COMPAT_FIX_2026-04-28.md](./BIG_FISH_WORKS_JSON_COMPAT_FIX_2026-04-28.md):记录大鱼作品列表 `items_json` 字段升级后的向后兼容修复口径,避免旧 JSON 直接打崩 works 接口。
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# 视觉小说模板交接与维护经验 2026-05-07
|
||||
|
||||
## 1. 先读什么
|
||||
|
||||
新开发者接手视觉小说时,建议按这个顺序看:
|
||||
|
||||
1. [AI 原生视觉小说模板 PRD](../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md)
|
||||
2. [视觉小说模板实现收口与交接说明](../technical/VISUAL_NOVEL_IMPLEMENTATION_HANDOFF_2026-05-07.md)
|
||||
3. [SpacetimeDB 表说明与查询目录](../technical/SPACETIMEDB_TABLE_CATALOG.md)
|
||||
4. [视觉小说 VN-03 Prompt 与 LLM 工具实现说明](../technical/VISUAL_NOVEL_PROMPT_AND_LLM_TOOLS_VN03_2026-05-05.md)
|
||||
5. [视觉小说 VN-11 负向扫描报告](../audits/VN11_NEGATIVE_SCAN_REPORT_2026-05-07.md)
|
||||
|
||||
## 2. 最容易踩的坑
|
||||
|
||||
1. 不要把 `visual_novel_runtime_history_entry` 当回放表来扩。
|
||||
2. 不要把 `visual_novel_runtime_event` 当业务回放数据源来用。
|
||||
3. 不要绕过平台资产对象去保存图片、音乐或文档。
|
||||
4. 不要让旧 TXT 迁移文档重新变成实现口径。
|
||||
5. 不要忘记发布后刷新作品架和公开聚合。
|
||||
6. 不要忘记退出登录时清理视觉小说私有状态。
|
||||
|
||||
## 3. 维护时的判断顺序
|
||||
|
||||
1. 先看是不是共享契约变化。
|
||||
2. 再看是不是 SpacetimeDB 表或 facade 变化。
|
||||
3. 然后看是不是作品架、广场或 runtime 的前端分流变化。
|
||||
4. 最后才看文档措辞和历史说明。
|
||||
|
||||
## 4. 常用检查
|
||||
|
||||
```bash
|
||||
npm run check:encoding
|
||||
npm run check:visual-novel-vn11
|
||||
npm run typecheck
|
||||
```
|
||||
|
||||
如果改了后端,再补:
|
||||
|
||||
```bash
|
||||
cd server-rs
|
||||
cargo test -p shared-contracts
|
||||
cargo test -p module-visual-novel
|
||||
cargo check -p api-server
|
||||
```
|
||||
|
||||
## 5. 一句话结论
|
||||
|
||||
视觉小说模板已经是平台内的正式模板玩法,不是外部平台迁移;后续维护只需要沿着 PRD、表目录、prompt 文档和这份交接说明往下走。
|
||||
863
docs/prd/AI_NATIVE_2048_GAMEPLAY_TEMPLATE_PRD_2026-05-05.md
Normal file
863
docs/prd/AI_NATIVE_2048_GAMEPLAY_TEMPLATE_PRD_2026-05-05.md
Normal file
@@ -0,0 +1,863 @@
|
||||
# AI 原生 2048 游戏玩法模板 PRD
|
||||
|
||||
更新时间:`2026-05-05`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份 PRD 用于在当前平台内新增一条 `2048` 游戏玩法模板,并冻结它从创作入口、Agent 生成、结果页编辑、试玩、发布、公开运行到作品架展示的完整产品边界。
|
||||
|
||||
本次不是只做一个浏览器本地 2048 小游戏,也不是把经典 2048 规则随手写进某个前端组件。正式落地时,`2048` 必须作为平台内独立玩法类型接入现有创作中心、作品、广场、运行态和后端 DDD 分层。
|
||||
|
||||
---
|
||||
|
||||
## 1. 一句话定义
|
||||
|
||||
`2048` 是一个主题化数字合成玩法模板:百梦主通过 Agent 设定棋盘主题、合成链、视觉皮肤、目标格和难度参数,系统生成可试玩、可发布的 2048 作品;玩家通过滑动方向移动棋盘格,相同等级方块合并升级,直到达成目标格或棋盘无可行动作。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前接入级别
|
||||
|
||||
根据 `genarrative-play-type-integration` 的接入分级,本玩法按 **完整玩法闭环** 设计:
|
||||
|
||||
1. 新增玩法 ID:`twenty-forty-eight`。
|
||||
2. 展示名称:`2048`。
|
||||
3. 子标题:`主题合成棋盘`。
|
||||
4. 新建作品入口可展示,开放节奏由 `src/config/newWorkEntryConfig.ts` 控制。
|
||||
5. 支持 Agent 创作、草稿生成、结果页编辑、试玩、发布、公开运行、作品架和广场。
|
||||
6. 后端以 `server-rs + Axum + SpacetimeDB` 为服务侧真相源。
|
||||
7. 前端负责棋盘渲染、输入采集和动画表现,不绕过后端保存正式运行结果、榜单、扣费和发布状态。
|
||||
|
||||
工程命名采用 `twenty-forty-eight` 而不是裸 `2048`,避免 TypeScript、Rust 模块、文件名和路由中出现数字开头命名;面向用户的标题始终显示 `2048`。
|
||||
|
||||
---
|
||||
|
||||
## 3. 产品定位
|
||||
|
||||
## 3.1 模板名称
|
||||
|
||||
1. 对外模板名称:`2048`。
|
||||
2. 对外子标题:`主题合成棋盘`。
|
||||
3. 开发代号:`TwentyFortyEight`。
|
||||
4. 工程玩法域:`twenty-forty-eight`。
|
||||
5. 后端模块命名:`twenty_forty_eight`。
|
||||
6. 公开作品号前缀:`TF-`。
|
||||
|
||||
## 3.2 核心乐趣
|
||||
|
||||
1. 玩家通过一次滑动改变整盘局势。
|
||||
2. 相同方块合并升级,形成清晰的成长反馈。
|
||||
3. 主题化合成链让数字升级变成可感知的叙事或收藏序列。
|
||||
4. 棋盘越来越拥挤,玩家在空间管理和短期收益之间做取舍。
|
||||
5. 达成目标格后可以继续冲击更高分,也可以结算分享成绩。
|
||||
|
||||
## 3.3 与现有玩法的区别
|
||||
|
||||
1. 不等同于拼图:不切图、不交换、不合并图片碎片。
|
||||
2. 不等同于抓大鹅:不做三消备选栏,不做物体堆叠点击。
|
||||
3. 不等同于方洞挑战:不做单次投放裁决,不靠反直觉规则制造误导。
|
||||
4. 不等同于大鱼吃小鱼:不做实时移动、吞噬和碰撞成长。
|
||||
5. 不复用 RPG 的世界、角色、章节或剧情推进结构。
|
||||
|
||||
---
|
||||
|
||||
## 4. 完整闭环目标
|
||||
|
||||
本玩法完整闭环必须补齐:
|
||||
|
||||
1. 平台创作中心选择 `2048`。
|
||||
2. Agent 对话收集主题、合成链、视觉风格、目标格和难度。
|
||||
3. 生成 2048 草稿。
|
||||
4. 进入结果页编辑作品名、简介、标签、封面、棋盘配置和方块皮肤。
|
||||
5. 支持发布前试玩。
|
||||
6. 发布作品。
|
||||
7. 玩家从作品详情、广场或作品架进入运行态。
|
||||
8. 后端初始化 run,保存种子、当前棋盘、分数、目标、状态和动作序列摘要。
|
||||
9. 玩家滑动方向后,前端提交动作,后端裁决新棋盘;前端按返回快照播放移动与合并动画。
|
||||
10. 达成目标、继续挑战、失败结算和排行榜写入都由后端正式裁决。
|
||||
11. 前端不得自行提交伪造分数、目标达成或榜单记录。
|
||||
|
||||
---
|
||||
|
||||
## 5. 明确不做
|
||||
|
||||
首版不做:
|
||||
|
||||
1. 不做多人实时对战。
|
||||
2. 不做复杂技能树或 RPG 数值养成。
|
||||
3. 不做可破坏障碍、棋盘机关和随机事件。
|
||||
4. 不支持玩家自定义任意 JavaScript 规则。
|
||||
5. 不在 UI 中默认展示长篇玩法说明、规则描述或内部字段解释。
|
||||
6. 不新增独立于平台之外的 2048 站点。
|
||||
7. 不复用 `customWorld`、`rpgWorld` 或旧 `server-node` 命名承载 2048 业务。
|
||||
8. 不把 LLM、生图、OSS 上传放进 SpacetimeDB reducer。
|
||||
|
||||
---
|
||||
|
||||
## 6. 创作锚点设计
|
||||
|
||||
Agent 型创作至少收集下面 5 个锚点:
|
||||
|
||||
| 锚点 | 字段建议 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| 合成主题 | `themePrompt` | 决定棋盘整体题材,例如修仙境界、猫咪成长、城市建设、料理升级。 |
|
||||
| 合成链 | `tileLadder` | 决定从 `2` 到目标格的每一级显示名、图标提示和视觉差异。 |
|
||||
| 视觉皮肤 | `visualStyle` | 决定方块材质、色彩、背景、动效气质和封面方向。 |
|
||||
| 难度参数 | `difficultyConfig` | 决定棋盘尺寸、目标格、初始方块、生成概率和是否允许撤销。 |
|
||||
| 反馈节奏 | `feedbackRhythm` | 决定移动、合并、升级、目标达成、失败结算的反馈强度。 |
|
||||
|
||||
Agent 行为要求:
|
||||
|
||||
1. 优先接住百梦主的一句话灵感,不把创作变成问卷。
|
||||
2. 每轮最多追问 1 个最影响成品质量的问题。
|
||||
3. 当主题和合成链已经足够明确时,优先生成草稿。
|
||||
4. 合成链必须围绕同一主题递进,不允许出现互不相关的方块名。
|
||||
5. 进入结果页前至少生成 `2` 到目标格之间的完整等级定义。
|
||||
|
||||
---
|
||||
|
||||
## 7. 玩法规则
|
||||
|
||||
## 7.1 棋盘
|
||||
|
||||
首版默认支持:
|
||||
|
||||
1. `4x4` 标准棋盘。
|
||||
2. 可选 `5x5` 放松棋盘。
|
||||
3. 可选 `3x3` 高压棋盘。
|
||||
|
||||
发布默认值:
|
||||
|
||||
1. `boardSize = 4`。
|
||||
2. `targetTileValue = 2048`。
|
||||
3. 初始方块数量为 `2`。
|
||||
4. 新方块生成值为 `2` 或 `4`。
|
||||
5. `2` 的生成概率为 `90%`,`4` 的生成概率为 `10%`。
|
||||
|
||||
## 7.2 输入
|
||||
|
||||
玩家每次只能提交一个方向:
|
||||
|
||||
```ts
|
||||
type TwentyFortyEightMoveDirection = 'up' | 'down' | 'left' | 'right';
|
||||
```
|
||||
|
||||
交互支持:
|
||||
|
||||
1. 移动端滑动。
|
||||
2. 桌面端方向键。
|
||||
3. 桌面端按钮或触控手势兜底。
|
||||
|
||||
无效输入规则:
|
||||
|
||||
1. 如果某方向不会改变棋盘,该动作不消耗步数。
|
||||
2. 无效动作返回当前快照和 `moveAccepted = false`。
|
||||
3. 前端只展示轻量反馈,不弹长说明。
|
||||
|
||||
## 7.3 合并
|
||||
|
||||
合并规则遵循经典 2048:
|
||||
|
||||
1. 同一行或列按移动方向压缩。
|
||||
2. 相邻且同值的两个方块合并成一个更高值方块。
|
||||
3. 每个方块在一次移动中最多合并一次。
|
||||
4. 合并后的方块值为原值的 `2` 倍。
|
||||
5. 本次得分增加合并后方块值。
|
||||
6. 移动完成后,如果棋盘有变化,随机空格生成一个新方块。
|
||||
|
||||
规则核心应封装为可测试的领域引擎。实现时优先评估成熟 2048 规则库;如 Rust / TypeScript 生态无合适库,必须把自研规则收敛在 `module-twenty-forty-eight` 的纯函数内,并用黄金用例、属性测试和前后端 fixture 保证一致。
|
||||
|
||||
## 7.4 胜负
|
||||
|
||||
状态取值:
|
||||
|
||||
```ts
|
||||
type TwentyFortyEightRunStatus =
|
||||
| 'playing'
|
||||
| 'target_reached'
|
||||
| 'continued_after_target'
|
||||
| 'game_over'
|
||||
| 'abandoned';
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
1. 首次出现 `targetTileValue` 时进入 `target_reached`。
|
||||
2. 玩家可选择结算,或继续挑战。
|
||||
3. 继续挑战后状态变为 `continued_after_target`。
|
||||
4. 棋盘无空格且四个方向都无法移动时进入 `game_over`。
|
||||
5. 玩家主动退出未结算时为 `abandoned`。
|
||||
|
||||
---
|
||||
|
||||
## 8. 草稿与结果页
|
||||
|
||||
## 8.1 结果页定位
|
||||
|
||||
2048 结果页是发布前的最小工作台,承担:
|
||||
|
||||
1. 编辑作品基本信息。
|
||||
2. 编辑棋盘参数。
|
||||
3. 编辑合成链显示名和视觉提示。
|
||||
4. 生成或上传封面。
|
||||
5. 进入试玩。
|
||||
6. 发布作品。
|
||||
|
||||
## 8.2 必备字段
|
||||
|
||||
```ts
|
||||
interface TwentyFortyEightResultDraft {
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
workTags: string[];
|
||||
coverImageSrc: string | null;
|
||||
coverAssetId: string | null;
|
||||
themePrompt: string;
|
||||
visualStyle: string;
|
||||
boardConfig: TwentyFortyEightBoardConfig;
|
||||
tileLadder: TwentyFortyEightTileDefinition[];
|
||||
scoringConfig: TwentyFortyEightScoringConfig;
|
||||
}
|
||||
|
||||
interface TwentyFortyEightBoardConfig {
|
||||
boardSize: 3 | 4 | 5;
|
||||
targetTileValue: 512 | 1024 | 2048 | 4096 | 8192;
|
||||
initialTileCount: 2 | 3 | 4;
|
||||
spawnValueWeights: Array<{ value: 2 | 4; weight: number }>;
|
||||
allowUndo: boolean;
|
||||
maxUndoCount: number;
|
||||
}
|
||||
|
||||
interface TwentyFortyEightTileDefinition {
|
||||
value: number;
|
||||
label: string;
|
||||
shortLabel: string;
|
||||
colorToken: string;
|
||||
iconPrompt: string;
|
||||
imageSrc: string | null;
|
||||
assetId: string | null;
|
||||
}
|
||||
|
||||
interface TwentyFortyEightScoringConfig {
|
||||
scoreMode: 'classic';
|
||||
leaderboardMetric: 'score_then_steps' | 'score_then_time';
|
||||
}
|
||||
```
|
||||
|
||||
## 8.3 字段约束
|
||||
|
||||
1. `workTitle` 必填,建议 `4~16` 个中文字符。
|
||||
2. `workDescription` 必填,建议 `12~80` 个中文字符。
|
||||
3. `workTags` 必须为 `3~6` 个中文短标签。
|
||||
4. `boardSize` 首版只能是 `3`、`4`、`5`。
|
||||
5. `targetTileValue` 必须存在于 `tileLadder`。
|
||||
6. `tileLadder` 必须从 `2` 开始按倍增连续覆盖到目标格。
|
||||
7. `shortLabel` 移动端格子内最多建议 `4` 个中文字符。
|
||||
8. `spawnValueWeights` 权重和必须大于 `0`,归一化后用于后端生成。
|
||||
9. `allowUndo = true` 时 `maxUndoCount` 必须在 `1~3`。
|
||||
|
||||
## 8.4 结果页 UI
|
||||
|
||||
结果页采用移动端优先的页签结构:
|
||||
|
||||
1. `基本信息`:标题、简介、标签。
|
||||
2. `棋盘`:棋盘尺寸、目标格、撤销次数、生成概率。
|
||||
3. `合成链`:每级方块的显示名、短标签、颜色和图标预览。
|
||||
4. `封面`:封面预览、生成、上传或历史素材选择。
|
||||
|
||||
交互要求:
|
||||
|
||||
1. 发布按钮放在结果页右下操作区,移动端固定在底部安全区。
|
||||
2. 试玩按钮与发布按钮并列,但试玩不触发发布阻断。
|
||||
3. 发布校验只在点击发布后进入独立发布面板展示。
|
||||
4. 合成链编辑使用独立面板或抽屉,不在当前列表下方展开大表单。
|
||||
5. 页面不默认展示玩法规则说明。
|
||||
|
||||
---
|
||||
|
||||
## 9. 作品发布与广场
|
||||
|
||||
## 9.1 发布阻断
|
||||
|
||||
发布前必须校验:
|
||||
|
||||
1. 作品标题非空。
|
||||
2. 简介非空。
|
||||
3. 标签数量为 `3~6`。
|
||||
4. 棋盘配置合法。
|
||||
5. 合成链完整覆盖到目标格。
|
||||
6. 目标格存在。
|
||||
7. 封面存在。
|
||||
8. 作者信息可读。
|
||||
|
||||
## 9.2 作品摘要
|
||||
|
||||
```ts
|
||||
interface TwentyFortyEightWorkSummary {
|
||||
workId: string;
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
authorDisplayName: string;
|
||||
gameName: string;
|
||||
summary: string;
|
||||
tags: string[];
|
||||
coverImageSrc: string;
|
||||
boardSize: 3 | 4 | 5;
|
||||
targetTileValue: number;
|
||||
bestScore: number | null;
|
||||
playCount: number;
|
||||
likeCount: number;
|
||||
sourceSessionId: string;
|
||||
publicationStatus: 'draft' | 'published';
|
||||
updatedAt: string;
|
||||
publishedAt: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
## 9.3 广场卡片
|
||||
|
||||
广场卡片至少展示:
|
||||
|
||||
1. 封面。
|
||||
2. 作品名。
|
||||
3. 作者名。
|
||||
4. 标签。
|
||||
5. 棋盘规格和目标格。
|
||||
6. 进入游戏按钮。
|
||||
|
||||
不在卡片内展示完整规则说明。
|
||||
|
||||
---
|
||||
|
||||
## 10. 运行态设计
|
||||
|
||||
## 10.1 首屏
|
||||
|
||||
运行态首屏必须直接展示棋盘:
|
||||
|
||||
1. 顶部 HUD:分数、最高格、目标格、步数。
|
||||
2. 中部正方形棋盘。
|
||||
3. 底部轻量操作区:撤销、重新开始、退出。
|
||||
4. 移动端棋盘尽量贴近屏幕两侧安全边界。
|
||||
5. 桌面端棋盘居中,不使用营销式大卡片布局。
|
||||
|
||||
## 10.2 运行快照
|
||||
|
||||
```ts
|
||||
interface TwentyFortyEightRunSnapshot {
|
||||
runId: string;
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
status: TwentyFortyEightRunStatus;
|
||||
seed: string;
|
||||
board: TwentyFortyEightBoardSnapshot;
|
||||
score: number;
|
||||
bestTileValue: number;
|
||||
moveCount: number;
|
||||
undoRemaining: number;
|
||||
targetTileValue: number;
|
||||
reachedTargetAtMove: number | null;
|
||||
startedAtMs: number;
|
||||
updatedAtMs: number;
|
||||
endedAtMs: number | null;
|
||||
lastMove: TwentyFortyEightMoveResult | null;
|
||||
work: TwentyFortyEightWorkSummary;
|
||||
}
|
||||
|
||||
interface TwentyFortyEightBoardSnapshot {
|
||||
size: 3 | 4 | 5;
|
||||
cells: TwentyFortyEightCellSnapshot[];
|
||||
}
|
||||
|
||||
interface TwentyFortyEightCellSnapshot {
|
||||
row: number;
|
||||
col: number;
|
||||
tile: TwentyFortyEightTileSnapshot | null;
|
||||
}
|
||||
|
||||
interface TwentyFortyEightTileSnapshot {
|
||||
tileId: string;
|
||||
value: number;
|
||||
mergedFromTileIds: string[];
|
||||
spawnedAtMove: number;
|
||||
}
|
||||
|
||||
interface TwentyFortyEightMoveResult {
|
||||
direction: TwentyFortyEightMoveDirection;
|
||||
moveAccepted: boolean;
|
||||
scoreDelta: number;
|
||||
spawnedTile: TwentyFortyEightTileSnapshot | null;
|
||||
mergedTileIds: string[];
|
||||
}
|
||||
```
|
||||
|
||||
## 10.3 前后端职责
|
||||
|
||||
前端负责:
|
||||
|
||||
1. 渲染棋盘、HUD、结算面板。
|
||||
2. 采集滑动、键盘和按钮输入。
|
||||
3. 根据后端返回的 `lastMove` 播放移动、合并和生成动画。
|
||||
4. 做乐观动画可以,但必须以服务端快照回正。
|
||||
|
||||
前端不负责:
|
||||
|
||||
1. 保存正式分数。
|
||||
2. 写入榜单。
|
||||
3. 伪造目标达成。
|
||||
4. 绕过后端生成新方块。
|
||||
5. 自行发布作品状态。
|
||||
|
||||
后端负责:
|
||||
|
||||
1. 创建 run。
|
||||
2. 按 seed 初始化棋盘。
|
||||
3. 裁决每次移动。
|
||||
4. 生成新方块。
|
||||
5. 保存分数、步数、最高格和状态。
|
||||
6. 裁决目标达成、继续挑战、失败和放弃。
|
||||
7. 写入排行榜和埋点事件。
|
||||
|
||||
---
|
||||
|
||||
## 11. 后端分层边界
|
||||
|
||||
正式实现必须遵循当前 `server-rs + Axum + SpacetimeDB` 路线:
|
||||
|
||||
1. `server-rs/crates/module-twenty-forty-eight`
|
||||
- 纯领域规则、棋盘移动、合并裁决、随机种子输入、分数计算、发布校验。
|
||||
- 不依赖 Axum、SpacetimeDB、OSS 或 LLM。
|
||||
2. `server-rs/crates/shared-contracts`
|
||||
- 暴露 Agent、作品、运行态、广场 DTO。
|
||||
3. `server-rs/crates/spacetime-module`
|
||||
- 存储 session、message、work profile、runtime run、leaderboard、event。
|
||||
- 表结构变化必须同步 `migration.rs` 与表目录。
|
||||
4. `server-rs/crates/spacetime-client`
|
||||
- 提供 api-server 调用 SpacetimeDB 的 typed facade。
|
||||
5. `server-rs/crates/api-server`
|
||||
- 暴露 `/api/creation/twenty-forty-eight/*` 与 `/api/runtime/twenty-forty-eight/*`。
|
||||
- 处理鉴权、错误 envelope、LLM turn、生图编排、OSS 资产和 HTTP facade。
|
||||
6. `platform-llm` / `platform-oss`
|
||||
- 分别承载外部模型和资产副作用。
|
||||
|
||||
涉及 SpacetimeDB 的表、reducer、procedure、绑定生成、前端 SDK 接入时,必须按 `spacetimedb-cli`、`spacetimedb-rust`、`spacetimedb-concepts`、`spacetimedb-typescript` 约束执行。
|
||||
|
||||
---
|
||||
|
||||
## 12. SpacetimeDB 表建议
|
||||
|
||||
首版建议新增:
|
||||
|
||||
1. `twenty_forty_eight_agent_session`
|
||||
2. `twenty_forty_eight_agent_message`
|
||||
3. `twenty_forty_eight_work_profile`
|
||||
4. `twenty_forty_eight_runtime_run`
|
||||
5. `twenty_forty_eight_leaderboard_entry`
|
||||
6. `twenty_forty_eight_event`
|
||||
|
||||
表职责:
|
||||
|
||||
| 表 | 职责 |
|
||||
| --- | --- |
|
||||
| `twenty_forty_eight_agent_session` | 创作会话、阶段、草稿、已发布 profile 绑定。 |
|
||||
| `twenty_forty_eight_agent_message` | Agent 对话消息和流式 turn 结果。 |
|
||||
| `twenty_forty_eight_work_profile` | 作品草稿、发布状态、封面、棋盘配置、合成链和统计投影。 |
|
||||
| `twenty_forty_eight_runtime_run` | 单次运行快照、动作摘要、分数、状态和结算时间。 |
|
||||
| `twenty_forty_eight_leaderboard_entry` | 按作品、用户、棋盘规格和目标格记录最好成绩。 |
|
||||
| `twenty_forty_eight_event` | 发布、试玩、开始、移动、达成目标、失败、结算等审计事件。 |
|
||||
|
||||
reducer / procedure 不允许调用 LLM、OSS、生图、HTTP 或非确定性外部服务。
|
||||
|
||||
---
|
||||
|
||||
## 13. API 设计
|
||||
|
||||
## 13.1 创作接口
|
||||
|
||||
统一前缀:
|
||||
|
||||
```text
|
||||
/api/creation/twenty-forty-eight
|
||||
```
|
||||
|
||||
建议接口:
|
||||
|
||||
1. `POST /api/creation/twenty-forty-eight/sessions`
|
||||
2. `GET /api/creation/twenty-forty-eight/sessions/{sessionId}`
|
||||
3. `POST /api/creation/twenty-forty-eight/sessions/{sessionId}/messages`
|
||||
4. `POST /api/creation/twenty-forty-eight/sessions/{sessionId}/messages/stream`
|
||||
5. `POST /api/creation/twenty-forty-eight/sessions/{sessionId}/actions`
|
||||
6. `POST /api/creation/twenty-forty-eight/sessions/{sessionId}/compile`
|
||||
7. `GET /api/creation/twenty-forty-eight/works`
|
||||
8. `GET /api/creation/twenty-forty-eight/works/{profileId}`
|
||||
9. `PUT /api/creation/twenty-forty-eight/works/{profileId}`
|
||||
10. `POST /api/creation/twenty-forty-eight/works/{profileId}/publish`
|
||||
11. `DELETE /api/creation/twenty-forty-eight/works/{profileId}`
|
||||
|
||||
## 13.2 运行接口
|
||||
|
||||
统一前缀:
|
||||
|
||||
```text
|
||||
/api/runtime/twenty-forty-eight
|
||||
```
|
||||
|
||||
建议接口:
|
||||
|
||||
1. `GET /api/runtime/twenty-forty-eight/gallery`
|
||||
2. `GET /api/runtime/twenty-forty-eight/gallery/{profileId}`
|
||||
3. `POST /api/runtime/twenty-forty-eight/works/{profileId}/runs`
|
||||
4. `GET /api/runtime/twenty-forty-eight/runs/{runId}`
|
||||
5. `POST /api/runtime/twenty-forty-eight/runs/{runId}/moves`
|
||||
6. `POST /api/runtime/twenty-forty-eight/runs/{runId}/undo`
|
||||
7. `POST /api/runtime/twenty-forty-eight/runs/{runId}/continue`
|
||||
8. `POST /api/runtime/twenty-forty-eight/runs/{runId}/restart`
|
||||
9. `POST /api/runtime/twenty-forty-eight/runs/{runId}/abandon`
|
||||
10. `POST /api/runtime/twenty-forty-eight/runs/{runId}/leaderboard`
|
||||
|
||||
移动请求:
|
||||
|
||||
```ts
|
||||
interface TwentyFortyEightMoveRequest {
|
||||
clientActionId: string;
|
||||
direction: TwentyFortyEightMoveDirection;
|
||||
baseSnapshotVersion: number;
|
||||
}
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```ts
|
||||
interface TwentyFortyEightMoveResponse {
|
||||
snapshot: TwentyFortyEightRunSnapshot;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 14. 前端落点
|
||||
|
||||
建议新增:
|
||||
|
||||
```text
|
||||
src/components/twenty-forty-eight-creation/TwentyFortyEightAgentWorkspace.tsx
|
||||
src/components/twenty-forty-eight-result/TwentyFortyEightResultView.tsx
|
||||
src/components/twenty-forty-eight-runtime/TwentyFortyEightRuntimeShell.tsx
|
||||
src/components/twenty-forty-eight-runtime/TwentyFortyEightBoard.tsx
|
||||
src/components/twenty-forty-eight-runtime/TwentyFortyEightHud.tsx
|
||||
src/services/twenty-forty-eight-creation/twentyFortyEightCreationClient.ts
|
||||
src/services/twenty-forty-eight-works/twentyFortyEightWorksClient.ts
|
||||
src/services/twenty-forty-eight-runtime/twentyFortyEightRuntimeClient.ts
|
||||
src/services/twenty-forty-eight-gallery/twentyFortyEightGalleryClient.ts
|
||||
```
|
||||
|
||||
平台入口接入时需要扩展:
|
||||
|
||||
1. `src/config/newWorkEntryConfig.ts`
|
||||
2. `src/components/platform-entry/platformEntryTypes.ts`
|
||||
3. `src/components/platform-entry/platformEntryCreationTypes.ts`
|
||||
4. `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
|
||||
5. `src/components/custom-world-home/creationWorkShelf.ts`
|
||||
6. `src/services/publicWorkCode.ts`
|
||||
|
||||
新增 selection stage:
|
||||
|
||||
```ts
|
||||
| 'twenty-forty-eight-agent-workspace'
|
||||
| 'twenty-forty-eight-result'
|
||||
| 'twenty-forty-eight-runtime'
|
||||
| 'twenty-forty-eight-gallery-detail'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 15. UI 要求
|
||||
|
||||
## 15.1 创作入口
|
||||
|
||||
入口卡片只表达:
|
||||
|
||||
1. `2048`
|
||||
2. `主题合成棋盘`
|
||||
3. 开放状态
|
||||
|
||||
不在入口卡片里堆规则说明。
|
||||
|
||||
## 15.2 Agent 工作台
|
||||
|
||||
工作台结构:
|
||||
|
||||
1. 对话流。
|
||||
2. 当前锚点摘要。
|
||||
3. 生成草稿动作。
|
||||
4. 进入结果页动作。
|
||||
|
||||
不展示世界观、角色、地点等 RPG 重结构。
|
||||
|
||||
## 15.3 运行态
|
||||
|
||||
运行态设计原则:
|
||||
|
||||
1. 棋盘是绝对主角。
|
||||
2. 移动端优先,单手可滑动。
|
||||
3. HUD 信息克制,只显示分数、目标、步数和最高格。
|
||||
4. 撤销、重新开始、退出使用 icon button 或短按钮。
|
||||
5. 目标达成、失败和排行榜使用独立弹窗或底部面板。
|
||||
6. 不把弹出面板实现成当前面板下方追加内容。
|
||||
|
||||
---
|
||||
|
||||
## 16. 测试与验收
|
||||
|
||||
## 16.1 领域测试
|
||||
|
||||
必须覆盖:
|
||||
|
||||
1. 向左移动压缩。
|
||||
2. 向右移动压缩。
|
||||
3. 单次移动中每个方块最多合并一次。
|
||||
4. 合并得分计算。
|
||||
5. 无效移动不生成新方块。
|
||||
6. 有效移动按 seed 生成新方块。
|
||||
7. 目标格达成。
|
||||
8. 无可行动作进入失败。
|
||||
9. 撤销次数消耗和快照恢复。
|
||||
|
||||
## 16.2 API 测试
|
||||
|
||||
必须覆盖:
|
||||
|
||||
1. 未登录不能创建作品和 run。
|
||||
2. 创建 session。
|
||||
3. 编译草稿。
|
||||
4. 发布校验阻断。
|
||||
5. 创建 run。
|
||||
6. 提交 move 后返回新快照。
|
||||
7. 无效 move 不增加步数。
|
||||
8. 达成目标后可继续挑战。
|
||||
9. 失败后不能继续提交 move。
|
||||
10. 排行榜只接受后端已结算 run。
|
||||
|
||||
## 16.3 前端测试
|
||||
|
||||
必须覆盖:
|
||||
|
||||
1. 入口展示与点击分流。
|
||||
2. Agent 工作台打开。
|
||||
3. 结果页编辑棋盘参数和合成链。
|
||||
4. 试玩进入运行态。
|
||||
5. 移动端滑动提交方向。
|
||||
6. 键盘方向键提交方向。
|
||||
7. 无效移动反馈。
|
||||
8. 目标达成弹窗。
|
||||
9. 失败结算弹窗。
|
||||
|
||||
## 16.4 建议验证命令
|
||||
|
||||
按改动范围执行:
|
||||
|
||||
```bash
|
||||
npm run check:encoding
|
||||
npm run typecheck
|
||||
npm run test
|
||||
cd server-rs
|
||||
cargo test -p shared-contracts twenty_forty_eight
|
||||
cargo test -p module-twenty-forty-eight
|
||||
cargo check -p api-server
|
||||
```
|
||||
|
||||
涉及 SpacetimeDB 表变化后:
|
||||
|
||||
```bash
|
||||
npm run spacetime:generate -- --rust-only
|
||||
npm run check:server-rs-ddd
|
||||
```
|
||||
|
||||
涉及 API smoke 时:
|
||||
|
||||
```bash
|
||||
npm run api-server
|
||||
```
|
||||
|
||||
启动后确认:
|
||||
|
||||
```text
|
||||
GET /healthz
|
||||
POST /api/creation/twenty-forty-eight/sessions
|
||||
POST /api/runtime/twenty-forty-eight/works/{profileId}/runs
|
||||
POST /api/runtime/twenty-forty-eight/runs/{runId}/moves
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 17. 并行任务拆分
|
||||
|
||||
## 任务 A:契约与共享类型
|
||||
|
||||
写入范围:
|
||||
|
||||
```text
|
||||
packages/shared/src/contracts/twentyFortyEightAgent.ts
|
||||
packages/shared/src/contracts/twentyFortyEightWorks.ts
|
||||
packages/shared/src/contracts/twentyFortyEightRuntime.ts
|
||||
packages/shared/src/contracts/twentyFortyEightGallery.ts
|
||||
server-rs/crates/shared-contracts/src/twenty_forty_eight_agent.rs
|
||||
server-rs/crates/shared-contracts/src/twenty_forty_eight_works.rs
|
||||
server-rs/crates/shared-contracts/src/twenty_forty_eight_runtime.rs
|
||||
server-rs/crates/shared-contracts/src/twenty_forty_eight_gallery.rs
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
```bash
|
||||
npm run typecheck
|
||||
cd server-rs
|
||||
cargo test -p shared-contracts twenty_forty_eight
|
||||
```
|
||||
|
||||
## 任务 B:领域规则模块
|
||||
|
||||
写入范围:
|
||||
|
||||
```text
|
||||
server-rs/crates/module-twenty-forty-eight/src/domain.rs
|
||||
server-rs/crates/module-twenty-forty-eight/src/application.rs
|
||||
server-rs/crates/module-twenty-forty-eight/src/rule_engine.rs
|
||||
server-rs/crates/module-twenty-forty-eight/src/random.rs
|
||||
server-rs/crates/module-twenty-forty-eight/src/lib.rs
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
```bash
|
||||
cd server-rs
|
||||
cargo test -p module-twenty-forty-eight
|
||||
```
|
||||
|
||||
## 任务 C:SpacetimeDB 表与 facade
|
||||
|
||||
写入范围:
|
||||
|
||||
```text
|
||||
server-rs/crates/spacetime-module/src/twenty_forty_eight.rs
|
||||
server-rs/crates/spacetime-module/src/lib.rs
|
||||
server-rs/crates/spacetime-module/src/migration.rs
|
||||
server-rs/crates/spacetime-client/src/twenty_forty_eight.rs
|
||||
docs/technical/SPACETIMEDB_TABLE_CATALOG.md
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
```bash
|
||||
npm run spacetime:generate -- --rust-only
|
||||
npm run check:server-rs-ddd
|
||||
cd server-rs
|
||||
cargo check -p spacetime-module
|
||||
cargo check -p spacetime-client
|
||||
```
|
||||
|
||||
## 任务 D:API / SSE facade
|
||||
|
||||
写入范围:
|
||||
|
||||
```text
|
||||
server-rs/crates/api-server/src/twenty_forty_eight.rs
|
||||
server-rs/crates/api-server/src/twenty_forty_eight_sse.rs
|
||||
server-rs/crates/api-server/src/app.rs
|
||||
server-rs/crates/api-server/src/state.rs
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
```bash
|
||||
cd server-rs
|
||||
cargo check -p api-server
|
||||
npm run api-server
|
||||
```
|
||||
|
||||
## 任务 E:前端创作、结果页与运行态
|
||||
|
||||
写入范围:
|
||||
|
||||
```text
|
||||
src/config/newWorkEntryConfig.ts
|
||||
src/components/platform-entry/*
|
||||
src/components/twenty-forty-eight-creation/*
|
||||
src/components/twenty-forty-eight-result/*
|
||||
src/components/twenty-forty-eight-runtime/*
|
||||
src/services/twenty-forty-eight-*
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
```bash
|
||||
npm run typecheck
|
||||
npm run test -- twenty
|
||||
npm run check:encoding
|
||||
```
|
||||
|
||||
## 任务 F:作品架、广场、分享与回归
|
||||
|
||||
写入范围:
|
||||
|
||||
```text
|
||||
src/components/custom-world-home/creationWorkShelf.ts
|
||||
src/services/publicWorkCode.ts
|
||||
src/components/common/PublishShareModal.tsx
|
||||
src/components/twenty-forty-eight-gallery/*
|
||||
docs/technical/NEW_WORK_ENTRY_CONFIG_2026-05-01.md
|
||||
docs/technical/SPACETIMEDB_TABLE_CATALOG.md
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
```bash
|
||||
npm run typecheck
|
||||
npm run test
|
||||
npm run check:encoding
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 18. 最小上线清单
|
||||
|
||||
1. `twenty-forty-eight` 入口可展示并进入工作台。
|
||||
2. Agent 可生成主题化 2048 草稿。
|
||||
3. 结果页可编辑基本信息、棋盘配置和合成链。
|
||||
4. 结果页可试玩。
|
||||
5. 运行态可完成标准 2048 移动、合并、生成新方块、目标达成和失败。
|
||||
6. 发布后作品进入作品架和广场。
|
||||
7. 玩家可从广场进入公开 run。
|
||||
8. 榜单只记录后端裁决的正式成绩。
|
||||
9. 前后端契约字段 camelCase / snake_case 映射明确。
|
||||
10. SpacetimeDB 表、migration、表目录和 bindings 同步。
|
||||
|
||||
---
|
||||
|
||||
## 19. 验收标准
|
||||
|
||||
当下面结果都成立时,视为 `2048` 玩法模板落地完成:
|
||||
|
||||
1. 平台有独立 `2048` 创作入口。
|
||||
2. 玩法 ID 使用 `twenty-forty-eight`。
|
||||
3. 能进入 2048 Agent 工作台。
|
||||
4. 能通过 Agent 生成草稿。
|
||||
5. 结果页可编辑作品名、简介、标签、棋盘参数、合成链和封面。
|
||||
6. 发布校验能阻断非法草稿。
|
||||
7. 试玩能进入 2048 运行态。
|
||||
8. 运行态支持移动端滑动和桌面方向键。
|
||||
9. 后端能裁决移动、合并、得分、新方块生成和胜负。
|
||||
10. 无效移动不增加步数,不生成新方块。
|
||||
11. 达成目标后可结算或继续挑战。
|
||||
12. 失败后不能继续提交移动。
|
||||
13. 发布作品能进入作品架、广场和分享链路。
|
||||
14. 排行榜只接受正式 run 的后端结算成绩。
|
||||
15. 新增表结构同步 `migration.rs`、表目录和 bindings。
|
||||
16. UI 不默认展示长篇规则说明,不把独立弹窗做成面板下方展开。
|
||||
17. 移动端和桌面端都能正常显示和操作。
|
||||
|
||||
---
|
||||
|
||||
## 20. 一句话结论
|
||||
|
||||
`2048` 在 Genarrative 中应被做成一个可创作、可换皮、可发布、可排行的主题合成棋盘模板:创作端让百梦主定义合成链和视觉承诺,运行端保持经典 2048 的滑动合并手感,服务端负责正式棋盘裁决、作品状态和成绩真相。
|
||||
@@ -0,0 +1,826 @@
|
||||
# AI 原生幸存者类游戏模板 PRD
|
||||
|
||||
更新时间:`2026-05-05`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份 PRD 用于在当前平台内新增一条“幸存者类游戏模板”产品链路,冻结它从创作入口、Agent 共创、结果页、试玩、发布到运行态结算的完整边界。
|
||||
|
||||
本模板参考的是幸存者 / 割草 / 轻度 Roguelite 类玩法的通用结构:玩家在俯视角战场中移动、生存、自动攻击、拾取经验、选择升级,并在持续敌潮中坚持到胜利时间或击败终局首领。
|
||||
|
||||
本次不是复制某个具体商业游戏,也不是新增一个孤立前端小游戏。正式实现必须接入 Genarrative 现有平台创作中心、作品架、广场、资产、钱包、埋点和 `server-rs + Axum + SpacetimeDB` 后端基线。
|
||||
|
||||
---
|
||||
|
||||
## 1. 一句话定义
|
||||
|
||||
`survivor` 是一个 AI 原生幸存者类游戏模板:百梦主通过 Agent 设定主角幻想、敌潮母题、武器技能、成长流派和战场节奏,系统编译出一个移动端优先的俯视角割草生存作品;玩家通过移动躲避敌潮,武器自动攻击,拾取经验升级,在若干分钟内完成生存挑战、击败首领或倒下结算。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前接入级别
|
||||
|
||||
根据新增玩法类型接入分级,本模板目标为 **完整玩法闭环**:
|
||||
|
||||
1. 新增玩法 ID:`survivor`。
|
||||
2. 对外模板名称:`幸存者挑战`。
|
||||
3. 对外子标题:`割草成长玩法`。
|
||||
4. 支持 Agent 创作、草稿生成、结果页编辑、试玩、发布和公开运行。
|
||||
5. 支持作品架恢复草稿和已发布作品二次编辑。
|
||||
6. 支持玩家从作品详情或广场进入运行态。
|
||||
7. 支持后端权威生成局面、升级候选、波次配置、结算和成绩基础数据。
|
||||
8. 前端负责高频模拟与表现,但不得自行发明正式规则、波次、掉落、升级池或结算真相。
|
||||
|
||||
---
|
||||
|
||||
## 3. 产品定位
|
||||
|
||||
## 3.1 命名
|
||||
|
||||
1. 对外模板名称:`幸存者挑战`。
|
||||
2. 对外子标题:`割草成长玩法`。
|
||||
3. 开发代号:`Survivor`。
|
||||
4. 工程玩法域:`survivor`。
|
||||
5. 后端模块命名预期:`survivor`。
|
||||
|
||||
## 3.2 核心乐趣
|
||||
|
||||
1. 玩家被敌潮包围,通过走位制造空间。
|
||||
2. 武器自动攻击,玩家专注移动、拾取、选择升级。
|
||||
3. 每次升级出现少量高价值选择,形成局内构筑。
|
||||
4. 敌人数量、速度、血量和特殊能力逐步加压。
|
||||
5. 后期屏幕内形成高密度清场反馈,玩家获得成长压倒敌潮的爽感。
|
||||
|
||||
## 3.3 与现有玩法的区别
|
||||
|
||||
1. 不等同于 RPG:不依赖世界章节、NPC 对话或剧情推进。
|
||||
2. 不等同于大鱼吃小鱼:不做吞噬收编和三合一实体升级。
|
||||
3. 不等同于抓大鹅:不做备选栏三消和堆叠点击。
|
||||
4. 不等同于拼图:不切图、不交换、不合并拼块。
|
||||
5. 不新增通用动作游戏引擎,本期只服务幸存者类模板。
|
||||
|
||||
---
|
||||
|
||||
## 4. 完整闭环目标
|
||||
|
||||
本模板首版必须补齐:
|
||||
|
||||
1. 平台创作入口展示“幸存者挑战”。
|
||||
2. Agent 对话收集玩法锚点。
|
||||
3. 后端编译幸存者玩法草稿。
|
||||
4. 结果页编辑作品名、封面、标签、主角、敌人、武器、成长和战场配置。
|
||||
5. 结果页支持生成或替换关键视觉资产。
|
||||
6. 结果页支持发布前试玩。
|
||||
7. 作品可保存、发布、删除和二次编辑。
|
||||
8. 玩家从作品详情或广场创建 run。
|
||||
9. 后端下发权威 run seed、波次、敌人、武器、升级候选和结算规则。
|
||||
10. 前端按权威配置执行高频运行表现,定期提交 checkpoint。
|
||||
11. 玩家升级时从后端确认的候选卡中选择一张。
|
||||
12. 玩家死亡、主动退出、倒计时胜利或终局首领胜利后进入结算。
|
||||
13. 结算成绩以后端确认的 run snapshot 为准。
|
||||
|
||||
---
|
||||
|
||||
## 5. 明确不做
|
||||
|
||||
首版明确不做:
|
||||
|
||||
1. 不做联机、PvP、组队或排行榜赛季。
|
||||
2. 不做横屏专属设计,移动端竖屏优先。
|
||||
3. 不做复杂地形寻路、真实物理碰撞和高精度弹幕编辑器。
|
||||
4. 不做多地图章节战役,只做单局挑战。
|
||||
5. 不做局外装备养成、抽卡、永久技能树或付费强化。
|
||||
6. 不要求百梦主逐帧编辑怪物 AI、弹道曲线或数值公式。
|
||||
7. 不把玩法规则说明长文默认写进 UI 面板。
|
||||
8. 不把按钮弹出的资产、升级或参数编辑做成当前卡片下方展开内容,统一使用独立面板。
|
||||
9. 不让前端本地结算直接写入正式成绩、钱包、任务或排行榜。
|
||||
10. 不复用 `server-node`、Express、PostgreSQL 或旧 RPG runtime 作为新增实现目标。
|
||||
|
||||
---
|
||||
|
||||
## 6. 创作锚点设计
|
||||
|
||||
Agent 型创作版本至少收集下面 5 个高杠杆锚点:
|
||||
|
||||
| 锚点 | 字段建议 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| 生存幻想 | `survivalFantasy` | 决定主角身份、战斗气质和作品一句话承诺。 |
|
||||
| 敌潮母题 | `hordeTheme` | 决定敌人类型、数量感、压迫方式和视觉风格。 |
|
||||
| 武器技能 | `weaponFantasy` | 决定自动攻击、范围技能、投射物和特效方向。 |
|
||||
| 成长流派 | `buildArchetype` | 决定升级卡池、进化组合和玩家构筑路线。 |
|
||||
| 战场节奏 | `stageRhythm` | 决定单局时长、波次曲线、首领节点和胜利条件。 |
|
||||
|
||||
Agent 必须围绕用户灵感收束这些锚点,不允许把创作入口做成一屏参数问卷。
|
||||
|
||||
## 6.1 锚点状态
|
||||
|
||||
每个锚点都支持:
|
||||
|
||||
1. `待补充`
|
||||
2. `Agent 推断`
|
||||
3. `已确认`
|
||||
4. `已锁定`
|
||||
|
||||
## 6.2 收束条件
|
||||
|
||||
满足下面条件后,系统允许编译第一版草稿:
|
||||
|
||||
1. `生存幻想` 已确认或已锁定。
|
||||
2. `敌潮母题` 已确认或已锁定。
|
||||
3. `武器技能` 至少有 `3` 个可用武器草稿。
|
||||
4. `成长流派` 至少有 `6` 张升级卡草稿。
|
||||
5. `战场节奏` 已确认,或使用系统默认 `8` 分钟短局配置。
|
||||
|
||||
## 6.3 快捷补全
|
||||
|
||||
当会话至少完成 `2` 轮后,工作区提供 `补充剩余关键字` 快捷动作:
|
||||
|
||||
1. 前端发送消息接口,并携带 `quickFillRequested: true`。
|
||||
2. 用户消息固定为“请补充剩余关键字。”。
|
||||
3. 后端 Agent 根据当前锚点补齐缺失内容。
|
||||
4. 前端不得自行推断武器、波次、敌人或升级卡。
|
||||
|
||||
## 6.4 Agent AI 生成契约
|
||||
|
||||
单轮模型输出必须是严格 JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"replyText": "",
|
||||
"progressPercent": 0,
|
||||
"anchors": {
|
||||
"survivalFantasy": { "status": "pending", "summary": "" },
|
||||
"hordeTheme": { "status": "pending", "summary": "" },
|
||||
"weaponFantasy": { "status": "pending", "summary": "" },
|
||||
"buildArchetype": { "status": "pending", "summary": "" },
|
||||
"stageRhythm": { "status": "pending", "summary": "" }
|
||||
},
|
||||
"nextDraftPatch": {}
|
||||
}
|
||||
```
|
||||
|
||||
落地约束:
|
||||
|
||||
1. `replyText` 是直接展示给百梦主的中文回复,不得出现 JSON、字段名或内部协议说明。
|
||||
2. `progressPercent` 只能由后端校验后采纳,范围 `0~100`。
|
||||
3. `nextDraftPatch` 只允许写入幸存者草稿字段,不允许修改平台账号、钱包或作品归属。
|
||||
4. 模型不可用或结果无法解析时,接口返回明确错误,不用固定模板伪装 AI 回复。
|
||||
|
||||
---
|
||||
|
||||
## 7. 草稿契约
|
||||
|
||||
## 7.1 `SurvivorResultDraft`
|
||||
|
||||
```ts
|
||||
export interface SurvivorResultDraft {
|
||||
profileId: string | null;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
workTags: string[];
|
||||
coverImageSrc: string | null;
|
||||
anchors: SurvivorAnchorPack;
|
||||
hero: SurvivorHeroDraft;
|
||||
enemies: SurvivorEnemyDraft[];
|
||||
weapons: SurvivorWeaponDraft[];
|
||||
upgrades: SurvivorUpgradeDraft[];
|
||||
evolutions: SurvivorEvolutionDraft[];
|
||||
stage: SurvivorStageDraft;
|
||||
wavePlan: SurvivorWavePlanDraft;
|
||||
runtimeConfig: SurvivorRuntimeConfigDraft;
|
||||
publishReady: boolean;
|
||||
validationIssues: SurvivorValidationIssue[];
|
||||
updatedAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 7.2 主角草稿
|
||||
|
||||
```ts
|
||||
export interface SurvivorHeroDraft {
|
||||
heroId: string;
|
||||
name: string;
|
||||
fantasy: string;
|
||||
moveSpeed: number;
|
||||
maxHp: number;
|
||||
defense: number;
|
||||
pickupRadius: number;
|
||||
spriteAssetId: string | null;
|
||||
portraitAssetId: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
默认范围:
|
||||
|
||||
1. `moveSpeed`:`80~180`,默认 `120`。
|
||||
2. `maxHp`:`50~300`,默认 `100`。
|
||||
3. `defense`:`0~50`,默认 `0`。
|
||||
4. `pickupRadius`:`30~160`,默认 `60`。
|
||||
|
||||
## 7.3 敌人草稿
|
||||
|
||||
```ts
|
||||
export interface SurvivorEnemyDraft {
|
||||
enemyId: string;
|
||||
name: string;
|
||||
role: 'fodder' | 'runner' | 'tank' | 'ranged' | 'elite' | 'boss';
|
||||
visualPrompt: string;
|
||||
maxHp: number;
|
||||
damage: number;
|
||||
moveSpeed: number;
|
||||
xpValue: number;
|
||||
spawnWeight: number;
|
||||
spriteAssetId: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
首版发布至少需要:
|
||||
|
||||
1. `2` 个 `fodder` 或 `runner` 敌人。
|
||||
2. `1` 个 `elite` 敌人。
|
||||
3. `1` 个 `boss` 敌人。
|
||||
|
||||
## 7.4 武器草稿
|
||||
|
||||
```ts
|
||||
export interface SurvivorWeaponDraft {
|
||||
weaponId: string;
|
||||
name: string;
|
||||
attackKind: 'projectile' | 'orbit' | 'area' | 'beam' | 'melee_aura';
|
||||
targeting: 'nearest' | 'random_enemy' | 'forward' | 'around_hero';
|
||||
baseDamage: number;
|
||||
cooldownMs: number;
|
||||
projectileCount: number;
|
||||
range: number;
|
||||
effectAssetId: string | null;
|
||||
upgradeTags: string[];
|
||||
}
|
||||
```
|
||||
|
||||
首版必须至少有 `3` 个武器。玩家开局默认持有第一个武器。
|
||||
|
||||
## 7.5 升级卡草稿
|
||||
|
||||
```ts
|
||||
export interface SurvivorUpgradeDraft {
|
||||
upgradeId: string;
|
||||
name: string;
|
||||
rarity: 'common' | 'rare' | 'epic';
|
||||
targetKind: 'hero' | 'weapon' | 'global';
|
||||
targetId: string | null;
|
||||
effectKind:
|
||||
| 'damage_percent'
|
||||
| 'cooldown_percent'
|
||||
| 'projectile_count'
|
||||
| 'move_speed_percent'
|
||||
| 'max_hp_flat'
|
||||
| 'pickup_radius_percent'
|
||||
| 'regen_flat';
|
||||
value: number;
|
||||
maxStack: number;
|
||||
iconAssetId: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
首版至少需要 `6` 张升级卡,并保证任意升级节点能从可用池中抽出 `3` 张候选。
|
||||
|
||||
## 7.6 进化组合
|
||||
|
||||
```ts
|
||||
export interface SurvivorEvolutionDraft {
|
||||
evolutionId: string;
|
||||
name: string;
|
||||
baseWeaponId: string;
|
||||
requiredUpgradeIds: string[];
|
||||
resultWeapon: SurvivorWeaponDraft;
|
||||
}
|
||||
```
|
||||
|
||||
进化组合首版可选,但字段必须预留。若启用进化,结果页必须展示组合条件,不在运行态长文解释。
|
||||
|
||||
## 7.7 战场草稿
|
||||
|
||||
```ts
|
||||
export interface SurvivorStageDraft {
|
||||
stageId: string;
|
||||
name: string;
|
||||
theme: string;
|
||||
backgroundAssetId: string | null;
|
||||
groundTextureAssetId: string | null;
|
||||
safeAreaShape: 'rectangle' | 'circle';
|
||||
width: number;
|
||||
height: number;
|
||||
obstacleDensity: number;
|
||||
}
|
||||
```
|
||||
|
||||
首版默认不生成实心障碍,`obstacleDensity` 固定为 `0`。后续要开放障碍,必须先补充寻路与碰撞方案。
|
||||
|
||||
## 7.8 波次草稿
|
||||
|
||||
```ts
|
||||
export interface SurvivorWavePlanDraft {
|
||||
durationSeconds: number;
|
||||
waves: SurvivorWaveDraft[];
|
||||
bossWave: SurvivorBossWaveDraft;
|
||||
}
|
||||
|
||||
export interface SurvivorWaveDraft {
|
||||
startSecond: number;
|
||||
endSecond: number;
|
||||
enemyPool: string[];
|
||||
spawnRatePerSecond: number;
|
||||
maxAlive: number;
|
||||
statMultiplier: number;
|
||||
}
|
||||
```
|
||||
|
||||
默认短局:
|
||||
|
||||
1. `durationSeconds`:`480`。
|
||||
2. 每 `60` 秒一个波次。
|
||||
3. `240` 秒出现精英压力波。
|
||||
4. `480` 秒出现终局首领或进入胜利结算。
|
||||
|
||||
---
|
||||
|
||||
## 8. 运行规则设计
|
||||
|
||||
## 8.1 单局结构
|
||||
|
||||
首版标准局为 `8` 分钟短局:
|
||||
|
||||
1. 玩家开局拥有 `1` 个基础武器。
|
||||
2. 玩家通过虚拟摇杆或键盘移动。
|
||||
3. 武器按冷却自动攻击。
|
||||
4. 敌人从屏幕外安全环刷出并向玩家移动。
|
||||
5. 敌人碰撞玩家造成伤害。
|
||||
6. 敌人死亡掉落经验晶体。
|
||||
7. 玩家拾取经验后升级。
|
||||
8. 升级时暂停运行态,展示 `3` 张升级卡。
|
||||
9. 玩家选择一张升级卡后继续运行。
|
||||
10. 玩家生命归零失败。
|
||||
11. 生存到终局时间或击败终局首领胜利。
|
||||
|
||||
## 8.2 移动与输入
|
||||
|
||||
1. 移动端使用左下角虚拟摇杆。
|
||||
2. 桌面端支持 `WASD` / 方向键移动。
|
||||
3. 首版不要求手动瞄准和手动开火。
|
||||
4. 前端必须保证摇杆、血量、经验条、升级面板和结算面板在竖屏下不遮挡核心战场。
|
||||
|
||||
## 8.3 自动攻击
|
||||
|
||||
1. 每个武器独立维护冷却。
|
||||
2. 目标选择策略由后端配置下发。
|
||||
3. 前端可本地执行攻击表现与命中模拟,但必须使用后端下发的武器参数和 RNG seed。
|
||||
4. 武器伤害、冷却、投射数量和范围变化来自后端确认的升级结果。
|
||||
|
||||
## 8.4 敌潮生成
|
||||
|
||||
1. 敌人只能从玩家当前视野外的刷怪环生成。
|
||||
2. 刷怪位置不得直接贴脸。
|
||||
3. 每个波次有 `spawnRatePerSecond` 和 `maxAlive` 上限。
|
||||
4. 前端不得自行增加敌人类型、刷新率或精英节点。
|
||||
5. 后端 checkpoint 校验时应能根据 seed、波次和输入摘要重放关键统计。
|
||||
|
||||
## 8.5 经验与升级
|
||||
|
||||
1. 敌人死亡生成经验晶体。
|
||||
2. 玩家碰到晶体或晶体进入拾取半径时获得经验。
|
||||
3. 经验达到当前等级阈值时触发升级。
|
||||
4. 升级候选由后端按当前 build、权重、稀有度和 seed 生成。
|
||||
5. 前端只能展示后端返回的候选卡。
|
||||
6. 玩家选择后,后端更新 run build snapshot。
|
||||
|
||||
## 8.6 失败与胜利
|
||||
|
||||
失败条件:
|
||||
|
||||
1. `heroHp <= 0`。
|
||||
2. 玩家主动退出并确认放弃。
|
||||
3. 后端判定 run 校验失败。
|
||||
|
||||
胜利条件:
|
||||
|
||||
1. 生存到 `durationSeconds` 并完成终局结算。
|
||||
2. 或在终局波次击败 `boss`。
|
||||
|
||||
---
|
||||
|
||||
## 9. 权威状态与高频模拟边界
|
||||
|
||||
幸存者类玩法需要高频碰撞和大量实体,不能把每一帧都交给 HTTP 往返。首版采用“后端权威配置 + 前端确定性运行表现 + 后端 checkpoint / 结算确认”的边界。
|
||||
|
||||
## 9.1 后端职责
|
||||
|
||||
后端负责:
|
||||
|
||||
1. 创建创作会话和玩法草稿。
|
||||
2. 校验和保存作品 profile。
|
||||
3. 编译 run seed、波次、敌人、武器、升级池和结算规则。
|
||||
4. 生成升级候选。
|
||||
5. 确认升级选择。
|
||||
6. 接收运行 checkpoint。
|
||||
7. 校验关键统计是否在合理范围内。
|
||||
8. 确认死亡、胜利、退出和最终成绩。
|
||||
9. 写入作品游玩次数、成绩、埋点和任务事件。
|
||||
|
||||
## 9.2 前端职责
|
||||
|
||||
前端负责:
|
||||
|
||||
1. 展示 Agent 工作台和结果页。
|
||||
2. 渲染战场、主角、敌人、投射物、特效、经验晶体和 HUD。
|
||||
3. 基于后端 run config 执行确定性高频模拟。
|
||||
4. 采集玩家移动输入。
|
||||
5. 展示攻击、受击、拾取、升级、胜利和失败反馈。
|
||||
6. 定期提交 checkpoint。
|
||||
7. 在后端拒绝 checkpoint 或结算时,展示同步失败并结束本局。
|
||||
|
||||
## 9.3 Checkpoint 规则
|
||||
|
||||
前端每 `5` 秒或关键节点提交 checkpoint:
|
||||
|
||||
```ts
|
||||
export interface SurvivorRunCheckpointRequest {
|
||||
runId: string;
|
||||
snapshotVersion: number;
|
||||
elapsedMs: number;
|
||||
inputDigest: string;
|
||||
rngStep: number;
|
||||
heroHp: number;
|
||||
heroLevel: number;
|
||||
killCount: number;
|
||||
eliteKillCount: number;
|
||||
bossKillCount: number;
|
||||
xpCollected: number;
|
||||
selectedUpgradeIds: string[];
|
||||
checksum: string;
|
||||
}
|
||||
```
|
||||
|
||||
关键节点包括:
|
||||
|
||||
1. 升级触发前。
|
||||
2. 选择升级后。
|
||||
3. 精英死亡。
|
||||
4. Boss 出现。
|
||||
5. Boss 死亡。
|
||||
6. 玩家死亡。
|
||||
7. 胜利结算。
|
||||
|
||||
---
|
||||
|
||||
## 10. 结果页设计
|
||||
|
||||
## 10.1 结果页职责
|
||||
|
||||
幸存者结果页是最小可编辑工作台,不是只读总结页。
|
||||
|
||||
结果页至少包含:
|
||||
|
||||
1. 作品基础信息。
|
||||
2. 主角配置。
|
||||
3. 敌人图鉴。
|
||||
4. 武器与升级卡池。
|
||||
5. 战场与波次。
|
||||
6. 资产状态。
|
||||
7. 试玩入口。
|
||||
8. 发布校验。
|
||||
|
||||
## 10.2 移动端优先布局
|
||||
|
||||
1. 首屏显示作品标题、封面、发布状态和试玩按钮。
|
||||
2. 主角、敌人、武器、战场使用分组入口。
|
||||
3. 点击分组入口打开独立编辑面板。
|
||||
4. 不在卡片下方展开长规则说明。
|
||||
5. 发布校验只展示短状态和可处理项,不展示底层协议。
|
||||
|
||||
## 10.3 资产要求
|
||||
|
||||
正式发布前至少需要:
|
||||
|
||||
1. 作品封面。
|
||||
2. 主角头像或主角小人资产。
|
||||
3. `3` 类普通敌人资产。
|
||||
4. `1` 类精英或首领资产。
|
||||
5. `3` 个武器或技能图标。
|
||||
6. `1` 张战场背景或地面纹理。
|
||||
|
||||
程序化色块或几何占位只允许用于开发调试和未发布草稿,不允许作为正式发布作品的默认资产。
|
||||
|
||||
## 10.4 结果页核心操作
|
||||
|
||||
结果页支持:
|
||||
|
||||
1. `生成主角资产`
|
||||
2. `生成敌人资产`
|
||||
3. `生成武器图标`
|
||||
4. `生成战场背景`
|
||||
5. `重新编译波次`
|
||||
6. `试玩`
|
||||
7. `保存草稿`
|
||||
8. `发布`
|
||||
9. `返回创作对话`
|
||||
|
||||
---
|
||||
|
||||
## 11. API 设计
|
||||
|
||||
## 11.1 创作接口
|
||||
|
||||
1. `POST /api/creation/survivor/sessions`
|
||||
2. `GET /api/creation/survivor/sessions/{sessionId}`
|
||||
3. `POST /api/creation/survivor/sessions/{sessionId}/messages`
|
||||
4. `POST /api/creation/survivor/sessions/{sessionId}/messages/stream`
|
||||
5. `POST /api/creation/survivor/sessions/{sessionId}/actions`
|
||||
6. `POST /api/creation/survivor/sessions/{sessionId}/compile`
|
||||
7. `GET /api/creation/survivor/works`
|
||||
8. `GET /api/creation/survivor/works/{profileId}`
|
||||
9. `PUT /api/creation/survivor/works/{profileId}`
|
||||
10. `POST /api/creation/survivor/works/{profileId}/publish`
|
||||
11. `DELETE /api/creation/survivor/works/{profileId}`
|
||||
|
||||
## 11.2 运行接口
|
||||
|
||||
1. `GET /api/runtime/survivor/gallery`
|
||||
2. `GET /api/runtime/survivor/gallery/{profileId}`
|
||||
3. `POST /api/runtime/survivor/works/{profileId}/runs`
|
||||
4. `GET /api/runtime/survivor/runs/{runId}`
|
||||
5. `POST /api/runtime/survivor/runs/{runId}/checkpoint`
|
||||
6. `POST /api/runtime/survivor/runs/{runId}/upgrade-options`
|
||||
7. `POST /api/runtime/survivor/runs/{runId}/choose-upgrade`
|
||||
8. `POST /api/runtime/survivor/runs/{runId}/settle`
|
||||
9. `POST /api/runtime/survivor/runs/{runId}/stop`
|
||||
10. `POST /api/runtime/survivor/runs/{runId}/restart`
|
||||
|
||||
## 11.3 SSE 事件
|
||||
|
||||
创作对话流式事件复用平台 Agent envelope。运行态首版不要求全程 SSE;如后续加入服务端实时推送,只允许推送权威 milestone,不传每帧实体状态。
|
||||
|
||||
---
|
||||
|
||||
## 12. 后端分层边界
|
||||
|
||||
完整实现时必须遵循当前后端路线:
|
||||
|
||||
1. `server-rs/crates/module-survivor`
|
||||
- 纯领域规则、草稿校验、波次编译、升级池、评分和 checkpoint 校验。
|
||||
- 不依赖 Axum、SpacetimeDB、OSS 或 LLM。
|
||||
2. `server-rs/crates/shared-contracts`
|
||||
- 暴露 Survivor Agent、作品、运行态 DTO。
|
||||
3. `server-rs/crates/spacetime-module`
|
||||
- 存储 session、message、work profile、runtime run 和 runtime event。
|
||||
- 表结构变化必须同步 `migration.rs` 与表目录。
|
||||
4. `server-rs/crates/spacetime-client`
|
||||
- 提供 api-server 调用 SpacetimeDB 的 typed facade。
|
||||
5. `server-rs/crates/api-server`
|
||||
- 暴露 `/api/creation/survivor/*` 与 `/api/runtime/survivor/*`。
|
||||
- 处理鉴权、错误 envelope、LLM turn、资产生成和 HTTP facade。
|
||||
6. `platform-agent` / `platform-llm`
|
||||
- 承接 Agent 对话与草稿生成。
|
||||
7. `platform-oss`
|
||||
- 承接封面、角色、敌人、武器图标和战场背景资产。
|
||||
|
||||
---
|
||||
|
||||
## 13. SpacetimeDB 表建议
|
||||
|
||||
首版建议新增:
|
||||
|
||||
1. `survivor_agent_session`
|
||||
- 创作会话主表,保存 owner、stage、anchors、draft、progress、published_profile_id。
|
||||
2. `survivor_agent_message`
|
||||
- 创作消息流水。
|
||||
3. `survivor_work_profile`
|
||||
- 作品 profile,保存发布态草稿、封面、标签、作者和公开状态。
|
||||
4. `survivor_runtime_run`
|
||||
- 运行态 run,保存 run config、seed、当前 snapshot、checkpoint 摘要和结算状态。
|
||||
5. `survivor_runtime_event`
|
||||
- 运行审计事件,记录 start、checkpoint、upgrade、death、victory、settle 等关键事件。
|
||||
|
||||
首版不新增正式排行榜表。若后续加入排行榜,再新增 `survivor_leaderboard_entry` 并补充反作弊和赛季边界。
|
||||
|
||||
---
|
||||
|
||||
## 14. 作品结构建议
|
||||
|
||||
```ts
|
||||
export interface SurvivorWorkProfile {
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
sourceSessionId: string | null;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
workTags: string[];
|
||||
coverImageSrc: string | null;
|
||||
publicationStatus: 'draft' | 'published' | 'archived';
|
||||
draft: SurvivorResultDraft;
|
||||
playCount: number;
|
||||
updatedAt: string;
|
||||
publishedAt: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
## 14.1 发布校验
|
||||
|
||||
发布必须满足:
|
||||
|
||||
1. `workTitle` 非空。
|
||||
2. 至少 `1` 个标签。
|
||||
3. 有封面图。
|
||||
4. 主角配置完整。
|
||||
5. 至少 `4` 个敌人,其中包含普通、精英或首领。
|
||||
6. 至少 `3` 个武器。
|
||||
7. 至少 `6` 张升级卡。
|
||||
8. 波次覆盖完整 `durationSeconds`。
|
||||
9. 资产覆盖满足正式发布要求。
|
||||
10. `runtimeConfig` 在后端数值上限内。
|
||||
|
||||
---
|
||||
|
||||
## 15. 运行态快照建议
|
||||
|
||||
```ts
|
||||
export interface SurvivorRunSnapshot {
|
||||
runId: string;
|
||||
profileId: string;
|
||||
ownerUserId: string | null;
|
||||
status: 'running' | 'level_up_pending' | 'victory' | 'defeat' | 'stopped' | 'settlement_failed';
|
||||
snapshotVersion: number;
|
||||
seed: string;
|
||||
elapsedMs: number;
|
||||
durationLimitMs: number;
|
||||
hero: SurvivorRunHeroSnapshot;
|
||||
build: SurvivorRunBuildSnapshot;
|
||||
wave: SurvivorRunWaveSnapshot;
|
||||
stats: SurvivorRunStatsSnapshot;
|
||||
pendingUpgradeOptions: SurvivorUpgradeOption[];
|
||||
settlement: SurvivorRunSettlement | null;
|
||||
updatedAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
前端渲染可维护更细的局内实体列表,但正式持久化只保存 run snapshot、checkpoint 摘要和结算结果。
|
||||
|
||||
---
|
||||
|
||||
## 16. 计分与结算
|
||||
|
||||
首版结算至少展示:
|
||||
|
||||
1. 胜利 / 失败状态。
|
||||
2. 生存时间。
|
||||
3. 击杀数。
|
||||
4. 等级。
|
||||
5. 精英击杀数。
|
||||
6. 首领击杀数。
|
||||
7. 选择过的核心升级。
|
||||
8. 再来一局。
|
||||
9. 返回作品详情。
|
||||
|
||||
基础分数公式:
|
||||
|
||||
```text
|
||||
score = survivedSeconds * 10
|
||||
+ killCount * 5
|
||||
+ eliteKillCount * 120
|
||||
+ bossKillCount * 500
|
||||
+ heroLevel * 80
|
||||
```
|
||||
|
||||
结算入库以后端确认结果为准。前端展示的即时结算在后端确认前必须标记为待确认状态。
|
||||
|
||||
---
|
||||
|
||||
## 17. 平台接入
|
||||
|
||||
## 17.1 创作入口
|
||||
|
||||
需要接入:
|
||||
|
||||
1. `src/config/newWorkEntryConfig.ts`
|
||||
2. `src/components/platform-entry/platformEntryCreationTypes.ts`
|
||||
3. `src/components/platform-entry/platformEntryTypes.ts`
|
||||
4. `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
|
||||
|
||||
新增阶段建议:
|
||||
|
||||
1. `survivor-agent-workspace`
|
||||
2. `survivor-generating`
|
||||
3. `survivor-result`
|
||||
4. `survivor-runtime`
|
||||
5. `survivor-gallery-detail`
|
||||
|
||||
## 17.2 前端组件建议
|
||||
|
||||
1. `src/components/survivor-creation/SurvivorAgentWorkspace.tsx`
|
||||
2. `src/components/survivor-result/SurvivorResultView.tsx`
|
||||
3. `src/components/survivor-runtime/SurvivorRuntimeShell.tsx`
|
||||
4. `src/services/survivorCreationClient.ts`
|
||||
5. `src/services/survivorRuntimeClient.ts`
|
||||
6. `src/services/survivorWorksClient.ts`
|
||||
|
||||
## 17.3 作品架与广场
|
||||
|
||||
发布后必须接入:
|
||||
|
||||
1. 创作页作品架。
|
||||
2. 平台作品详情。
|
||||
3. 首页或发现页公开作品流。
|
||||
4. 公开作品试玩入口。
|
||||
5. 删除、二次编辑和重新发布。
|
||||
|
||||
---
|
||||
|
||||
## 18. UI 设计约束
|
||||
|
||||
1. 移动端竖屏优先,桌面端居中或宽屏增强。
|
||||
2. HUD 只保留血量、经验、时间、等级、击杀数和暂停入口。
|
||||
3. 升级卡使用独立面板,最多显示 `3` 张候选。
|
||||
4. 暂停、结算、资产生成、参数编辑都使用独立面板。
|
||||
5. 不默认展示规则说明长文。
|
||||
6. 运行态主画面不能被功能介绍、键位说明或装饰卡片遮挡。
|
||||
7. 触控区、摇杆、升级卡和按钮必须满足移动端可点击尺寸。
|
||||
8. 图标按钮优先使用现有图标库;无图标时再使用简短文本。
|
||||
|
||||
---
|
||||
|
||||
## 19. 里程碑拆分
|
||||
|
||||
## 19.1 Phase 1:入口与 PRD 骨架
|
||||
|
||||
1. 冻结 `survivor` 玩法 ID。
|
||||
2. 新增入口配置。
|
||||
3. 新增前端阶段枚举。
|
||||
4. 新增 shared contracts 草案。
|
||||
5. 入口可以进入占位工作台。
|
||||
|
||||
## 19.2 Phase 2:创作会话与结果页
|
||||
|
||||
1. 新增 Agent session。
|
||||
2. 新增消息与流式回复。
|
||||
3. 编译第一版 `SurvivorResultDraft`。
|
||||
4. 结果页可编辑主角、敌人、武器、升级和波次。
|
||||
5. 支持保存草稿。
|
||||
|
||||
## 19.3 Phase 3:后端运行态
|
||||
|
||||
1. `module-survivor` 实现波次、升级池、结算和 checkpoint 校验。
|
||||
2. SpacetimeDB 表、migration 和 facade 收口。
|
||||
3. api-server 暴露 runtime API。
|
||||
4. 支持创建 run、选择升级、提交 checkpoint 和结算。
|
||||
|
||||
## 19.4 Phase 4:前端运行态
|
||||
|
||||
1. 实现竖屏战场。
|
||||
2. 实现摇杆移动。
|
||||
3. 实现自动攻击、敌潮、经验和升级面板。
|
||||
4. 实现胜利、失败、暂停和结算。
|
||||
5. 接入后端 checkpoint 与升级确认。
|
||||
|
||||
## 19.5 Phase 5:发布与平台闭环
|
||||
|
||||
1. 发布作品。
|
||||
2. 接入作品架。
|
||||
3. 接入公开详情和广场。
|
||||
4. 支持二次编辑。
|
||||
5. 接入埋点、任务和基础成绩记录。
|
||||
|
||||
---
|
||||
|
||||
## 20. 验收标准
|
||||
|
||||
1. `src/config/newWorkEntryConfig.ts` 中存在 `survivor` 类型。
|
||||
2. 新建作品入口和创作类型弹层能展示“幸存者挑战”。
|
||||
3. 能进入 `survivor-agent-workspace`。
|
||||
4. Agent 能生成锚点和草稿。
|
||||
5. 能进入 `survivor-result` 并编辑基础字段。
|
||||
6. 发布校验能阻止缺少主角、敌人、武器、升级卡、波次或资产的作品发布。
|
||||
7. 能从结果页进入试玩运行态。
|
||||
8. 运行态能移动、自动攻击、刷怪、拾取经验、升级和结算。
|
||||
9. 升级候选必须来自后端返回,不由前端临时生成。
|
||||
10. 前端提交 checkpoint 后,后端能接受或拒绝并返回明确结果。
|
||||
11. 作品发布后能在作品架和公开入口恢复。
|
||||
12. 移动端竖屏下主战场、摇杆、HUD、升级卡和结算不互相遮挡。
|
||||
13. 后端实现后执行对应 DDD 验收命令,并用 `npm run api-server` 启动后端检查 `/healthz`。
|
||||
14. 修改包含中文的文档后执行 `npm run check:encoding`。
|
||||
|
||||
---
|
||||
|
||||
## 21. 后续可选增强
|
||||
|
||||
以下能力不进入首版,但需要保留扩展空间:
|
||||
|
||||
1. 多地图主题。
|
||||
2. 局外角色解锁。
|
||||
3. 进化武器动画。
|
||||
4. 精英词缀。
|
||||
5. Boss 特殊弹幕。
|
||||
6. 道具掉落。
|
||||
7. 排行榜。
|
||||
8. 赛季挑战。
|
||||
9. 更多输入模式。
|
||||
10. 服务端更严格的确定性重放校验。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1787
docs/prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md
Normal file
1787
docs/prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
20
docs/prd/README.md
Normal file
20
docs/prd/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# PRD 总览
|
||||
|
||||
本目录用于存放产品需求、玩法闭环、阶段计划和可直接指导编码的需求拆分文档。
|
||||
|
||||
## 重点入口
|
||||
|
||||
- [AI 原生幕间文字游戏模板 PRD:参考 MOKU 的剧本模拟器闭环](./AI_NATIVE_TEXT_GAME_TEMPLATE_MOKU_REFERENCE_PRD_2026-05-05.md):参考 MOKU / 幕间类 AI 文游的剧本游乐场、自由行动、AI GM、记忆和模拟器强反馈经验,但只落为百梦 `text-game` 模板,复用平台接口,不迁入外部社区、支付、私有存档或回放。
|
||||
- [AI 原生视觉小说模板 PRD:TXT 玩法平台化接入](./AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md):参考 `Interactive-fiction-backend` / `Interactive-fiction-frontend` 的 TXT 玩法经验,但只保留视觉小说模板创作与运行闭环,完全使用 Genarrative 平台接口,并明确删除回放和外部平台功能。
|
||||
- [AI 原生幸存者类游戏模板 PRD](./AI_NATIVE_SURVIVOR_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-05.md):定义 `survivor` 幸存者挑战模板,从 Agent 创作、结果页、资产、试玩、发布到后端权威配置与前端高频运行表现的完整闭环。
|
||||
- [创意互动内容生成 Agent Phase 1 PRD:LangChain-Rust PoC + 拼图闭环](./CREATIVE_INTERACTIVE_AGENT_PHASE1_LANGCHAIN_RUST_PUZZLE_LOOP_PRD_2026-05-05.md):首版只支持拼图模板,Agent 使用 APIMart Responses `gpt-5` 支持文本和图像多模态输入,明确模板选择、积分范围、草稿字段填充、单关卡/多关卡图片生成、立即试玩、自然语言修改和可并行任务拆分。
|
||||
- [AI 原生 2048 游戏玩法模板 PRD](./AI_NATIVE_2048_GAMEPLAY_TEMPLATE_PRD_2026-05-05.md):新增 `twenty-forty-eight` 玩法模板,定义主题化合成链创作、结果页、发布、公开运行、后端棋盘裁决、排行榜和并行落地任务。
|
||||
- [AI 原生拼图玩法创作工具与玩法系统 PRD](./AI_NATIVE_PUZZLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-22.md):拼图玩法创作、结果页、发布、广场和运行时主链路。
|
||||
- [AI 原生方洞挑战玩法创作工具与玩法系统 PRD](./AI_NATIVE_SQUARE_HOLE_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-05-04.md):方洞挑战创作、发布与试玩闭环。
|
||||
- [后台管理独立前端工程 PRD](./ADMIN_WEB_CONSOLE_PRD_2026-04-30.md):后台管理端产品边界。
|
||||
|
||||
## 使用规则
|
||||
|
||||
- 新玩法、新 Agent 阶段、新创作闭环或较大功能落地前,优先补 PRD。
|
||||
- PRD 必须写到可以编码的程度,包含字段、接口、状态、验收和并行任务拆分。
|
||||
- 若 PRD 与最新代码或技术方案冲突,以代码和最新技术方案为准,并同步修正 PRD。
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
更新时间:`2026-04-20`
|
||||
|
||||
> 2026-05-05 更新口径:本文保留为历史参考。视觉小说模板后续落地以 [`AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md`](./AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md) 为准;冲突时不再按“外部 TXT 模式原样迁入”执行,必须只保留模板玩法能力、完全使用 Genarrative 平台接口,并删除回放功能。
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份 PRD 只定义 `Interactive-fiction-frontend` + `Interactive-fiction-backend` 中 TXT 模式在 `Genarrative` 落地时的**核心玩法闭环**。
|
||||
|
||||
@@ -115,3 +115,24 @@
|
||||
2. 该失败只代表登录方式配置探测失败,不代表登录功能不可用,因此不把 `读取登录方式失败` 写入登录弹窗错误条。
|
||||
3. 登录弹窗仍展示密码登录表单,玩家可继续登录后进入创作链路。
|
||||
4. 本地仍需要启动 `api-server`,否则后续 `POST /api/auth/entry` 等真实登录请求无法完成。
|
||||
|
||||
## 9. 2026-05-07 本地短信入口恢复记录
|
||||
|
||||
如果登录弹窗里短信登录页签“像是被删了”,先不要改前端表单,优先检查本地登录方式探测结果:
|
||||
|
||||
1. 仓库根目录 `.env.local` 里必须显式保留 `SMS_AUTH_ENABLED=true`。
|
||||
2. 本地启动请优先使用 `npm run api-server`、`npm run dev:rust` 或 `npm run dev`,这些脚本会按“shell 环境优先、`.env.local` 覆盖 `.env`”合并配置。
|
||||
3. 若 `GET /api/auth/login-options` 只返回 `["password"]`,说明短信入口没有被服务端配置打开,前端只是按 contract 正常降级。
|
||||
4. 当 `SMS_AUTH_ENABLED=true` 生效时,`GET /api/auth/login-options` 至少应返回 `["phone", "password"]`,短信登录页签才会重新出现。
|
||||
|
||||
## 10. 2026-05-07 前端代理端口错配修复记录
|
||||
|
||||
如果 Rust API 直连返回 `["phone", "password"]`,但从前端域名请求 `GET /api/auth/login-options` 返回 `500`,短信页签同样会消失。此时不是登录 UI 被删除,而是 `AuthGate` 按第 5.3 节降级成 `["password"]`。
|
||||
|
||||
本地排查顺序固定为:
|
||||
|
||||
1. 先请求 `http://127.0.0.1:3000/api/auth/login-options`,确认前端代理是否成功返回 JSON。
|
||||
2. 再请求当前 Rust API 目标,例如 `http://127.0.0.1:3100/api/auth/login-options` 或 `http://127.0.0.1:8082/api/auth/login-options`。
|
||||
3. 若直连 API 成功而 3000 返回 `500`,检查 `RUST_SERVER_TARGET`、`GENARRATIVE_API_TARGET`、`GENARRATIVE_RUNTIME_SERVER_TARGET` 是否指向仍在监听的 API 端口。
|
||||
4. `npm run dev` / `npm run dev:rust` 完整栈默认由脚本计算 API 端口;加载 `.env.local` 给后端使用后,脚本必须重新固定 `RUST_SERVER_TARGET`,避免 `.env.local` 中的旧代理目标覆盖本次启动的实际 API 端口。
|
||||
5. `npm run dev:web` 只启动前端,不会自动拉起 Rust API;如果单独使用它,必须同时确认其打印的 backend target 已有 `api-server` 正在监听。
|
||||
|
||||
@@ -0,0 +1,948 @@
|
||||
# 创意互动内容生成 Agent 技术方案 2026-05-05
|
||||
|
||||
## 1. 目标
|
||||
|
||||
构建一个基于 LangChain-Rust 的创意互动内容生成 Agent。用户输入文字、图片、文档或混合素材后,Agent 不通过规则分类硬选玩法,而是以模型为核心完成理解、判断、规划和执行:先理解用户真正想表达的创作意图,再选择当前可用的互动内容模板,最后调用拼图模块工具把内容填入草稿契约中。
|
||||
|
||||
当前版本只支持拼图模板。RPG 世界、大鱼吃小鱼、抓大鹅 Match3D、方洞挑战等模板必须在 Agent 可见能力中标记为 `unsupported`,不能创建这些玩法的目标 session。即便只有拼图可用,Agent 仍必须先展示多个拼图模板候选,用户选择某个模板后,再确认该模板下的关卡模式、关卡数和预计积分范围,确认后才进入草稿生成。
|
||||
|
||||
本方案不再把 Agent 设计成“规则路由 workflow”。规则只作为安全护栏、契约校验和成本控制。真正的模板选择、素材理解、草稿构思、行动顺序和补问判断由模型通过工具调用和反思循环完成。
|
||||
|
||||
## 2. LangChain-Rust 选型依据
|
||||
|
||||
当前可参考 `langchainrust` crate 作为 Rust 侧 Agent 编排底座。官方 crate 页面显示 `0.2.18` 支持 Agents、Tools、Memory、Chains、RAG、BM25、Hybrid Retrieval、LangGraph、Typed/JSON output parser、Function Calling、Callbacks 等能力;其中 Agent 层包括 ReActAgent、FunctionCallingAgent、AgentExecutor 和 LangGraph,Memory 层包括 Buffer、Window、Summary、SummaryBuffer、Persistent。
|
||||
|
||||
落地时建议先以 `langchainrust = "0.2.18"` 做隔离性 PoC,不直接替换现有 `platform-llm`。若 crate API 与 docs.rs 最新构建存在差异,以源码和本地编译结果为准,先封装一层 `platform-agent` adapter,再接入 `api-server`。
|
||||
|
||||
参考:
|
||||
|
||||
- `langchainrust` crates.io/docs.rs 页面:https://docs.rs/crate/langchainrust/latest
|
||||
- 仓库主页:https://github.com/atliliw/langchainrust
|
||||
|
||||
## 2.1 Agent 模型与多模态输入
|
||||
|
||||
创意互动内容 Agent 的感知、思考、反思和自然语言草稿修订统一使用 APIMart OpenAI 兼容 Responses API 的 `gpt-5`。这里的 `gpt-5` 负责理解用户文字和图片、选择拼图模板、规划草稿字段和生成结构化工具调用参数;拼图图片生成仍由拼图模块图片工具使用 `gpt-image-2`,不要把“理解/规划模型”和“生图模型”混在同一个配置里。
|
||||
|
||||
请求协议以 APIMart 文档 `OpenAI 多模态响应接口` 为准:
|
||||
|
||||
```text
|
||||
POST https://api.apimart.ai/v1/responses
|
||||
model: gpt-5
|
||||
input[].content[].type: input_text | input_image
|
||||
```
|
||||
|
||||
Phase 1 的 `platform-agent` / `platform-llm` 必须支持下面的项目内请求结构:
|
||||
|
||||
```ts
|
||||
export interface CreativeAgentMultimodalInputPart {
|
||||
type: 'input_text' | 'input_image';
|
||||
text?: string;
|
||||
imageUrl?: string;
|
||||
}
|
||||
|
||||
export interface CreativeAgentGpt5Request {
|
||||
model: 'gpt-5';
|
||||
input: Array<{
|
||||
role: 'system' | 'user' | 'assistant';
|
||||
content: CreativeAgentMultimodalInputPart[];
|
||||
}>;
|
||||
stream: boolean;
|
||||
tools?: CreativeAgentToolSchema[];
|
||||
}
|
||||
```
|
||||
|
||||
落地约束:
|
||||
|
||||
1. Agent 入口支持文本 + 图片多模态输入,首版至少支持 1 张图片,协议层预留多图。
|
||||
2. 图片必须先进入资产系统,Agent 请求使用可访问的 `readUrl` 或受控 Data URI;SpacetimeDB 不保存大图 base64。
|
||||
3. `platform-llm` 当前已有 Responses 协议骨架,但 Phase 1 需要把 content part 从纯文本扩展成 `input_text` / `input_image` 两类。
|
||||
4. `CREATION_TEMPLATE_LLM_MODEL` 等旧文本创作模型不能作为创意互动内容 Agent 的默认模型;本 Agent 必须显式使用 `gpt-5`。
|
||||
5. 如果 LangChain-Rust adapter 暂时无法直接表达多模态 Responses 请求,应在 `platform-agent` 内桥接到 `platform-llm` 的多模态 Responses client,不能退回纯文本摘要替代图片理解。
|
||||
6. 模型工具调用可用 APIMart Responses 的 `tools` 能力承载;工具真正执行仍由 `platform-agent` 注册表和后端 typed Tool 控制。
|
||||
|
||||
## 3. 总体架构
|
||||
|
||||
Agent 由六大核心模块组成,形成“感知 -> 思考 -> 记忆 -> 行动 -> 反思 -> 协作”的闭环。
|
||||
|
||||
```text
|
||||
用户图文输入
|
||||
-> 感知 Perception
|
||||
-> 思考 Reasoning
|
||||
-> 记忆 Memory
|
||||
-> 行动 Action
|
||||
-> 反思 Reflection
|
||||
-> 协作 Collaboration
|
||||
-> 目标玩法草稿 / 追问 / 人工确认
|
||||
```
|
||||
|
||||
Rust 分层建议:
|
||||
|
||||
```text
|
||||
server-rs/crates/platform-agent
|
||||
langchain_adapter.rs LangChain-Rust 封装,屏蔽第三方 API 变化
|
||||
agent_graph.rs 六模块 LangGraph / AgentExecutor 编排
|
||||
tools.rs 工具注册与权限边界
|
||||
output_parsers.rs Typed / JSON 输出解析
|
||||
callbacks.rs Trace、SSE、成本与错误事件
|
||||
|
||||
server-rs/crates/module-creative-agent
|
||||
domain.rs Agent 会话、目标、模板语义、计划、反思记录
|
||||
commands.rs 创建会话、写入输入、确认计划、保存结果
|
||||
application.rs 纯领域校验、阶段迁移、契约门槛
|
||||
errors.rs 字段错误与领域错误
|
||||
|
||||
server-rs/crates/api-server/src/creative_agent.rs
|
||||
HTTP / SSE facade,调用 platform-agent 和 spacetime-client
|
||||
```
|
||||
|
||||
DDD 边界保持不变:
|
||||
|
||||
- `platform-agent` 负责 Agent 编排和工具调用抽象,不保存业务真相。
|
||||
- `module-creative-agent` 只放纯领域类型、阶段、校验和决策记录结构。
|
||||
- `api-server` 负责鉴权、SSE、LLM/视觉/工具编排。
|
||||
- `spacetime-module` 保存会话、输入、记忆索引、目标玩法绑定和审计事件。
|
||||
- 当前目标玩法只允许拼图。拼图模板协议、积分范围、单关卡/多关卡图片生成计划、草稿校验和工具实现全部封装在 `module-puzzle` / 拼图相关 facade 中;通用 Agent 不复制拼图字段推导逻辑。
|
||||
|
||||
## 4. 六大核心模块
|
||||
|
||||
### 4.1 感知模块 Perception
|
||||
|
||||
职责:把用户输入的字、图、文档和上下文变成模型可推理的多模态语义状态。
|
||||
|
||||
它不是关键词分类器。它要做的是“看懂素材”和“看懂用户想要什么”。
|
||||
|
||||
输入:
|
||||
|
||||
```ts
|
||||
export interface CreativePerceptionInput {
|
||||
text: string;
|
||||
documents: CreativeTextAttachment[];
|
||||
images: CreativeImageAttachment[];
|
||||
currentUserProfile?: CreativeUserPreferenceSnapshot | null;
|
||||
entryContext: 'creation_home' | 'puzzle_workspace' | 'gallery_remix' | 'draft_restore';
|
||||
}
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```ts
|
||||
export interface CreativePerceptionState {
|
||||
userIntent: string;
|
||||
emotionalTone: string;
|
||||
targetAudience: string | null;
|
||||
sourceMaterials: CreativeMaterialSummary[];
|
||||
visualUnderstanding: CreativeImageUnderstanding[];
|
||||
constraints: CreativeConstraint[];
|
||||
uncertainties: CreativeUncertainty[];
|
||||
}
|
||||
```
|
||||
|
||||
实现方式:
|
||||
|
||||
1. 文档输入复用 `creationAgentDocumentInput`,再交给 LangChain-Rust 的 text splitter / document chain 做摘要。
|
||||
2. 图片输入必须先上传为资产,Agent 只拿 `readUrl`、缩略图、尺寸和视觉摘要,不把大 data URL 存入 SpacetimeDB。
|
||||
3. 图像理解首版直接通过 APIMart Responses API 的 `gpt-5` 多模态输入完成,返回主体、场景、风格、OCR、构图线索和安全风险;后续如独立 `platform-vision`,也必须保持相同的文本/图像内容块契约。
|
||||
4. 模板和玩法说明通过 RAG 检索注入,而不是写死规则。检索源包括玩法模板注册表、拼图草稿契约、已有优秀作品摘要和玩法适配说明。
|
||||
|
||||
LangChain-Rust 对应能力:
|
||||
|
||||
- Document loader / splitter / summarization chain
|
||||
- RAG、BM25、Hybrid retrieval
|
||||
- Typed / JSON output parser
|
||||
- Callback 将感知进度推给前端 SSE
|
||||
|
||||
### 4.2 思考模块 Reasoning
|
||||
|
||||
职责:让模型在可用工具、用户意图和玩法知识之间主动做计划。
|
||||
|
||||
思考模块不是 `if playType == puzzle` 的路由函数,而是一个 FunctionCallingAgent 或 LangGraph 中的 planner 节点。模型可以自主选择:
|
||||
|
||||
- 先调用拼图模板知识检索
|
||||
- 先返回拼图模板目录
|
||||
- 请求用户选择模板
|
||||
- 用户选中模板后,再确认该模板的关卡模式、关卡数和积分范围
|
||||
- 确认后生成单关卡或多关卡草稿计划
|
||||
- 先调用图片理解
|
||||
- 先问用户一个关键问题
|
||||
- 委托拼图专家 Agent
|
||||
|
||||
当前版本的思考模块不能选择非拼图玩法作为行动目标。如果模型认为输入更适合 RPG、Match3D、大鱼或方洞挑战,应输出“当前仅支持拼图模板”的说明,并尝试给出可转化为拼图的创意方案;若无法转化,应进入 `waiting_user`,不能创建非拼图 session。
|
||||
|
||||
核心状态:
|
||||
|
||||
```ts
|
||||
export interface CreativeReasoningState {
|
||||
goal: string;
|
||||
candidatePlayTypes: CreativePlayCandidate[];
|
||||
selectedPlayType: CreativePlayType | null;
|
||||
selectedTemplateId: string | null;
|
||||
selectedPuzzleTemplate: PuzzleCreativeTemplateSelection | null;
|
||||
selectedImageGenerationPlan: PuzzleImageGenerationPlan | null;
|
||||
plan: CreativeAgentPlanStep[];
|
||||
confidence: number;
|
||||
needUserClarification: boolean;
|
||||
rationale: string;
|
||||
}
|
||||
```
|
||||
|
||||
建议使用 LangChain-Rust:
|
||||
|
||||
- `FunctionCallingAgent` 作为主决策 Agent,所有玩法能力以工具形式暴露。
|
||||
- `AgentExecutor` 控制最大迭代次数、超时、工具调用错误回传。
|
||||
- `LangGraph` 表达长链路:`perceive -> plan -> act -> reflect -> finalize`,允许循环和人工确认。
|
||||
- `JsonOutputParser` / `TypedOutputParser` 保证模型最终输出能落到 Rust/TS shared contract。
|
||||
|
||||
系统提示词要明确:
|
||||
|
||||
1. 你是创意互动内容生成 Agent,不是分类器。
|
||||
2. 你可以相信自己的多模态理解能力。
|
||||
3. 你应选择能最大化互动体验的玩法,而不是机械匹配关键词。
|
||||
4. 当前产品只开放拼图模板,非拼图模板只能解释为暂不支持,不能调用非拼图工具。
|
||||
5. 即便只有拼图玩法可用,也必须先显式展示多个拼图子模板;用户选中模板后,才展示选择理由、关卡配置和预计积分范围。
|
||||
6. 当输入足够明确时不要过度追问。
|
||||
7. 当合规、素材权属、人物肖像或儿童内容存在风险时进入确认或降级。
|
||||
|
||||
### 4.3 记忆模块 Memory
|
||||
|
||||
职责:让 Agent 能利用当前会话、用户偏好、历史作品和反思经验,而不是每次从零判断。
|
||||
|
||||
记忆分四层:
|
||||
|
||||
```text
|
||||
短期记忆:当前会话消息、工具调用、草稿状态
|
||||
工作记忆:本次任务的目标、计划、候选、未解决问题
|
||||
长期记忆:用户偏好、常用玩法、作品风格、发布反馈
|
||||
反思记忆:过去失败原因、模板误选案例、修正策略
|
||||
```
|
||||
|
||||
推荐结构:
|
||||
|
||||
```ts
|
||||
export interface CreativeAgentMemorySnapshot {
|
||||
shortTermSummary: string;
|
||||
workingPlan: CreativeAgentPlanStep[];
|
||||
retrievedUserPreferences: CreativeUserPreference[];
|
||||
retrievedTemplateMemories: CreativeTemplateMemory[];
|
||||
retrievedReflections: CreativeReflectionMemory[];
|
||||
}
|
||||
```
|
||||
|
||||
落地方式:
|
||||
|
||||
1. LangChain-Rust Memory 用于单次 AgentExecutor 内的短期上下文,可用 Buffer / Window / SummaryBuffer。
|
||||
2. SpacetimeDB 保存长期真相:`creative_agent_session`、`creative_agent_message`、`creative_agent_reflection`、`creative_agent_target_binding`。
|
||||
3. 向量/混合检索保存可召回记忆:用户偏好、模板选择结果、发布后反馈、失败反思。首版可用 SQLite 或 Redis feature,生产再评估 Qdrant/Redis。
|
||||
4. 每次生成结束后写一条反思记忆:选择了什么模板、为什么、哪些字段由模型推断、用户是否接受、是否返回编辑。
|
||||
|
||||
记忆使用原则:
|
||||
|
||||
- 记忆给模型参考,不替代用户本轮输入。
|
||||
- 用户本轮明确要求优先级最高。
|
||||
- 任何长期记忆都要带来源、时间和置信度。
|
||||
- 涉及个人隐私、图片内容和未发布作品时只在用户私有 namespace 检索。
|
||||
|
||||
### 4.4 行动模块 Action
|
||||
|
||||
职责:把 Agent 的计划变成可审计、可回滚、可测试的工具调用。
|
||||
|
||||
所有对系统产生影响的操作都必须以 LangChain-Rust Tool 的形式注册。模型通过 function calling 选择工具,工具内部再调用现有服务或 SpacetimeDB facade。
|
||||
|
||||
首批工具:
|
||||
|
||||
```text
|
||||
perceive_image(imageAssetId)
|
||||
retrieve_puzzle_template_catalog(query)
|
||||
retrieve_user_creation_memory(userId, query)
|
||||
create_puzzle_agent_session(payload)
|
||||
compile_puzzle_draft(sessionId, payload)
|
||||
plan_puzzle_level_images(payload)
|
||||
generate_puzzle_level_images(sessionId, payload)
|
||||
select_puzzle_template(payload)
|
||||
confirm_puzzle_template(payload)
|
||||
apply_puzzle_draft_natural_language_edit(sessionId, payload)
|
||||
start_puzzle_draft_test_run(sessionId, payload)
|
||||
ask_user_clarification(question, options?)
|
||||
request_user_confirmation(summary, candidates)
|
||||
validate_target_draft(playType, draft)
|
||||
save_creative_reflection(payload)
|
||||
```
|
||||
|
||||
工具设计要求:
|
||||
|
||||
1. 工具描述要清楚告诉模型何时使用,而不是由外层规则决定。
|
||||
2. 工具输入必须是 JSON Schema / Rust typed struct,禁止自由字符串拼接。
|
||||
3. 工具只做一件事。比如“创建拼图 session”和“编译拼图草稿”分开。
|
||||
4. 工具返回结构化结果,包含 `ok`、`summary`、`nextSuggestedTools`、`warnings`。
|
||||
5. 所有写操作必须鉴权,不能信任模型传入的 `ownerUserId`。
|
||||
6. 工具调用审计写入 SpacetimeDB,便于排障和反思。
|
||||
7. 当前工具注册表只能暴露拼图工具。非拼图工具即使已有实现,也不能注册给当前 Agent。
|
||||
|
||||
拼图草稿不是路由器手填,而是 Action 模块通过工具让 Agent 产出 typed payload。这里的“草稿字段”只指用户表单和 Agent 自然语言都共同编辑的那一组字段:
|
||||
|
||||
```ts
|
||||
export interface CreativePuzzleDraftToolInput {
|
||||
templateId: string;
|
||||
templateCostRange: PuzzleTemplateCostRange;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
workTags: string[];
|
||||
levels: CreativePuzzleLevelDraftInput[];
|
||||
}
|
||||
|
||||
export interface CreativePuzzleLevelDraftInput {
|
||||
levelName: string;
|
||||
pictureDescription: string;
|
||||
pictureReference?: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
工具内部负责映射到现有 `PuzzleAgentActionRequest` 和 `PuzzleResultDraft`,并调用拼图领域校验。`workTitle`、`workDescription`、`workTags`、`levels[].levelName`、`levels[].pictureDescription`、`levels[].pictureReference` 是 Agent 直接写入的草稿真相;`summary`、`anchorPack`、`forbiddenDirectives`、`imagePrompt`、候选图等都属于拼图模块内部派生或生成结果,不作为 Agent 的直接填表目标。
|
||||
|
||||
拼图模块必须额外暴露模板和多关卡图片协议:
|
||||
|
||||
```ts
|
||||
export interface PuzzleCreativeTemplateProtocol {
|
||||
templateId: string;
|
||||
title: string;
|
||||
description: string;
|
||||
supportedLevelMode: 'single' | 'multi' | 'single_or_multi';
|
||||
defaultLevelCount: number;
|
||||
minLevelCount: number;
|
||||
maxLevelCount: number;
|
||||
costRange: PuzzleTemplateCostRange;
|
||||
requiredDraftFields: string[];
|
||||
imageGenerationPolicy: PuzzleTemplateImageGenerationPolicy;
|
||||
}
|
||||
|
||||
export interface PuzzleTemplateCostRange {
|
||||
minPoints: number;
|
||||
maxPoints: number;
|
||||
pricingUnit: 'point';
|
||||
reason: string;
|
||||
}
|
||||
|
||||
export interface PuzzleTemplateImageGenerationPolicy {
|
||||
allowUploadedImageDirectly: boolean;
|
||||
allowGeneratedImages: boolean;
|
||||
allowPerLevelReferenceImage: boolean;
|
||||
defaultCandidateCountPerLevel: number;
|
||||
}
|
||||
|
||||
export interface PuzzleImageGenerationPlan {
|
||||
mode: 'single_level' | 'multi_level';
|
||||
levels: CreativePuzzleLevelDraftInput[];
|
||||
estimatedCostRange: PuzzleTemplateCostRange;
|
||||
}
|
||||
```
|
||||
|
||||
积分范围由拼图模板协议提供,Agent 只能解释和选择,不能自行发明价格。真实扣费仍以后端钱包/任务系统最终结算为准。
|
||||
|
||||
### 4.5 反思模块 Reflection
|
||||
|
||||
职责:让 Agent 在交付前检查自己的选择是否真的适合用户,而不是一次模型输出就结束。
|
||||
|
||||
反思节点运行在每次关键行动后:
|
||||
|
||||
1. 模板选择后:检查是否已经向用户显式展示拼图模板和积分范围。
|
||||
2. 用户确认前:检查是否误承诺了非拼图模板或非真实价格。
|
||||
3. 草稿填充后:检查字段是否完整、玩法体验是否成立。
|
||||
4. 图片使用前:检查单关卡/多关卡图片计划是否与模板协议一致。
|
||||
5. 最终交付前:检查是否需要用户确认。
|
||||
|
||||
反思输出:
|
||||
|
||||
```ts
|
||||
export interface CreativeReflectionReport {
|
||||
pass: boolean;
|
||||
score: number;
|
||||
issues: CreativeReflectionIssue[];
|
||||
revisionInstruction?: string | null;
|
||||
shouldAskUser: boolean;
|
||||
shouldTryAlternativePlayType: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
实现方式:
|
||||
|
||||
- 用 LangGraph 增加 `reflect` 节点。
|
||||
- 反思模型拿到感知状态、计划、工具调用结果和目标草稿。
|
||||
- 如果 `pass=false` 且迭代次数未超限,回到 `plan` 或 `act`。
|
||||
- 如果问题是用户偏好缺失,调用 `ask_user_clarification`。
|
||||
- 如果问题是契约字段缺失,调用目标玩法 draft 修复工具。
|
||||
- 如果问题是未展示模板选择或积分范围,回到模板确认节点。
|
||||
- 如果问题是多关卡计划超出模板 `maxLevelCount`,调用拼图计划修复工具。
|
||||
|
||||
硬性终止条件:
|
||||
|
||||
- 最大反思循环 2 次。
|
||||
- 同一工具同一参数失败 2 次后停止并返回可读错误。
|
||||
- 预算超限时返回当前可用草稿和补救建议。
|
||||
|
||||
反思记忆要沉淀:
|
||||
|
||||
- 模板误选原因。
|
||||
- 用户是否接受模板积分范围。
|
||||
- 单关卡或多关卡图片生成计划是否被用户调整。
|
||||
- 用户手动改选的玩法。
|
||||
- 结果页返回编辑最多的字段。
|
||||
- 发布失败 blockers。
|
||||
|
||||
### 4.6 协作模块 Collaboration
|
||||
|
||||
职责:把复杂创意任务拆给多个专长 Agent,而不是让单个提示词吞掉所有任务。
|
||||
|
||||
当前首版只开放拼图协作,不开放其它玩法子 Agent。建议四个子 Agent:
|
||||
|
||||
```text
|
||||
创意导演 Agent:理解用户目标,决定整体方向和互动体验。
|
||||
视觉解读 Agent:理解图片、构图、主体、风格和可交互线索。
|
||||
拼图模板策展 Agent:基于拼图模板协议和历史作品选择候选拼图模板,并读取积分范围。
|
||||
拼图专家 Agent:生成单关卡或多关卡拼图草稿 payload 和图片生成计划。
|
||||
契约审校 Agent:检查字段、发布门槛、积分展示、安全边界和可恢复性。
|
||||
```
|
||||
|
||||
LangChain-Rust 落地:
|
||||
|
||||
- 用 LangGraph 的 subgraph 表达子 Agent。
|
||||
- 子 Agent 共享 `CreativeAgentState`,但只能写自己负责的字段。
|
||||
- 主 Agent 通过 handoff 工具委托子任务。
|
||||
- 必要时并行执行视觉解读和拼图模板知识检索,再由创意导演合并。
|
||||
- 协作结果由契约审校 Agent 最终检查。
|
||||
|
||||
协作不是增加 UI 复杂度。前端仍只看到一个 Agent,但后端内部有多个可观测步骤,SSE 推送简短阶段即可。
|
||||
|
||||
## 5. Agent 状态机
|
||||
|
||||
LangGraph 状态建议:
|
||||
|
||||
```rust
|
||||
pub struct CreativeAgentGraphState {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub perception: Option<CreativePerceptionState>,
|
||||
pub memory: Option<CreativeAgentMemorySnapshot>,
|
||||
pub reasoning: Option<CreativeReasoningState>,
|
||||
pub tool_results: Vec<CreativeToolResult>,
|
||||
pub reflection: Option<CreativeReflectionReport>,
|
||||
pub target_binding: Option<CreativeTargetSessionBinding>,
|
||||
pub final_response: Option<CreativeAgentFinalResponse>,
|
||||
pub iteration_count: u32,
|
||||
}
|
||||
```
|
||||
|
||||
Graph 节点:
|
||||
|
||||
```text
|
||||
load_memory
|
||||
perceive_input
|
||||
plan_with_agent
|
||||
act_with_tools
|
||||
reflect_result
|
||||
collaborate_if_needed
|
||||
finalize_or_ask_user
|
||||
persist_memory
|
||||
```
|
||||
|
||||
边:
|
||||
|
||||
```text
|
||||
load_memory -> perceive_input
|
||||
perceive_input -> plan_with_agent
|
||||
plan_with_agent -> act_with_tools
|
||||
act_with_tools -> reflect_result
|
||||
reflect_result(pass) -> finalize_or_ask_user
|
||||
reflect_result(revise) -> plan_with_agent
|
||||
reflect_result(collaborate) -> collaborate_if_needed
|
||||
collaborate_if_needed -> act_with_tools
|
||||
finalize_or_ask_user -> persist_memory
|
||||
```
|
||||
|
||||
## 6. 数据契约
|
||||
|
||||
新增 shared contracts:
|
||||
|
||||
```text
|
||||
packages/shared/src/contracts/creativeAgent.ts
|
||||
server-rs/crates/shared-contracts/src/creative_agent.rs
|
||||
```
|
||||
|
||||
核心 DTO:
|
||||
|
||||
```ts
|
||||
export type CreativeAgentStage =
|
||||
| 'perceiving'
|
||||
| 'thinking'
|
||||
| 'remembering'
|
||||
| 'selecting_puzzle_template'
|
||||
| 'waiting_template_confirmation'
|
||||
| 'planning_puzzle_levels'
|
||||
| 'acting'
|
||||
| 'reflecting'
|
||||
| 'collaborating'
|
||||
| 'waiting_user'
|
||||
| 'target_ready'
|
||||
| 'failed';
|
||||
|
||||
export interface CreativeAgentSessionSnapshot {
|
||||
sessionId: string;
|
||||
stage: CreativeAgentStage;
|
||||
perception: CreativePerceptionState | null;
|
||||
reasoning: CreativeReasoningState | null;
|
||||
puzzleTemplateCatalog: PuzzleCreativeTemplateProtocol[];
|
||||
puzzleTemplateSelection: PuzzleCreativeTemplateSelection | null;
|
||||
puzzleImageGenerationPlan: PuzzleImageGenerationPlan | null;
|
||||
reflection: CreativeReflectionReport | null;
|
||||
targetBinding: CreativeTargetSessionBinding | null;
|
||||
messages: CreativeAgentMessage[];
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface PuzzleCreativeTemplateSelection {
|
||||
templateId: string;
|
||||
title: string;
|
||||
reason: string;
|
||||
costRange: PuzzleTemplateCostRange;
|
||||
supportedLevelMode: 'single' | 'multi' | 'single_or_multi';
|
||||
selectedLevelMode: 'single_level' | 'multi_level';
|
||||
plannedLevelCount: number;
|
||||
requiresUserConfirmation: true;
|
||||
}
|
||||
```
|
||||
|
||||
HTTP facade:
|
||||
|
||||
```text
|
||||
POST /api/runtime/creative-agent/sessions
|
||||
GET /api/runtime/creative-agent/sessions/{sessionId}
|
||||
POST /api/runtime/creative-agent/sessions/{sessionId}/messages/stream
|
||||
POST /api/runtime/creative-agent/sessions/{sessionId}/confirm
|
||||
POST /api/runtime/creative-agent/sessions/{sessionId}/cancel
|
||||
```
|
||||
|
||||
SSE 事件:
|
||||
|
||||
```text
|
||||
stage
|
||||
agent_message_delta
|
||||
puzzle_template_catalog
|
||||
puzzle_template_selection
|
||||
puzzle_cost_range
|
||||
puzzle_level_plan
|
||||
tool_started
|
||||
tool_completed
|
||||
reflection
|
||||
target_session
|
||||
need_user_input
|
||||
session
|
||||
error
|
||||
```
|
||||
|
||||
## 7. SpacetimeDB 持久化
|
||||
|
||||
新增表:
|
||||
|
||||
```text
|
||||
creative_agent_session
|
||||
creative_agent_message
|
||||
creative_agent_input_asset
|
||||
creative_agent_tool_call
|
||||
creative_agent_reflection
|
||||
creative_agent_target_binding
|
||||
creative_agent_memory_index
|
||||
puzzle_creative_template_snapshot
|
||||
puzzle_creative_level_generation_plan
|
||||
```
|
||||
|
||||
关键约束:
|
||||
|
||||
1. SpacetimeDB 保存结构化真相和 JSON 快照,不保存大图片 data URL。
|
||||
2. 工具调用和反思必须可追溯,便于排查模型为什么选择某个模板。
|
||||
3. `creative_agent_memory_index` 只保存记忆元数据和向量索引引用,不直接承担向量数据库职责。
|
||||
4. 表结构变更必须同步 `migration.rs`、`SPACETIMEDB_TABLE_CATALOG.md` 和 bindings。
|
||||
5. `creative_agent_session` 必须保存当前拼图模板目录、已确认的模板选择快照和积分范围,保证刷新后仍能恢复“先选模板、再确认配置”的两段式状态。
|
||||
6. `puzzle_creative_level_generation_plan` 保存单关卡/多关卡图片生成计划,包括每关 `level_id`、`level_name`、`picture_description`、`image_prompt`、`generation_status`、`candidate_count` 和 `estimated_cost_points`。
|
||||
7. 非拼图玩法不新增 target binding,避免后续误恢复到暂不支持的玩法。
|
||||
8. 自然语言修订草稿字段要记录工具调用、原始用户指令、结构化 patch 和修改后的 draft 版本,便于撤销、审计和反思。
|
||||
9. 试玩 run 与草稿 session 需要有绑定关系,确保“立即玩”后返回结果页能恢复同一草稿。
|
||||
|
||||
## 8. 拼图首版落地
|
||||
|
||||
拼图首版不是“规则判断为拼图”,而是模型通过工具和反思得出选择。但产品边界明确:当前只支持拼图模板。Agent 必须把非拼图创意转化为拼图可承接的方案,或告诉用户当前不支持该模板。
|
||||
|
||||
### 8.1 强制模板选择与积分展示
|
||||
|
||||
任何草稿生成前都必须先进入 `selecting_puzzle_template` 和 `waiting_template_confirmation`。
|
||||
|
||||
前端至少展示:
|
||||
|
||||
- 拼图模板标题
|
||||
- 模板缩略图或示意图
|
||||
- Agent 选择理由
|
||||
- 支持单关卡、多关卡或二者皆可
|
||||
- 计划关卡数
|
||||
- 预计积分范围,例如 `预计消耗 8 到 18 光点`
|
||||
|
||||
积分范围来自拼图模板协议:
|
||||
|
||||
```ts
|
||||
export interface PuzzleTemplateCostRange {
|
||||
minPoints: number;
|
||||
maxPoints: number;
|
||||
pricingUnit: 'point';
|
||||
reason: string;
|
||||
}
|
||||
```
|
||||
|
||||
Agent 可以解释 `reason`,但不能修改 `minPoints` / `maxPoints`。如果模板协议没有积分范围,该模板不能展示为可选项。
|
||||
|
||||
Agent 可调用工具:
|
||||
|
||||
```text
|
||||
retrieve_puzzle_template_catalog
|
||||
inspect_puzzle_draft_contract
|
||||
select_puzzle_template
|
||||
confirm_puzzle_template
|
||||
plan_puzzle_level_images
|
||||
create_puzzle_agent_session
|
||||
compile_puzzle_draft
|
||||
apply_puzzle_draft_natural_language_edit
|
||||
validate_puzzle_result_preview
|
||||
select_uploaded_image_as_puzzle_cover
|
||||
generate_puzzle_images
|
||||
start_puzzle_draft_test_run
|
||||
return_to_puzzle_result
|
||||
```
|
||||
|
||||
### 8.2 拼图模板协议
|
||||
|
||||
拼图模板协议应封装在拼图模块,不放在通用 Agent:
|
||||
|
||||
```text
|
||||
server-rs/crates/module-puzzle/src/creative_templates.rs
|
||||
server-rs/crates/module-puzzle/src/creative_tools.rs
|
||||
server-rs/crates/shared-contracts/src/puzzle_creative_template.rs
|
||||
packages/shared/src/contracts/puzzleCreativeTemplate.ts
|
||||
```
|
||||
|
||||
协议至少包含:
|
||||
|
||||
```ts
|
||||
export interface PuzzleCreativeTemplateProtocol {
|
||||
templateId: string;
|
||||
title: string;
|
||||
summary: string;
|
||||
previewImageSrc: string | null;
|
||||
supportedLevelMode: 'single' | 'multi' | 'single_or_multi';
|
||||
minLevelCount: number;
|
||||
maxLevelCount: number;
|
||||
defaultLevelCount: number;
|
||||
costRange: PuzzleTemplateCostRange;
|
||||
imagePolicy: PuzzleTemplateImageGenerationPolicy;
|
||||
draftFieldHints: PuzzleTemplateDraftFieldHints;
|
||||
}
|
||||
```
|
||||
|
||||
模板示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"templateId": "puzzle.family-keepsake",
|
||||
"title": "家庭纪念拼图",
|
||||
"supportedLevelMode": "single_or_multi",
|
||||
"minLevelCount": 1,
|
||||
"maxLevelCount": 6,
|
||||
"defaultLevelCount": 3,
|
||||
"costRange": {
|
||||
"minPoints": 8,
|
||||
"maxPoints": 24,
|
||||
"pricingUnit": "point",
|
||||
"reason": "按关卡数、每关候选图数量和是否使用上传图估算"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 单关卡与多关卡图片生成
|
||||
|
||||
拼图草稿必须支持两种计划:
|
||||
|
||||
```ts
|
||||
export type PuzzleLevelGenerationMode = 'single_level' | 'multi_level';
|
||||
|
||||
export interface PuzzleImageGenerationPlan {
|
||||
mode: PuzzleLevelGenerationMode;
|
||||
templateId: string;
|
||||
estimatedCostRange: PuzzleTemplateCostRange;
|
||||
levels: PuzzleImageGenerationPlanLevel[];
|
||||
}
|
||||
|
||||
export interface PuzzleImageGenerationPlanLevel {
|
||||
levelId: string;
|
||||
levelName: string;
|
||||
pictureDescription: string;
|
||||
imagePrompt: string;
|
||||
pictureReference?: string | null;
|
||||
candidateCount: number;
|
||||
}
|
||||
```
|
||||
|
||||
单关卡:
|
||||
|
||||
- `levels.length = 1`
|
||||
- 可使用上传图直出,也可生成一张候选图。
|
||||
- 适合纪念照、商品图、单张海报、单主题知识图。
|
||||
|
||||
多关卡:
|
||||
|
||||
- `levels.length` 必须在模板 `minLevelCount` 到 `maxLevelCount` 之间。
|
||||
- 每关有独立 `levelName`、`pictureDescription` 和 `imagePrompt`。
|
||||
- 可选择每关生成一张图,也可第一关使用上传图、后续关卡生图。
|
||||
- 适合故事型照片组、知识步骤、活动流程、系列商品、节日卡片组。
|
||||
|
||||
生成工具建议:
|
||||
|
||||
```ts
|
||||
export interface GeneratePuzzleLevelImagesToolInput {
|
||||
sessionId: string;
|
||||
plan: PuzzleImageGenerationPlan;
|
||||
imageModel: 'gpt-image-2';
|
||||
}
|
||||
|
||||
export interface GeneratePuzzleLevelImagesToolOutput {
|
||||
draft: PuzzleResultDraft;
|
||||
levels: PuzzleDraftLevel[];
|
||||
costEstimate: PuzzleTemplateCostRange;
|
||||
generatedCount: number;
|
||||
uploadedCount: number;
|
||||
}
|
||||
```
|
||||
|
||||
工具内部可以复用现有 `generate_puzzle_images` action,但必须以 `levelId` 为粒度逐关执行,或新增拼图后端 action `generate_puzzle_level_images` 批量处理。批量 action 仍归属拼图模块,通用 Agent 只负责调用。
|
||||
|
||||
### 8.5 模板草稿字段填充与自然语言修订
|
||||
|
||||
Agent 创作互动内容的本质就是向模板中的草稿字段填充内容。拼图模板草稿字段是唯一创作真相:表单化创作页是这些字段的可视化编辑器,Agent 对话是这些字段的自然语言编辑器,二者属于同一条创作流程。
|
||||
|
||||
通用 Agent 只负责把用户自然语言转成“草稿字段填充 / 修订意图”,真正的字段写入仍通过拼图模块 Tool 完成:
|
||||
|
||||
```ts
|
||||
export interface PuzzleDraftFieldEditInstruction {
|
||||
scope: 'work' | 'level' | 'tags' | 'cover' | 'images' | 'all';
|
||||
operation: 'set' | 'append' | 'replace' | 'remove' | 'reorder';
|
||||
fieldPath: string;
|
||||
value: string | string[] | boolean | number | null;
|
||||
rationale: string;
|
||||
}
|
||||
|
||||
export interface ApplyPuzzleDraftNaturalLanguageEditToolInput {
|
||||
sessionId: string;
|
||||
userInstruction: string;
|
||||
currentDraftSnapshot: PuzzleResultDraft;
|
||||
}
|
||||
|
||||
export interface ApplyPuzzleDraftNaturalLanguageEditToolOutput {
|
||||
updatedDraft: PuzzleResultDraft;
|
||||
editInstructions: PuzzleDraftFieldEditInstruction[];
|
||||
needsUserConfirmation: boolean;
|
||||
confirmationSummary: string;
|
||||
}
|
||||
```
|
||||
|
||||
这个工具由拼图模块封装,内部要做三步:
|
||||
|
||||
1. 用模型把自然语言改写成结构化草稿字段 patch。
|
||||
2. 用拼图领域规则校验 patch 是否会破坏草稿约束。
|
||||
3. 通过现有草稿保存接口写回同一份 `PuzzleResultDraft` 或 `formDraft`。
|
||||
|
||||
典型自然语言字段修订场景:
|
||||
|
||||
- “把这张图改成更适合家庭纪念。”
|
||||
- “第二关再多加一张风景图。”
|
||||
- “标题别太正式,轻松一点。”
|
||||
- “主题标签里去掉商品感,增加温暖和节日感。”
|
||||
|
||||
Agent 不能直接篡改结果页 DOM,也不能绕过拼图草稿字段写最终发布数据。用户在表单里手动编辑、用户用自然语言让 Agent 编辑,本质上都必须落到同一份草稿字段 patch。
|
||||
|
||||
### 8.6 立即玩与试玩闭环
|
||||
|
||||
生成好的互动内容必须能立即玩到。对拼图来说,Agent 完成草稿后必须直接导向现有 `puzzle-result`,并提供明确的“立即玩”入口。
|
||||
|
||||
闭环要求:
|
||||
|
||||
1. 草稿创建成功后,结果页首屏就能看到 `Play` 或“立即玩”按钮。
|
||||
2. 点击后直接启动 `puzzle-runtime`,不需要用户再手动跳过别的中间页。
|
||||
3. 如果当前草稿还在生成更多关卡图片,已完成关卡可先试玩,后续图片再逐关补齐。
|
||||
4. 试玩入口必须复用现有 `PuzzleRuntimeShell` 和 `startPuzzleRun` 链路。
|
||||
5. 试玩后返回结果页时,仍然停留在同一草稿上下文,不丢失表单草稿状态。
|
||||
|
||||
结果页到运行态之间的切换不由通用 Agent 再次判断,而是由拼图模块暴露的 `start_run` / `resume_run` / `return_to_result` 工具完成。
|
||||
|
||||
### 8.4 拼图专家输出
|
||||
|
||||
拼图专家 Agent 需要产出:
|
||||
|
||||
```ts
|
||||
export interface PuzzleCreativeDraftIntent {
|
||||
templateSelection: PuzzleCreativeTemplateSelection;
|
||||
imageGenerationPlan: PuzzleImageGenerationPlan;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
workTags: string[];
|
||||
levels: CreativePuzzleLevelDraftInput[];
|
||||
}
|
||||
```
|
||||
|
||||
字段映射仍必须对齐现有契约:
|
||||
|
||||
- `PuzzleResultDraft.workTitle`
|
||||
- `PuzzleResultDraft.workDescription`
|
||||
- `PuzzleResultDraft.workTags`
|
||||
- `PuzzleResultDraft.levels[].levelName`
|
||||
- `PuzzleResultDraft.levels[].pictureDescription`
|
||||
- `PuzzleResultDraft.levels[].pictureReference`
|
||||
|
||||
领域校验仍由 `module-puzzle` 负责。Agent 可以创造内容,但不能绕过发布 blockers。表单化创作页与 Agent 自然语言修订都只是这些字段的不同编辑界面。
|
||||
|
||||
## 9. 前端体验
|
||||
|
||||
前端只呈现一个“智能创作 Agent”入口:
|
||||
|
||||
1. 用户输入文字、上传图片或文档。
|
||||
2. 前端显示 Agent 正在理解素材、构思玩法、生成草稿。
|
||||
3. Agent 必须先展示拼图模板目录。
|
||||
4. 用户选择模板并确认关卡模式、关卡数和预计积分范围后,Agent 才能生成草稿。
|
||||
5. 生成完成后进入拼图结果页,并提供“立即玩”入口,点击后直接进入拼图运行态。
|
||||
6. 结果页保留原来的表单化创作能力,包括作品标题、作品描述、作品标签、关卡名称、关卡图面描述、关卡图面参考、关卡图片生成和选图;这些控件编辑的是同一份模板草稿字段。
|
||||
7. Agent 对话区继续可用,用户可以用自然语言补填或修订模板草稿字段,后端通过拼图模块 Tool 生成结构化 patch 并回写同一份草稿;可写字段仅限 `workTitle`、`workDescription`、`workTags`、`levels[].levelName`、`levels[].pictureDescription`、`levels[].pictureReference`。
|
||||
8. 若 Agent 有关键不确定点,弹出独立确认面板。
|
||||
9. 用户确认或回答后,Agent 继续执行并进入拼图结果页或保持在当前草稿上下文。
|
||||
|
||||
UI 不展示大段规则说明,只展示:
|
||||
|
||||
- 当前阶段
|
||||
- 简短 Agent 回复
|
||||
- 拼图模板选择和积分范围
|
||||
- 单关卡 / 多关卡计划
|
||||
- 需要确认的问题
|
||||
- 最终草稿入口
|
||||
- 立即玩入口
|
||||
- 表单化草稿字段编辑入口
|
||||
- Agent 自然语言补填 / 修订入口
|
||||
|
||||
移动端优先,上传图片预览使用横向缩略图条,确认面板用底部抽屉。
|
||||
|
||||
## 10. 安全与治理
|
||||
|
||||
模型能力是核心,但不能没有边界:
|
||||
|
||||
1. 工具权限边界:模型只能调用已注册工具,不能直接写库。
|
||||
2. 契约边界:Typed parser 和目标玩法 validator 必须通过。
|
||||
3. 成本边界:AgentExecutor 设置最大迭代、最大工具调用、超时和预算。
|
||||
4. 内容安全:人物肖像、儿童内容、版权图、隐私图进入确认或拒绝。
|
||||
5. 记忆安全:长期记忆按用户 namespace 隔离。
|
||||
6. 可观测性:Callbacks 记录每个节点、工具、token、耗时和错误。
|
||||
|
||||
## 11. 分阶段落地
|
||||
|
||||
### Phase 1:LangChain-Rust PoC + 拼图闭环
|
||||
|
||||
- 新增 `platform-agent` PoC。
|
||||
- 封装 LangChain-Rust FunctionCallingAgent / AgentExecutor。
|
||||
- 注册拼图相关工具。
|
||||
- 只支持拼图模板;非拼图模板在 Agent 能力中标记为暂不支持。
|
||||
- 强制展示拼图模板选择、选择理由和预计积分范围。
|
||||
- 支持文字 + 单图输入,模型自主选择拼图模板并填入草稿字段。
|
||||
- 支持单关卡图片生成计划和多关卡图片生成计划。
|
||||
- 生成后的拼图内容点击“立即玩”可直接进入 `puzzle-runtime`。
|
||||
- 保留结果页原有表单化草稿字段编辑入口。
|
||||
- 支持 Agent 自然语言补填 / 修订模板草稿字段,并通过拼图模块 Tool 回写草稿。
|
||||
- SSE 推送六模块阶段。
|
||||
- 结果进入现有 `puzzle-result`。
|
||||
|
||||
### Phase 2:记忆与反思闭环
|
||||
|
||||
- 增加 `creative_agent_tool_call`、`creative_agent_reflection`、`creative_agent_memory_index`。
|
||||
- 引入短期 Memory 和长期检索。
|
||||
- 记录用户改选、发布失败、返回编辑等反馈。
|
||||
- 反思循环支持自动修正草稿。
|
||||
|
||||
### Phase 3:多玩法协作
|
||||
|
||||
- 在产品开放后再增加 Match3D、大鱼吃小鱼、方洞挑战、RPG 世界专家 Agent。
|
||||
- 使用 LangGraph subgraph 做多 Agent 协作。
|
||||
- 支持多候选玩法对比和人工确认。
|
||||
|
||||
## 12. 验收标准
|
||||
|
||||
功能验收:
|
||||
|
||||
1. 用户输入含图文材料时,Agent 能说出它理解到的创作意图。
|
||||
2. Agent 能调用拼图模板知识检索,而不是靠硬编码规则选模板。
|
||||
3. Agent 必须显式展示拼图模板、选择理由和预计积分范围,用户确认后才生成草稿。
|
||||
4. 非拼图输入不会创建其它玩法 session,只能转成拼图方案或提示暂不支持。
|
||||
5. Agent 能自主选择拼图模板并生成可通过契约校验的 `PuzzleResultDraft`。
|
||||
6. 当图片更适合直接作为拼图图面时,Agent 能选择 uploaded candidate,而不是强制生图。
|
||||
7. Agent 能生成单关卡图片计划,也能生成多关卡图片计划。
|
||||
8. 多关卡计划中每关都有独立 `levelName`、`pictureDescription` 和 `imagePrompt`。
|
||||
9. 多关卡图片生成逻辑通过拼图模块工具执行,通用 Agent 不直接拼接 `levelsJson`。
|
||||
10. 生成好的拼图内容点击“立即玩”后能直接进入 `puzzle-runtime`。
|
||||
11. 从 `puzzle-runtime` 返回时仍恢复同一 `puzzle-result` 草稿上下文。
|
||||
12. 结果页保留表单化草稿字段编辑能力,用户可以修改作品标题、作品描述、作品标签、关卡名称、关卡图面描述和关卡图面参考。
|
||||
13. 用户用自然语言提出“把标题改轻松一点”“第二关加一张风景图”等请求时,Agent 能生成结构化草稿字段 patch 并通过拼图模块 Tool 回写同一份草稿。
|
||||
14. 自然语言修订草稿字段后必须重新通过拼图草稿校验和结果预览校验。
|
||||
15. 当不确定时,Agent 只问一个关键问题,而不是把所有字段丢给用户填写。
|
||||
16. 反思节点能发现未展示积分范围、关卡数越界、草稿字段缺失或自然语言字段 patch 风险,并自动修正一次。
|
||||
17. 工具调用、反思报告、模板选择、草稿字段 patch 和目标拼图 session 绑定能恢复和审计。
|
||||
|
||||
建议命令:
|
||||
|
||||
```bash
|
||||
cd server-rs
|
||||
cargo test -p shared-contracts creative_agent
|
||||
cargo test -p module-creative-agent
|
||||
cargo check -p platform-agent
|
||||
cargo check -p api-server
|
||||
```
|
||||
|
||||
涉及 SpacetimeDB schema 后:
|
||||
|
||||
```bash
|
||||
npm run spacetime:generate -- --rust-only
|
||||
npm run check:server-rs-ddd
|
||||
```
|
||||
|
||||
前端:
|
||||
|
||||
```bash
|
||||
npm run typecheck
|
||||
npm run check:encoding
|
||||
```
|
||||
|
||||
## 13. 当前实现状态
|
||||
|
||||
截至 `2026-05-05`,任务 C 已完成首版 PoC 落地:
|
||||
|
||||
1. `server-rs/crates/platform-agent` 已新增为 workspace member。
|
||||
2. `platform-agent` 已提供项目自有的 `CreativeAgentExecutor`、工具注册表、回调事件、`gpt-5` 多模态请求适配器和 mock executor。
|
||||
3. `platform-llm` 已支持 Responses 多模态输入块,`input_text` 与 `input_image` 会按 content part 序列化到请求体。
|
||||
4. 任务 C 的验收命令已通过:`cargo check -p platform-agent`、`cargo test -p platform-agent`、`cargo test -p platform-llm responses_multimodal`。
|
||||
|
||||
截至 `2026-05-05`,任务 E 的 API / SSE facade 已补充 Windows debug 稳定性修复:
|
||||
|
||||
1. `/api/runtime/creative-agent/sessions/{sessionId}/messages/stream` 不再把 Agent 执行、模型请求、会话更新和所有 SSE 事件内联到单个大型 `async_stream` 中。
|
||||
2. 当前实现使用后台 `tokio::spawn` 执行业务流程,并通过 `mpsc` / `UnboundedReceiverStream` 向 Axum 返回轻量 SSE stream;执行失败会更新会话为 `failed` 并发送 SSE `error`。
|
||||
3. 已补实际消费 SSE body 的回归测试,覆盖 `stage`、`puzzle_template_catalog` 与 `done` 事件;`puzzle_template_selection`、`puzzle_cost_range`、`puzzle_level_plan` 只在用户确认后进入后续快照或流程。
|
||||
|
||||
## 14. 本方案相对旧方案的变化
|
||||
|
||||
旧方案偏“规则预筛 + workflow + Adapter”。新方案调整为:
|
||||
|
||||
1. 模型负责理解素材、整理候选和草稿构思;最终模板由用户从多个候选中主动选择。
|
||||
2. LangChain-Rust AgentExecutor / FunctionCallingAgent 承担工具调用决策。
|
||||
3. LangGraph 承担六模块闭环和反思循环。
|
||||
4. Memory/RAG 让 Agent 学习用户偏好和模板经验。
|
||||
5. 当前只开放拼图玩法,但模板选择仍是显式 Agent 步骤,不因只有一个玩法而跳过。
|
||||
6. 拼图模板协议必须携带积分范围,用户选择模板并确认配置后才进入草稿生成。
|
||||
7. 单关卡/多关卡图片生成通过拼图模块 Tool 和模板协议实现,不写进通用 Agent。
|
||||
8. Agent 创作方式就是填充和修订模板草稿字段;表单化创作页和 Agent 自然语言修订都操作同一份 `PuzzleResultDraft`,并围绕 `workTitle`、`workDescription`、`workTags`、`levels[].levelName`、`levels[].pictureDescription`、`levels[].pictureReference` 这一组字段协同。
|
||||
9. Adapter 从“路由实现”降级为 Agent action tool。
|
||||
10. 规则只保留为安全、契约、成本和权限边界。
|
||||
@@ -2,17 +2,18 @@
|
||||
|
||||
## 背景
|
||||
|
||||
创作中心顶部“新建作品”入口和平台创作类型弹层都依赖同一组玩法模板。此前入口开放状态、隐藏状态和中文文案集中写在 `src/components/platform-entry/platformEntryCreationTypes.ts` 与入口组件中,后续切换玩法开放节奏时容易出现多个入口不一致。
|
||||
创作中心的模板 Tab、平台创作类型弹层和旧“新建作品”卡片配置都依赖同一组玩法模板。此前入口开放状态、隐藏状态和中文文案集中写在 `src/components/platform-entry/platformEntryCreationTypes.ts` 与入口组件中,后续切换玩法开放节奏时容易出现多个入口不一致。
|
||||
|
||||
## 落地规则
|
||||
|
||||
1. 新建作品入口配置统一放在 `src/config/newWorkEntryConfig.ts`。
|
||||
2. `visible` 控制玩法是否展示在新建作品入口和创作类型弹层中。
|
||||
2. `visible` 控制玩法是否展示在创作 Tab 模板入口、新建作品入口和创作类型弹层中。
|
||||
3. `open` 控制玩法是否允许点击创建;`open: false` 时入口保持展示但禁用。
|
||||
4. `title`、`subtitle`、`badge` 控制玩法卡片文案。
|
||||
5. `startCard` 控制创作中心顶部新建作品模块的标题、辅助文案和移动端角标文案。
|
||||
5. `startCard` 控制旧创作中心顶部新建作品模块的标题、辅助文案和移动端角标文案;当前创作 Tab 首屏标题固定在 `PlatformEntryFlowShellImpl.tsx`,不再由 `startCard` 控制。
|
||||
6. `typeModal` 控制平台创作类型弹层标题和描述。
|
||||
7. 入口排序仍遵循“可创建玩法在前,未开放玩法在后”;同组内部沿用配置顺序。
|
||||
8. `creative-agent` 可以继续保留运行链路,但默认 `visible: false`,不出现在创作 Tab 模板入口。
|
||||
|
||||
## 当前状态
|
||||
|
||||
@@ -20,16 +21,19 @@
|
||||
| --- | --- | --- | --- |
|
||||
| 角色扮演 | 否 | 是 | 暂时从创作端入口下线,既有链路与作品能力保留 |
|
||||
| 大鱼吃小鱼 | 否 | 是 | 功能仍保留,不在新建作品入口展示 |
|
||||
| 拼图 | 是 | 是 | 点击后进入拼图 Agent 共创工作台 |
|
||||
| 拼图 | 是 | 是 | 创作 Tab 默认选中并内嵌展示拼图创作表单,提交后进入拼图草稿生成 |
|
||||
| 抓大鹅 | 否 | 是 | 暂时从创作端入口下线,既有链路与作品能力保留 |
|
||||
| 方洞挑战 | 是 | 是 | 点击后进入方洞挑战 Agent 共创工作台,支持草稿、结果页、发布、试玩、作品架与广场 |
|
||||
| AIRP | 是 | 否 | 保留入口,显示敬请期待 |
|
||||
| 视觉小说 | 是 | 否 | 保留入口,显示敬请期待 |
|
||||
| 视觉小说 | 是 | 是 | 点击后进入视觉小说创作工作台 |
|
||||
| 智能创作 | 否 | 是 | 入口隐藏,既有 `creative-agent` 链路保留 |
|
||||
|
||||
## 验收
|
||||
|
||||
1. 修改 `src/config/newWorkEntryConfig.ts` 后,创作中心顶部卡带和平台创作类型弹层应同步变化。
|
||||
1. 修改 `src/config/newWorkEntryConfig.ts` 后,创作 Tab 模板入口、创作中心顶部卡带和平台创作类型弹层应同步变化。
|
||||
2. 隐藏玩法不触发入口预加载,也不出现在新建作品入口中。
|
||||
3. 未开放玩法点击态保持禁用,不应进入鉴权或创建会话链路。
|
||||
4. 已开放玩法点击后必须进入对应创建链路;若用户未登录,先走登录保护。
|
||||
5. 方洞挑战作品发布后应生成 `SH-` 作品号,并能从作品架、广场详情和试玩 runtime 回到同一作品详情。
|
||||
5. 创作 Tab 首屏应显示“10分钟创作一个精品互动玩法”,并默认展示拼图创作表单。
|
||||
6. 智能创作入口隐藏后,不应出现“Hi, 朋友”“问一问百梦”或“一句话生成闪应用”等旧首页入口。
|
||||
7. 方洞挑战作品发布后应生成 `SH-` 作品号,并能从作品架、广场详情和试玩 runtime 回到同一作品详情。
|
||||
|
||||
@@ -408,7 +408,7 @@ WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module
|
||||
并发与清理规则:
|
||||
|
||||
- 同一个 Rust 构建 Job 建议使用 `disableConcurrentBuilds()`,避免同一组件的多个 release 构建同时写入同一最终产物路径。
|
||||
- 如果 Linux agent 未安装 `sccache`,应先运行 `Genarrative-Server-Provision` 补齐缓存工具;Rust 构建流水线仍必须自动取消 `RUSTC_WRAPPER`,回退到直接使用 `rustc`,不能因为缺少可选缓存工具阻断真实构建。
|
||||
- 如果 Linux/Windows agent 未安装 `sccache`,或 `sccache --version` 无法实际执行,应先补齐缓存工具;Rust 构建流水线仍必须自动取消 `RUSTC_WRAPPER`,回退到直接使用 `rustc`,不能因为缺少可选缓存工具阻断真实构建。
|
||||
- 生产发布流水线只能消费 `build/<version>/` 或 Jenkins 归档产物,不允许从共享 `cargo-target` 目录直接发布。
|
||||
- `SCCACHE_CACHE_SIZE` 必须设置上限,避免编译缓存无限增长。
|
||||
- 对 `/var/cache/genarrative-build/*/cargo-target` 或数据盘对应目录配置定期清理,建议保留最近 14 到 30 天。
|
||||
|
||||
@@ -2,44 +2,53 @@
|
||||
|
||||
## 背景
|
||||
|
||||
拼图创作入口已经从对话式 Agent 收口为填表式表单。本次改版目标是让“点击拼图创作”后的表单更接近图像创作工具的单屏体验:先选创作模板,再补充提示词,最后直接生成首关草稿与首张拼图图。
|
||||
拼图创作入口已经从对话式 Agent 收口为填表式表单。本次改版目标是让“点击拼图创作”后的表单更接近图像创作工具的单屏体验:优先上传参考图或填写画面描述,然后直接生成首关草稿与首张拼图图。2026-05-07 起,入口表单删除 Template 模块,模板参考图只保留为历史资产,不再作为表单首屏交互。
|
||||
|
||||
## 落地范围
|
||||
|
||||
1. `src/components/puzzle-agent/PuzzleAgentWorkspace.tsx`
|
||||
- 改为顶部标题、模板横滑区、大输入框、底部操作区的布局。
|
||||
- 改为顶部标题、超大参考图上传区、大输入框、底部操作区的布局。
|
||||
- 保留参考图上传、模型切换和生成草稿。
|
||||
- 删除 Template 模块与模板卡切换入口。
|
||||
- 不再提供输入框底部的 `try` 示例入口。
|
||||
2. `src/components/puzzle-agent/puzzleCreationTemplates.ts`
|
||||
- 新增拼图创作模板数据。
|
||||
- 模板来源按社交、热点、职场学习、电商、治愈、营销、儿童教育等场景抽样。
|
||||
- 点击模板后把模板提示词写入画面描述。
|
||||
- 保留历史拼图创作模板数据,当前表单不再消费。
|
||||
- 后续若重新开放模板入口,必须先更新本文档和移动端首屏验收。
|
||||
3. `public/puzzle-creation-templates/`
|
||||
- 存放模板样例图。
|
||||
- 样例图只用于创作模板缩略图,不作为正式拼图作品资产。
|
||||
4. `.codex/skills/gpt-image-2-apimart/`
|
||||
- 存放历史模板样例图。
|
||||
- 样例图不作为正式拼图作品资产,当前也不再出现在拼图入口表单。
|
||||
4. `public/creation-type-references/`
|
||||
- 存放平台创作入口和玩法类型弹层的参考图。
|
||||
- 每个玩法一个参考图,首版用于视觉识别,不承载规则说明。
|
||||
- 当前创作 Tab 顶部玩法卡带必须直接渲染这些图片,避免参考图只出现在隐藏弹层里。
|
||||
5. `.codex/skills/gpt-image-2-apimart/`
|
||||
- 封装仓库内 `gpt-image-2` 的 APIMart OpenAI 兼容调用流程。
|
||||
- Skill 默认读取本地环境变量,不把密钥写入代码、文档或前端。
|
||||
|
||||
## UI 规则
|
||||
|
||||
1. 顶部只展示“创建拼图”和轻量状态标识,不写玩法规则说明。
|
||||
2. 模板区横向滚动,移动端优先;每个模板卡包含样例图、短标题和选中态。
|
||||
3. 点击模板时:
|
||||
- 立即选中该模板。
|
||||
- 如果输入框为空,直接填入模板提示词。
|
||||
- 如果输入框已有内容,替换为该模板提示词,避免追加后变得冗长。
|
||||
1. 顶部主标题展示“想做个什么玩法?”和轻量状态标识,不写玩法规则说明。
|
||||
2. 上传拼图图片区优先占据首屏左侧/上方的大块区域,移动端也必须完整露出。
|
||||
- 上传区自身就是图片卡片,不再额外封装为 `platform-subpanel` 模块壳。
|
||||
- 亮色主题下上传卡片必须使用白色或暖浅色卡面,不得显示整块黑色底。
|
||||
- 上传卡片固定为 1:1 正方形,避免拼图主画面在首屏出现非正方形预期。
|
||||
- 上传卡片底部不再叠加文件名 bar;卡片下方只保留 `点击上传拼图图片` 纯文字入口。
|
||||
- 上传卡片上方固定展示 `拼图画面` 标题。
|
||||
- 叠在上传卡片上的 `AI重绘` 和图标必须和卡面保持足够对比,避免浅色主题重映射后不可读。
|
||||
3. 画面描述输入框高度约为旧版大输入框的 1/2,避免移动端把上传参考图和提交区挤出首屏。
|
||||
4. 输入区保留:
|
||||
- 参考图上传按钮。
|
||||
- 上传拼图图片按钮。
|
||||
- 图片模型切换按钮。
|
||||
5. 输入区不保留:
|
||||
- `try` 文本。
|
||||
- 示例 prompt chip。
|
||||
- 画面描述输入框默认提示词或占位示例。
|
||||
- 玩法规则说明。
|
||||
- Template 模块和模板卡切换。
|
||||
|
||||
## 模板抽样
|
||||
## 历史模板抽样
|
||||
|
||||
首批模板不追求覆盖图二所有条目,而是选择高频且适合拼图主图的代表项:
|
||||
以下模板曾用于表单 Template 模块。2026-05-07 后入口表单不再展示这些模板,列表仅作为历史资产索引:
|
||||
|
||||
1. 情侣合照拼图
|
||||
2. 家庭纪念拼图
|
||||
@@ -76,12 +85,45 @@ n = 1
|
||||
|
||||
本次 Skill 只封装生成样例图和研发复用流程,不改变正式后端接口、扣费、OSS、SpacetimeDB 写入和发布链路。
|
||||
|
||||
## 2026-05-07 AI 重绘与上传直用
|
||||
|
||||
拼图入口上传区右上角新增 `AI重绘` 开关,默认打开;未上传拼图图片前不显示开关,上传成功后才显示。
|
||||
|
||||
1. `AI重绘=true`
|
||||
- 上传区文案为 `点击上传拼图图片`,上传图作为生图参考图。
|
||||
- 未上传图片时,输入框标题为 `画面描述`。
|
||||
- 已上传图片时,输入框标题为 `画面AI重绘要求(提示词)`。
|
||||
- 展示图片模型切换。
|
||||
- `compile_puzzle_draft` 携带 `aiRedraw: true`,继续走 APIMart 生图与 `PUZZLE_IMAGE_GENERATION_POINTS_COST = 2` 扣费链路。
|
||||
- 生成按钮展示 `消耗2光点`。
|
||||
2. `AI重绘=false`
|
||||
- 隐藏画面描述输入框和模型切换。
|
||||
- 必须上传拼图图片,按钮不展示 `消耗2光点`。
|
||||
- `compile_puzzle_draft` 携带 `aiRedraw: false`,后端只编译草稿和生成首关名,不调用 APIMart,不进入光点扣费 wrapper。
|
||||
- 后端把上传图片 Data URL 按拼图资产路径持久化,构造 `sourceType=uploaded` 的候选图并直接选为第一关正式图。
|
||||
3. 上传裁剪
|
||||
- 前端读取上传图原始宽高。
|
||||
- 非 1:1 图片必须先弹出正方形裁剪工具,裁剪完成后再进入表单状态和提交 payload。
|
||||
- 裁剪输出仍按参考图体积预算压缩,避免上传图撑爆 JSON body。
|
||||
|
||||
契约字段同步:
|
||||
|
||||
```ts
|
||||
CreatePuzzleAgentSessionRequest.aiRedraw?: boolean
|
||||
PuzzleAgentActionRequest.compile_puzzle_draft.aiRedraw?: boolean
|
||||
```
|
||||
|
||||
Rust 共享契约使用 `ai_redraw: Option<bool>` 并按 camelCase 序列化为 `aiRedraw`。
|
||||
|
||||
## 验收
|
||||
|
||||
1. 点击拼图创作后,表单首屏呈现模板横滑区和大输入框。
|
||||
2. 点击任一模板后,输入框填入该模板提示词。
|
||||
3. 输入框里没有 `try` 示例功能。
|
||||
4. 图片模型切换仍可打开并选择 `gpt-image-2` / `nanobanana2`。
|
||||
5. 模板样例图文件存在,并能在创作表单缩略图中显示。
|
||||
6. gpt-image-2 Skill 校验通过,且脚本 dry-run 能输出计划请求而不泄露密钥。
|
||||
7. `npm run check:encoding` 通过。
|
||||
1. 点击拼图创作后,表单首屏呈现大参考图区和半高文本输入框。
|
||||
2. 输入框里没有 `try` 示例功能。
|
||||
3. 图片模型切换仍可打开并选择 `gpt-image-2` / `nanobanana2`。
|
||||
4. 历史模板样例图文件可保留,但不出现在拼图入口表单。
|
||||
5. 当前创作 Tab 顶部的拼图、方洞挑战、视觉小说和 AIRP 卡片能看到对应 `creation-type-references` 图片。
|
||||
6. 默认 `AI重绘` 打开时,无图状态展示 `画面描述` 与 `消耗2光点`;上传图片后输入框标题改为 `画面AI重绘要求(提示词)`。
|
||||
7. 关闭 `AI重绘` 后隐藏画面描述输入框,生成按钮不展示 `消耗2光点`,后端直接应用上传图片为第一关图片。
|
||||
8. 上传非 1:1 图片时必须先完成正方形裁剪。
|
||||
9. gpt-image-2 Skill 校验通过,且脚本 dry-run 能输出计划请求而不泄露密钥。
|
||||
10. `npm run check:encoding` 通过。
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
- [RUST_WORKSPACE_DEPENDENCY_CONSOLIDATION_2026-05-07.md](./RUST_WORKSPACE_DEPENDENCY_CONSOLIDATION_2026-05-07.md):记录 `server-rs` Cargo 依赖集中配置口径,第三方版本和 workspace 内部 crate path 统一维护在根 `server-rs/Cargo.toml`,成员 crate 只保留 feature/optional 差异。
|
||||
- [API_SERVER_EXTERNAL_SERVICE_ENV_CONFIG_2026-05-07.md](./API_SERVER_EXTERNAL_SERVICE_ENV_CONFIG_2026-05-07.md):冻结 api-server 外部服务配置边界,公共服务 URL 可保留代码默认值,非公共模型名和私有网关 URL 统一通过环境变量注入。
|
||||
- [CREATIVE_INTERACTIVE_CONTENT_AGENT_TECHNICAL_SOLUTION_2026-05-05.md](./CREATIVE_INTERACTIVE_CONTENT_AGENT_TECHNICAL_SOLUTION_2026-05-05.md):冻结基于 LangChain-Rust 的创意互动内容生成 Agent 技术方案,明确首版只支持拼图模板、必须显式展示模板选择和积分范围,通过拼图模块 Tool/模板协议填充同一份草稿字段,支持单关卡与多关卡图片生成、立即试玩、表单化编辑和 Agent 自然语言修订草稿字段。
|
||||
- [VISUAL_NOVEL_PROMPT_AND_LLM_TOOLS_VN03_2026-05-05.md](./VISUAL_NOVEL_PROMPT_AND_LLM_TOOLS_VN03_2026-05-05.md):记录视觉小说模板 `VN-03` Prompt / LLM 工具落地,包含创作底稿 Prompt、运行时 GM Prompt、repair Prompt、工具参数 schema、Responses 请求口径和定向验证结果。
|
||||
- [VISUAL_NOVEL_IMPLEMENTATION_HANDOFF_2026-05-07.md](./VISUAL_NOVEL_IMPLEMENTATION_HANDOFF_2026-05-07.md):记录视觉小说模板 `VN-13` 实现收口、当前正式入口、表目录、路由、作品 / 运行 / 资产和负向扫描口径。
|
||||
- [PROFILE_TASK_AND_TRACKING_SYSTEM_2026-05-03.md](./PROFILE_TASK_AND_TRACKING_SYSTEM_2026-05-03.md):冻结个人任务与埋点系统首版方案,明确 `tracking_event`、`tracking_daily_stat`、`profile_task_config`、任务进度、领奖记录和光点钱包流水的边界。
|
||||
- [SQUARE_HOLE_IMAGE_SLOT_AND_RUNTIME_INTERACTION_FIX_2026-05-06.md](./SQUARE_HOLE_IMAGE_SLOT_AND_RUNTIME_INTERACTION_FIX_2026-05-06.md):记录方洞挑战结果页图片槽位局部生成、洞口图历史素材、运行态拖拽与点击投放交互的修正口径。
|
||||
- [MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md](./MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md):冻结 Maincloud 历史残留引用禁用策略,明确后续不得新增、运行或引用 `api-server:maincloud`、`GENARRATIVE_SPACETIME_MAINCLOUD_*` 和相关测试/文档口径。
|
||||
@@ -87,6 +90,7 @@
|
||||
- [PUZZLE_IMAGE_AND_FRONTEND_RULES_ALIGNMENT_2026-04-29.md](./PUZZLE_IMAGE_AND_FRONTEND_RULES_ALIGNMENT_2026-04-29.md):记录拼图生成图片回到 1:1,运行时拖动、交换、合并与拆分由前端即时裁决,以及移动端棋盘贴近屏幕边缘的落地边界。
|
||||
- [PUZZLE_FORM_CREATION_FLOW_2026-04-29.md](./PUZZLE_FORM_CREATION_FLOW_2026-04-29.md):冻结拼图填表式创作入口、初始表单自动保存草稿、生成前退出后的表单恢复,以及草稿编译/首图生成的前后端边界。
|
||||
- [PUZZLE_PICTURE_ONLY_CREATION_AND_AI_TAGS_2026-05-03.md](./PUZZLE_PICTURE_ONLY_CREATION_AND_AI_TAGS_2026-05-03.md):记录拼图入口只填写画面描述、首关名默认作品名、作品描述和标签初始为空、AI 生成 6 个作品标签以及发布前校验的落地规则。
|
||||
- [PUZZLE_TEMPLATE_FORM_AND_GPT_IMAGE_SKILL_2026-05-03.md](./PUZZLE_TEMPLATE_FORM_AND_GPT_IMAGE_SKILL_2026-05-03.md):记录拼图入口模板样例图与 gpt-image-2 Skill 约定,2026-05-07 起表单不再展示 Template 模块,改为大参考图区 + 大输入框的单屏布局。
|
||||
- [PUZZLE_LEADERBOARD_FRONTEND_LEVEL_AND_RPG_COMING_SOON_2026-04-30.md](./PUZZLE_LEADERBOARD_FRONTEND_LEVEL_AND_RPG_COMING_SOON_2026-04-30.md):记录拼图第二关排行榜提交以前端当前关卡为准、不被 SpacetimeDB 旧 run 快照误杀,以及 RPG 创作入口改为敬请期待的落地边界。
|
||||
- [PUZZLE_NEXT_LEVEL_AND_SIMILAR_WORK_HANDOFF_2026-04-30.md](./PUZZLE_NEXT_LEVEL_AND_SIMILAR_WORK_HANDOFF_2026-04-30.md):记录拼图通关后优先同作品下一关、无下一关时按 RPG/build 标签语义相似度返回三个候选作品,并在跨作品时只切换到候选作品第 1 张图、运行时关卡序号继续累进的落地规则。
|
||||
- [PUZZLE_FAILURE_EXTENSION_AND_SAVE_ARCHIVE_2026-05-01.md](./PUZZLE_FAILURE_EXTENSION_AND_SAVE_ARCHIVE_2026-05-01.md):记录拼图失败后重新开始/付费续时,以及进入作品与过关后同步存档页投影的落地规则。
|
||||
@@ -261,7 +265,7 @@
|
||||
- [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 与滚动权责修复记录。
|
||||
- [RPG_FOUNDATION_DRAFT_EIGHT_ANCHOR_SEED_FIX_2026-04-25.md](./RPG_FOUNDATION_DRAFT_EIGHT_ANCHOR_SEED_FIX_2026-04-25.md):记录 RPG 创作 Agent session 八锚点进入 foundation draft seed 时被旧字段压缩的根因、修复和后续约束。
|
||||
- [TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md](./TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md):把外部仓库 TXT 模式完整迁入当前项目的冻结边界、模块映射、分阶段计划与验收清单。
|
||||
- [TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md](./TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md):旧 TXT 模式迁移方案的历史参考;视觉小说模板最新落地口径以 PRD [`AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md`](../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md) 为准,不再按外部平台工程完整迁入执行。
|
||||
- [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 产品形态与能力拆解。
|
||||
|
||||
@@ -30,6 +30,7 @@ spacetime sql <db> "SELECT * FROM custom_world_gallery_entry"
|
||||
| 拼图 | `puzzle_agent_session`, `puzzle_agent_message`, `puzzle_work_profile`, `puzzle_event`, `puzzle_runtime_run`, `puzzle_leaderboard_entry` |
|
||||
| 抓大鹅 Match3D | `match3d_agent_session`, `match3d_agent_message`, `match3d_work_profile`, `match3d_runtime_run` |
|
||||
| 方洞挑战 | `square_hole_agent_session`, `square_hole_agent_message`, `square_hole_work_profile`, `square_hole_runtime_run` |
|
||||
| 视觉小说 | `visual_novel_agent_session`, `visual_novel_agent_message`, `visual_novel_work_profile`, `visual_novel_runtime_run`, `visual_novel_runtime_history_entry`, `visual_novel_runtime_event` |
|
||||
| 大鱼吃小鱼 | `big_fish_creation_session`, `big_fish_agent_message`, `big_fish_asset_slot`, `big_fish_event`, `big_fish_runtime_run` |
|
||||
| 资产 | `asset_object`, `asset_entity_binding`, `asset_event` |
|
||||
| AI 任务 | `ai_task`, `ai_task_stage`, `ai_text_chunk`, `ai_result_reference`, `ai_task_event` |
|
||||
@@ -717,6 +718,78 @@ SELECT * FROM square_hole_runtime_run WHERE owner_user_id = '<user_id>' ORDER BY
|
||||
SELECT * FROM square_hole_runtime_run WHERE profile_id = '<profile_id>';
|
||||
```
|
||||
|
||||
## 视觉小说表
|
||||
|
||||
> VN-13 复核:当前视觉小说首版只保留本节 6 张表;`visual_novel_runtime_history_entry` 和 `visual_novel_runtime_event` 均不得扩展成回放数据源。维护入口见 [视觉小说模板实现收口与交接说明](./VISUAL_NOVEL_IMPLEMENTATION_HANDOFF_2026-05-07.md)。
|
||||
|
||||
### `visual_novel_agent_session`
|
||||
|
||||
- 作用:视觉小说创作 Agent 会话主表,保存创建起点、源资产、当前阶段、底稿 JSON、待执行 action 和发布 profile 指针。
|
||||
- 结构:`session_id PK: String`, `owner_user_id: String`, `source_mode: String`, `status: String`, `seed_text: String`, `source_asset_ids_json: String`, `current_turn: u32`, `progress_percent: u32`, `draft_json: String`, `pending_action_json: String`, `last_assistant_reply: String`, `published_profile_id: String`, `created_at: Timestamp`, `updated_at: Timestamp`。
|
||||
- 索引:`owner_user_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_agent_session WHERE session_id = '<session_id>';
|
||||
SELECT * FROM visual_novel_agent_session WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||
```
|
||||
|
||||
### `visual_novel_agent_message`
|
||||
|
||||
- 作用:视觉小说创作 Agent 消息流水,保存用户输入和模型回复。
|
||||
- 结构:`message_id PK: String`, `session_id: String`, `role: String`, `kind: String`, `text: String`, `created_at: Timestamp`。
|
||||
- 索引:`session_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_agent_message WHERE session_id = '<session_id>' ORDER BY created_at ASC;
|
||||
```
|
||||
|
||||
### `visual_novel_work_profile`
|
||||
|
||||
- 作用:视觉小说作品草稿 / 发布 profile 表,保存平台作品摘要字段、源资产引用、完整 `VisualNovelResultDraft` JSON、发布状态和游玩次数。
|
||||
- 结构:`profile_id PK: String`, `work_id: String`, `owner_user_id: String`, `source_session_id: String`, `author_display_name: String`, `work_title: String`, `work_description: String`, `tags_json: String`, `cover_image_src: String`, `source_asset_ids_json: String`, `draft_json: String`, `publication_status: String`, `publish_ready: bool`, `play_count: u32`, `created_at: Timestamp`, `updated_at: Timestamp`, `published_at: Option<Timestamp>`。
|
||||
- 索引:`owner_user_id`, `publication_status`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_work_profile WHERE profile_id = '<profile_id>';
|
||||
SELECT * FROM visual_novel_work_profile WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||
SELECT * FROM visual_novel_work_profile WHERE publication_status = 'published';
|
||||
```
|
||||
|
||||
### `visual_novel_runtime_run`
|
||||
|
||||
- 作用:视觉小说测试或正式运行态表,保存当前场景、阶段、可见角色、旗标、指标、可选项和运行快照 JSON。
|
||||
- 结构:`run_id PK: String`, `owner_user_id: String`, `profile_id: String`, `mode: String`, `status: String`, `current_scene_id: String`, `current_phase_id: String`, `visible_character_ids_json: String`, `flags_json: String`, `metrics_json: String`, `available_choices_json: String`, `text_mode_enabled: bool`, `snapshot_json: String`, `created_at: Timestamp`, `updated_at: Timestamp`。
|
||||
- 索引:`owner_user_id`, `profile_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_runtime_run WHERE run_id = '<run_id>';
|
||||
SELECT * FROM visual_novel_runtime_run WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||
SELECT * FROM visual_novel_runtime_run WHERE profile_id = '<profile_id>';
|
||||
```
|
||||
|
||||
### `visual_novel_runtime_history_entry`
|
||||
|
||||
- 作用:视觉小说运行时历史表,保存每轮玩家 / 模型 / 系统事实、step JSON 和快照哈希,用于继续体验与历史重生成边界;不是回放表。
|
||||
- 结构:`entry_id PK: String`, `run_id: String`, `owner_user_id: String`, `profile_id: String`, `turn_index: u32`, `source: String`, `action_text: String`, `steps_json: String`, `snapshot_before_hash: String`, `snapshot_after_hash: String`, `created_at: Timestamp`。
|
||||
- 索引:`run_id`, `owner_user_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_runtime_history_entry WHERE run_id = '<run_id>' ORDER BY turn_index ASC;
|
||||
SELECT * FROM visual_novel_runtime_history_entry WHERE owner_user_id = '<user_id>' ORDER BY created_at DESC;
|
||||
```
|
||||
|
||||
### `visual_novel_runtime_event`
|
||||
|
||||
- 作用:视觉小说运行时审计事件表,用于订阅端、BFF 或排障流程感知 run 事实;该表明确不是 replay、分享回放或片段回放数据源。
|
||||
- 可见性:`public event`。
|
||||
- 结构:`event_id PK: String`, `run_id: String`, `owner_user_id: String`, `profile_id: String`, `event_kind: String`, `client_event_id: String`, `history_entry_id: String`, `payload_json: String`, `occurred_at: Timestamp`。
|
||||
- 索引:`run_id`, `owner_user_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_runtime_event WHERE run_id = '<run_id>' ORDER BY occurred_at ASC;
|
||||
SELECT * FROM visual_novel_runtime_event WHERE owner_user_id = '<user_id>' ORDER BY occurred_at DESC;
|
||||
```
|
||||
|
||||
## 大鱼吃小鱼表
|
||||
|
||||
### `big_fish_creation_session`
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
更新时间:`2026-04-20`
|
||||
|
||||
> 2026-05-05 更新口径:本文保留为历史迁移参考。视觉小说模板后续落地以 [`../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md`](../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md) 为准;冲突时不再迁入外部平台工程、不使用 `server-node` 作为新功能落点、不保留回放,统一接入 Genarrative `server-rs + Axum + SpacetimeDB` 与平台接口。
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份执行方案用于指导 `Genarrative` 在**不改动外部 TXT 模式提示词正文、不改动外部 TXT 模式功能需求**的前提下,把下面两个仓库中已经跑通的 TXT 模式创作流程与运行机制完整迁入当前项目:
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# 视觉小说模板实现收口与交接说明 2026-05-07
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本文记录 `AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md` 的 `VN-13` 收口结果,作为视觉小说模板后续维护的一页式入口。
|
||||
|
||||
本文只总结当前已经落地且需要长期遵守的实现边界,不再把视觉小说描述成外部 TXT 平台迁移,也不重复旧迁移方案里的临时讨论。
|
||||
|
||||
## 2. 当前正式入口
|
||||
|
||||
后续维护时优先看这些文档:
|
||||
|
||||
1. [AI 原生视觉小说模板 PRD](../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md)
|
||||
2. [SpacetimeDB 表说明与查询目录](./SPACETIMEDB_TABLE_CATALOG.md)
|
||||
3. [视觉小说 VN-03 Prompt 与 LLM 工具实现说明](./VISUAL_NOVEL_PROMPT_AND_LLM_TOOLS_VN03_2026-05-05.md)
|
||||
4. [视觉小说 VN-11 负向扫描报告](../audits/VN11_NEGATIVE_SCAN_REPORT_2026-05-07.md)
|
||||
5. [视觉小说模板交接与维护经验](../experience/VISUAL_NOVEL_HANDOFF_AND_MAINTENANCE_2026-05-07.md)
|
||||
|
||||
旧的 `TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md` 只保留历史参考意义,不再作为实现口径。
|
||||
|
||||
## 3. 已收口的实现边界
|
||||
|
||||
### 3.1 创作链路
|
||||
|
||||
- 创作链统一走 `/api/creation/visual-novel/*`。
|
||||
- 入口、工作台、结果页和服务端 prompt 已围绕 `visual-novel` 模板闭环对齐。
|
||||
- `VisualNovelResultDraft`、`VisualNovelCreationSessionSnapshot` 等共享契约已经成型。
|
||||
|
||||
### 3.2 运行链路
|
||||
|
||||
- 运行链统一走 `/api/runtime/visual-novel/*`。
|
||||
- 运行时只认 typed step 和快照,不让前端从 `raw_text` 猜业务真相。
|
||||
- `visual_novel_runtime_history_entry` 只用于继续体验和历史重生成边界,不是回放表。
|
||||
|
||||
### 3.3 数据链路
|
||||
|
||||
- SpacetimeDB 首版只保留 6 张视觉小说表。
|
||||
- `visual_novel_runtime_event` 是 `public event` 审计事件表,不是 replay 数据源。
|
||||
- 表结构变化必须同步 `migration.rs`、`SPACETIMEDB_TABLE_CATALOG.md` 和 Rust bindings。
|
||||
|
||||
### 3.4 作品与发布
|
||||
|
||||
- 作品架、广场和分享都复用平台现有链路。
|
||||
- 公开作品码统一使用 `VN-` 前缀。
|
||||
- 发布后要刷新作品架和公开聚合。
|
||||
|
||||
### 3.5 资产与登录态
|
||||
|
||||
- 文档、封面、背景、角色和音乐都只保留平台资产对象引用。
|
||||
- 不保存大 Data URL、不走独立对象存储、不新增视觉小说私有存档系统。
|
||||
- 退出登录时要清空视觉小说私有 session、work、run 和错误状态。
|
||||
|
||||
## 4. 长期维护规则
|
||||
|
||||
1. 看到视觉小说相关改动,先确认是不是契约改动;如果是,先同步 TS / Rust shared contracts。
|
||||
2. 看到表结构改动,先同步 `migration.rs` 和表目录,再补 bindings。
|
||||
3. 看到资产链路改动,只改平台资产引用,不回退到本地路径或二进制直存。
|
||||
4. 看到运行时历史改动,只维护 typed history 和审计事件,不把它改成回放能力。
|
||||
5. 看到旧 TXT 文档时,只把它当历史来源,不把其中的平台工程目标重新带回实现。
|
||||
|
||||
## 5. 验证口径
|
||||
|
||||
收口后建议按下面顺序检查:
|
||||
|
||||
```bash
|
||||
npm run check:encoding
|
||||
npm run check:visual-novel-vn11
|
||||
npm run typecheck
|
||||
|
||||
cd server-rs
|
||||
cargo test -p shared-contracts
|
||||
cargo test -p module-visual-novel
|
||||
cargo check -p api-server
|
||||
```
|
||||
|
||||
如果本轮没有改代码,只要编码检查和负向扫描通过,通常就说明 VN-13 的文档收口已经站稳。
|
||||
@@ -0,0 +1,111 @@
|
||||
# 视觉小说 VN-03 Prompt 与 LLM 工具实现说明
|
||||
|
||||
日期:`2026-05-05`
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本文记录 `AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md` 中 `VN-03` 的工程落地口径。
|
||||
|
||||
本次只实现视觉小说模板的 Prompt / LLM 工具层:
|
||||
|
||||
1. 创作底稿生成 Prompt,目标输出 `VisualNovelResultDraft`。
|
||||
2. 运行时 GM Prompt,目标输出 `VisualNovelRuntimeStep[]`。
|
||||
3. 结构化 repair Prompt,用于解析失败后的后端修复。
|
||||
4. 创作 action 与图片生成 action 的工具参数 schema。
|
||||
5. `platform-llm` Responses 请求构造口径。
|
||||
|
||||
本次不保存数据、不新增 HTTP 路由、不写前端 UI、不触碰 SpacetimeDB schema。
|
||||
|
||||
## 2. 代码落点
|
||||
|
||||
主要实现位于:
|
||||
|
||||
1. `server-rs/crates/api-server/src/prompt/visual_novel.rs`
|
||||
2. `server-rs/crates/api-server/src/prompt/mod.rs`
|
||||
|
||||
为了让当前工作树中已有的 creative-agent / puzzle 并行改动可继续编译,本次还补了两个编译闭口:
|
||||
|
||||
1. `server-rs/crates/module-puzzle/Cargo.toml` 增加 `serde_json = "1"`。
|
||||
2. `server-rs/crates/platform-agent/src/puzzle_phase1_agent.rs` 给 `MockLangChainRustAgentExecutor` 补 `Debug` 派生。
|
||||
|
||||
## 3. Prompt 约束
|
||||
|
||||
### 3.1 创作底稿
|
||||
|
||||
创作系统 Prompt 明确要求:
|
||||
|
||||
1. 只输出一个 JSON 对象。
|
||||
2. 内容必须是中文视觉小说底稿。
|
||||
3. 补齐世界观、玩家身份、角色、场景、剧情阶段和开场。
|
||||
4. 角色必须有可生成立绘的 `appearance`。
|
||||
5. 场景必须有可生成背景图的 `description`。
|
||||
6. 不输出回放、商城、会员、后台、平台活动、促销、订单或独立账号字段。
|
||||
7. 不生成第二套存档、发布、钱包、广场或资产系统。
|
||||
|
||||
### 3.2 运行时 GM
|
||||
|
||||
运行时系统 Prompt 明确要求:
|
||||
|
||||
1. 只输出 `VisualNovelRuntimeStep[]` JSON 数组。
|
||||
2. step 数量不超过输入的 `maxAssistantStepCountPerTurn`。
|
||||
3. 场景变化必须输出 `scene_change`。
|
||||
4. 旁白、对白、转场、选项、flag、metric 分别使用契约内 step 类型。
|
||||
5. 前端不得从 `raw_text` 猜业务 step。
|
||||
6. 不输出回放、录制、商城、会员、后台、平台活动或独立存档元数据。
|
||||
|
||||
### 3.3 Repair
|
||||
|
||||
repair Prompt 只负责把坏格式修成目标 JSON:
|
||||
|
||||
1. `VisualNovelResultDraft`
|
||||
2. `VisualNovelRuntimeStep[]`
|
||||
|
||||
repair 仍失败时,由后续 `VN-05` API 接入层返回可重试错误。
|
||||
|
||||
## 4. LLM 请求口径
|
||||
|
||||
视觉小说创作、运行和 repair 请求统一使用 `platform-llm`:
|
||||
|
||||
1. model:`CREATION_TEMPLATE_LLM_MODEL`,当前为 `deepseek-v3-2-251201`。
|
||||
2. protocol:`LlmTextProtocol::Responses`。
|
||||
3. 创作底稿请求可按 API 配置开启 web search。
|
||||
4. 运行时 GM 与 repair 默认不开 web search,避免运行态引入外部噪声。
|
||||
|
||||
## 5. 工具参数
|
||||
|
||||
本次定义两个工具描述:
|
||||
|
||||
1. `visual_novel_apply_creation_action`
|
||||
- 支持 `generate_draft`、`patch_world`、`patch_character`、`patch_scene`、`patch_story_phase`、`compile_work_profile`。
|
||||
- 只写回视觉小说底稿或编译平台 work profile 草稿。
|
||||
2. `visual_novel_generate_image_asset`
|
||||
- 支持 `generate_scene_image`、`generate_character_image`。
|
||||
- 输出应接后续平台资产引用,不保存二进制或大 Data URL。
|
||||
|
||||
工具 schema 不包含 replay / Replay 字段。
|
||||
|
||||
## 6. 验证结果
|
||||
|
||||
已执行:
|
||||
|
||||
```bash
|
||||
cargo test -p shared-contracts visual_novel --manifest-path server-rs/Cargo.toml
|
||||
cargo test -p module-puzzle creative_tools --manifest-path server-rs/Cargo.toml
|
||||
cargo test -p platform-agent puzzle_phase1_agent --manifest-path server-rs/Cargo.toml
|
||||
cargo test -p api-server prompt::visual_novel --manifest-path server-rs/Cargo.toml
|
||||
```
|
||||
|
||||
结果:全部通过。
|
||||
|
||||
## 7. 后续接入点
|
||||
|
||||
`VN-05` 接 API Server 时直接复用:
|
||||
|
||||
1. `build_visual_novel_creation_llm_request`
|
||||
2. `build_visual_novel_runtime_llm_request`
|
||||
3. `build_visual_novel_repair_llm_request`
|
||||
4. `parse_visual_novel_result_draft_fixture`
|
||||
5. `parse_visual_novel_runtime_steps_fixture`
|
||||
6. `visual_novel_tool_descriptors`
|
||||
|
||||
若后续 `VN-01` 契约发生破坏性变更,必须同步更新本 Prompt 模块的 output contract、fixture 和解析测试。
|
||||
Reference in New Issue
Block a user