1
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-20 11:30:19 +08:00
parent 50759f3c1e
commit 8a7bd90458
85 changed files with 7290 additions and 1903 deletions

View File

@@ -254,58 +254,49 @@ MVP 支持三种主形象输入方式:
MVP 必须与当前项目可扮演角色动作槽位对齐。
当前落地实现补充约束(`2026-04-19`
当前落地实现补充约束(`2026-04-20`
- 角色资产工坊默认固定生成入口收敛`idle / run / attack / die`
- `hurt` 不再作为固定按钮动作
- 角色资产工坊固定生成入口`idle / run / attack / die`
- `run / attack` 是固定基础必生成动作
- `idle / die` 改为固定可选动作,不再作为发布硬门槛
- `idle` 未生成时默认直接使用主图静止显示
- `die` 未生成时默认播放一段基于主图的倒地过渡动画,并最终停在翻转倒地姿态
- 角色已配置的每个技能,都必须在技能编辑面板里补出对应动作预览
- 图生视频默认走火山方舟 `Seedance` 首尾帧方案
- 接口请求体中的两张参考图分别固定为 `first_frame / last_frame`
- 固定参数为 `1:1``480p``4 秒`、单次 `1` 个视频
- 提示词中的动作名统一传英文动作名
第一版要求以下基础动作槽位不能为空
第一版动作生成按下面两层规则落地
| 动作槽位 | 是否必填 | 备注 |
| --- | --- | --- |
| `idle` | 必填 | 循环动作 |
| `acquire` | 必填 | 可由短变体衍生 |
| `attack` | 必填 | 一次性动作 |
| `run` | 必填 | 循环动作 |
| `jump` | 必填 | 一次性动作 |
| `double_jump` | 必填 | 可由跳跃二次变体生成 |
| `jump_attack` | 必填 | 一次性动作 |
| `dash` | 必填 | 一次性动作 |
| `hurt` | 必填 | 一次性动作 |
| `die` | 必填 | 一次性动作 |
| `climb` | 必填 | 可由模板生成 |
| `wall_slide` | 必填 | 可由攀爬停帧变体生成 |
| 类别 | 动作槽位 | 是否必填 | 备注 |
| -------- | ------------------------------- | -------- | -------------------------------------------------- |
| 基础动作 | `run` | 必填 | 角色移动主循环动作 |
| 基础动作 | `attack` | 必填 | 角色普通攻击主动作 |
| 技能动作 | `skills[*].actionPreviewConfig` | 必填 | 当前角色每个已配置技能都要有独立动作资源 |
| 可选动作 | `idle` | 可选 | 缺失时默认走主图静止待机 |
| 可选动作 | `die` | 可选 | 缺失时默认走主图倒地过渡动画,最终停在翻转倒地姿态 |
这里“不能为空”指的是:
这里“必生成”指的是:
- 每个槽位必须最终指向一套可播放资源
- 允许少量槽位由近似动作衍生
- 但不允许在运行时读到空动画映射
- `run / attack` 必须最终指向可播放资源
- 每个已配置技能都必须带独立 `actionPreviewConfig`
- 发布判定不再要求 `idle / die` 一定存在动画映射
- 运行时仍然不能出现无可用表现;`idle / die` 的缺口由默认兜底承担
## 8.2 技能动作要求
本期不要求自动补齐
本期不要求把整套固定技能枚举一次性自动补齐,但对“角色当前实际配置的技能”改为必做
- `skill1`
- `skill1_jump`
- `skill1_bullet`
- `skill1_bullet_fx`
- `skill2`
- `skill2_jump`
- `skill3`
- `skill3_jump`
- `skill3_bullet`
- `skill3_bullet_fx`
- `skill4`
- 不要求预先把 `skill1 / skill2 / skill3 / skill4` 这套历史枚举全部补满
- 只要求当前角色 `skills` 数组里的每个技能都生成独立动作预览
- 技能动作生成入口继续放在技能编辑面板逐个处理,不塞进固定四按钮里
结论:
- 技能动作本期可选
- 基础动作本期必做
- 技能动作从“固定枚举可选”调整为“按角色已配技能必做”
- 固定基础动作收敛为 `run / attack`
- `idle / die` 保留为可选增强动作
## 8.3 动作生成方式
@@ -606,7 +597,7 @@ type GeneratedCharacterAnimationAsset = {
目标:
-基础动作槽位全部非空,并可一键发布
-必生成动作全部就绪,并为 `idle / die` 提供明确默认兜底
产出:

View File

@@ -200,7 +200,7 @@
`CustomWorldAgentDraftDetailPanel` 中,当当前卡类型为:
```ts
kind === 'character'
kind === 'character';
```
显示按钮:
@@ -239,11 +239,19 @@ kind === 'character'
基于主图生成当前工坊支持的核心动作:
1. `run`
2. `attack`
可选增强动作:
1. `idle`
2. `run`
3. `attack`
4. `hurt`
5. `die`
2. `die`
补充约束:
1. `run / attack` 为固定必生成动作
2. 角色已配置技能时,对应技能动作也属于必生成动作
3. `idle / die` 只作为可选增强,缺失时分别走主图静止 / 主图倒地过渡动画兜底,死亡动画最终停在翻转倒地姿态
### 阶段 D动作发布
@@ -350,15 +358,15 @@ type CustomWorldRoleAssetStatus =
发布主图成功后,必须写回:
```ts
imageSrc
generatedVisualAssetId
imageSrc;
generatedVisualAssetId;
```
发布动作成功后,必须写回:
```ts
generatedAnimationSetId
animationMap
generatedAnimationSetId;
animationMap;
```
### 明确要求
@@ -440,8 +448,8 @@ type SyncRoleAssetsResult = {
### 输入
```ts
buildRoleAssetStudioContext(snapshot, roleId)
applyRoleAssetPublishResult(snapshot, payload)
buildRoleAssetStudioContext(snapshot, roleId);
applyRoleAssetPublishResult(snapshot, payload);
```
### 说明
@@ -465,8 +473,8 @@ applyRoleAssetPublishResult(snapshot, payload)
### 导出函数建议
```ts
rebuildRoleAssetCoverage(draftProfile)
mergeRoleAssetIntoDraftProfile(draftProfile, payload)
rebuildRoleAssetCoverage(draftProfile);
mergeRoleAssetIntoDraftProfile(draftProfile, payload);
```
## 10.3 修改 `customWorldAgentOrchestrator.ts`
@@ -598,7 +606,7 @@ showRoleAssetStudio: boolean;
3. 统一回调:
```ts
onPublishSuccess(payload)
onPublishSuccess(payload);
```
### `onPublishSuccess` 最小字段

View File

@@ -39,9 +39,11 @@
目标用户分三类:
1. 轻创作者
- 有世界灵感,但不擅长结构化填表
2. 中度创作者
- 愿意精修角色、地点、主线第一幕,但不想维护大量底层字段
3. 重度创作者
@@ -138,37 +140,48 @@
本次 PRD 必须复用以下现有基础:
1. `src/services/customWorldCreatorIntent.ts`
- 已有创作者意图、锚点包、锁定状态的基础结构
2. `src/types/customWorld.ts`
- 已有 `creatorIntent / anchorPack / lockState / generationMode / generationStatus`
3. `src/services/aiService.ts`
- 已有自定义世界 session 与生成 API 客户端
4. `server-node/src/services/customWorldSessionStore.ts`
- 已有澄清问题与 session 的基础概念
5. `server-node/src/services/customWorldGenerationService.ts`
- 已有分阶段生成骨架
6. `src/components/game-shell/PreGameSelectionFlow.tsx`
- 已有世界创建流程入口
7. `src/components/CustomWorldResultView.tsx`
- 已有结果页壳层
8. `src/components/CustomWorldRoleAssetStudioModal.tsx`
- 已有角色主图与核心动作资产工坊原型
9. `src/services/ai.ts`
- 已有 `generateCustomWorldSceneImage(...)` 场景图生成入口
10. `server-node/src/modules/assets/characterAssetRoutes.ts`
- 已有角色主图发布、角色动作发布、动作模板等资产路由
- 已有角色主图发布、角色动作发布、动作模板等资产路由
11. `server-node/src/routes/runtimeRoutes.ts`
- 已有 `/custom-world/scene-image` 场景背景图生成路由
- 已有 `/custom-world/scene-image` 场景背景图生成路由
## 3.2 必须替换或重构的现有行为
@@ -220,6 +233,7 @@
最终必须输出两类产物:
1. 创作工作产物
- 世界圣经摘要
- 关键角色卡
- 关键地点卡
@@ -478,9 +492,11 @@ type CustomWorldAssetPriorityTier = 'hero' | 'featured' | 'supporting';
判定规则:
1. `hero`
- 所有 `playableNpcs`
2. `featured`
- 被锁定的 `storyNpcs`
- 主线第一幕直接关联的 `storyNpcs`
- 势力代表角色
@@ -499,6 +515,7 @@ type CustomWorldScenePriorityTier = 'key' | 'supporting';
判定规则:
1. `key`
- `camp`
- 被锁定的 `landmark`
- 主线第一幕直接关联的 `landmark`
@@ -530,32 +547,43 @@ type CustomWorldScenePriorityTier = 'key' | 'supporting';
### 动作抽卡策略
角色动作不能一开始就把完整核心动作集全部抽出来
角色动作不能一开始就把所有动作一次性抽完
必须采用两段式
必须采用“先必需、再增强”的两层策略
#### 阶段 A动作试片
#### 阶段 A基础必需动作
每个角色先生成:
每个角色先生成:
1. `idle`
1. `run`
2. `attack`
用途:
1. 检查角色一致性是否稳定
2. 检查动作风格是否匹配
2. 检查移动和出手两条主动作是否可用
3. 检查武器、衣摆和轮廓是否容易漂移
#### 阶段 B完整核心动作集
#### 阶段 B技能动作补齐
只有当动作试片确认通过后,才允许生成:
当角色基础动作通过后,再逐个补当前角色已经配置的技能动作。
1. `run`
2. `hurt`
3. `die`
要求:
加上已确认的 `idle / attack`,组成当前阶段完整核心动作集。
1. 每个技能都必须有独立 `actionPreviewConfig`
2. 技能动作入口放在技能编辑面板,不并入固定四按钮
#### 可选增强动作
以下动作不再作为发布硬门槛,可按需要补:
1. `idle`
2. `die`
默认兜底:
1. `idle` 缺失时使用主图静止
2. `die` 缺失时使用主图倒地过渡动画,最终停在翻转倒地姿态
### 场景图抽卡策略
@@ -616,16 +644,26 @@ type CustomWorldScenePriorityTier = 'key' | 'supporting';
发布前,每个角色至少需要以下动作槽位可用:
1. `idle`
2. `run`
3. `attack`
4. `hurt`
5. `die`
1. `run`
2. `attack`
3. 当前角色 `skills` 中每个技能的 `actionPreviewConfig`
判定方式:
1. `generatedAnimationSetId` 非空
2. `animationMap`以上 5 个槽位都存在有效映射
2. `animationMap`至少存在有效的 `run / attack`
3. `skills` 数组里的每个技能都带有效 `actionPreviewConfig`
可选动作:
1. `idle`
2. `die`
说明:
1. `idle / die` 不再是发布硬门槛
2. `idle` 缺失时运行时默认使用主图静止
3. `die` 缺失时运行时默认播放主图倒地过渡动画,最终停在翻转倒地姿态
说明:
@@ -664,34 +702,34 @@ type CustomWorldAgentStage =
## 6.2 状态迁移规则
| 当前阶段 | 触发 | 下一阶段 |
| --- | --- | --- |
| `collecting_intent` | 最小锚点不足Agent 追问 | `clarifying` |
| `clarifying` | 用户补齐锚点 | `foundation_review` |
| `collecting_intent` | 用户信息已足够并请求底稿 | `foundation_review` |
| `foundation_review` | 用户精修关键对象 | `object_refining` |
| `object_refining` | 用户请求生成角色或场景资产 | `visual_refining` |
| `visual_refining` | 关键角色与场景资产进入可用状态 | `long_tail_review` |
| `object_refining` | 用户明确跳过人工精修并走自动补齐 | `long_tail_review` |
| `long_tail_review` | 用户请求发布 | `ready_to_publish` |
| `ready_to_publish` | 发布成功 | `published` |
| 任意阶段 | 发生不可恢复错误 | `error` |
| 当前阶段 | 触发 | 下一阶段 |
| ------------------- | -------------------------------- | ------------------- |
| `collecting_intent` | 最小锚点不足Agent 追问 | `clarifying` |
| `clarifying` | 用户补齐锚点 | `foundation_review` |
| `collecting_intent` | 用户信息已足够并请求底稿 | `foundation_review` |
| `foundation_review` | 用户精修关键对象 | `object_refining` |
| `object_refining` | 用户请求生成角色或场景资产 | `visual_refining` |
| `visual_refining` | 关键角色与场景资产进入可用状态 | `long_tail_review` |
| `object_refining` | 用户明确跳过人工精修并走自动补齐 | `long_tail_review` |
| `long_tail_review` | 用户请求发布 | `ready_to_publish` |
| `ready_to_publish` | 发布成功 | `published` |
| 任意阶段 | 发生不可恢复错误 | `error` |
## 6.3 阶段显示规则
前端顶部摘要区必须展示当前阶段中文标签:
| 阶段 | 展示文案 |
| --- | --- |
| 阶段 | 展示文案 |
| ------------------- | ------------ |
| `collecting_intent` | 收集世界锚点 |
| `clarifying` | 补充关键设定 |
| `clarifying` | 补充关键设定 |
| `foundation_review` | 校对世界底稿 |
| `object_refining` | 精修关键对象 |
| `visual_refining` | 生成视觉资产 |
| `long_tail_review` | 补全长尾内容 |
| `ready_to_publish` | 准备发布 |
| `published` | 已发布 |
| `error` | 处理异常 |
| `object_refining` | 精修关键对象 |
| `visual_refining` | 生成视觉资产 |
| `long_tail_review` | 补全长尾内容 |
| `ready_to_publish` | 准备发布 |
| `published` | 已发布 |
| `error` | 处理异常 |
---
@@ -980,7 +1018,15 @@ interface SendCustomWorldAgentMessageResponse {
type CustomWorldAgentActionRequest =
| { action: 'lock_cards'; cardIds: string[] }
| { action: 'unlock_cards'; cardIds: string[] }
| { action: 'regenerate_scope'; scope: 'focus_card' | 'long_tail_npcs' | 'long_tail_landmarks' | 'sidequest_seeds'; targetCardId?: string | null }
| {
action: 'regenerate_scope';
scope:
| 'focus_card'
| 'long_tail_npcs'
| 'long_tail_landmarks'
| 'sidequest_seeds';
targetCardId?: string | null;
}
| { action: 'draft_foundation' }
| { action: 'generate_role_assets'; roleIds: string[] }
| {
@@ -1909,9 +1955,12 @@ Agent 会话每次 operation 完成后自动保存 session snapshot。
15. `src/components/custom-world-agent/CustomWorldAgentDraftDetailPanel.tsx`
16. `src/components/custom-world-agent/CustomWorldSceneAssetStudioModal.tsx`
17. `src/components/CustomWorldRoleAssetStudioModal.tsx`
- 改成 Agent 可调用版
- 改成 Agent 可调用版
18. `src/components/asset-studio/characterAssetWorkflowPersistence.ts`
- 继续复用现有资产接口客户端
- 继续复用现有资产接口客户端
## 15.3 backend

View File

@@ -109,6 +109,7 @@
- 技能冷却要按“本次动作结束后”推进
- 恢复类动作可额外提供冷却推进收益
- 物品动作在战斗态下也算一次战斗回合
- 战斗中使用物品要先结算物品恢复 / buff / 额外冷却收益,再结算这一回合是否承受敌方单次反击
### 4.3 结果文本
@@ -200,6 +201,12 @@ ongoing battle 的本地/后端结果文本只负责说明这一次动作结算
5. 前端支持 disabled battle option 展示
6. 文档、测试同步更新
补充落地备注2026-04-20
- `inventory_use` 在战斗中按战斗动作结算,而不是按非战斗库存动作直接短路返回
- 战斗态 `inventory_use` 使用后要消费物品、累计 `itemsUsed`、推进 1 回合基础冷却,再叠加物品自带的 `cooldownReduction`
- 若物品动作结算后战斗仍在继续,`storyText` 直接等于本次战斗结果文本,不触发 AI 续写
本期不做:
1. 新增复杂目标选择 UI

View File

@@ -1,6 +1,6 @@
# “我的”Tab 设置与账号安全 PRD
更新时间:`2026-04-19`
更新时间:`2026-04-20`
## 0. 目标
@@ -56,7 +56,12 @@
## 3. 信息架构
设置中心建议固定为段:
设置中心首层固定为段:
1. 主题外观
2. 账号信息
其中“账号信息”二级面板固定承载以下内容:
1. 账号概况
2. 当前安全状态
@@ -66,10 +71,14 @@
交互层级要求补充为:
1. 设置首页只展示分区入口与危险操作,不在首页内联展开具体详情
1. 设置首页只展示“主题外观”“账号信息”两个分区入口与危险操作,不在首页内联展开具体详情
2. 点击任一分区入口后,必须进入独立二级面板
3. 二级面板负责单一任务,不允许把详情继续堆在入口列表下面
4. 更换手机号属于独立操作面板,不允许在账号概况面板内直接展开表单
3. 安全状态、登录设备、操作记录不再作为首页独立入口,统一归入“账号信息”二级面板
4. 更换手机号属于独立操作面板,不允许在账号信息面板内直接展开表单
5. 设置首页头部只保留一套主标题,不允许在内容区再重复放置“设置首页”“选择要管理的内容”这类二次标题块
6. 子面板导航动作必须单一明确;同一层面板内有“返回”时,不再同时展示“关闭”
7. 设置首页与各级子面板都必须定义单一滚动容器,列表内容必须可稳定滚动,禁止外层与内层同时争夺滚动
8. 二级或三级面板打开后,下层内容必须进入不可交互状态,并把焦点主动转移到当前面板内;禁止对仍保留焦点的祖先节点使用 `aria-hidden`
底部保留两个危险操作按钮:
@@ -87,7 +96,6 @@
- 登录方式
- 手机号脱敏值
- 微信绑定状态
- 账号状态
这里只看信息,不做大编辑动作。
@@ -201,11 +209,14 @@
1. 设置继续采用当前账号弹窗基础形态即可
2. 移动端优先底部弹层,桌面端可居中弹窗
3. 设置首页只保留分区入口,不直接承载分区详情内容
4. 分区详情必须通过独立子面板承载,移动端优先使用全宽底部子弹层,桌面端使用覆盖在设置首页之上的居中子面板
3. 设置首页只保留“主题外观”“账号信息”两个入口,不再单独展示安全状态、登录设备、操作记录入口
4. “账号信息”二级面板直接承载账号概况、安全状态、登录设备、操作记录四块内容,移动端优先纵向滚动,桌面端保持同一面板内稳定扫读
5. 更换手机号必须通过独立操作面板完成,不再使用当前面板内联展开表单
6. 危险操作按钮与普通按钮必须明显区分
7. 设置首页标题处禁止展示手机号、脱敏手机号或手机号形态的 displayName
8. 设置首页不额外堆砌规则说明文案,标题下直接进入可操作内容
9. 子面板采用覆盖式独立面板承载详情,返回上一级时恢复首页,不在同层同时出现双导航动作
10. 面板切换必须保证键盘焦点始终停留在当前活跃面板内,返回上一级后焦点恢复到触发入口
---

View File

@@ -1,6 +1,6 @@
# 平台“存档”Tab PRD
更新时间:`2026-04-19`
更新时间:`2026-04-20`
## 0. 目标
@@ -84,15 +84,13 @@
## 3.1 存档 Tab 首屏结构
页面由两部分组成:
页面首屏直接展示存档列表,不再单独保留顶部“最近存档”摘要卡。
1. 顶部摘要卡
2. 存档列表
列表容器本身需要承担首屏入口作用:
顶部摘要卡用于表达:
- 当前共有多少个可恢复存档
- 最近一次更新的存档是谁
- 用户进入“存档”Tab 后第一屏就看到可恢复存档列表
- 不额外重复展示首个存档的大卡摘要
- 存档数量、排序状态如需表达,应收敛在列表标题或轻量状态信息中
不要在 UI 中默认堆规则说明文案,只保留简洁的状态表达。