Merge remote-tracking branch 'origin/master' into codex/bark-battle
This commit is contained in:
@@ -54,8 +54,9 @@
|
||||
|
||||
- 背景:`server-rs/crates/api-server/src/puzzle.rs` 已膨胀为数千行大文件,混合 Axum handler、草稿编译、图片生成、VectorEngine / OSS 持久化、DTO mapper、标签生成和测试;继续在单文件内迭代会降低定位和评审效率。
|
||||
- 决策:原超大 `puzzle.rs` 改为同名入口 `server-rs/crates/api-server/src/puzzle.rs` 加 `server-rs/crates/api-server/src/puzzle/` 子模块目录。`puzzle.rs` 只保留聚合入口和 handler re-export;`handlers.rs` 放 HTTP handler;`draft.rs` 放表单草稿 / 编译 / snapshot helper;`generation.rs` 放图片与 UI 背景生成编排;`vector_engine.rs` 放 VectorEngine、下载、OSS、asset object / binding 和错误归一;`mappers.rs` / `tags.rs` 保留映射和标签 / 错误 helper;`tests.rs` 承接原 puzzle 单测。
|
||||
- 2026-05-21 追加决策:拼图 HTTP/BFF handler 不再直接提取完整 `AppState`,统一通过 `PuzzleApiState` 暴露拼图能力需要的 SpacetimeDB facade、gallery cache、OSS、作者查询、LLM 和少量配置快照。`modules/puzzle.rs` 仍接收全局 `AppState` 以挂接鉴权和回到全局路由树,但内部路由先 `.with_state(PuzzleApiState::from_ref(&state))`,handler 使用 `State<PuzzleApiState>`。确需复用计费、外部失败审计等仍要求 `AppState` 的横切 helper 时,先经 `PuzzleApiState::root_state()` 显式过渡,后续再继续收窄。
|
||||
- 边界:本次只改变 `api-server` 内部文件组织,不改变 `/api/runtime/puzzle/*` 路由、DTO、error envelope、SpacetimeDB schema、公开 gallery cache 语义或计费语义。领域规则后续仍应逐步沉到 `module-puzzle`,SpacetimeDB 表、reducer、procedure 和 row shape 仍留在 `spacetime-module`。
|
||||
- 影响范围:`server-rs/crates/api-server/src/puzzle/`、`server-rs/crates/api-server/src/modules/puzzle.rs` 的 handler 引用、后端架构文档。
|
||||
- 影响范围:`server-rs/crates/api-server/src/state.rs`、`server-rs/crates/api-server/src/puzzle/`、`server-rs/crates/api-server/src/modules/puzzle.rs` 的 handler 引用、后端架构文档。
|
||||
- 验证方式:执行 `cargo check -p api-server --manifest-path server-rs\Cargo.toml`;后续若改动 puzzle API 行为,再按对应路由补充定向测试和 `npm run dev:api-server` `/healthz` smoke。
|
||||
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
@@ -103,20 +104,14 @@
|
||||
- 验证方式:执行 `npm run container:config` 展开 compose 配置;需要真实运行时再执行 `npm run container:build`、`npm run container:up`、`npm run container:k6`,并结合容器 Nginx log 与 OTLP debug exporter 判断瓶颈。
|
||||
- 关联文档:`deploy/container/README.md`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 2026-05-18 生产 provision 改为构建机准备工具包再上传安装
|
||||
## 2026-05-19 生产 provision 改为 Windows 下载包后由目标机本地安装
|
||||
|
||||
- 背景:目标 release 服务器无法访问 GitHub,之前的 server provision 默认仍假设 `spacetime` 和 `otelcol-contrib` 已经存在于目标机本地路径,和真实运维条件不符。
|
||||
- 决策:Jenkins 新增 `Prepare Provision Tools` 阶段,在 `linux && genarrative-build` 构建机执行 `scripts/prepare-server-provision-tools.sh`,通过官方 SpacetimeDB 安装入口和 OpenTelemetry release 包生成 `provision-tools/`,再用 `stash/unstash` 带到 release 部署 agent;`scripts/jenkins-server-provision.sh` 只从工作区工具包复制安装,不再要求目标机自己下载或预装二进制。
|
||||
- 背景:当前 `development` provision 目标实际就是 Linux agent `genarrative-build-01`,之前把 `Prepare Provision Tools` 放在 `linux && genarrative-build` 会让目标机自己连 GitHub 和 `install.spacetimedb.com`,违背“Windows 本机先下载再传到目标机”的运维要求。
|
||||
- 决策:`Genarrative-Server-Provision` 拆成 Windows 下载阶段和 Linux 目标机安装阶段。Windows 节点的 `Download Provision Tool Archives` 只下载 `spacetime-x86_64-unknown-linux-gnu.tar.gz` 和 `otelcol-contrib_0.151.0_linux_amd64.tar.gz`,通过 `stash/unstash` 传到目标 Linux 节点;目标机执行 `scripts/prepare-server-provision-tools.sh` 时设置 `PROVISION_REQUIRE_LOCAL_DOWNLOADS=true`,只消费已下载件生成 `provision-tools/`,缺包直接失败,不回退外网下载。
|
||||
- 追加决策:Server-Provision 的 Windows helper 不再对 Jenkins `writeFile` 刚写出的 `.ps1` 做原地 UTF-8 BOM 重写,而是由显式 `powershell.exe` 按 UTF-8 读入脚本文本,并用 `ScriptBlock::Create(...)` 在内存中执行;这样既保留中文脚本内容,又避免同一个 workspace 脚本被立即重写时触发 `拒绝访问`。
|
||||
- 追加决策:GitHub release asset 的可用校验信息使用 `digest` 字段,实际是 `sha256:...`,不是 MD5;Windows 下载阶段先查 digest,再决定是否复用已有文件。
|
||||
- 影响范围:`jenkins/Jenkinsfile.production-server-provision`、`scripts/prepare-server-provision-tools.sh`、`scripts/jenkins-server-provision.sh`、生产运维文档。
|
||||
- 验证方式:Jenkins 构建机可完成工具包准备,release 部署 agent 只消费工作区文件;目标机不再依赖 GitHub 外网下载。
|
||||
- 关联文档:`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 2026-05-19 otelcol-contrib 改为 Jenkins 手动上传归档再解包
|
||||
|
||||
- 背景:Genarrative-Server-Provision 中 `otelcol-contrib` 的构建机下载步骤耗时较长,且本机已经提前准备好安装包。
|
||||
- 决策:`jenkins/Jenkinsfile.production-server-provision` 新增 `OTELCOL_CONTRIB_ARCHIVE` 手动上传参数,默认要求上传 `otelcol-contrib_0.151.0_linux_amd64.tar.gz`;`scripts/prepare-server-provision-tools.sh` 优先从上传归档解包生成 `provision-tools/otelcol-contrib`,不再默认联网下载 OpenTelemetry release 包。
|
||||
- 影响范围:`jenkins/Jenkinsfile.production-server-provision`、`scripts/prepare-server-provision-tools.sh`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
- 验证方式:Jenkins 日志应显示使用手动上传的 otelcol 包,`MANIFEST.txt` 记录 source 为 manual archive;当 `ENABLE_OTELCOL=false` 时可以跳过 collector 工具包准备。
|
||||
- 验证方式:Jenkins 日志应先出现 Windows 节点的 `[jenkins-powershell] workspace:`、`[jenkins-powershell] loaded bytes:` 和 `[prepare-provision-downloads]` 下载日志,再在 `genarrative-build-01` 上出现“使用已下载的 ...”日志;目标机不应出现直接访问 `install.spacetimedb.com` 或 OpenTelemetry GitHub release 下载地址的回退日志,且不再需要 `spacetimedb-update-*` 作为离线交付包。
|
||||
- 关联文档:`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 2026-05-19 公开 gallery 入口发布限流以快拒绝保护后端
|
||||
@@ -127,6 +122,38 @@
|
||||
- 验证方式:容器连续 10 轮不重启 SpacetimeDB 压测,`PEAK_RPS=2500` 等价约 5000 HTTP req/s,平均实际吞吐约 `4219 HTTP req/s`,总计 `0` 个 5xx,200 请求平均 `p95=123ms`、`p99=234ms`;同时观察 SpacetimeDB 内存高水位,后续优化先处理连接 / 订阅 / tracking 下游状态。
|
||||
- 关联文档:`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`、`deploy/container/README.md`。
|
||||
|
||||
## 2026-05-19 新增玩法创作工具平台 SOP 冻结
|
||||
|
||||
- 背景:新增玩法的创作工具如果默认复制既有玩法的聊天式 Agent、轻输入 Agent 或专属素材模型,平台会不断复制出不可控分支,后续接入、测试和恢复语义都会漂移。
|
||||
- 决策:新增玩法创作工具统一收敛为平台级 SOP:默认使用表单/图片输入创作工作台;单图资产统一通过 `CreativeImageInputPanel`;系列素材统一走批量规划、sheet 生图、后端切图、透明化、OSS 持久化和局部重生成流水线;不把任一玩法专属素材模型当平台通用模型。
|
||||
- 影响范围:`CONTEXT.md`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`.codex/skills/genarrative-play-type-integration/SKILL.md`、`.hermes/skills/genarrative-play-type-integration/SKILL.md`、后续新增玩法 PRD 和工程实现。
|
||||
- 验证方式:新增玩法 PRD 必须显式声明单图资产槽位和系列素材槽位;新增工作台测试确认没有默认聊天式 Agent 输入;skill 通过 `quick_validate.py`。
|
||||
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`.codex/skills/genarrative-play-type-integration/SKILL.md`、`.hermes/skills/genarrative-play-type-integration/SKILL.md`。
|
||||
|
||||
## 2026-05-21 RPG publish_world 设定文本以后端草稿真相派生
|
||||
|
||||
- 背景:RPG 结果页发布动作只保证提交 `{ action: 'publish_world' }`;旧 agent 会话可能没有 `seed_text`,但 `draft_profile_json` 已经通过 `publish_gate` 并可发布。
|
||||
- 决策:发布正式世界时,`spacetime-module` 不再把 `session.seed_text` 当作唯一 `setting_text` 兜底,而是调用 `module-custom-world::resolve_custom_world_publish_setting_text(...)` 从 payload、当前草稿 profile 和 seed 依次派生。
|
||||
- 影响范围:RPG / custom-world agent 发布链路、`custom_world_profile` 编译入库、公开 gallery 投影。
|
||||
- 验证方式:`cargo test -p module-custom-world publish_setting_text --manifest-path server-rs\Cargo.toml`;`cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml`;本地 api-server 重启后检查 `/healthz`。
|
||||
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`、`.hermes/shared-memory/pitfalls.md`。
|
||||
|
||||
## 2026-05-19 系列素材 n*n 图集抽为 api-server 通用模块
|
||||
|
||||
- 背景:抓大鹅物品 sheet 已包含 prompt 组装、固定网格切图、绿幕 / 近白底透明化、切片 PNG 持久化和 prompt 追踪;继续留在 Match3D 私有模块会让跳一跳、后续地块 / 道具类玩法重复复制同一套算法和 OSS 元数据口径。
|
||||
- 决策:`server-rs/crates/api-server/src/generated_asset_sheets.rs` 作为通用系列素材图集模块,`n` 作为必选 `grid_size` 参数;物品名称 prompt 模板与特殊设定 prompt 作为可选输入;模块负责 sheet prompt、`n*n` 切片、透明化、PNG 输出、OSS private upload 请求构造,以及 sheet / item / special prompt 的 base64 元数据持久化。玩法只负责生图 provider、计费、slot 规划、失败回写和把通用切片结果映射回自身 DTO / 草稿 / runtime 字段。
|
||||
- 影响范围:`api-server` 系列素材生成、Match3D 物品五视角素材、后续新增玩法的地块 / 物品 / 障碍 / 装饰图集生成。
|
||||
- 验证方式:`cargo test -p api-server generated_asset_sheets --manifest-path server-rs\Cargo.toml -- --nocapture` 覆盖通用 prompt、切片、`n` 校验和 prompt 元数据;玩法侧执行对应素材流水线定向测试。
|
||||
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
## 2026-05-19 跳一跳玩法采用正式 scoring DTO 与 public view 投影
|
||||
|
||||
- 背景:跳一跳玩法新增后,前端、shared-contracts、SpacetimeDB 生成绑定和后端 mapper 对 scoring 字段口径不一致,schema guard 也要求 table / view 目录与 `migration.rs` 同步。
|
||||
- 决策:跳一跳的 `JumpHopScoring` 统一采用 `chargeToDistanceRatio/maxChargeMs/hitBonus/perfectBonus`,公开广场优先使用 `jump_hop_gallery_card_view`,详情兼容投影保留 `jump_hop_gallery_view`。`spacetime-module` 新增的 `jump_hop_*` table 必须同步进入 `migration.rs` 和后端架构文档。
|
||||
- 影响范围:`packages/shared/src/contracts/jumpHop.ts`、`server-rs/crates/shared-contracts/src/jump_hop.rs`、`server-rs/crates/spacetime-client/src/mapper/jump_hop.rs`、`server-rs/crates/spacetime-module/src/migration.rs`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
- 验证方式:`cargo check -p shared-contracts --manifest-path server-rs/Cargo.toml`、`cargo check -p spacetime-client --manifest-path server-rs/Cargo.toml`、`cargo check -p api-server --manifest-path server-rs/Cargo.toml`、`npm run check:spacetime-schema`。
|
||||
- 关联文档:`docs/prd/【玩法创作】跳一跳俯视角玩法模板PRD-2026-05-19.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
## 2026-05-16 公开作品列表短期由 BFF 订阅读模型缓存
|
||||
|
||||
- 背景:作品列表压测和实时性讨论中,曾考虑让浏览器前端直接订阅公开作品列表,减少 HTTP 拉取和 BFF 压力。
|
||||
@@ -194,6 +221,7 @@
|
||||
|
||||
## 2026-05-14 抓大鹅物品素材 sheet 改用 VectorEngine Gemini
|
||||
|
||||
- 状态:历史决策,已被 `2026-05-22 抓大鹅素材生成改为关卡整图派生三图` 取代;当前物品 spritesheet 走 `gpt-image-2` 参考关卡整图编辑生成 `2K 1:1`、`10*10` 绿幕图,上传 OSS 前扣成透明 PNG。
|
||||
- 背景:抓大鹅 2D 五视角物品素材仍沿用 5x5 sheet、绿幕去背、切图、OSS 转存和 `generatedItemAssets` 持久化,但用户要求物品素材图片生成步骤改用 VectorEngine Apifox `api-381740608` 对应的 Gemini 原生图片接口。
|
||||
- 决策:抓大鹅物品素材 sheet 生图固定走 VectorEngine `POST {VECTOR_ENGINE_BASE_URL}/v1beta/models/gemini-3-pro-image-preview:generateContent?key={VECTOR_ENGINE_API_KEY}`,请求体使用 `contents[].parts[].text` 与 `generationConfig.responseModalities = ["TEXT", "IMAGE"]`、`imageConfig.aspectRatio = "1:1"`;响应从 `candidates[].content.parts[].inlineData.data` / `inline_data.data` 读取 base64 图片。封面、9:16 纯背景图、1:1 容器 UI 图、切图、OSS、扣费和运行态消费链路保持不变;音频以后续“拼图与抓大鹅音频生成入口临时关闭”决策为准。
|
||||
- 影响范围:`server-rs/crates/api-server/src/match3d.rs`、`server-rs/crates/api-server/src/config.rs`、`deploy/env/api-server.env.example`、抓大鹅素材生成技术文档。
|
||||
@@ -245,7 +273,7 @@
|
||||
## 2026-05-12 抓大鹅入口素材风格改为 2D 常见素材风格
|
||||
|
||||
- 背景:抓大鹅草稿素材生成已经收敛为多视角 2D 图片素材,但入口页和旧参考图仍沿用黏土、低多边形、塑料、木雕、体素、金属等偏 3D 素材语言,容易让后续生成链路和用户预期继续漂移。
|
||||
- 决策:抓大鹅创作入口 `2D素材风格` 固定为 `扁平图标 / 赛璐璐卡通 / 像素复古 / 手绘水彩 / 贴纸描边 / 厚涂图标 / 自定义`;默认风格为 `flat-icon`。入口参考图统一由 `npm run assets:match3d-style-references -- --live` 调用 VectorEngine `gpt-image-2-all` 生成,输出到 `public/match3d-style-references/`。旧 3D 风格参考图不再保留为入口资产。
|
||||
- 决策:抓大鹅创作入口 `2D素材风格` 固定为 `扁平图标 / 赛璐璐卡通 / 像素复古 / 手绘水彩 / 贴纸描边 / 厚涂图标 / 自定义`;默认风格为 `flat-icon`。入口参考图统一由 `npm run assets:match3d-style-references -- --live` 调用 VectorEngine `gpt-image-2` 生成,输出到 `public/match3d-style-references/`。旧 3D 风格参考图不再保留为入口资产。
|
||||
- 影响范围:`Match3DAgentWorkspace`、抓大鹅入口交互测试、Match3D PRD、素材生成流水线技术文档、F1 入口文档和 `public/match3d-style-references/` 静态资产。
|
||||
- 验证方式:执行 `npm run test -- src\components\match3d-creation\Match3DAgentWorkspace.interaction.test.tsx`、`cargo test -p shared-contracts match3d --manifest-path server-rs\Cargo.toml`、`npm run typecheck`、`npm run check:encoding`,并人工抽查 `.tmp/match3d-style-preview.png`。
|
||||
- 关联文档:`docs/prd/AI_NATIVE_MATCH3D_CREATOR_AND_GAMEPLAY_SYSTEM_PRD_2026-04-30.md`、`docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`、`docs/technical/MATCH3D_F1_CREATION_ENTRY_AND_AGENT_UI_2026-04-30.md`。
|
||||
@@ -261,8 +289,9 @@
|
||||
## 2026-05-12 拼图 UI 背景图复用 levels_json 持久化
|
||||
|
||||
- 背景:拼图草稿结果页需要像抓大鹅一样支持 UI 背景生成,但首版只需要作品级/首关背景,不应为图片生成结果新增 SpacetimeDB 表结构。
|
||||
- 决策:拼图 UI 背景字段存入首关 `levels_json`,字段为 `uiBackgroundPrompt`、`uiBackgroundImageSrc`、`uiBackgroundImageObjectKey`;`compile_puzzle_draft` 草稿编译阶段自动生成首关 UI 背景,自动草稿阶段必须拿到 `uiBackgroundImageSrc` 或 `uiBackgroundImageObjectKey` 才能返回成功;结果页新增 `UI` Tab,可编辑提示词并触发 `generate_puzzle_ui_background`,手动生成失败只展示在当前面板。`api-server` 读取 `public/ui-previews/puzzle-image-compact-ui-2026-05-08.png` 作为非拼图 UI 参考图,调用 VectorEngine `gpt-image-2-all` 生成 9:16 背景并要求中央正方形拼图区与外部 UI 背景边界清晰。SpacetimeDB 只保存结果,不做外部 I/O。
|
||||
- 决策:拼图 UI 背景字段存入首关 `levels_json`,字段为 `uiBackgroundPrompt`、`uiBackgroundImageSrc`、`uiBackgroundImageObjectKey`;`compile_puzzle_draft` 草稿编译阶段自动生成首关 UI 背景,自动草稿阶段必须拿到 `uiBackgroundImageSrc` 或 `uiBackgroundImageObjectKey` 才能返回成功;结果页新增 `UI` Tab,可编辑提示词并触发 `generate_puzzle_ui_background`,手动生成失败只展示在当前面板。`api-server` 读取 `public/ui-previews/puzzle-image-compact-ui-2026-05-08.png` 作为非拼图 UI 参考图,调用 VectorEngine `gpt-image-2` 生成 9:16 背景并要求中央正方形拼图区与外部 UI 背景边界清晰。SpacetimeDB 只保存结果,不做外部 I/O。
|
||||
- 2026-05-18 追加:为缩短首版草稿等待,`compile_puzzle_draft` 在首关命名和 `uiBackgroundPrompt` 稳定后并行启动首关关卡图生成与 UI 背景生成;上传主图且关闭 AI 重绘时,并行执行上传图持久化与 UI 背景生成。生成页预计完成时间按 5 分钟展示。
|
||||
- 2026-05-21 追加:拼图结果页独立“素材配置”Tab 已移除,UI spritesheet 与关卡纯背景收口到每关图片生成资产包。每次 `gpt-image-2` 预计 90 秒;草稿完整 AI 重绘路径约 298 秒,上传图且关闭 AI 重绘路径跳过首图生成约 208 秒。结果页关卡详情继续复用 `CreativeImageInputPanel`,本次上传/历史选择图优先成为主图卡片,正式图只作为无新参考图时的预览;仅有正式图时仍允许在画面描述框上传多张参考图。
|
||||
- 影响范围:拼图结果页、拼图运行态背景渲染、拼图 agent action、`module-puzzle` / `spacetime-module` / `spacetime-client` 的拼图关卡 JSON 映射、拼图流程技术文档。
|
||||
- 验证方式:执行 `npm run test -- src/components/puzzle-result/PuzzleResultView.test.tsx`、`cargo test -p api-server puzzle_ui_background --manifest-path server-rs/Cargo.toml`、`cargo check -p api-server --manifest-path server-rs/Cargo.toml`、`npm run typecheck`、`npm run check:encoding`。
|
||||
- 关联文档:`docs/technical/PUZZLE_FORM_CREATION_FLOW_2026-04-29.md`。
|
||||
@@ -270,7 +299,7 @@
|
||||
## 2026-05-12 抓大鹅结果页素材编辑统一走作品级资产面板
|
||||
|
||||
- 背景:抓大鹅结果页需要支持封面图上传 / AI 重绘、物品素材独立预览、单项删除和批量新增,且不能把素材编辑继续做成列表内联展开或前端临时状态。
|
||||
- 决策:结果页 `作品信息` 的封面图点击打开独立面板,封面图面板对齐拼图入口上传卡。已有上传主图时,请求体传 `uploadedImageSrc`,AI 重绘走 VectorEngine `/v1/images/edits`;关闭 AI 重绘时只写回上传图,不调用生图。没有上传主图时,请求体传 `referenceImageSrcs`,可混合本地上传、物品素材和 UI 素材,多参考图作为 `gpt-image-2-all` generations 的 `image` 数组传入。生成结果统一调用 `POST /api/creation/match3d/works/{profileId}/cover-image` 并转存到 `generated-match3d-assets`。`素材配置 > 物品` 列表项点击打开独立预览面板,不再提供单项重新生成按钮;单项删除和批量新增都写回同一份 `generated_item_assets_json`。批量新增调用 `POST /api/creation/match3d/works/{profileId}/item-assets`,复用草稿生成的 2D 素材图、5x5 切图、OSS 上传和可选点击音效链路,仅作用于新增物品,不新增 SpacetimeDB 表。
|
||||
- 决策:结果页 `作品信息` 的封面图点击打开独立面板,封面图面板对齐拼图入口上传卡。已有上传主图时,请求体传 `uploadedImageSrc`,AI 重绘走 VectorEngine `/v1/images/edits`,后端把上传图作为 multipart `image` part 传入 `gpt-image-2`;关闭 AI 重绘时只写回上传图,不调用生图。没有上传主图但存在 `referenceImageSrcs` 时,多参考图同样走 edits 的多个 `image` part;完全无参考图时走 `/v1/images/generations`。生成结果统一调用 `POST /api/creation/match3d/works/{profileId}/cover-image` 并转存到 `generated-match3d-assets`。`素材配置 > 物品` 列表项点击打开独立预览面板,不再提供单项重新生成按钮;单项删除和批量新增都写回同一份 `generated_item_assets_json`。批量新增调用 `POST /api/creation/match3d/works/{profileId}/item-assets`;该接口的物品 spritesheet 生成口径已被 2026-05-22 决策更新为关卡整图参考、`10*10` 绿幕图和上传前透明化。
|
||||
- 影响范围:Match3D 结果页、Match3D works shared contracts、`api-server` Match3D 作品路由、生成资产历史类型和草稿恢复路径。
|
||||
- 验证方式:执行 `npm run test -- src/components/match3d-result/Match3DResultView.test.tsx`、`npm run typecheck`、`cargo test -p api-server match3d --manifest-path server-rs/Cargo.toml`、`cargo check -p api-server --manifest-path server-rs/Cargo.toml`、`npm run check:encoding`。
|
||||
- 关联文档:`docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`。
|
||||
@@ -294,7 +323,7 @@
|
||||
## 2026-05-13 宝贝爱画先作为寓教于乐独立本地 Demo 落地
|
||||
|
||||
- 背景:第三关 `宝贝爱画` 需要默认出现在“发现 / 寓教于乐”板块下方,但本阶段只验证画板、手部绘制、绘画魔法和本地保存闭环,不进入创作模板、公开作品或正式持久化。
|
||||
- 决策:`baby-love-drawing / 宝贝爱画` 先作为独立运行态接入,入口由发现页寓教于乐默认卡片打开,并支持 `/runtime/baby-love-drawing` 直达;关闭 `VITE_ENABLE_EDUTAINMENT_ENTRY` 时前端不展示频道/卡片且直达路由回落主应用。绘画魔法统一走 `POST /api/creation/edutainment/baby-love-drawing/magic` 后端安全代理,使用 VectorEngine `gpt-image-2-all` 与原始画布 Data URL 参考图生成绘本风图片;保存只写 localStorage,正式持久化后续再设计。
|
||||
- 决策:`baby-love-drawing / 宝贝爱画` 先作为独立运行态接入,入口由发现页寓教于乐默认卡片打开,并支持 `/runtime/baby-love-drawing` 直达;关闭 `VITE_ENABLE_EDUTAINMENT_ENTRY` 时前端不展示频道/卡片且直达路由回落主应用。绘画魔法统一走 `POST /api/creation/edutainment/baby-love-drawing/magic` 后端安全代理,使用 VectorEngine `gpt-image-2` 与原始画布 Data URL 参考图生成绘本风图片;保存只写 localStorage,正式持久化后续再设计。
|
||||
- 影响范围:`packages/shared/src/contracts/edutainmentBabyDrawing.ts`、`src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.tsx`、`src/services/edutainment-baby-drawing/`、`src/routing/appRoutes.tsx`、`src/components/rpg-entry/RpgEntryHomeView.tsx`、`server-rs/crates/api-server/src/edutainment_baby_drawing.rs`、`src/index.css`、宝贝爱画 PRD 与技术方案。
|
||||
- 验证方式:执行宝贝爱画 model/runtime/service/route 定向测试、`npm run typecheck`、定向 ESLint、`cargo test -p api-server edutainment_baby_drawing --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server resolves_runtime_paths_to_creation_type_ids --manifest-path server-rs/Cargo.toml` 和编码检查;真实魔法生成需配置 `VECTOR_ENGINE_BASE_URL` 与 `VECTOR_ENGINE_API_KEY`。
|
||||
- 关联文档:`docs/prd/BABY_LOVE_DRAWING_EDUTAINMENT_LEVEL_PRD_2026-05-13.md`、`docs/technical/BABY_LOVE_DRAWING_RUNTIME_DEMO_IMPLEMENTATION_2026-05-13.md`。
|
||||
@@ -327,7 +356,7 @@
|
||||
## 2026-05-10 儿童动作 Demo 视觉资产统一为绘本草地舞台
|
||||
|
||||
- 背景:儿童动作 Demo 需要从暗色科技风切换到更适合儿童互动的卡通绘本草地风格,并且要让背景、地面、UI、地面指示环和用户轮廓使用同一套 image-2 资源口径。
|
||||
- 决策:热身舞台及后续儿童动作 Demo 场景、物品、UI 资源统一采用明亮卡通绘本草地视觉语言。真实资源默认输出到 `public/child-motion-demo/`。背景沿用 `picture-book-grass-stage.png`;地面、指示环、角色指示器和 UI 已拆分为用途专属资源:`picture-book-foreground-grass-v2.png`、`picture-book-ground-ring-v3.png`、`picture-book-character-outline-v4.png`、`picture-book-hud-strip-v2.png`、`picture-book-calibration-strip-v2.png`、`picture-book-start-panel-v2.png` 和 `picture-book-ui-button-v2.png`。其中角色指示器 v4 基于 v2 本地后处理为更细的白色描边样式,内部透明,耳朵、手指、脚趾等细节已弱化,页面显示尺寸相对上一版放大 50%。生成脚本固定为 `scripts/generate-child-motion-demo-assets.mjs`,并通过 `npm run assets:child-motion-demo` 调用 VectorEngine `gpt-image-2-all`;透明资源使用品红底生成后本地去背,中间源图仅保存在 `tmp/child-motion-demo-assets/`。在缺少 `VECTOR_ENGINE_BASE_URL` 或 `VECTOR_ENGINE_API_KEY` 时,只允许 dry-run 和 CSS 兜底,不伪造 live 生图结果。
|
||||
- 决策:热身舞台及后续儿童动作 Demo 场景、物品、UI 资源统一采用明亮卡通绘本草地视觉语言。真实资源默认输出到 `public/child-motion-demo/`。背景沿用 `picture-book-grass-stage.png`;地面、指示环、角色指示器和 UI 已拆分为用途专属资源:`picture-book-foreground-grass-v2.png`、`picture-book-ground-ring-v3.png`、`picture-book-character-outline-v4.png`、`picture-book-hud-strip-v2.png`、`picture-book-calibration-strip-v2.png`、`picture-book-start-panel-v2.png` 和 `picture-book-ui-button-v2.png`。其中角色指示器 v4 基于 v2 本地后处理为更细的白色描边样式,内部透明,耳朵、手指、脚趾等细节已弱化,页面显示尺寸相对上一版放大 50%。生成脚本固定为 `scripts/generate-child-motion-demo-assets.mjs`,并通过 `npm run assets:child-motion-demo` 调用 VectorEngine `gpt-image-2`;透明资源使用品红底生成后本地去背,中间源图仅保存在 `tmp/child-motion-demo-assets/`。在缺少 `VECTOR_ENGINE_BASE_URL` 或 `VECTOR_ENGINE_API_KEY` 时,只允许 dry-run 和 CSS 兜底,不伪造 live 生图结果。
|
||||
- 影响范围:`src/index.css`、`src/components/child-motion-demo/ChildMotionWarmupDemo.tsx` 的舞台视觉层、儿童动作 Demo 技术文档、后续 image-2 资产生成流程。
|
||||
- 验证方式:检查 `/child-motion-demo` 舞台是否在未生成资产时仍有可用草地绘本兜底;补齐 VectorEngine 私密配置后运行 `npm run assets:child-motion-demo -- --live` 或 `--live --only <asset-id>` 应能写出对应 PNG,并确认页面静态资源返回 `image/png`。若只调整透明去背、裁切或品红边缘,可运行 `npm run assets:child-motion-demo -- --live --postprocess-only --force --only <asset-id>` 复用源图后处理。页面接入时必须按资源原始比例等比使用,不得把方形软纸面板拉伸成 HUD、状态条或底部草坪。
|
||||
- 关联文档:`docs/technical/CHILD_MOTION_DEMO_WARMUP_IMPLEMENTATION_SPEC_2026-05-09.md`、`docs/technical/VECTOR_ENGINE_GPT_IMAGE_2_GENERATION_2026-05-09.md`。
|
||||
@@ -348,6 +377,14 @@
|
||||
- 验证方式:执行入口配置、创作 Hub、平台入口交互和 api-server 路由熔断定向测试,确认“视觉小说”不出现在创作页且 `/api/creation/visual-novel/*` 默认被熔断。
|
||||
- 关联文档:`docs/design/PLATFORM_CREATE_TAB_CREATIVE_AGENT_HOME_2026-05-05.md`、`docs/technical/ADMIN_CREATION_ENTRY_SWITCH_CONFIG_2026-05-11.md`。
|
||||
|
||||
## 2026-05-20 RPG 创作入口开放
|
||||
|
||||
- 背景:RPG 文字冒险能力已经具备历史 custom-world 创作和运行闭环,但入口默认种子仍 `visible=false`,创作页不展示。
|
||||
- 决策:SpacetimeDB `creation_entry_type_config` 默认种子中 `rpg.visible=true` 且 `open=true`,旧默认隐藏配置只在标题、subtitle、badge、图片、排序和开关完全匹配时迁移为可见可创建。`airp` 仍保持 AI RPG 占位,不接管当前 RPG 链路。结构化创作 / RPG JSON 链路默认关闭 Responses `web_search`,需要联网增强时才通过 `GENARRATIVE_RPG_LLM_WEB_SEARCH_ENABLED=true` 或 `GENARRATIVE_CREATION_AGENT_LLM_WEB_SEARCH_ENABLED=true` 显式启用;未开通工具的上游会返回 `ToolNotOpen`,不能把这类失败暴露成“模型返回结果解析失败”。
|
||||
- 影响范围:创作入口默认种子、旧库入口纠偏、`api-server` 入口熔断、创作页模板 Tab、创作 Hub 测试、玩法链路文档和后端路由文档。
|
||||
- 验证方式:执行入口配置、api-server 路由熔断、创作 Hub 和平台入口交互定向测试,确认“文字冒险”出现在创作入口,`/api/runtime/custom-world*`、`/api/story/*`、`/api/runtime/chat/*` 都按 `rpg` 入口开关熔断。
|
||||
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
## 2026-05-10 运行态输入设备抽象层全项目通用化
|
||||
|
||||
- 背景:拼图运行态接入 mocap 后,鼠标/触控和 mocap 各自维护输入逻辑会导致合并大块、拖拽语义和取消会话行为不一致;后续其他玩法也需要复用体感、摇杆、键盘等设备输入。
|
||||
@@ -375,11 +412,19 @@
|
||||
## 2026-05-09 GPT-image-2 图片生成统一迁移到 VectorEngine
|
||||
|
||||
- 背景:仓库内 RPG、拼图、方洞和本地模板脚本的 GPT-image-2 生图此前依赖 APIMart 图片网关;团队要求参考 VectorEngine Apifox `api-448710071`,后续不再使用 APIMart 执行 GPT-image-2 图片生成。
|
||||
- 决策:所有 GPT-image-2 生图请求统一走 VectorEngine `POST /v1/images/generations`,基础配置读取 `VECTOR_ENGINE_BASE_URL` / `VECTOR_ENGINE_API_KEY` / `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`,上游模型使用 `gpt-image-2-all`,请求体不再携带 `official_fallback`,参考图字段改为 `image`。APIMart 只保留给创意 Agent 的 `gpt-5` Responses 文本/多模态链路。
|
||||
- 决策:所有 GPT-image-2 无参考图生图请求统一走 VectorEngine `POST /v1/images/generations`,有参考图请求走 `POST /v1/images/edits` multipart,基础配置读取 `VECTOR_ENGINE_BASE_URL` / `VECTOR_ENGINE_API_KEY` / `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`,上游模型使用 `gpt-image-2`,请求体不再携带 `official_fallback`。APIMart 只保留给创意 Agent 的 `gpt-5` Responses 文本/多模态链路。
|
||||
- 影响范围:`api-server` 共享图片 helper、拼图图片生成、角色主图、RPG 场景图、开局 CG 故事板、方洞视觉资产、生产环境示例、gpt-image-2 本地 skill 和相关技术文档。
|
||||
- 验证方式:执行 `npm run check:encoding`、`cargo test -p api-server openai_image --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server puzzle --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server custom_world_ai --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server character_visual --manifest-path server-rs/Cargo.toml`,并用 `npm run dev:api-server` + `/healthz` 做后端 smoke。
|
||||
- 关联文档:`docs/technical/VECTOR_ENGINE_GPT_IMAGE_2_GENERATION_2026-05-09.md`、`docs/technical/API_SERVER_EXTERNAL_SERVICE_ENV_CONFIG_2026-05-07.md`。
|
||||
|
||||
## 2026-05-21 GPT-image-2 参考图统一走 edits multipart
|
||||
|
||||
- 背景:VectorEngine Apifox 创建 `api-446794806` 与编辑 `api-446794807` 明确区分无参考图创建和有参考图编辑;仓库旧实现曾把参考图塞入 `gpt-image-2` generations 的 `image` 数组,导致与供应商当前契约不一致。
|
||||
- 决策:所有 GPT-image-2 无参考图生成调用 `POST /v1/images/generations`,所有有参考图生成调用 `POST /v1/images/edits`,模型固定 `gpt-image-2`,参考图作为 multipart `image` part 传入;仓库不再调用 `gpt-image-2-all`。
|
||||
- 影响范围:`api-server` 共享图片 helper、拼图图片生成、Match3D 封面重绘和容器 UI 图、gpt-image-2 本地 skill、玩法链路文档和后端架构文档。
|
||||
- 验证方式:搜索仓库不应再出现 VectorEngine 图片编辑路径调用;执行 `cargo test -p api-server openai_image_generation --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server puzzle_vector_engine --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server match3d_background --manifest-path server-rs/Cargo.toml`。
|
||||
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
## 2026-05-08 Hyper3D Rodin Gen-2 只通过后端安全代理接入
|
||||
|
||||
- 背景:需要接入 Hyper3D Rodin Gen-2 的文生 3D 模型与图生 3D 模型,但供应商 API Key 不能进入前端、文档或 Git;本次只是外部副作用代理,不需要新增平台真相表。
|
||||
@@ -553,7 +598,7 @@
|
||||
## 2026-05-10 视觉小说入口收敛为单句创作 + 画风选择
|
||||
|
||||
- 背景:视觉小说入口页要对齐抓大鹅式的线性创作入口,只保留最小可用输入,避免再暴露文档 / 空白 / 对话式工作台。
|
||||
- 决策:入口页只展示一句话创作输入框和横向视觉画风卡片;画风通过 `seedText` 追加 `视觉画风` 和 `画风要求` 两行透传给既有创作链路;点击生成后先进入 `visual-novel-generating` 过程页,再自动进入 `visual-novel-result`。画风卡片主视觉固定消费 `public/visual-novel-style-references/` 下由 VectorEngine `gpt-image-2-all` 生成的静态参考图,不在前端运行时现场调用生图接口。
|
||||
- 决策:入口页只展示一句话创作输入框和横向视觉画风卡片;画风通过 `seedText` 追加 `视觉画风` 和 `画风要求` 两行透传给既有创作链路;点击生成后先进入 `visual-novel-generating` 过程页,再自动进入 `visual-novel-result`。画风卡片主视觉固定消费 `public/visual-novel-style-references/` 下由 VectorEngine `gpt-image-2` 生成的静态参考图,不在前端运行时现场调用生图接口。
|
||||
- 影响范围:`VisualNovelAgentWorkspace`、`visualNovelEntryGeneration`、`PlatformEntryFlowShellImpl`、视觉小说 PRD 和创作 Tab 设计文档;不新增后端字段或数据库结构。
|
||||
- 验证方式:执行 `npm run test -- VisualNovelAgentWorkspace`、视觉小说工作台相关 ESLint、`npx prettier --check` 和 `npm run check:encoding`;`npm run typecheck` 若失败需先区分是否来自无关 Match3D / RPG 既有改动。
|
||||
- 关联文档:`docs/prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md`、`docs/design/PLATFORM_CREATE_TAB_CREATIVE_AGENT_HOME_2026-05-05.md`。
|
||||
@@ -577,7 +622,7 @@
|
||||
## 2026-05-12 抓大鹅物品种类从消除次数中拆出并改为 2D 五视角素材
|
||||
|
||||
- 背景:结果页草稿素材已经能生成和预览,但标准 / 硬核难度仍可能按 `clearCount` 误判需要 12 / 20 种素材,且继续生产 GLB 会拉长草稿生成耗时。
|
||||
- 决策:难度配置统一使用 `物品种类`:轻松 3、标准 9、进阶 15、硬核 21;历史硬核 `clearCount=20` 在运行态升为 21 组三消。新草稿和批量新增不再调用 Rodin、不再生成 GLB。每个物品生成 5 个不同 2D 视角,单张 1K 素材图固定按 5x5 切割,最多承载 5 个物品;超过 5 个物品时由 `api-server` 自动分批并行生图。发布必须校验已生成 `image_ready` 且有 `imageViews[]` 或首图引用的素材数量满足当前难度;试玩通过 `itemTypeCountOverride` 自动降到可用 2D 素材数量。历史模型字段只作为旧数据兼容,不再进入新生产链路。
|
||||
- 决策:难度配置统一使用运行态 `物品种类`:轻松 3、标准 9、进阶 15、硬核 20;历史硬核 `clearCount=20` 在运行态仍升为 21 组三消,但类型池最多 20 种。新草稿和批量新增不再调用 Rodin、不再生成 GLB。每次固定从 `2K 1:1`、`10*10` 物品 spritesheet 解析并持久化 20 个物品、每个 5 个不同 2D 形态,物品信息列表全部展示 20 个;持久化行列索引按每行两种物品计算,不能超过 `1..=10`。发布必须校验已生成 `image_ready` 且有 `imageViews[]`、首图引用或可解析的物品 spritesheet 满足当前难度;试玩通过 `itemTypeCountOverride` 自动降到可用 2D 素材数量。历史模型字段只作为旧数据兼容,不再进入新生产链路。
|
||||
- 影响范围:Match3D 结果页、运行态启动契约、`module-match3d` 初始 run 生成、SpacetimeDB start input / restart、发布校验和 Match3D 技术文档。
|
||||
- 验证方式:`npm run test -- src/components/match3d-result/Match3DResultView.test.tsx`、`cargo test -p module-match3d --manifest-path server-rs\Cargo.toml`、相关后端 check / tests。
|
||||
- 关联文档:`docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`。
|
||||
@@ -646,6 +691,14 @@
|
||||
- 验证方式:server provision 跑过后,目标机应同时具备 Brotli 模块包与 `nginx -t` 可接受的 brotli 指令;再由 Nginx 模板启用对应指令。
|
||||
- 关联文档:`deploy/nginx/README.md`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 2026-05-19 server provision 下载件固定由 Windows 节点断点续传
|
||||
|
||||
- 背景:`SpacetimeDB` 和 `otelcol-contrib` release 资产在 Linux 目标机直接下载很慢;改到 Windows Jenkins 节点下载后,GitHub 大文件仍可能出现 `curl: (18)` 响应体截断。
|
||||
- 决策:`Genarrative-Server-Provision` 的 `Download Provision Tool Archives` 阶段继续只在 Windows 节点下载,再通过 `stash/unstash` 交给目标 Linux agent;下载前查 GitHub release asset `digest`,本地最终文件 SHA256 命中即跳过,`.download` 临时文件用于 `curl -C -` 断点续传,完整返回但 digest 不匹配才清理重下。
|
||||
- 影响范围:`jenkins/Jenkinsfile.production-server-provision`、目标机 `scripts/prepare-server-provision-tools.sh` 的本地下载件消费路径、生产 provision 运维排障。
|
||||
- 验证方式:Windows 下载日志应出现 digest 查询、已存在校验跳过或 `curl 断点续传`;Linux 目标机阶段只使用 `provision-tool-downloads/` 中的 tarball,不访问 GitHub 下载地址。
|
||||
- 关联文档:`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 个人任务与埋点首版边界冻结
|
||||
|
||||
- 背景:“我的”Tab、任务、奖励、钱包和埋点涉及用户、运营、分析多条链路,需要避免范围泛化。
|
||||
|
||||
@@ -112,6 +112,24 @@ SpacetimeDB bindings 生成:
|
||||
npm run spacetime:generate
|
||||
```
|
||||
|
||||
CodeGraph 本地语义索引:
|
||||
|
||||
```bash
|
||||
npm run codegraph:init
|
||||
npm run codegraph:status
|
||||
npm run codegraph:sync
|
||||
npm run codegraph:index
|
||||
```
|
||||
|
||||
`.codegraph/config.json` 可随仓库共享;`.codegraph/codegraph.db`、缓存和日志为本机生成物,不提交。
|
||||
|
||||
Codex 项目级 hook 保存在 `.codex/config.toml` 与 `.codex/hooks/`:
|
||||
|
||||
- `PreToolUse` hook:`node .codex/hooks/pre-submit-compile-check.mjs`,Codex 准备执行 `git commit` 前检查 `npm run typecheck`、`npm run admin-web:typecheck`、`cargo check -p api-server --manifest-path server-rs/Cargo.toml`。
|
||||
- `PostToolUse` hook:`node .codex/hooks/post-edit-codegraph-sync.mjs`,工具修改文件后执行 `npm run codegraph:sync`。
|
||||
|
||||
个人 token、模型路由、MCP server 仍属于个人环境;需要时由成员本机执行 `codegraph install` 或查看 `codegraph install --print-config codex`,不要提交个人全局配置。
|
||||
|
||||
## 常用检查命令
|
||||
|
||||
- 后端通用用户行为埋点统一通过 `record_tracking_event_and_return` procedure、`SpacetimeRuntimeClient::record_tracking_event(...)` 与 api-server `tracking` 中间件写入 `tracking_event` / `tracking_daily_stat`;后台、RPG、大鱼吃小鱼、Visual Novel、Story、Combat 默认排除;作品级游玩埋点统一使用 `work_play_start`,详细事件清单见 `docs/technical/BACKEND_TRACKING_EVENT_COVERAGE_2026-05-09.md`。
|
||||
|
||||
@@ -14,6 +14,32 @@
|
||||
- 关联:相关文件、文档、提交或 Issue
|
||||
```
|
||||
|
||||
## 抓大鹅新 UI spritesheet 不要回退成中心容器图
|
||||
|
||||
- 现象:新素材流程生成后,运行态棋盘中心可能叠出一整张 UI spritesheet,导致按钮素材、方格和空白图集覆盖容器区域。
|
||||
- 原因:为了兼容旧 DTO,后端可能把 `uiSpritesheetImage*` 同步写入历史 `containerImage*` 字段;旧前端只看 `containerImage*`,会误把 UI 图集当透明中心容器。
|
||||
- 处理:读取中心容器图时先比较归一化后的 `containerImage*` 与 `uiSpritesheetImage*`。两者同源时忽略 `containerImage*`,只把它作为旧数据兼容字段;新流程背景图本身已经保留容器,运行态只需加载背景和解析 UI / 物品 spritesheet。
|
||||
- 验证:`npm run test -- src/components/match3d-runtime/Match3DRuntimeShell.test.tsx` 应覆盖“运行态不把兼容写入的UI spritesheet当中心容器图”。
|
||||
- 关联:`src/components/match3d-runtime/Match3DRuntimeShell.tsx`、`server-rs/crates/api-server/src/match3d/mappers.rs`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
## UI spritesheet 不要依赖模型直接生成透明背景
|
||||
|
||||
- 现象:拼图或抓大鹅运行态解析 UI spritesheet 时,把整张背景图、棋盘格、叶子或装饰图也当作 UI 素材区域,按钮映射错乱;截图里常表现为底部按钮区只剩透明棋盘格或素材碎片。
|
||||
- 原因:前端解析依赖 alpha 连通域检测,透明背景是前提;但生图模型收到“透明背景 spritesheet”提示后仍可能输出带实景背景或伪透明棋盘格的普通不透明 PNG,OSS 中保存的图没有真实 alpha。
|
||||
- 处理:UI spritesheet 提示词应要求统一纯绿色绿幕背景,而不是让模型直接产透明背景;后端在上传 OSS 前复用 `generated_asset_sheets::apply_generated_asset_sheet_green_screen_alpha(...)` 把绿幕扣成真实透明 PNG,再把透明图写入 `uiSpritesheetImageSrc/uiSpritesheetImageObjectKey`。
|
||||
- 验证:`cargo test -p api-server puzzle_ui_spritesheet_postprocess_turns_green_screen_transparent --manifest-path server-rs\Cargo.toml`、`cargo test -p api-server puzzle_level_scene_spritesheet_and_background_requests_use_references --manifest-path server-rs\Cargo.toml`、`cargo test -p api-server match3d_derived_asset_prompts_match_three_sheet_pipeline --manifest-path server-rs\Cargo.toml`。
|
||||
- 关联:`server-rs/crates/api-server/src/puzzle/generation.rs`、`server-rs/crates/api-server/src/match3d/works.rs`、`server-rs/crates/api-server/src/generated_asset_sheets.rs`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
## 拼图 UI spritesheet 运行态不要二次包圆底或拉伸比例
|
||||
|
||||
- 现象:拼图运行态左上返回和右上设置按钮外面出现白色圆圈;底部“提示 / 原图 / 冻结”三枚素材被压扁、拉宽或拉成正圆,和图集原始按钮比例不一致。
|
||||
- 原因:UI spritesheet 已经包含按钮视觉本体,但运行态仍给顶部按钮套默认圆形 icon 容器;底部三枚素材用 `h-full w-full rounded-full` 铺满按钮格,覆盖了自动检测矩形的真实宽高比。
|
||||
- 处理:有 `uiSpritesheetImage*` 时,顶部返回 / 设置按钮容器只保留透明点击区和 focus 状态,不再叠加默认圆形底;`buildPuzzleUiSpriteBackgroundStyle(...)` 对检测到的矩形写入 `aspectRatio`,底部三枚素材按原始宽高比和最大尺寸渲染,不强制 `w-full`。
|
||||
- 验证:`npm run test -- src/components/puzzle-runtime/PuzzleRuntimeShell.test.tsx`、`npm run test -- src/services/puzzle-runtime/puzzleUiSpritesheetParser.test.ts`。
|
||||
- 关联:`src/components/puzzle-runtime/PuzzleRuntimeShell.tsx`、`src/services/puzzle-runtime/puzzleUiSpritesheetParser.ts`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
2026-05-22 补充:展示矩形和点击热区要分开处理。`puzzleUiSpritesheetParser` 的 `regions` 保留完整视觉裁切矩形,`hitRegions` 用较高 alpha 阈值只包住实心按钮主体;运行态底部 spritesheet 道具按钮启用 `puzzle-runtime-sprite-tool-button--precise-hit`,父按钮不吃整块透明留白,内部 `puzzle-runtime-ui-sprite-hit-zone` 才接收指针事件,避免透明区域成为点击热区。
|
||||
|
||||
## 图像输入组件不要把业务状态藏在页面内联实现里
|
||||
|
||||
- 现象:拼图页把参考图上传、缩略图、主图删除确认和 AI 重绘开关内联实现后,后续想复用到其它创作页时,页面级状态和通用 UI 状态混在一起,容易出现多套上传卡和参考图展示口径。
|
||||
@@ -22,6 +48,62 @@
|
||||
- 验证:拼图入口测试仍可通过,且新组件可通过不同页面复用而不需要复制上传卡实现。
|
||||
- 关联:`src/components/common/CreativeImageInputPanel.tsx`、`src/components/puzzle-agent/PuzzleAgentWorkspace.tsx`。
|
||||
|
||||
## RPG 发布不能只依赖 agent session seed_text
|
||||
|
||||
- 现象:RPG 结果页 `publish_world` 返回 `UPSTREAM_ERROR`,details 为 `custom_world.setting_text 不能为空`;同一 session 的 `result-view` 日志显示 `publish_ready=true`。
|
||||
- 原因:前端发布动作只提交 `{ action: 'publish_world' }`,旧 agent 会话的 `seed_text` 可能为空;如果后端只从 action payload 或 `seed_text` 取 `setting_text`,就会在最终 compile / publish 校验阶段失败。
|
||||
- 处理:`module-custom-world::resolve_custom_world_publish_setting_text(...)` 以当前 `draft_profile_json` 为草稿真相,优先读取 `settingText`、`creatorIntent.rawSettingText`、`creatorIntent.worldHook`、`worldHook`、`anchorContent.worldPromise(.hook)`、`summary`、`name/title`,最后才回退 `seed_text`。
|
||||
- 验证:`cargo test -p module-custom-world publish_setting_text --manifest-path server-rs\Cargo.toml`;`cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml`。
|
||||
- 关联:`server-rs/crates/module-custom-world/src/application.rs`、`server-rs/crates/spacetime-module/src/custom_world.rs`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
## RPG 已发布结果页进入世界不能重复 publish_world
|
||||
|
||||
- 现象:RPG 草稿发布成功后,按钮文案已变为“进入世界”,但点击仍请求 `POST /api/runtime/custom-world/agent/sessions/{sessionId}/actions` 且 payload 为 `{"action":"publish_world"}`,后端返回 `publish_world is only available during object_refining, visual_refining, long_tail_review or ready_to_publish`。
|
||||
- 原因:按钮文案依据 agent session `stage === 'published'` 切换,但点击处理仍走发布协调路径;如果前端只依赖草稿同步回包判断是否已发布,回包为空或缺少可进入状态时就会继续重复发送 `publish_world`。
|
||||
- 处理:进入世界协调器接收当前 agent session stage;当 stage 已为 `published` 时,只调用 `result-view` 回读已发布 profile 并启动运行态,不再调用 `sync_result_profile` 或 `publish_world`。
|
||||
- 验证:`npm run test -- src/components/rpg-entry/useRpgCreationEnterWorld.test.tsx`;确认已发布场景下 `syncAgentDraftResultProfile` 与 `executePublishWorld` 均未被调用。
|
||||
- 关联:`src/components/rpg-entry/useRpgCreationEnterWorld.ts`、`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
## RPG 点击启动黑屏 / 默认 profile 先查 profile 归一化和摘要覆盖
|
||||
|
||||
- 现象:作品详情点击“启动”后页面切到 RPG runtime,但用户只看到黑屏、空白,或进入默认角色 / 默认 profile;从作品详情点“作品编辑”后开局 CG、封面、角色图、技能动作预览、初始物品图标或场景背景图丢失;DevTools 里可能同时看到旧自动存档 `/api/runtime/save/snapshot` 被主动 cancel。
|
||||
- 原因:`/custom-world-library` / `/custom-world-gallery` 详情接口可能返回历史或摘要式 `profile`,缺少 `playableNpcs`、`storyNpcs`、`landmarks`、`attributeSchema` 等运行态字段;前端 client 若直接把该对象传给 runtime,角色选择首屏会在 `buildCustomWorldPlayableCharacters(profile)` 或后续属性解析处抛错。另一类常见原因是详情接口已回读完整 profile 后,`savedCustomWorldEntries` 里的列表摘要又把 `selectedDetailEntry` 覆盖回空 profile,导致启动或编辑时只剩卡片摘要。发布 / 回读 result-view 若返回字段更少的旧视图,也可能把当前结果页已编辑资产降级掉。`save/snapshot (canceled)` 通常是切 runtime 或卸载时 `AbortController` 取消旧自动存档,不是黑屏根因。
|
||||
- 处理:RPG 入口作品库 client 在所有返回 `CustomWorldLibraryEntry<CustomWorldProfile>` 的接口边界统一调用 `normalizeCustomWorldProfileRecord`,并用 `profileId/worldName/subtitle/summaryText` 补齐旧数据缺字段;详情页已拿到运行态字段或资产槽位更多的完整 profile 时,不允许列表摘要覆盖当前详情;同一 `profile.id` 下,正式进入世界发布 / 回读不得用字段更少的后端旧视图降级当前结果页 profile。`normalizeCustomWorldProfileRecord` 必须近似无损保留 `cover`、`openingCg`、`camp.narrativeResidues`、`landmark.visualDescription/narrativeResidues`、`skills[].actionPreviewConfig`、`initialItems[].iconSrc`、`attributeSchema`、角色 `attributeProfile` 和 `sceneChapterBlueprints[].acts[]` 的背景与结构字段;只有背景资产的 act 也不能被过滤。角色选择页对角色生成异常或空数组回退默认角色,并保留返回按钮/轻量空态;顶层 runtime 懒加载 fallback 不使用纯 `null`。
|
||||
- 验证:`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "creation hub published work start uses loaded detail profile instead of library summary|creation hub published work edit keeps loaded detail profile assets instead of library summary"`;`npm run test -- src/data/customWorldLibrary.test.ts -t "保留结果页封面和关键图片资产槽位|近似无损保留编辑态和运行态结构字段|保留只有背景资产的场景幕"`;`npm run test -- src/components/rpg-entry/useRpgEntryAgentDraftRestore.test.tsx -t "默认封面和角色编辑结构差异也不能被列表摘要覆盖"`;`npm run test -- src/components/rpg-entry/useRpgCreationEnterWorld.test.tsx -t "正式进入世界回读结果页字段更少时不降级当前完整 profile"`;`npm run typecheck`。
|
||||
- 关联:`src/components/rpg-entry/useRpgEntryLibraryDetail.ts`、`src/components/rpg-entry/useRpgCreationEnterWorld.ts`、`src/data/customWorldLibrary.ts`、`src/services/rpg-entry/rpgEntryLibraryClient.ts`、`src/components/rpg-entry/RpgEntryCharacterSelectView.tsx`、`src/App.tsx`、`src/components/rpg-runtime-shell/RpgRuntimeShell.tsx`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
## RPG 战后一轮战斗后卡在观察/试探/调息先查 post-battle finalization
|
||||
|
||||
- 现象:RPG 一轮战斗胜利后,运行态只显示默认 `观察周围迹象 / 主动出声试探 / 原地调息`,这些按钮只有文字反馈;点“继续冒险”后又回到同样选项,点探索只播退场/进场动画,场景和剧情不推进。
|
||||
- 原因:终局战斗 action 如果只走通用 `resolve_story_runtime_action` fallback,而没有在后端调用 `finalize_post_battle_resolution(...)`,就不会持久写入 `story_continue_adventure`、`deferredOptions` 和下一幕 `currentSceneActState`。另外旧 bootstrap 快照可能只有 `connectedSceneIds` / `forwardSceneId`、没有 `connections`,战后选项生成若只读 `connections` 也会退回 `idle_explore_forward` 循环。
|
||||
- 处理:`module-runtime-story` 在 story action 投影后统一调用 post-battle finalization;`idle_explore_forward` 清理战斗态并生成下一段遭遇预览;`idle_travel_next_scene` / `camp_travel_home_scene` 由后端写入新 `currentScenePreset`、场景 act 状态、遭遇预览和 `runtimeStats.scenesTraveled`。前端只负责播放继续、探索和切场景动画,不承接正式剧情推进真相。
|
||||
- 验证:`cargo test -p module-runtime-story --manifest-path server-rs\Cargo.toml battle_tests -- --nocapture` 应覆盖战斗终局持久化 `story_continue_adventure`、`deferredOptions`、下一幕 act,以及 `idle_travel_next_scene` 真正切换场景。
|
||||
- 关联:`server-rs/crates/module-runtime-story/src/session_action.rs`、`server-rs/crates/module-runtime-story/src/post_battle.rs`、`server-rs/crates/module-runtime-story/src/battle_tests.rs`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
## RPG 战斗飘字不要只靠低对比红绿文字
|
||||
|
||||
- 现象:暗色或棕黑噪声背景下,战斗伤害飘字看起来像背景纹理,尤其是远端敌人头顶的小号红字几乎不可读。
|
||||
- 原因:旧 `CombatFloatingNumber` 主要依赖 `text-rose-200` / `text-emerald-200` 和 8px 同色 glow;在暗红、棕黑、像素噪声背景上,颜色与背景混在一起,1px 深色描边也不足以形成轮廓。
|
||||
- 处理:飘字本体使用高亮近白文字、小面积半透明深色底、明显深色描边和多层黑色阴影;只增强瞬时反馈,不新增说明面板,不遮挡主要战斗画面。
|
||||
- 验证:`npm run test -- src/components/game-canvas/GameCanvasEntityLayer.test.tsx` 覆盖伤害/治疗飘字样式策略;运行态截图中敌方头顶伤害数字应能在暗场景上辨认。
|
||||
- 关联:`src/components/game-canvas/GameCanvasEntityLayer.tsx`、`docs/【项目基线】当前产品与工程约束-2026-05-15.md`。
|
||||
|
||||
## 弹窗里复用 CreativeImageInputPanel 要保留画面卡高度
|
||||
|
||||
- 现象:拼图草稿结果页的关卡详情弹窗中仍能看到“画面图”标题、画面描述和生成按钮,但实际画面图卡片视觉上消失。
|
||||
- 原因:`CreativeImageInputPanel` 内部依赖 `flex-1`、`h-full` 和 `max-h-full` 撑开正方形画面卡;放进弹窗里的普通 `section` 后,父级没有可计算高度,卡片会被压到不可见。
|
||||
- 处理:通用画面卡 `puzzle-image-upload-card` 保持 `aspect-square` 的同时设置稳定 `min-height`,让入口页和关卡详情弹窗都能显示主图/上传区。
|
||||
- 验证:`npm run test -- src/components/puzzle-result/PuzzleResultView.test.tsx -t "opens an independent level detail dialog"` 应断言关卡详情中的 `.puzzle-image-upload-card` 具备最小高度类;`npm run test -- src/components/common/CreativeImageInputPanel.test.tsx` 应继续通过。
|
||||
- 关联:`src/components/common/CreativeImageInputPanel.tsx`、`src/components/puzzle-result/PuzzleResultView.tsx`、`src/components/puzzle-result/PuzzleResultView.test.tsx`。
|
||||
|
||||
## Windows provision 下载截断要断点续传而不是回退目标机下载
|
||||
|
||||
- 现象:`Genarrative-Server-Provision` 在 `Download Provision Tool Archives` 阶段出现 `curl: (18) end of response ... bytes missing`,常见于 `otelcol-contrib_0.151.0_linux_amd64.tar.gz` 等 GitHub release 大文件。
|
||||
- 原因:这是 Windows Jenkins 节点到 GitHub 的响应体被截断;若每轮都删除 `.download` 临时文件,就会丢掉已下载部分,下一次又从头开始。
|
||||
- 处理:Windows 下载函数保留 `${Output}.download`,`curl` 失败时下一轮使用 `-C -` 断点续传;最终只以 GitHub release asset 的 SHA256 `digest` 作为放行条件,完整返回但 digest 不匹配才删除临时文件重新下载。不要把 SpacetimeDB 或 `otelcol-contrib` 下载挪回 Linux 目标机。
|
||||
- 验证:日志应显示 `curl 断点续传 ... resumeBytes=...`,最终出现 `已下载 ... bytes=...`;目标 Linux 阶段只消费 `stash/unstash` 带过去的下载件。
|
||||
- 关联:`jenkins/Jenkinsfile.production-server-provision`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## OTLP 端点只填 Collector HTTP base endpoint
|
||||
|
||||
- 现象:生产或容器 env 里把 `OTEL_EXPORTER_OTLP_ENDPOINT` 填成 `4317`、Rider 端口或别的非 HTTP base endpoint 后,api-server 发不出 OTLP,或者链路被错误转发。
|
||||
@@ -38,6 +120,30 @@
|
||||
- 验证:普通 route 请求在 SpacetimeDB 不可用时仍能返回,恢复后 sealed 文件会继续被清理。
|
||||
- 关联:`server-rs/crates/api-server/src/tracking_outbox.rs`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## release tracking outbox 权限错误先查 env 缺失
|
||||
|
||||
- 现象:release 机器 `journalctl -u genarrative-api.service` 每秒刷 `tracking outbox 定时封存 active 文件失败 error=Permission denied (os error 13)` 和 `tracking outbox 批量写入 SpacetimeDB 失败`。
|
||||
- 原因:旧 `/etc/genarrative/api-server.env` 没有 `GENARRATIVE_TRACKING_OUTBOX_DIR` 时,api-server 会回退到本地开发默认相对路径 `server-rs/.data/tracking-outbox`;systemd 工作目录是只读发布目录 `/opt/genarrative/releases/<version>`,`genarrative` 用户不能在其中创建 `server-rs`。
|
||||
- 处理:补齐 `GENARRATIVE_TRACKING_OUTBOX_DIR=/var/lib/genarrative/tracking-outbox` 及 batch/flush/max 配置,创建并授权 `/var/lib/genarrative/tracking-outbox` 给 `genarrative:genarrative`,再重启 `genarrative-api.service`。Server-Provision 与 API-Deploy 会保留旧 env 但自动补缺这些运行态路径。
|
||||
- 验证:`tr '\0' '\n' < /proc/$(systemctl show genarrative-api.service -p MainPID --value)/environ | grep GENARRATIVE_TRACKING_OUTBOX_DIR` 应指向 `/var/lib/genarrative/tracking-outbox`;重启后当前 PID 不再出现 `Permission denied (os error 13)`。
|
||||
- 关联:`scripts/deploy/production-api-deploy.sh`、`scripts/jenkins-server-provision.sh`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 外部 API 失败没法追溯先查 external_api_call_failure
|
||||
|
||||
- 现象:VectorEngine 图片生成 / 编辑接口对前端只表现为 `502` / `504` 或“上游服务请求失败”,但难以区分是请求发送失败、上游 429/5xx、响应解析失败、未返回图片,还是下载图片失败。
|
||||
- 原因:外部 API 失败如果只靠普通日志,不一定能和 OTLP 指标、trace 与 SpacetimeDB 历史查询稳定关联;重启后也容易丢失上下文。
|
||||
- 处理:先查 OTLP 指标 `genarrative.external_api.failures{provider,failure_stage,status_class,retryable}`,再查 `tracking_event` 中 `event_key = 'external_api_call_failure'` 的 `metadata_json`。当前通用 VectorEngine `gpt-image-2-all` 适配器会记录 provider、endpoint、operation、failureStage、statusCode、statusClass、timeout、retryable、errorMessage、latencyMs、promptChars、referenceImageCount、imageModel 和 rawExcerpt。
|
||||
- 验证:`SELECT event_id, scope_id AS provider, metadata_json, occurred_at FROM tracking_event WHERE event_key = 'external_api_call_failure' ORDER BY occurred_at DESC LIMIT 50;`;如果查不到同时看 tracking outbox 目录权限和 sealed 文件是否堆积。
|
||||
- 关联:`server-rs/crates/api-server/src/external_api_audit.rs`、`server-rs/crates/api-server/src/openai_image_generation.rs`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## release 创作接口 413 先查是否还在提交 Data URL
|
||||
|
||||
- 现象:release 上 `POST /api/runtime/puzzle/agent/sessions/{session_id}/actions` 携带参考图 Data URL 时返回 `413 Request Entity Too Large`,access log 显示 `request_time=0.000`、`upstream_status=-`。
|
||||
- 原因:Nginx 默认 `client_max_body_size` 只有 1 MiB,请求在反代层被拒绝,根本没有到达 `api-server`;即使模板放宽到 `64m`,把图片 base64 放进创作 JSON body 仍会放大请求体并把上限问题推给下一层。
|
||||
- 处理:长期修复不是继续调大 Nginx,而是让浏览器先走 `/api/assets/direct-upload-tickets` 直传 OSS,再 `/api/assets/objects/confirm` 确认 `asset_object`,拼图 action 只提交 `referenceImageAssetObjectId(s)`;后端校验 owner / bucket / kind / MIME / size 后签只读 URL 给 VectorEngine。Nginx `client_max_body_size 64m` 只保留为旧客户端和兼容输入兜底,发布后仍需 `nginx -t && nginx -s reload`。
|
||||
- 验证:前端 action payload 不应再出现大段 `data:image/...;base64`;`nginx -T 2>/dev/null | grep client_max_body_size` 可确认反代兜底;再次提交参考图时 access log 应有正常 `upstream_status`,后端测试 `puzzle_reference_image_sources_prefer_asset_object_ids` / `puzzle_asset_object_reference_requires_matching_owner` 应通过。
|
||||
- 关联:`src/services/puzzle-works/puzzleAssetClient.ts`、`server-rs/crates/api-server/src/puzzle/vector_engine.rs`、`deploy/nginx/genarrative.conf`、`deploy/nginx/genarrative-dev-http.conf`、`deploy/container/nginx.conf`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 汪汪声浪入口不要再回到独立配置阶段
|
||||
|
||||
- 现象:汪汪声浪入口如果继续切换到独立配置阶段,会和拼图、抓大鹅的创作页内嵌结构不一致,用户会感觉入口跳页。
|
||||
@@ -187,7 +293,7 @@
|
||||
|
||||
## 陶泥儿 logo 生图慢请求先缩短 prompt 并单张串行
|
||||
|
||||
- 现象:使用 VectorEngine `gpt-image-2-all` 生成陶泥儿 logo 概念图时,部分 prompt 会超过 10 分钟仍无响应,或返回 `429` / `当前分组上游负载已饱和`;同一批次里后续图片会被前面的慢请求拖住。
|
||||
- 现象:使用 VectorEngine `gpt-image-2` 生成陶泥儿 logo 概念图时,部分 prompt 会超过 10 分钟仍无响应,或返回 `429` / `当前分组上游负载已饱和`;同一批次里后续图片会被前面的慢请求拖住。
|
||||
- 原因:复杂抽象 logo prompt 同时包含品牌解释、禁用元素、中文结构和多重隐喻时,上游排队与生成时长不稳定;并发或批量运行会放大单条慢请求的影响。
|
||||
- 处理:先 `--dry-run` 看请求体;真实生成时优先短 prompt、单一造型、单张串行或小批量。失败后不要反复重试同一长 prompt,先压缩到“一个主体 + 一个负形 + 颜色 + 禁用文字/播放键/聊天气泡”再跑。联系表中的中文标签不要通过 PowerShell 管道内联 Python 写入,容易因编码链路显示为问号,可改用英文标签或脚本文件方式。
|
||||
- 验证:生成文件落在 `public/branding/taonier-logo-*/`,用 Pillow 检查图片尺寸和非空;执行 `node --check scripts/generate-taonier-logo-concepts.mjs`、`npm run check:encoding`、`git diff --check`。
|
||||
@@ -205,11 +311,11 @@
|
||||
|
||||
- 现象:点击生成抓大鹅草稿后,页面只提示“服务暂不可用”,或者本地 `npm run dev:api-server` 看似启动但生成接口不可用。
|
||||
- 原因:配置缺失类错误通常在后端 `error.details.reason` 中给出具体缺项,前端如果只读 `details.message` 会吞掉原因;本地只配置 `ALIYUN_OSS_BUCKET` / `ALIYUN_OSS_ENDPOINT` 时,旧逻辑还会在启动期构造空 AccessKey 的 OSS 客户端并失败。抓大鹅新链路仍是 2D 生图切割,不需要也不应回退 Rodin/GLB。
|
||||
- 处理:前端 API 错误展示优先读取 `details.reason`,再读取 `details.message`,避免底层 `error sending request` 覆盖真正可操作的配置或网络原因;`api-server` 只有在 OSS 四件套齐全时初始化 OSS 客户端,部分缺失只记 warning 并让具体 generated 上传/换签接口返回 `OSS 未完成环境变量配置`。抓大鹅素材、封面和背景生成在调用 VectorEngine 前先预检 OSS,并通过 `details.missingEnv` 列出缺项;真实生成需补齐 `VECTOR_ENGINE_BASE_URL`、`VECTOR_ENGINE_API_KEY` 和完整 `ALIYUN_OSS_*` 四件套。抓大鹅 `5*5` 素材图提示词还必须要求相邻物体主体至少保留 `1/4` 单格宽度空白间距,避免切割后相邻格内容污染。
|
||||
- 处理:前端 API 错误展示优先读取 `details.reason`,再读取 `details.message`,避免底层 `error sending request` 覆盖真正可操作的配置或网络原因;`api-server` 只有在 OSS 四件套齐全时初始化 OSS 客户端,部分缺失只记 warning 并让具体 generated 上传/换签接口返回 `OSS 未完成环境变量配置`。抓大鹅素材、封面和背景生成在调用 VectorEngine 前先预检 OSS,并通过 `details.missingEnv` 列出缺项;真实生成需补齐 `VECTOR_ENGINE_BASE_URL`、`VECTOR_ENGINE_API_KEY` 和完整 `ALIYUN_OSS_*` 四件套。抓大鹅 UI spritesheet 和物品 spritesheet 的提示词必须要求纯绿色绿幕背景,后端上传 OSS 前统一扣成透明 PNG,避免运行态 alpha 连通域解析失败。
|
||||
- 验证:`npm run test -- src/services/apiClient.test.ts` 覆盖 `details.reason`;`cargo test -p api-server state --manifest-path server-rs/Cargo.toml` 覆盖半配置 OSS 不阻断启动;`npm run dev:api-server` 后按实际 `GENARRATIVE_API_PORT` 请求 `/healthz`,不要默认打 `3100`。
|
||||
- 关联:`packages/shared/src/http.ts`、`server-rs/crates/api-server/src/state.rs`、`docs/technical/API_SERVER_EXTERNAL_SERVICE_ENV_CONFIG_2026-05-07.md`、`docs/technical/AUTH_SNAPSHOT_AND_MATCH3D_LOCAL_DEV_FIX_2026-05-01.md`。
|
||||
|
||||
2026-05-14 补充:抓大鹅“物品素材 sheet”已改用 VectorEngine Gemini `gemini-3-pro-image-preview` 原生 `generateContent`,真实生成读取 `VECTOR_ENGINE_BASE_URL`、`VECTOR_ENGINE_API_KEY` 和 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`;封面和 `9:16` 背景图走 VectorEngine `/v1/images/generations`,`1:1` 容器 UI 走 VectorEngine `/v1/images/edits` multipart 参考图链路。排查素材 sheet 时看请求路径是否为 `/v1beta/models/gemini-3-pro-image-preview:generateContent?key=...`,响应图片在 `candidates[].content.parts[].inlineData.data` / `inline_data.data`,不要再按 APIMart `/images/generations` 或 `/tasks/{task_id}` 排查。
|
||||
2026-05-22 补充:抓大鹅“物品 spritesheet”不再按旧 Gemini `generateContent` / `5*5` sheet 路径排查;当前链路先用 `gpt-image-2` 无参考图生成 `9:16` 关卡整图,再以该关卡整图作为 multipart `image` 参考并发编辑生成 `1K 1:1` UI spritesheet、`1K 9:16` 背景图和 `2K 1:1` 物品 spritesheet。UI 与物品 spritesheet 都要求纯绿色绿幕背景,上传 OSS 前通过后端透明化处理写入真实 alpha PNG。
|
||||
|
||||
## 抓大鹅发布按钮要先开发布面板,封面编辑收口到发布面板内
|
||||
|
||||
@@ -303,7 +409,7 @@
|
||||
## 儿童动作 Demo 绘本风资源未生成先查 VectorEngine 配置
|
||||
|
||||
- 现象:`/child-motion-demo` 已经呈现绘本草地风格,但 `public/child-motion-demo/picture-book-grass-stage.png`、`picture-book-grass-floor.png`、`picture-book-ground-ring.png`、`picture-book-character-outline.png`、`picture-book-ui-panel.png` 或 `picture-book-ui-button.png` 不存在,Network 里对应图片返回 404,或运行 `npm run assets:child-motion-demo -- --live` 返回缺少 VectorEngine 配置。
|
||||
- 原因:儿童动作 Demo 的真实背景、地面、UI、地面指示环和角色轮廓资源都使用 VectorEngine `gpt-image-2-all` 生成,脚本只读取 `VECTOR_ENGINE_BASE_URL`、`VECTOR_ENGINE_API_KEY` 和可选 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`;仓库内不能提交真实 key,缺配置时页面只能使用 CSS 草地绘本兜底。
|
||||
- 原因:儿童动作 Demo 的真实背景、地面、UI、地面指示环和角色轮廓资源都使用 VectorEngine `gpt-image-2` 生成,脚本只读取 `VECTOR_ENGINE_BASE_URL`、`VECTOR_ENGINE_API_KEY` 和可选 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`;仓库内不能提交真实 key,缺配置时页面只能使用 CSS 草地绘本兜底。
|
||||
- 处理:在本地私密环境补齐 `VECTOR_ENGINE_BASE_URL=https://api.vectorengine.ai` 与 `VECTOR_ENGINE_API_KEY`,不要把 key 写入 Git;先运行 `npm run assets:child-motion-demo -- --dry-run` 核对 prompt,再运行 `npm run assets:child-motion-demo -- --live` 或 `npm run assets:child-motion-demo -- --live --only ui-panel` 等小批量命令生成资源。透明资源的品红底源图写入 `tmp/child-motion-demo-assets/`,不要把源图或预览图放入 `public/child-motion-demo/` 作为正式资产。
|
||||
- 验证:生成后确认 `public/child-motion-demo/` 只保留页面引用的最终 PNG,重新打开 `/child-motion-demo` 可看到真实绘本草地背景、地面、圆环、角色轮廓和 UI 资源;`npm run check:encoding` 仍通过。
|
||||
- 关联:`scripts/generate-child-motion-demo-assets.mjs`、`src/index.css`、`docs/technical/CHILD_MOTION_DEMO_WARMUP_IMPLEMENTATION_SPEC_2026-05-09.md`。
|
||||
@@ -327,8 +433,8 @@
|
||||
## GPT-image-2 不再读 APIMart 图片配置
|
||||
|
||||
- 现象:配置了 `APIMART_BASE_URL` / `APIMART_API_KEY` 后,RPG、拼图或方洞的 GPT-image-2 生图仍返回缺配置,或请求体里还出现 `official_fallback` / `image_urls`。
|
||||
- 原因:2026-05-09 后 GPT-image-2 图片生成已切到 VectorEngine `gpt-image-2-all`,APIMart 只保留给创意 Agent 的 `gpt-5` Responses 文本/多模态链路。
|
||||
- 处理:为图片生成配置 `VECTOR_ENGINE_BASE_URL=https://api.vectorengine.ai`、`VECTOR_ENGINE_API_KEY`、`VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`;排查请求体时确认路径为 `/v1/images/generations`、模型为 `gpt-image-2-all`、参考图字段为 `image`。
|
||||
- 原因:2026-05-21 后 GPT-image-2 图片生成按 VectorEngine 创建/编辑接口分流,APIMart 只保留给创意 Agent 的 `gpt-5` Responses 文本/多模态链路。
|
||||
- 处理:为图片生成配置 `VECTOR_ENGINE_BASE_URL=https://api.vectorengine.ai`、`VECTOR_ENGINE_API_KEY`、`VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`;排查请求体时确认无参考图路径为 `/v1/images/generations`、有参考图路径为 `/v1/images/edits`,模型为 `gpt-image-2`。
|
||||
- 验证:运行 `cargo test -p api-server openai_image --manifest-path server-rs/Cargo.toml` 和相关玩法图片生成测试;真实联调只在本地私密环境放置 VectorEngine key。
|
||||
- 关联:`docs/technical/VECTOR_ENGINE_GPT_IMAGE_2_GENERATION_2026-05-09.md`、`server-rs/crates/api-server/src/openai_image_generation.rs`。
|
||||
|
||||
@@ -348,19 +454,19 @@
|
||||
- 验证:后端单测覆盖 `build_puzzle_levels_with_primary_update` 和 `apply_generated_puzzle_candidates_to_session_snapshot`;结果页重新生成应在未重新上传时继续带入 `level.pictureReference`。
|
||||
- 关联:`server-rs/crates/api-server/src/puzzle.rs`、`src/components/puzzle-result/PuzzleResultView.tsx`。
|
||||
|
||||
## 拼图图生图仍不像参考图时先看是否走了 edits
|
||||
## 拼图参考图不像时先看 edits multipart image
|
||||
|
||||
- 现象:Network payload 已带 `referenceImageSrc`,但 VectorEngine 生成结果仍明显不像上传图。
|
||||
- 原因:`gpt-image-2-all` 的 `/v1/images/generations` 更适合纯文生图;有参考图且需要重绘时应切到 `/v1/images/edits` 的 multipart 图生图接口。
|
||||
- 处理:`referenceImageSrc` 存在且 `aiRedraw = true` 时直接走 edits,prompt 仍保留参考图强约束;入口页关闭 AI 重绘时直接应用上传图,不调用图片生成;前端把参考图压到单边 1024 内,后端解析后拒绝超过 8MB 的参考图字节。
|
||||
- 验证:后端单测应覆盖 `images/edits` 路由、`b64_json` 响应解码和参考图强提示;真实联调先看日志里是否命中 `拼图 VectorEngine 图片编辑 HTTP 返回`。
|
||||
- 原因:参考图只在 `aiRedraw = true` 时由后端解析并传给 `gpt-image-2` `/v1/images/edits` 的 multipart `image` part;若前端没传 `referenceImageSrc`、后端解析失败或 prompt 缺少参考图强约束,生成会退化为纯文生图。
|
||||
- 处理:`referenceImageSrc` 存在且 `aiRedraw = true` 时走 edits multipart,prompt 保留参考图强约束;入口页关闭 AI 重绘时直接应用上传图,不调用图片生成;前端把参考图压到单边 1024 内,后端解析后拒绝超过 8MB 的参考图字节。
|
||||
- 验证:后端单测应覆盖 `/v1/images/edits` 路由、`b64_json` 响应解码和参考图强提示;真实联调看日志里是否命中 `拼图 VectorEngine 图片编辑 HTTP 返回`。
|
||||
- 关联:`server-rs/crates/api-server/src/puzzle.rs`、`src/services/puzzleReferenceImage.ts`、`docs/technical/VECTOR_ENGINE_GPT_IMAGE_2_GENERATION_2026-05-09.md`。
|
||||
|
||||
## 拼图 edits 报 error sending request 先看网络分类
|
||||
|
||||
- 现象:拼图有参考图时返回 `拼图图片生成失败:创建拼图 VectorEngine 图片编辑任务失败:error sending request for url (https://api.vectorengine.ai/v1/images/edits)`,后端没有 `拼图 VectorEngine 图片编辑 HTTP 返回` 日志。
|
||||
- 原因:这是 `reqwest` 在 `send()` 阶段失败,尚未收到 VectorEngine HTTP 响应;常见原因是服务器网络 / DNS / 防火墙 / 代理问题,或上游网关中断 multipart 连接。
|
||||
- 处理:查看错误响应 `details.reason/source/connect/body/timeout/endpoint` 和 `拼图 VectorEngine 请求发送失败` 日志。拼图图片客户端已强制 HTTP/1.1,降低 multipart HTTP/2 兼容风险;若 `connect=true` 先查网络出口,若 `body=true` 先查参考图大小和 multipart 发送。
|
||||
- 处理:查看错误响应和 `拼图 VectorEngine 图片编辑` 相关日志;若请求发送阶段失败,先查网络出口、DNS、防火墙、代理、参考图大小和 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`。
|
||||
- 验证:`curl --http1.1 -i -X POST https://api.vectorengine.ai/v1/images/edits -H "Authorization: Bearer invalid" -F "model=gpt-image-2" -F "prompt=test" -F "n=1" -F "size=1024x1024" -F "image=@public/match3d-background-references/pot-fused-reference.png;type=image/png"` 至少应返回 HTTP `401`,说明域名、TLS、路径和 multipart 上传可达;执行 `cargo test -p api-server puzzle_vector_engine --manifest-path server-rs/Cargo.toml`。
|
||||
- 关联:`server-rs/crates/api-server/src/puzzle.rs`、`docs/technical/VECTOR_ENGINE_GPT_IMAGE_2_GENERATION_2026-05-09.md`、`docs/technical/API_SERVER_EXTERNAL_SERVICE_ENV_CONFIG_2026-05-07.md`。
|
||||
|
||||
@@ -391,17 +497,41 @@
|
||||
## 拼图草稿生成 180 秒后 502/504 先查 VectorEngine 超时与前端重试
|
||||
|
||||
- 现象:点击“生成拼图游戏草稿”后,`POST /api/runtime/puzzle/agent/sessions/{sessionId}/actions` 等待约 180 秒返回 `502 Bad Gateway` 或 `504 Gateway Timeout`;钱包流水里同一 session 可能出现连续两组 `puzzle_initial_image` 扣费后退款。
|
||||
- 原因:首图生成走 VectorEngine `gpt-image-2-all`,默认 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS=1000000`;若上游在该窗口内未返回,后端退款并返回超时错误。旧前端 action 写请求会对 502/503/504 自动重试一次,导致同一次点击重复触发生图与扣退费。
|
||||
- 原因:首图生成走 VectorEngine `gpt-image-2`,默认 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS=1000000`;若上游在该窗口内未返回,后端退款并返回超时错误。旧前端 action 写请求会对 502/503/504 自动重试一次,导致同一次点击重复触发生图与扣退费。
|
||||
- 处理:拼图/创作 Agent 的 `executeAction` 默认不做前端自动重试;后端将 VectorEngine / 图片请求超时映射为 `504 Gateway Timeout`,`error.details.provider=vector-engine` 且 `timeout=true`。真实排障按日志同一 `session_id` 查 `拼图 VectorEngine 图片生成 HTTP 返回` 是否缺失,以及钱包流水扣费到退款的时间差是否接近 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`。
|
||||
- 验证:运行 `npm run test -- src/services/creation-agent/creationAgentClientFactory.test.ts src/services/apiClient.test.ts`、`cargo test -p api-server puzzle_vector_engine --manifest-path server-rs/Cargo.toml`,真实联调重启 `npm run dev:api-server` 后检查 `/healthz`。
|
||||
- 关联:`src/services/creation-agent/creationAgentClientFactory.ts`、`server-rs/crates/api-server/src/puzzle.rs`、`docs/technical/API_SERVER_EXTERNAL_SERVICE_ENV_CONFIG_2026-05-07.md`。
|
||||
|
||||
## 开局 CG 故事板生图失败先查 VectorEngine 请求预算和旧进程
|
||||
|
||||
- 现象:RPG 结果页点击开局 CG 后,`POST /api/runtime/custom-world/opening-cg` 在较长等待后返回“开局 CG 故事板生成失败:创建图片生成任务失败:error sending request for url (https://api.vectorengine.ai/v1/images/generations)”。
|
||||
- 原因:该故事板会把角色图和首幕背景图作为参考图一起传给 VectorEngine `gpt-image-2-all`,请求体和上游生成耗时都比普通单图更大;若运行中的 `api-server` 仍沿用旧 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS`,或者参考图过大,会在请求发送/等待阶段被 reqwest 截断。日志里 `timeout=false connect=false request=true body=false source=client error (SendRequest)` 表示还没拿到上游 HTTP 响应,通常优先怀疑大 JSON 请求体、上游网关中断或 HTTP 协议兼容,而不是业务响应解析失败。直接请求 VectorEngine 若无效 token 可快速返回 401,不能据此判断真实生图不会超时。
|
||||
- 处理:开局 CG 参考图入参先压到单边 768 的 JPEG;`/v1/images/generations` 保持 reqwest 默认 HTTP 协商,只有 multipart `/v1/images/edits` 单独强制 HTTP/1.1。后端图片 helper 将 `request_body_bytes`、每张参考图 Data URL 长度、`timeout/connect/body/source/rootSource/sourceChain/endpoint` 分类写入日志和 `error.details`,前端优先展示 `details.reason`。修改 `.env.secrets.local` 后必须重启 `api-server`,`npm run dev` 终端用 `rs api-server`,否则旧进程仍按旧超时运行。
|
||||
- 验证:分别运行 `cargo test -p api-server custom_world_ai --manifest-path server-rs/Cargo.toml` 和 `cargo test -p api-server openai_image_generation --manifest-path server-rs/Cargo.toml`;真实联调重启后再触发开局 CG,若仍失败看返回的 `details.reason/source/rootSource/sourceChain/timeout/connect/body/endpoint` 和 `logs/api-server/` 同一 request_id。
|
||||
- 关联:`server-rs/crates/api-server/src/custom_world_ai.rs`、`server-rs/crates/api-server/src/custom_world_ai/opening_cg.rs`、`server-rs/crates/api-server/src/openai_image_generation.rs`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 开局 CG 成功后又变空白要保留 profile.openingCg
|
||||
|
||||
- 现象:RPG 结果页里的开局 CG 成功显示一瞬后,窗口又退回空白占位。
|
||||
- 原因:`openingCg` 只存在于结果页 profile 槽位,如果父层在 `onProfileChange` 后重新同步了 profile,却经过 `normalizeCustomWorldProfileRecord` 或作品库写回时丢掉 `openingCg`,预览就会从视频 / 故事板回退为空白。
|
||||
- 处理:`src/data/customWorldLibrary.ts` 的 profile 归一化必须透传 `openingCg`;结果页和父层后续同步都应把它当作受控资产槽位,而不是临时 UI 状态。
|
||||
- 验证:`npm run test -- src/data/customWorldLibrary.test.ts src/components/CustomWorldResultView.test.tsx`,确认生成后即使父层做一次归一化回写,开局 CG 仍继续显示。
|
||||
- 关联:`src/data/customWorldLibrary.ts`、`src/components/rpg-creation-result/RpgCreationResultViewImpl.tsx`、`src/components/CustomWorldEntityCatalog.tsx`。
|
||||
|
||||
## RPG 发布报 legacy_result_profile_json 非法先查 null 兼容
|
||||
|
||||
- 现象:RPG 结果页发布动作返回 `UPSTREAM_ERROR`,SpacetimeDB details 里是 `custom_world.compile.legacy_result_profile_json 不是合法 JSON object`。
|
||||
- 原因:`publish_world` 前端契约只要求 `{ action: 'publish_world' }`;`ExecuteCustomWorldAgentActionRequest.legacy_result_profile` 是可选字段,经 HTTP / serde / SpacetimeDB payload 传递时可能显式成为 JSON `null`。旧的编译器只接受 object 或缺省,把 `Some("null")` 当成非法 legacy JSON。
|
||||
- 处理:`module-custom-world` 的 optional JSON object 解析要把 `null` 视为未提供,仍拒绝数组、字符串、数字和坏 JSON;正式发布继续以 session `draft_profile_json` 为草稿真相。
|
||||
- 验证:`cargo test -p module-custom-world published_profile_compile --manifest-path server-rs/Cargo.toml`。
|
||||
- 关联:`server-rs/crates/module-custom-world/src/application.rs`、`server-rs/crates/spacetime-module/src/custom_world.rs`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
## 本地脚本调 VectorEngine 生图卡住先区分 fetch 首部超时
|
||||
|
||||
- 现象:用 Node `fetch` 直接请求 `POST /v1/images/generations`,已经设置较长的 AbortController 超时,但仍在约 180 到 300 秒后抛 `AbortError`、`TypeError: fetch failed` 或 `UND_ERR_HEADERS_TIMEOUT`;同一 prompt 改用原生 `https.request` 可以在较短时间内成功返回图片。
|
||||
- 原因:Node/Undici 的默认 headers timeout 可能早于业务脚本期望的长生图等待窗口触发,表现上容易被误判成 VectorEngine 上游本身超时。
|
||||
- 处理:长期脚本优先复用后端 reqwest 或项目已有生成脚本;临时本地工具若必须用 Node,可改用原生 `http`/`https.request` 并显式设置 socket timeout,或为 Undici 单独配置 headers timeout。仍需隐藏 `VECTOR_ENGINE_API_KEY`,只报告配置是否存在。
|
||||
- 验证:同一 `gpt-image-2-all` 请求体、同一环境变量下,原生 HTTP 请求能返回 `url` / `b64_json` 并落盘;失败时错误里能区分请求发送、首部等待、下载和解码阶段。
|
||||
- 验证:同一 `gpt-image-2` 请求体、同一环境变量下,原生 HTTP 请求能返回 `url` / `b64_json` 并落盘;失败时错误里能区分请求发送、首部等待、下载和解码阶段。
|
||||
- 关联:`.codex/skills/gpt-image-2-apimart/SKILL.md`、`server-rs/crates/api-server/src/openai_image_generation.rs`。
|
||||
|
||||
## 旧后端路线文档造成判断漂移
|
||||
@@ -774,6 +904,14 @@
|
||||
- 验证:运行 `git ls-files --stage scripts/prepare-server-provision-tools.sh`,确认 mode 为 `100755`;重新跑 `Genarrative-Server-Provision` 时应进入工具下载/打包日志,而不是停在 `Permission denied`。
|
||||
- 关联:`jenkins/Jenkinsfile.production-server-provision`、`scripts/prepare-server-provision-tools.sh`、`scripts/jenkins-checkout-source.sh`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## Server-Provision 下载阶段不要放回 genarrative-build-01
|
||||
|
||||
- 现象:`Genarrative-Server-Provision` 日志里 `Prepare Provision Tools` 显示 `Running on genarrative-build-01 in /root/...`,随后在该节点上下载 GitHub release 或 `install.spacetimedb.com` 失败。
|
||||
- 原因:`genarrative-build-01` 在当前 provision 流程里是 Linux 目标发布机/目标 agent,不是用户本地 Windows 下载环境;把下载阶段放在 `linux && genarrative-build` 等于让目标机自己外连。
|
||||
- 处理:下载必须发生在 Jenkins `windows` 节点的 `Download Provision Tool Archives` 阶段,先下载 SpacetimeDB Linux release tarball 和 `otelcol-contrib` Linux amd64 包,再 `stash/unstash` 到目标 Linux 节点。目标机执行 `scripts/prepare-server-provision-tools.sh` 时设置 `PROVISION_REQUIRE_LOCAL_DOWNLOADS=true`,缺少下载件直接失败,不回退联网下载。
|
||||
- 验证:Jenkins 日志应先出现 `Running on ... windows` 和 `[prepare-provision-downloads] 下载 ...`,目标节点只出现 `[prepare-provision-tools] 使用已下载的 ...`;如果目标节点出现 `下载 otelcol-contrib:` 或 `下载 SpacetimeDB 官方安装器脚本:`,说明又回退到错误路径。
|
||||
- 关联:`jenkins/Jenkinsfile.production-server-provision`、`scripts/prepare-server-provision-tools.sh`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 个人任务 scope 不得扩成 work/site/module
|
||||
|
||||
- 现象:个人任务配置为 `work` / `site` / `module` 后进度串桶或静默按 0 处理。
|
||||
@@ -810,7 +948,7 @@
|
||||
|
||||
- 现象:修改抓大鹅素材时容易沿用旧 Rodin/GLB 方案,导致新草稿生成耗时变长、进度停在模型阶段,或运行态等待不存在的 GLB。
|
||||
- 原因:仓库里保留了 Hyper3D 通用代理和历史模型字段,旧文档也曾要求草稿阶段同步生成 GLB。当前产品口径已经改为 2D 多视角素材。
|
||||
- 处理:新 `match3d_compile_draft` 与批量新增只生成 2D 图片:每个物品 5 个视角,单张 1K 素材图固定 5x5,最多承载 5 个物品,一行对应一个物品,不足 5 个物品也补齐到完整 5 行;超过 5 个物品自动分批并行生图。素材图 prompt 固定要求纯绿色绿幕背景,切割前先把绿幕处理为透明 alpha,再做格内内容前景边界校准并带留白,避免固定内缩切掉贴近格线的主体。`generatedItemAssets[].status` 使用 `image_ready`,发布校验看 `imageViews[]` 或首图引用。`generated-models` 仅用于历史外部模型链接转存,不能作为新生产链路。
|
||||
- 处理:新 `match3d_compile_draft` 与批量新增只生成 2D 图片:每个物品 5 个形态,单张 `2K 1:1` 物品 spritesheet 固定 `10*10`,每行承载两种物品、每种五个形态,单张最多承载 20 种物品。素材图 prompt 固定要求纯绿色绿幕背景,上传 OSS 前先把整张 spritesheet 绿幕处理为透明 alpha,再由运行态和编辑器按 alpha 连通域解析;`generatedItemAssets[].status` 使用 `image_ready`,发布校验看 `imageViews[]`、首图引用或可解析的物品 spritesheet。`generated-models` 仅用于历史外部模型链接转存,不能作为新生产链路。
|
||||
- 验证:`cargo test -p api-server match3d --manifest-path server-rs/Cargo.toml`、`npm run test -- src\services\miniGameDraftGenerationProgress.test.ts src\components\match3d-result\Match3DResultView.test.tsx src\components\match3d-runtime\Match3DRuntimeShell.test.tsx`。
|
||||
- 关联:`server-rs/crates/api-server/src/match3d.rs`、`src/components/match3d-runtime/Match3DRuntimeShell.tsx`、`docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`。
|
||||
|
||||
@@ -846,11 +984,11 @@
|
||||
- 验证:执行 `npm run test -- src/components/match3d-runtime/Match3DRuntimeShell.test.tsx` 和 `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "Match3D runtime"`;浏览器 Network 中背景和容器 generated path 应先请求 `/api/assets/read-url` 换签,局内出现 `match3d-background-image` 和 `match3d-container-image` 对应图片。
|
||||
- 关联:`src/components/match3d-runtime/Match3DRuntimeShell.tsx`、`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`、`src/components/rpg-entry/rpgEntryWorldPresentation.ts`、`docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`。
|
||||
|
||||
## 抓大鹅容器参考图必须走 edits 并接管棋盘外观
|
||||
## 抓大鹅容器参考图必须进入 edits multipart image 并接管棋盘外观
|
||||
|
||||
- 现象:抓大鹅结果页看似有容器生成入口,但真实生成出的局内容器不像 `pot-fused-reference.png`,或进入试玩后仍被默认圆形锅壳、金色边框和径向底色覆盖/裁切。
|
||||
- 原因:`/v1/images/generations` 的 `image` 数组更适合弱参考文生图,难以稳定锁定大尺寸轻俯视容器构图;即使生成了容器图,如果运行态继续保留默认 `rounded-full` 锅壳和 `overflow-hidden`,生成图也会被默认视觉覆盖或裁掉。
|
||||
- 处理:抓大鹅 `1:1` 容器 UI 图必须用 VectorEngine `POST /v1/images/edits` multipart,把 `public/match3d-background-references/pot-fused-reference.png` 作为 `image` part 上传;共享 GPT-image-2 HTTP client 承载 multipart 时强制 HTTP/1.1。`Match3DRuntimeShell` 在容器图换签并成功加载后,把棋盘外壳切为透明和 `overflow-visible`,只在容器缺失或加载失败时使用默认圆形容器。
|
||||
- 原因:容器参考图必须进入 `gpt-image-2` `/v1/images/edits` multipart `image` part,并配合强 prompt 锁定大尺寸轻俯视容器构图;即使生成了容器图,如果运行态继续保留默认 `rounded-full` 锅壳和 `overflow-hidden`,生成图也会被默认视觉覆盖或裁掉。
|
||||
- 处理:抓大鹅 `1:1` 容器 UI 图统一调用 VectorEngine `POST /v1/images/edits`,参考 `public/match3d-background-references/pot-fused-reference.png` 的透明容器图由后端作为 `image` part 上传;该参考图属于后端生图协议输入,需通过 `include_bytes!` 编译进 `api-server`,不能在运行时按当前工作目录读取 `public/`。`Match3DRuntimeShell` 在容器图换签并成功加载后,把棋盘外壳切为透明和 `overflow-visible`,只在容器缺失或加载失败时使用默认圆形容器。
|
||||
- 验证:执行 `cargo test -p api-server vector_engine --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server match3d_background --manifest-path server-rs/Cargo.toml`、`npm run test -- src/components/match3d-runtime/Match3DRuntimeShell.test.tsx src/components/match3d-result/Match3DResultView.test.tsx`;真实联调看容器生成请求是否命中 `/v1/images/edits`,局内 `match3d-container-image` 是否渲染且 `match3d-board` 不再含默认 `rounded-full`。
|
||||
- 关联:`server-rs/crates/api-server/src/openai_image_generation.rs`、`server-rs/crates/api-server/src/match3d.rs`、`src/components/match3d-runtime/Match3DRuntimeShell.tsx`、`docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`。
|
||||
|
||||
@@ -928,9 +1066,9 @@
|
||||
|
||||
## 抓大鹅难度配置的物品种类和消除次数必须分离
|
||||
|
||||
- 现象:历史草稿选择标准 / 硬核难度后,系统可能把 `clearCount` 当成局内物品种类数量,导致标准需要 12 种、硬核需要 20/21 种;素材不足时发布或试玩行为不一致。
|
||||
- 现象:历史草稿选择标准 / 硬核难度后,系统可能把 `clearCount` 当成局内物品种类数量,导致标准需要 12 种、硬核需要 20/21 种;或者把第 11 到 20 个物品持久化为第 11 到 20 行,触发“系列素材图集持久化的行列索引必须落在 n*n 范围内”。
|
||||
- 原因:旧运行态把消除次数和类型数量绑在一起,结果页文案又同时展示“素材图片 / 局内类型”,导致前端、发布校验和 run start 口径不一致。
|
||||
- 处理:统一使用 `物品种类` 口径:轻松 3、标准 9、进阶 15、硬核 21;历史 `clearCount=20` 且难度为硬核的运行态按新硬核升为 21 组三消,避免 20 组却要求 21 种素材。发布前按 `image_ready` 且有 `imageViews[]` 或 `imageSrc/imageObjectKey` 的生成素材数量阻断不足难度;试玩不阻断,但通过 `itemTypeCountOverride` 自动降到已生成 2D 素材数量。重启从已有 run 快照反推实际物品种类,保持同一局重开不变。
|
||||
- 处理:生成和持久化固定使用 20 个物品素材;运行态物品种类口径为轻松 3、标准 9、进阶 15、硬核 20,历史 `clearCount=20` 且难度为硬核的运行态仍可升为 21 组三消,但类型池不超过 20。10*10 sheet 每行两种物品、每种五个形态,持久化行列为 `row = itemIndex / 2 + 1`、`col = itemIndex % 2 * 5 + viewIndex + 1`。发布前按 `image_ready` 且有 `imageViews[]` 或 `imageSrc/imageObjectKey` 的生成素材数量阻断不足难度;试玩不阻断,但通过 `itemTypeCountOverride` 自动降到已生成 2D 素材数量。重启从已有 run 快照反推实际物品种类,保持同一局重开不变。
|
||||
- 验证:`npm run test -- src\components\match3d-result\Match3DResultView.test.tsx`、`cargo test -p module-match3d --manifest-path server-rs\Cargo.toml`,涉及发布 reducer 时补跑 `cargo test -p spacetime-module match3d --manifest-path server-rs\Cargo.toml`。
|
||||
- 关联:`src/components/match3d-result/Match3DResultView.tsx`、`src/services/match3d-runtime/match3dRuntimeClient.ts`、`server-rs/crates/module-match3d/src/application.rs`、`server-rs/crates/spacetime-module/src/match3d.rs`、`docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`。
|
||||
|
||||
@@ -947,7 +1085,7 @@
|
||||
- 现象:抓大鹅生成的物品视角图裁剪后仍带白边,或者整块纯绿色绿幕背景没有被透明化,运行态看到绿色方块。
|
||||
- 原因:素材 sheet 可能是“每格内部绿幕、整张图外圈近白底”,内部绿幕不一定连通到 sheet 外边缘;旧 flood fill 只从外边缘找背景会漏掉这种绿幕块。白底抗锯齿如果不纳入抠像和边缘去污染,也会随裁剪输出成一圈白边。即使顺序已是先整张 sheet 去绿再裁剪,较厚的半透明或混色软绿边仍可能低于高置信绿幕阈值,被当作前景带进独立 PNG。
|
||||
- 处理:`api-server` 的 `slice_match3d_material_sheet` 必须先在整张 sheet 上做透明背景后处理:外边缘连通绿幕/近白底清 alpha,非连通但高置信纯绿块也清 alpha,沿整张 sheet 透明背景继续吃掉软绿边,边缘近白和绿幕抗锯齿做透明或去污染;同时保护不够纯的绿色主体像素。不要改成先裁剪单格再去绿。
|
||||
- 验证:`cargo test -p api-server match3d_material_sheet_slicing --manifest-path server-rs\Cargo.toml` 覆盖非连通绿幕、白边、贴边主体保留和固定 5x5 切图。
|
||||
- 验证:`cargo test -p api-server match3d_material_sheet_slicing --manifest-path server-rs\Cargo.toml` 覆盖非连通绿幕、白边、贴边主体保留和固定 `10*10` 切图;`cargo test -p api-server match3d_spritesheet_green_screen_postprocess_turns_background_transparent --manifest-path server-rs\Cargo.toml` 覆盖完整 spritesheet 上传前绿幕透明化。
|
||||
- 关联:`server-rs/crates/api-server/src/match3d.rs`、`docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`。
|
||||
|
||||
## 抓大鹅物品详情大方格只做单张大图查看
|
||||
@@ -1014,6 +1152,14 @@
|
||||
- 验证:运行 `npm run test -- src/components/puzzle-runtime/PuzzleRuntimeShell.test.tsx -t "拖拽合并大块时底层单格不显示选中色块"`,并确认合并块拖拽时底层 `[data-piece-id]` 仍为 `puzzle-runtime-piece--merged`。
|
||||
- 关联:`src/components/puzzle-runtime/PuzzleRuntimeShell.tsx`、`src/components/puzzle-runtime/PuzzleRuntimeShell.test.tsx`、`docs/technical/PUZZLE_FORM_CREATION_FLOW_2026-04-29.md`。
|
||||
|
||||
## 推荐页嵌入拼图通关结算不要放在运行态内部 absolute 层
|
||||
|
||||
- 现象:推荐页里玩拼图通关后,结算面板只显示上半部分,排行榜、下一关按钮或相似作品卡被截断。
|
||||
- 原因:推荐页把运行态放在滑动作品卡的视觉区内,`platform-recommend-swipe-page`、`platform-recommend-swipe-card__visual` 和 `platform-recommend-runtime-viewport` 都是 `overflow: hidden`;拼图通关结算如果仍是运行态内部 `absolute inset-0` 弹层,就只能在半屏卡片区域里显示。
|
||||
- 处理:`PuzzleRuntimeShell` 在 `embedded` 模式下把通关结算层通过 portal 挂到 `document.body`,使用 `puzzle-runtime-modal-overlay--fixed` 页面级 fixed 浮层;非嵌入态继续使用运行态内部覆盖层。
|
||||
- 验证:运行 `npm run test -- src/components/puzzle-runtime/PuzzleRuntimeShell.test.tsx -t "推荐页嵌入拼图通关结算使用页面级浮层避免卡片裁剪"`,确认弹层不再位于 `.platform-recommend-runtime-viewport` 内。
|
||||
- 关联:`src/components/puzzle-runtime/PuzzleRuntimeShell.tsx`、`src/index.css`、`src/components/rpg-entry/RpgEntryHomeView.tsx`。
|
||||
|
||||
## 拼图历史图片列表不要把账号归属当图片名
|
||||
|
||||
- 现象:拼图创作页或结果页打开“选择历史图片”后,历史列表显示 `账号 user-1` 之类归属文案而不是图片名;`1713686400.000000Z` 这类时间显示为未知;选中后预览或生成参考图可能被怀疑不可用。
|
||||
@@ -1032,12 +1178,22 @@
|
||||
|
||||
## 拼图结果页局部生图不要污染草稿生成态
|
||||
|
||||
- 现象:拼图草稿已经生成完成后,在结果页重新生成 UI 背景或追加关卡生成图片,草稿页仍显示整卡“生成中”,点击草稿会回到生成过程页,无法查看已有结果;UI 背景生成中还会禁用“新增关卡”和关卡图生成。
|
||||
- 现象:拼图草稿已经生成完成后,在结果页重新生成关卡图片或追加关卡生成图片,草稿页仍显示整卡“生成中”,点击草稿会回到生成过程页,无法查看已有结果;关卡图片生成中还会禁用“新增关卡”和其它关卡详情编辑。
|
||||
- 原因:结果页局部 action 复用了全局 `isPuzzleBusy` / 持久化 `generationStatus=generating` 语义,作品架没有区分“初始草稿不可查看”和“已有结果上的局部关卡生成”。
|
||||
- 处理:作品架只在拼图没有可用封面、首关候选图或任一可查看关卡时才把 `generationStatus=generating` 解释为初始草稿生成;结果页 UI 背景和关卡图走 background action,不设置全局 busy,UI 背景只禁用自己的按钮;SpacetimeDB/API mapper 读写时把已有图片但状态仍是 `generating` 的历史关卡归一为 `ready`。
|
||||
- 处理:作品架只在拼图没有可用封面、首关候选图或任一可查看关卡时才把 `generationStatus=generating` 解释为初始草稿生成;结果页关卡图走 background action,不设置全局 busy,只标记对应关卡局部生成进度;SpacetimeDB/API mapper 读写时把已有图片但状态仍是 `generating` 的历史关卡归一为 `ready`。
|
||||
- 验证:`npm run test -- src/components/custom-world-home/CustomWorldCreationHub.test.tsx src/components/puzzle-result/PuzzleResultView.test.tsx`、`cargo test -p api-server puzzle --manifest-path server-rs\Cargo.toml`。
|
||||
- 关联:`src/components/custom-world-home/creationWorkShelf.ts`、`src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`、`src/components/puzzle-result/PuzzleResultView.tsx`、`server-rs/crates/api-server/src/puzzle/mappers.rs`、`server-rs/crates/spacetime-module/src/puzzle.rs`。
|
||||
|
||||
2026-05-22 补充:结果页关卡详情的“关卡测试”不能把单关 `draft` 传给父级再调用 `updatePuzzleWork`。`updatePuzzleWork` 会同步 `puzzle_work_profile.levels_json` 和 source session 草稿,单关快照会把整份多关卡草稿覆盖成一个关卡,退出重进后只剩最后测试的关卡且序号表现为第一关。修复口径是 `PuzzleResultView` 始终传完整 `syncedDraft`,额外用 `{ levelId }` 指定起始关卡;父级持久化完整 levels 后调用 `startLocalPuzzleRun(item, levelId)`。
|
||||
|
||||
## 拼图上传图关闭 AI 重绘不要走首图生图
|
||||
|
||||
- 现象:用户在拼图入口页或结果页关卡详情上传图片并关闭 AI 重绘后,生成页仍显示“生成拼图首图”,或者后端仍调用 `generate_puzzle_image_candidates` 生成第一张 1:1 候选图。
|
||||
- 原因:上传图直用路径应把 Data URL 或 `/generated-*` 历史图解析后持久化为 `sourceType=uploaded` 的正式候选,再继续生成 9:16 关卡画面、UI spritesheet 和纯背景;如果只把 `aiRedraw=false` 当作“不参考图片生成”,就会误走首图生成。
|
||||
- 处理:入口页用 payload 的 `aiRedraw` 写入生成页 metadata,`puzzleAiRedraw=false` 时进度跳过 `生成拼图首图`;后端 `compile_puzzle_draft` 和结果页 `generate_puzzle_images` 都在 `aiRedraw=false && referenceImageSrc 非空` 时走上传图直用候选。结果页关卡详情必须复用 `CreativeImageInputPanel`,不要把正式图当成可重绘参考图;本次上传或历史选择的图才显示 AI 重绘开关并可删除。
|
||||
- 验证:`npm run test -- src/services/miniGameDraftGenerationProgress.test.ts src/components/puzzle-result/PuzzleResultView.test.tsx`、`cargo test -p api-server puzzle_result_level_direct_upload_skips_cover_image_generation --manifest-path server-rs\Cargo.toml`。
|
||||
- 关联:`src/services/miniGameDraftGenerationProgress.ts`、`src/components/puzzle-agent/PuzzleAgentWorkspace.tsx`、`src/components/puzzle-result/PuzzleResultView.tsx`、`server-rs/crates/api-server/src/puzzle/draft.rs`、`server-rs/crates/api-server/src/puzzle/generation.rs`。
|
||||
|
||||
## Jenkins 数据库导入导出脚本先补 Node 工具链 PATH
|
||||
|
||||
- 现象:`Genarrative-Database-Import` 或 `Genarrative-Database-Export` 运行到迁移脚本时,`bash` 报 `node: command not found`,常见在日志里表现为某个 `sh` 块内第 61 行直接调用 `node` 失败。
|
||||
@@ -1054,6 +1210,22 @@
|
||||
- 验证:检查 Jenkins build log 中是否出现 `[jenkins-powershell] user:` 和 `[jenkins-powershell] exe:`,以及 `[stdb-checkout] current HEAD:`。上游 Full Build 传下来的 `COMMIT_HASH` 若已等于当前 GitSCM checkout,日志应显示 `requested commit already matches Jenkins GitSCM checkout` 并继续进入构建阶段;同时确认 `builds/<n>/log` 不再停在 `PipelineNodeTreeScanner... Cannot run program "powershell"` 或 Checkout 内部 exit code 5。
|
||||
- 关联:`jenkins/Jenkinsfile.production-stdb-module-build`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## Server-Provision Windows 下载 helper 不要原地重写临时 ps1
|
||||
|
||||
- 现象:`Genarrative-Server-Provision` 的 Windows 下载阶段已经打印了 `[jenkins-powershell] user:` 和 `[jenkins-powershell] exe:`,但在 `.ps1` 原地 BOM 重写前后仍然返回 `exit code 5` / `拒绝访问`,且下载目录还没创建。
|
||||
- 原因:Jenkins `writeFile` 生成的临时 `.ps1` 正被同一个 workspace 里的 PowerShell 进程马上重写成 BOM 文件,这个原地改写在本地 Windows Jenkins 环境里比直接脚本执行更容易碰到 workspace 占用或 ACL 拒绝。对这条流水线来说,BOM 不是必须的执行条件。
|
||||
- 处理:`runWindowsPowerShell(...)` 改成先 `writeFile`,再由显式 `powershell.exe` 读取脚本文本并用 `ScriptBlock::Create(...)` 直接在内存中执行,不再对同一个 `.ps1` 做 BOM 重写。Windows 下载脚本里先把 `PROVISION_DOWNLOADS_DIR` 归一到 workspace 绝对路径,并补 `Windows workspace` / `download dir` / `已创建下载目录` 三段日志,方便区分是路径问题还是下载问题。
|
||||
- 验证:Jenkins log 应先出现 `[jenkins-powershell] workspace:`、`[jenkins-powershell] loaded bytes:`,再出现 `[prepare-provision-downloads] Windows workspace:` 和 `[prepare-provision-downloads] 已创建下载目录:`;如果下载 URL 故意指到不可达地址,应该只在 `curl 下载失败` 处结束,而不是卡在 BOM 重写前。
|
||||
- 关联:`jenkins/Jenkinsfile.production-server-provision`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## SpacetimeDB update installer 不要按带 host 后缀的下载文件名执行
|
||||
|
||||
- 现象:Server-Provision 目标机阶段已经显示“使用已下载的 SpacetimeDB Linux update installer”,随后报 `Error: unexpected argument '-y' found` 或前置 `unknown command name for spacetimedb-update multicall binary`。
|
||||
- 原因:`spacetimedb-update-*` 不是当前离线交付的最终形态,GitHub release 页面真正可比较的缓存对象是 `spacetime-x86_64-unknown-linux-gnu.tar.gz` 这种 release tarball;GitHub release asset API 暴露的是 `digest` / SHA256,不是 MD5。
|
||||
- 处理:Windows 下载阶段应直接缓存 release tarball 和 `otelcol-contrib_0.151.0_linux_amd64.tar.gz`,目标机 `scripts/prepare-server-provision-tools.sh` 只解压本地 tarball 生成 `bin/current/spacetimedb-cli` 与 `bin/current/spacetimedb-standalone`,不要再把 update installer 当成最终离线包执行。
|
||||
- 验证:Jenkins 目标机日志不再出现 `unexpected argument '-y'`、`unknown command name for spacetimedb-update multicall binary`,后续应继续检查 `bin/current/spacetimedb-cli` 和 `bin/current/spacetimedb-standalone` 是否生成。
|
||||
- 关联:`scripts/prepare-server-provision-tools.sh`、`jenkins/Jenkinsfile.production-server-provision`。
|
||||
|
||||
## QQ 浏览器发现页推荐封面全不显示先查 aspect-ratio 兜底
|
||||
|
||||
- 现象:发现页的“推荐”子频道作品卡标题、作者和数据正常,但所有封面图不显示,常见于 QQ 浏览器 / X5 等旧移动内核。
|
||||
|
||||
@@ -1,348 +1,253 @@
|
||||
---
|
||||
name: genarrative-play-type-integration
|
||||
description: 在 Genarrative 中新增一个创作入口/玩法类型时,按入口配置、前端分流、契约、后端接口、工作台、结果页、可选 runtime 与作品架的顺序接入。
|
||||
version: 1.0.0
|
||||
author: Hermes Agent
|
||||
license: MIT
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [Genarrative, 玩法接入, 创作入口, 前端, 后端, contracts, runtime]
|
||||
related_skills: []
|
||||
description: 在 Genarrative 新增、开放或重构玩法创作工具时,按平台级强约束 SOP 接入入口配置、表单/图片输入创作工作台、单图资产槽位、系列素材图集生成、独立契约、后端 DDD、结果页、运行态、作品架、广场与验证;用于避免复制既有玩法、默认对话式 Agent、页面内手写图片输入或复用玩法专属素材模型。
|
||||
---
|
||||
|
||||
# Genarrative 新增玩法类型接入流程
|
||||
# Genarrative 新增玩法创作工具平台 SOP
|
||||
|
||||
用于在 Genarrative 中新增一个创作入口/玩法类型,而不是单纯说明用户如何从入口创建作品。
|
||||
把新增玩法当成平台能力接入,不把任何既有玩法当作默认模板。先确定通用模式和契约,再写具体玩法代码。
|
||||
|
||||
## 适用场景
|
||||
## 硬性禁区
|
||||
|
||||
- 新增一个游戏玩法入口
|
||||
- 让某个玩法从“敬请期待”变为可创建
|
||||
- 为新玩法补齐创作工作台、结果页、发布与试玩链路
|
||||
- 将新玩法接入创作中心作品架与广场
|
||||
- 不恢复前端硬编码入口配置;创作入口事实源必须来自 SpacetimeDB 和 `/api/creation-entry/config`。
|
||||
- 不把聊天输入区、流式消息或轻输入 Agent 作为新增玩法默认工作台。
|
||||
- 不在新页面内手写图片上传、参考图、AI 重绘、历史图选择、预览或删除确认逻辑。
|
||||
- 不把通用系列素材建模成任一玩法专属 DTO;玩法只能追加自己的运行态字段。
|
||||
- 不让前端承接正式业务真相;发布、试玩、通关、失败、计分、资产持久化和作品状态以后端投影为准。
|
||||
- 不新建平行入口系统、平行作品架或平行公开列表;优先扩展现有平台壳、现有阶段和现有聚合。
|
||||
- 不在 UI 面板内默认写功能说明、规则说明或开发解释文案。
|
||||
|
||||
## 先判断接入级别
|
||||
## 接入前输入
|
||||
|
||||
### 1. 只做入口占位
|
||||
开始编码前,PRD 或当前玩法文档必须已经明确:
|
||||
|
||||
只需要新增入口配置,不接 session/workspace/result/runtime。
|
||||
- `playId`、对外名称、工程域名、入口 `visible/open` 状态。
|
||||
- 创作链路:入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态。
|
||||
- 表单字段:字段名、默认值、校验、后端落库位置、生成提示词来源。
|
||||
- 单图资产槽位:`slotId`、`slotType`、`slotName`、提示词来源、读取字段、写回字段、是否允许历史图和 AI 重绘。
|
||||
- 系列素材槽位:`batchId` 语义、`sheetSpec`、`slotSpecs`、切图规则、透明化规则、失败回写、局部重生成策略。
|
||||
- API 命名空间:`/api/creation/<play>/sessions`、`actions`、`works`、`runtime`。
|
||||
- 草稿恢复、生成中恢复、失败重试、登录切换、发布后回读和移动端行为。
|
||||
- 验证命令和例外声明;没有例外时写明“无创作工具模式例外”。
|
||||
|
||||
适合:
|
||||
- 敬请期待
|
||||
- 灰度占位
|
||||
## 默认模式
|
||||
|
||||
### 2. 可进入创作工作台
|
||||
新增玩法默认采用表单/图片输入创作工作台:
|
||||
|
||||
需要补齐前端分流、session、工作台、结果页,至少能生成草稿。
|
||||
```text
|
||||
创作入口 -> 表单/图片输入工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态
|
||||
```
|
||||
|
||||
### 3. 完整玩法闭环
|
||||
工作台只提交结构化表单、图片槽位和配置 payload。确需自然语言对话时,先走“例外流程”,不能把聊天区直接加进默认工作台。
|
||||
|
||||
需要补齐:
|
||||
- 创作入口
|
||||
- 工作台
|
||||
- 草稿生成
|
||||
- 结果页
|
||||
- 发布
|
||||
- 试玩 runtime
|
||||
- 作品架 / 广场 / 分享
|
||||
## SOP
|
||||
|
||||
## 推荐接入顺序
|
||||
### 1. 文档和领域词先行
|
||||
|
||||
### Step 1: 先定玩法 ID 和能力边界
|
||||
先读:
|
||||
|
||||
先明确:
|
||||
- `id` 是什么
|
||||
- 入口是否可见
|
||||
- 是否可点击创建
|
||||
- 是否需要对话式创作
|
||||
- 是否需要生成中页面
|
||||
- 是否需要 result/runtime/gallery/share
|
||||
- `AGENTS.md`
|
||||
- `.hermes/shared-memory/`
|
||||
- `CONTEXT.md`
|
||||
- `docs/README.md`
|
||||
- `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
|
||||
- 相关玩法 PRD 或设计文档
|
||||
|
||||
不要先随便起临时 ID 再改名。
|
||||
如果文档不能精确指导字段、契约、资产槽位、生成流程和恢复语义,先补文档再编码。新增长期约定时同步 `.hermes/shared-memory/`。
|
||||
|
||||
### Step 2: 新增入口配置
|
||||
### 2. 定玩法边界
|
||||
|
||||
文件:
|
||||
- `src/config/newWorkEntryConfig.ts`
|
||||
固定 `playId`、对外名称、工程域、入口状态、是否支持结果页、试玩、发布、作品架、广场、分享和 runtime。不要先用临时 ID 接线后再批量改名。
|
||||
|
||||
在 `NEW_WORK_ENTRY_CONFIG.creationTypes` 中新增或调整:
|
||||
- `id`
|
||||
- `title`
|
||||
- `subtitle`
|
||||
- `badge`
|
||||
- `visible`
|
||||
- `open`
|
||||
### 3. 接入口配置
|
||||
|
||||
字段语义:
|
||||
- `visible: true`:在创作页签 / 新建作品入口中展示。
|
||||
- `visible: false`:不在平台入口展示,但不删除既有玩法路由和能力。
|
||||
- `open: true`:可点击进入创作流程。
|
||||
- `open: false`:展示为锁定 / 敬请期待,不应进入创建流程。
|
||||
入口配置事实源是 SpacetimeDB `creation_entry_type_config`。后台通过 `/admin/api/creation-entry/config` 管理,前台通过 `/api/creation-entry/config` 读取。
|
||||
|
||||
如果只是占位:
|
||||
- `visible: true`
|
||||
- `open: false`
|
||||
前端只允许在展示层派生:
|
||||
|
||||
相关渲染与过滤位置:
|
||||
- `src/components/platform-entry/platformEntryCreationTypes.ts`:将 `NEW_WORK_ENTRY_CONFIG.creationTypes` 映射为平台入口卡片,`getVisiblePlatformCreationTypes()` 会过滤隐藏项,并把可创建模板排在敬请期待模板前面。
|
||||
- `src/components/custom-world-home/CustomWorldCreationStartCard.tsx`:创作页签首屏模板入口卡片的实际渲染位置。
|
||||
- `src/components/platform-entry/PlatformEntryCreationTypeModal.tsx`:选择创作类型弹层的渲染位置。
|
||||
- 可见入口卡片。
|
||||
- 锁定或开放状态。
|
||||
- 排序、图标、短标题等展示信息。
|
||||
|
||||
注意:当前项目工作区通常已经是 `<repo-root>`,路径不要再额外拼接 `./Genarrative/`。
|
||||
`api-server` 路由熔断必须使用同一份入口配置。禁止新增或恢复前端本地默认入口配置作为事实源。
|
||||
|
||||
### Step 3: 确认类型过滤逻辑
|
||||
### 4. 前端阶段
|
||||
|
||||
文件:
|
||||
- `./Genarrative/src/components/platform-entry/platformEntryCreationTypes.ts`
|
||||
按需要扩展 `SelectionStage`:
|
||||
|
||||
检查:
|
||||
- `getVisiblePlatformCreationTypes()` 是否能展示新类型
|
||||
- `isPlatformCreationTypeVisible()` 是否能识别新类型
|
||||
- `locked` / `hidden` 是否正确映射
|
||||
- `<play>-workspace`
|
||||
- `<play>-generating`
|
||||
- `<play>-result`
|
||||
- `<play>-runtime`
|
||||
- `<play>-gallery-detail`
|
||||
|
||||
### Step 4: 扩展页面阶段
|
||||
阶段名可以按玩法命名,UI 形态必须仍是表单/图片创作工作台。进入工作台时只初始化结构化草稿状态,不启动默认聊天会话。
|
||||
|
||||
文件:
|
||||
- `./Genarrative/src/components/platform-entry/platformEntryTypes.ts`
|
||||
### 5. 工作台实现
|
||||
|
||||
为新玩法补充 `SelectionStage`:
|
||||
- `*-agent-workspace`
|
||||
- `*-generating`(可选)
|
||||
- `*-result`
|
||||
- `*-runtime`(可选)
|
||||
- `*-gallery-detail`(可选)
|
||||
工作台必须满足:
|
||||
|
||||
### Step 5: 在总流程中加类型分流
|
||||
- 使用表单控件、图片槽位、风格选项、难度选项、开关和提交按钮组织输入。
|
||||
- 单图槽位统一使用 `CreativeImageInputPanel`。
|
||||
- 组件缺少能力时先扩展 `CreativeImageInputPanel` 的受控 props,不在玩法页面复制上传、参考图、AI 重绘、历史图、预览或删除确认。
|
||||
- 主图读取、裁剪、历史素材弹层、计费确认、自动保存和后端请求由外层页面持有;通用面板只表达输入 UI 和短生命周期 UI 状态。
|
||||
- 提交 payload 必须是表单字段与图片槽位结构,不是用户消息文本。
|
||||
|
||||
文件:
|
||||
- `./Genarrative/src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
|
||||
### 6. 单图资产槽位
|
||||
|
||||
在 `handleCreationHubCreateType(type)` 中新增分支,确保:
|
||||
- 能进入对应工作台
|
||||
- 能设置对应 `selectionStage`
|
||||
- 能关闭类型弹层
|
||||
角色形象、UI 背景、容器、封面、分享图、图标等单张图都按单图资产槽位处理。
|
||||
|
||||
同时补:
|
||||
- `open<Play>AgentWorkspace()`
|
||||
- `leave<Play>Flow()`
|
||||
- `submit<Play>Message()`(对话式玩法)
|
||||
- `execute<Play>Action()`
|
||||
统一约定:
|
||||
|
||||
### Step 6: 接入通用 Agent flow controller
|
||||
- 槽位用 `slotId` 稳定标识,`slotType` 表达用途,`slotName` 用于 UI 标签。
|
||||
- 上传图、参考图、AI 重绘、历史图选择和删除确认都通过 `CreativeImageInputPanel` 入口表达。
|
||||
- 后端写回 `imageSrc`、`imageObjectKey`、`assetObjectId` 中可用字段;前端展示前通过平台资产读取能力换签。
|
||||
- 单个槽位重生成只禁用该槽位动作,不阻塞结果页其它槽位、系列素材槽位或导航。
|
||||
|
||||
文件:
|
||||
- `./Genarrative/src/components/platform-entry/usePlatformCreationAgentFlowController.ts`
|
||||
### 7. 系列素材图集生成
|
||||
|
||||
如果是 Agent 型玩法,复用通用控制器:
|
||||
- `createSession`
|
||||
- `getSession`
|
||||
- `streamMessage`
|
||||
- `executeAction`
|
||||
- `isBusy`
|
||||
地块、物品、障碍、装饰、UI 部件等一组同类素材都走通用系列素材图集生成流程:
|
||||
|
||||
```text
|
||||
批量规划 -> sheet 生图 -> 后端切图 -> 去背景/透明化 -> PNG 输出 -> OSS 持久化 -> 状态回写 -> 局部重生成
|
||||
```
|
||||
|
||||
玩法只提供:
|
||||
|
||||
- `sheetSpec`:画布比例、行列、单格尺寸、输出格式、背景处理策略。
|
||||
- `slotSpecs`:每个素材槽位的 `slotId`、`slotType`、`slotName`、提示词、sheet 单元格映射。
|
||||
- 玩法字段映射:把通用素材结果映射回玩法自己的 draft/profile/runtime 字段。
|
||||
|
||||
通用系列素材结果建议字段:
|
||||
|
||||
- `batchId`
|
||||
- `slotId`
|
||||
- `slotType`
|
||||
- `slotName`
|
||||
- `prompt`
|
||||
- `imageSrc`
|
||||
- `imageObjectKey`
|
||||
- `assetObjectId`
|
||||
- `sourceSheetCell`
|
||||
- `status`
|
||||
- `error`
|
||||
- `streamingReplyText`
|
||||
- `selectionStage` 切换
|
||||
|
||||
### Step 7: 定义 shared contracts
|
||||
玩法可追加运行态字段,例如半径、宽度、视图索引或碰撞参数,但不能依赖任何玩法专属字段作为平台通用模型。新增玩法 compile action 内部调用通用系列素材服务;如果通用服务还缺能力,先补通用服务再接玩法。
|
||||
|
||||
前端:
|
||||
- `./Genarrative/packages/shared/src/contracts/`
|
||||
### 8. 契约与 API
|
||||
|
||||
后端:
|
||||
- `./Genarrative/server-rs/crates/shared-contracts/src/`
|
||||
前后端必须同步补契约:
|
||||
|
||||
至少补齐:
|
||||
- session snapshot
|
||||
- create session request/response
|
||||
- message request/response
|
||||
- action request/response
|
||||
- draft/result 结构
|
||||
- work summary / gallery 结构(如果需要)
|
||||
- runtime 结构(如果需要)
|
||||
- `packages/shared/src/contracts/`
|
||||
- `server-rs/crates/shared-contracts/src/`
|
||||
|
||||
### Step 8: 实现前端 service client
|
||||
玩法 API 保留独立命名空间:
|
||||
|
||||
目录参考:
|
||||
- `./Genarrative/src/services/`
|
||||
- `POST /api/creation/<play>/sessions`
|
||||
- `GET /api/creation/<play>/sessions/{sessionId}`
|
||||
- `POST /api/creation/<play>/sessions/{sessionId}/actions`
|
||||
- `/api/creation/<play>/works`
|
||||
- `/api/creation/<play>/runtime`
|
||||
|
||||
按玩法补:
|
||||
- creation client
|
||||
- runtime client(可选)
|
||||
- works client(可选)
|
||||
- gallery client(可选)
|
||||
契约需要区分:
|
||||
|
||||
建议保持和现有玩法一致的 API base 与命名风格。
|
||||
- 工作台输入。
|
||||
- 草稿 snapshot。
|
||||
- 单图资产槽位。
|
||||
- 系列素材批次与槽位。
|
||||
- 结果页操作。
|
||||
- 发布作品摘要。
|
||||
- runtime snapshot。
|
||||
|
||||
### Step 9: 接后端 API
|
||||
### 9. 后端分层
|
||||
|
||||
文件参考:
|
||||
- `./Genarrative/server-rs/crates/api-server/src/puzzle.rs`
|
||||
- `./Genarrative/server-rs/crates/api-server/src/puzzle_agent_turn.rs`
|
||||
- `./Genarrative/server-rs/crates/api-server/src/match3d.rs`
|
||||
按 DDD 边界落地:
|
||||
|
||||
通常需要:
|
||||
- create session
|
||||
- get session
|
||||
- send message
|
||||
- stream message
|
||||
- execute action
|
||||
- publish / save / delete
|
||||
- runtime start / action(可选)
|
||||
- gallery / detail(可选)
|
||||
- `module-<play>`:纯领域规则、状态机、draft/runtime 校验。
|
||||
- `shared-contracts`:前后端 DTO。
|
||||
- `spacetime-module`:表、reducer、procedure、事务编排、migration。
|
||||
- `spacetime-client`:typed facade 和 row mapper。
|
||||
- `api-server`:Axum 路由、鉴权、BFF、SSE、生成编排。
|
||||
- `platform-*`:LLM、图片生成、OSS、认证等外部副作用。
|
||||
|
||||
后端设计优先按 Genarrative 的 DDD 分层拆开,不要把玩法规则、数据库事务、LLM 调用和 HTTP handler 混在一个文件里:
|
||||
- `module-<play>`:纯领域规则、状态机、draft/runtime 校验,不依赖 Axum、SpacetimeDB 或外部平台。
|
||||
- `shared-contracts`:前后端 DTO、请求/响应、session snapshot、draft/result/runtime 结构。
|
||||
- `spacetime-module`:表定义、reducer/procedure、事务编排、migration;表结构变化要同步生成绑定。
|
||||
- `spacetime-client`:api-server 到 SpacetimeDB 的 facade,隐藏 reducer 调用细节。
|
||||
- `api-server`:Axum 路由、鉴权、SSE/stream、应用层编排。
|
||||
- `platform-*`:LLM、资产上传、鉴权、第三方服务等副作用。
|
||||
涉及 SpacetimeDB schema 时同步 `migration.rs`、表目录和绑定,并运行 `npm run check:spacetime-schema`。
|
||||
|
||||
建议按四条线设计后端能力:
|
||||
- Agent 创作线:session、turn、stream、compile action。
|
||||
- Works 作品线:保存、发布、删除、草稿恢复。
|
||||
- Gallery 广场线:公开列表、详情、like/remix/share。
|
||||
- Runtime 运行态线:开始试玩、提交动作、读取状态。
|
||||
|
||||
### Step 10: 新增工作台组件
|
||||
|
||||
目录建议:
|
||||
- `./Genarrative/src/components/<play>-creation/<Play>AgentWorkspace.tsx`
|
||||
|
||||
两种形态:
|
||||
|
||||
#### 对话式
|
||||
适合设定逐轮补齐。
|
||||
|
||||
参考:
|
||||
- `BigFishAgentWorkspace.tsx`
|
||||
- `Match3DAgentWorkspace.tsx`
|
||||
|
||||
#### 表单式
|
||||
适合输入结构明确的玩法。
|
||||
|
||||
参考:
|
||||
- `PuzzleAgentWorkspace.tsx`
|
||||
|
||||
### Step 11: 在渲染树中挂载新页面
|
||||
|
||||
文件:
|
||||
- `./Genarrative/src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
|
||||
|
||||
补齐:
|
||||
- workspace 分支
|
||||
- generating 分支(如需要)
|
||||
- result 分支
|
||||
- runtime 分支(如需要)
|
||||
|
||||
### Step 12: 新增结果页
|
||||
|
||||
目录建议:
|
||||
- `./Genarrative/src/components/<play>-result/<Play>ResultView.tsx`
|
||||
### 10. 结果页
|
||||
|
||||
结果页至少支持:
|
||||
- 展示 draft
|
||||
- 返回编辑
|
||||
- 发布
|
||||
- 试玩
|
||||
- 错误展示
|
||||
|
||||
### Step 13: 需要试玩就补 runtime
|
||||
- 展示草稿和生成状态。
|
||||
- 返回工作台编辑。
|
||||
- 单图槽位重生成。
|
||||
- 系列素材追加、替换、局部重生成。
|
||||
- 发布。
|
||||
- 试玩。
|
||||
- 错误展示和失败重试。
|
||||
|
||||
目录建议:
|
||||
- `./Genarrative/src/components/<play>-runtime/<Play>RuntimeShell.tsx`
|
||||
单图槽位和系列素材槽位的生成状态互不阻塞。已有可查看结果时,局部重生成不能把作品架草稿重新变成不可打开的全局生成中。
|
||||
|
||||
如果玩法是游戏类,建议补完整 runtime 闭环。
|
||||
### 11. 运行态、作品架和广场
|
||||
|
||||
### Step 14: 接入作品架 / 广场 / 分享
|
||||
需要试玩或发布时补齐:
|
||||
|
||||
需要改:
|
||||
- `./Genarrative/src/components/custom-world-home/creationWorkShelf.ts`
|
||||
- `./Genarrative/src/components/custom-world-home/CustomWorldCreationHub.tsx`
|
||||
- `./Genarrative/src/services/publicWorkCode.ts`
|
||||
- runtime start/action/finish API。
|
||||
- 作品保存、发布、删除、回读。
|
||||
- 作品架摘要。
|
||||
- 公开列表、详情、分享码。
|
||||
- 公开列表优先消费后端投影或 BFF 缓存,不让前端直接拼源表事实。
|
||||
|
||||
如果玩法支持发布,还要补:
|
||||
- public work code
|
||||
- public detail
|
||||
- publish share modal
|
||||
- like/remix(可选)
|
||||
运行态可以做低延迟表现,但正式胜负、分数、奖励、排行榜和发布状态以后端裁决为准。
|
||||
|
||||
### Step 15: 处理登录态与草稿恢复
|
||||
### 12. 恢复与登录态
|
||||
|
||||
要考虑:
|
||||
- 刷新恢复草稿
|
||||
- 退出登录清空私有状态
|
||||
- result/draft 缺失时回退
|
||||
- busy / generating / runtime 中断恢复
|
||||
必须处理:
|
||||
|
||||
### Step 16: 补测试
|
||||
- 刷新恢复生成中草稿。
|
||||
- 生成页计时从后端摘要时间恢复。
|
||||
- 失败后回读 session/work detail 再决定是否展示失败。
|
||||
- 退出登录清空私有玩法状态。
|
||||
- 私有生成图展示前换签。
|
||||
- result/runtime 缺必要 draft 时回到可恢复入口,不停在空白页。
|
||||
|
||||
至少覆盖:
|
||||
- 入口展示
|
||||
- 类型分流
|
||||
- 工作台打开
|
||||
- session 创建
|
||||
- compile action
|
||||
- result 页切换
|
||||
- 发布后刷新作品架
|
||||
- runtime 进入与退出
|
||||
### 13. 例外流程
|
||||
|
||||
## 最小改动清单
|
||||
任何非表单/图片工作台、对话式 Agent、独立创作系统或特殊资产模型都必须先更新 PRD 和平台文档。例外声明至少写清:
|
||||
|
||||
### 只做占位
|
||||
- 为什么默认表单/图片工作台不能满足。
|
||||
- 例外影响哪些输入、契约、后端流程和测试。
|
||||
- 如何保留单图资产槽位和系列素材槽位的通用能力。
|
||||
- 如何回退到平台默认链路。
|
||||
|
||||
只改:
|
||||
- `./Genarrative/src/config/newWorkEntryConfig.ts`
|
||||
没有文档例外,不进入编码。
|
||||
|
||||
### 做到可进入工作台
|
||||
## PRD 检查块
|
||||
|
||||
至少改:
|
||||
- `newWorkEntryConfig.ts`
|
||||
- `platformEntryTypes.ts`
|
||||
- `PlatformEntryFlowShellImpl.tsx`
|
||||
- 新玩法 service client
|
||||
- 新玩法工作台组件
|
||||
- shared contracts
|
||||
- 后端 API
|
||||
在新增玩法 PRD 中保留这一段:
|
||||
|
||||
### 做到完整闭环
|
||||
```md
|
||||
## 创作工具平台接入声明
|
||||
|
||||
还要补:
|
||||
- result 页
|
||||
- runtime
|
||||
- works / gallery
|
||||
- public code
|
||||
- share
|
||||
- 作品架聚合
|
||||
- 测试
|
||||
- 工作台模式:表单/图片输入创作工作台
|
||||
- 创作链路:入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态
|
||||
- 单图资产槽位:
|
||||
- slotId / slotType / slotName / 提示词来源 / 写回字段 / 是否允许历史图 / 是否允许 AI 重绘
|
||||
- 系列素材槽位:
|
||||
- batchId / sheetSpec / slotSpecs / 切图规则 / 透明化规则 / 失败回写 / 局部重生成
|
||||
- API 命名空间:/api/creation/<play>/...
|
||||
- 业务真相:后端裁决字段和前端表现字段边界
|
||||
- 创作工具模式例外:无;如有,先写明例外原因和回退方式
|
||||
- 验证命令:
|
||||
```
|
||||
|
||||
## 常见坑
|
||||
## 验证门禁
|
||||
|
||||
1. 只加入口配置不够,类型分流和页面阶段也要补。
|
||||
2. `SelectionStage` 不扩展,前端无法安全切页。
|
||||
3. 新玩法如果要出现在作品架,必须改聚合逻辑,不只是加入口。
|
||||
4. 发布后不刷新 works/gallery,用户会看不到新作品。
|
||||
5. 如果走 SpacetimeDB,表结构变化要同步 migration 和绑定;`spacetime-client/src/module_bindings/` 通常是生成物,不要为了修编译或格式化而手改,优先改 module 源 schema/reducer/procedure 后重新生成。
|
||||
6. 做 analytics/tracking 这类 runtime 能力时,不要只补 API DTO;先在 `module-runtime` 写纯函数测试(例如 day/week/month/quarter/year bucket 聚合、scope/event 过滤),RED 后再补领域类型与聚合函数。
|
||||
7. 时间粒度聚合建议复用已有 date dimension 逻辑,把 daily stat 映射到 day/week/month/quarter/year bucket;bucket 输出要有稳定排序,并显式携带 `bucketKey`、`bucketStartDateKey`、`bucketEndDateKey`、`value`。
|
||||
8. 后端 shared-contracts 与前端 `packages/shared/src/contracts/runtime.ts` 要同步补 request/response/type union;admin-web 若有独立 `api/adminApiTypes.ts`,也要同步,避免共享包已更新但管理端本地类型缺失。
|
||||
9. 退出登录时要清空新玩法私有状态,避免串用户。
|
||||
10. 移动端入口卡片增多后要检查布局和滚动体验。
|
||||
按改动范围运行:
|
||||
|
||||
## 参考资料
|
||||
|
||||
- `references/genarrative-analytics-tracking-runtime.md`:analytics/tracking runtime 粒度聚合、contracts 同步与 SpacetimeDB 生成物注意事项。
|
||||
|
||||
## 验证标准
|
||||
|
||||
一个玩法算真正接入成功,至少要满足:
|
||||
|
||||
- 入口能展示
|
||||
- 能进入对应工作台
|
||||
- 能创建 session
|
||||
- 能生成草稿
|
||||
- 能进入结果页
|
||||
- 能返回编辑
|
||||
- 如果需要,可试玩
|
||||
- 如果需要,可发布
|
||||
- 发布后能回到作品架 / 广场 / 分享链路
|
||||
- `npm run check:encoding`
|
||||
- `npm run typecheck`
|
||||
- 前端工作台测试:确认没有聊天式 Agent 输入,提交的是表单/图片 payload。
|
||||
- `CreativeImageInputPanel` 测试:覆盖多玩法标签、上传、AI 重绘、参考图上限、历史图入口和删除确认。
|
||||
- 系列素材测试:覆盖 sheet layout、切图、透明化、OSS 持久化、追加、替换、局部重生成和失败回写。
|
||||
- 结果页测试:覆盖单图槽位重生成和系列素材槽位重生成互不阻塞。
|
||||
- 后端定向测试:覆盖 compile action、资产持久化、失败回写、发布和 runtime start。
|
||||
- 涉及 SpacetimeDB schema 时运行 `npm run check:spacetime-schema`。
|
||||
|
||||
Reference in New Issue
Block a user