This commit is contained in:
2026-04-19 20:33:18 +08:00
parent 692643136f
commit 67c584b4df
123 changed files with 11898 additions and 4082 deletions

View File

@@ -1,6 +1,13 @@
# 账号系统与登录入口重构 PRD
更新时间:`2026-04-09`
更新时间:`2026-04-19`
> 2026-04-19 入口策略补充:
> 平台首页现调整为“未登录也可浏览公开首页”,不再要求用户先登录才能进入平台。
> 登录拦截点改为“点击作品进入详情/世界”与“选择游戏类型开始创作”等受保护动作触发时再弹出登录弹窗。
> 本次入口策略与弹窗约束以
> [`docs/design/PLATFORM_HOME_PUBLIC_BROWSE_AND_LOGIN_MODAL_GATING_DESIGN_2026-04-19.md`](../design/PLATFORM_HOME_PUBLIC_BROWSE_AND_LOGIN_MODAL_GATING_DESIGN_2026-04-19.md)
> 为准;本 PRD 中“先登录再进入开始界面”的旧表述不再作为当前前台入口实现依据。
## 0. 目标
@@ -175,7 +182,7 @@ MVP 阶段建议采用最稳妥规则:
4. 微信后强制绑定手机号
5. 账号会话管理
6. 账号与存档/自定义世界/运行时设置统一绑定
7. 基础账号中心与退出登录
7. 基础账号中心、平台设置面板与退出登录
## 3.2 本期不做
@@ -460,6 +467,7 @@ MVP 阶段建议至少提供一个轻量账号中心,包含:
- 已绑定手机号(脱敏展示)
- 微信绑定状态
- 最近登录时间
- 平台设置面板中的亮色 / 暗色主题切换
- 退出登录
二期可以再补:

View File

@@ -1,6 +1,6 @@
# AI 角色形象与角色动画 MVP PRD
更新时间:`2026-04-04`
更新时间:`2026-04-19`
## 0. 一句话结论
@@ -254,6 +254,15 @@ MVP 支持三种主形象输入方式:
MVP 必须与当前项目可扮演角色动作槽位对齐。
当前落地实现补充约束(`2026-04-19`
- 角色资产工坊默认固定生成入口收敛为 `idle / run / attack / die`
- `hurt` 不再作为固定按钮动作
- 图生视频默认走火山方舟 `Seedance` 首尾帧方案
- 接口请求体中的两张参考图分别固定为 `first_frame / last_frame`
- 固定参数为 `1:1``480p``4 秒`、单次 `1` 个视频
- 提示词中的动作名统一传英文动作名
第一版要求以下基础动作槽位不能为空:
| 动作槽位 | 是否必填 | 备注 |
@@ -345,7 +354,6 @@ MVP 支持两种方式:
- `attack`
- `jump_attack`
- `hurt`
- `die`
要求末帧清晰,不与下一动作切换冲突。
@@ -634,4 +642,3 @@ type GeneratedCharacterAnimationAsset = {
- 路径清晰
- 能真正进入当前仓库
- 后续可以在此基础上再加技能动作、剧情演出和多供应商增强路线

View File

@@ -0,0 +1,226 @@
# AI Native 战斗单行为 Function PRD2026-04-18
## 1. 目标
本次迭代把战斗中的 function 从“战术风格 function”收敛为“单次可直接结算的原子行为 function”。
核心目标:
1. 战斗中一次点击只完成一个明确行为,不再做连续多轮击打、连续多 actor 轮转的 function 设计。
2. 战斗中除逃跑外,不再为每次动作额外触发剧情推理,而是直接结算数值并刷新下一轮战斗选项。
3. 只有在逃跑成功或战斗正式结束后,才触发一次剧情推理,生成脱战后的 storyText 与后续剧情选项。
---
## 2. 新战斗 option 池
`inBattle = true` 时,默认战斗选项池固定收敛为以下结构,顺序按下列规则输出:
1. `battle_attack_basic`
2. `battle_recover_breath`
3. `inventory_use`
4. `battle_use_skill`
5. `battle_escape_breakout`
其中第 4 项不是单个 option而是“每个技能一个 option 实例”。
### 2.1 普通攻击
- functionId`battle_attack_basic`
- 含义:不消耗灵力的基础攻击。
- 结算:直接结算一次基础伤害。
- 不触发剧情推理。
### 2.2 恢复
- functionId`battle_recover_breath`
- 含义:本回合做恢复与节奏调整。
- 结算:直接恢复血量/灵力,并推进技能冷却。
- 不触发剧情推理。
### 2.3 使用物品
- functionId`inventory_use`
- 含义:战斗中直接使用一个可结算的消耗品。
- 本期战斗选项池只给一个“推荐可用物品” option不展开整包物品列表。
- option 必须携带 `runtimePayload.itemId`
- 若当前没有可用消耗品,则仍保留该项,但以 disabled 态展示。
- 不触发剧情推理。
### 2.4 使用技能
- functionId`battle_use_skill`
- 每个角色技能都生成一个独立 option。
- option 文案直接对应技能名,不再包装成“稳扎试探 / 破架 / 终结窗口”这类抽象战术文案。
- option 必须携带 `runtimePayload.skillId`
- 若技能因蓝量不足或冷却中不可用,仍保留该 option但以 disabled 态展示。
- 点击后直接结算该技能本次效果,不触发剧情推理。
### 2.5 逃跑
- functionId`battle_escape_breakout`
- 含义:立即尝试脱离当前战斗。
- 结算:直接处理脱战结果。
- 逃跑成功后必须触发剧情推理。
---
## 3. 旧战斗 function 的处理
以下旧 function 不再进入默认战斗选项池:
- `battle_all_in_crush`
- `battle_guard_break`
- `battle_probe_pressure`
- `battle_feint_step`
- `battle_finisher_window`
兼容规则:
- 后端仍允许解析这些旧 functionId避免旧存档 / 旧 currentStory 点击时报错。
- 兼容结算统一按“单次攻击型行为”处理,不再保留旧的战术风格分支。
- 新生成的新选项、新 currentStory、新 viewModel 不再继续下发这些旧 function。
---
## 4. 单行为结算规则
### 4.1 单次点击的边界
一次点击只允许完成一次玩家声明行为:
- 普通攻击
- 恢复
- 使用物品
- 使用某个具体技能
- 逃跑
不再允许一次点击里继续串:
- 多轮连续攻击
- 多个技能连续释放
- 多个角色依次轮转
- 为了“表现完整”再补一整串额外战斗回合
### 4.2 回合感保留
虽然不再做连续多轮击打,但每个战斗动作仍然视为消耗了一个战斗回合,因此:
- 技能冷却要按“本次动作结束后”推进
- 恢复类动作可额外提供冷却推进收益
- 物品动作在战斗态下也算一次战斗回合
### 4.3 结果文本
ongoing battle 的本地/后端结果文本只负责说明这一次动作结算结果,不负责续写新的剧情段落。
例如:
- 你挥出一记普通攻击,命中前方敌人。
- 你稳住呼吸,恢复了部分气血与灵力。
- 你立刻服下疗伤药,当前状态回升。
- 你释放了【试锋斩】,直接压低了对方血线。
---
## 5. 剧情推理触发边界
### 5.1 不触发剧情推理的情况
当动作执行后仍处于战斗中时,以下 function 不触发剧情推理:
- `battle_attack_basic`
- `battle_recover_breath`
- `inventory_use`
- `battle_use_skill`
- 旧攻击类兼容 function
此时系统行为为:
1. 直接结算动作
2. 更新 HP / MP / CD / 物品 / 战斗状态
3. 直接刷新新一轮战斗选项
4. `storyText` 直接使用本次结算结果文本,不请求 AI 续写
### 5.2 必须触发剧情推理的情况
以下情况必须触发剧情推理:
1. `battle_escape_breakout` 执行后成功脱战
2. 任意战斗动作执行后,战斗正式结束
战斗正式结束包括:
- 敌方被击败
- 切磋结束
- 玩家被系统判定为本轮战斗已断开
此时系统行为为:
1. 先完成数值结算与状态落地
2. 再以“本次动作 + 本次战斗结果”为上下文触发一次剧情推理
3. 生成脱战后的 `storyText` 与非战斗态 options
---
## 6. 前后端数据约束
### 6.1 Option 扩展字段
为了支持“单 functionId + 多实例技能/物品 option”战斗 option 允许携带以下运行时字段:
- `runtimePayload`
- `skillId?: string`
- `itemId?: string`
- `disabled?: boolean`
- `disabledReason?: string`
### 6.2 前端职责
- 前端只负责展示 option、透传 `runtimePayload`、展示 disabled 态
- 前端不再自己推导战斗中“是否需要剧情推理”
- 前端不再把技能 option 重写成抽象战术描述
### 6.3 后端职责
- 后端负责生成战斗 option 池
- 后端负责解析 `skillId / itemId`
- 后端负责决定 battle ongoing / battle end / escape 后是否触发剧情推理
---
## 7. 本次落地范围
本期必须落地:
1. 后端 runtime 战斗 option 池切换到单行为模型
2. 后端 combat resolution 支持普通攻击 / 指定技能 / 恢复 / 战斗物品 / 逃跑
3. 后端只在逃跑或战斗结束后做剧情推理
4. 前端支持透传战斗 option 的 `runtimePayload`
5. 前端支持 disabled battle option 展示
6. 文档、测试同步更新
本期不做:
1. 新增复杂目标选择 UI
2. 一次展开完整背包的战斗 item 子面板
3. 重做整套战斗演出系统
4. 把所有旧本地 battle plan 彻底删除到只剩后端一条链
---
## 8. 验收口径
满足以下条件视为本次需求完成:
1. 战斗中不再出现 `battle_all_in_crush / battle_guard_break / battle_probe_pressure / battle_feint_step / battle_finisher_window` 作为默认候选项。
2. 战斗默认候选项能看到:
- 普通攻击
- 恢复
- 使用物品
- 每个技能一个独立技能项
- 逃跑
3. 点击普通攻击 / 恢复 / 使用物品 / 技能时,不请求新的剧情推理,直接返回结算结果并刷新下一轮战斗 options。
4. 点击逃跑成功后,会请求一次剧情推理并切回脱战后的剧情 options。
5. 任意攻击或技能把敌人打死后,会请求一次剧情推理并切回脱战后的剧情 options。
6. 旧存档里残留旧 battle functionId 时,不会因为 function 不识别而报错。

View File

@@ -484,6 +484,29 @@ interface ListCustomWorldWorksResponse {
- 当前用户作品量预计不大
- 先把结构做稳,比先做分页更重要
### 公开浏览与登录边界
创作首页与世界选择页必须拆分两类数据:
1. 公开浏览数据
2. 当前用户私有数据
其中以下接口必须定义为公开只读:
- `GET /api/runtime/custom-world-gallery`
- `GET /api/runtime/custom-world-gallery/:ownerUserId/:profileId`
明确约束:
1. 未登录用户进入世界选择页时,也必须能读取公开作品广场
2. 公开作品广场读取不能依赖 access token也不能因为 refresh 失败返回 401
3. 已发布作品详情允许未登录用户查看
4. 只有“继续创作 / 发布 / 下架 / 删除 / 查看我的草稿 / 查看我的统计”等私有能力必须要求登录
也就是说:
**平台首页要支持“先浏览公开作品,再决定是否登录进入世界或开始创作”。**
## 9.3 数据来源
### 草稿来源

View File

@@ -17,17 +17,20 @@
## 1. 当前“我的”Tab 功能拆分
当前页面可拆成以下 `9` 个独立功能
说明
-`2026-04-19` 起,“最近游玩 / 历史浏览”已从“我的”页迁出,改为平台一级主 Tab“存档”。
- 对应母文档见 [PLATFORM_SAVE_TAB_PRD_2026-04-19.md](/E:/Repos/Genarrative/docs/prd/PLATFORM_SAVE_TAB_PRD_2026-04-19.md)。
当前“我的”页保留以下 `7` 个独立功能:
1. 账号资料与身份卡
2. 会员中心与充值
3. 我的数据看板
4. 最近游玩
5. 历史浏览
6. 邀请好友
7. 填邀请码
8. 玩家社区
9. 设置与账号安全
4. 邀请好友
5. 填邀请码
6. 玩家社区
7. 设置与账号安全
---
@@ -36,12 +39,11 @@
1. [MY_TAB_PROFILE_IDENTITY_CARD_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_PROFILE_IDENTITY_CARD_PRD_2026-04-16.md)
2. [MY_TAB_MEMBERSHIP_CENTER_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_MEMBERSHIP_CENTER_PRD_2026-04-16.md)
3. [MY_TAB_DATA_DASHBOARD_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_DATA_DASHBOARD_PRD_2026-04-16.md)
4. [MY_TAB_RECENT_PLAY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_RECENT_PLAY_PRD_2026-04-16.md)
5. [MY_TAB_BROWSE_HISTORY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_BROWSE_HISTORY_PRD_2026-04-16.md)
6. [MY_TAB_INVITE_FRIENDS_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_INVITE_FRIENDS_PRD_2026-04-16.md)
7. [MY_TAB_INVITE_CODE_REDEMPTION_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_INVITE_CODE_REDEMPTION_PRD_2026-04-16.md)
8. [MY_TAB_PLAYER_COMMUNITY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_PLAYER_COMMUNITY_PRD_2026-04-16.md)
9. [MY_TAB_SETTINGS_AND_SECURITY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_SETTINGS_AND_SECURITY_PRD_2026-04-16.md)
4. [PLATFORM_SAVE_TAB_PRD_2026-04-19.md](/E:/Repos/Genarrative/docs/prd/PLATFORM_SAVE_TAB_PRD_2026-04-19.md)
5. [MY_TAB_INVITE_FRIENDS_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_INVITE_FRIENDS_PRD_2026-04-16.md)
6. [MY_TAB_INVITE_CODE_REDEMPTION_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_INVITE_CODE_REDEMPTION_PRD_2026-04-16.md)
7. [MY_TAB_PLAYER_COMMUNITY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_PLAYER_COMMUNITY_PRD_2026-04-16.md)
8. [MY_TAB_SETTINGS_AND_SECURITY_PRD_2026-04-16.md](/E:/Repos/Genarrative/docs/prd/MY_TAB_SETTINGS_AND_SECURITY_PRD_2026-04-16.md)
---
@@ -51,20 +53,19 @@
1. 账号资料与身份卡
2. 设置与账号安全
3. 最近游玩
4. 历史浏览
5. 我的数据看板
6. 会员中心与充值
7. 邀请好友
8. 填邀请码
9. 玩家社区
3. 我的数据看板
4. 平台存档 Tab
5. 会员中心与充值
6. 邀请好友
7. 邀请
8. 玩家社区
原因:
- `1 + 2` 复用现有账号系统最多,最容易先落地
- `3 + 4 + 5` 直接增强“我的”页内容密度,短期收益高
- `6 + 7` 涉及商业化和关系绑定,依赖结算与奖励台账
- `8` 最适合放在平台内容层能力稳定后再做
- `3 + 4` 直接增强账号资产与回流体验,短期收益高
- `5 + 6` 涉及商业化和关系绑定,依赖结算与奖励台账
- `7` 最适合放在平台内容层能力稳定后再做
---

View File

@@ -0,0 +1,252 @@
# 平台“存档”Tab PRD
更新时间:`2026-04-19`
## 0. 目标
把原本堆在“我的”页中的“最近游玩 / 历史浏览”移出,新增平台一级主 Tab“存档”用于承载当前账号在平台里玩过的所有游戏留下的最近可恢复存档。
这次改动的核心目标不是做复杂多槽位存档系统,而是先落地一个稳定、可跨设备同步、可直接继续游玩的账号级存档入口。
---
## 1. 信息架构调整
## 1.1 平台主导航
平台主导航从:
- 首页
- 创作
- 我的
调整为:
- 首页
- 创作
- 存档
- 我的
移动端底部导航与桌面端左侧纵向导航都必须同步调整。
## 1.2 “我的”页调整
“我的”页删除以下内容块:
- 最近游玩
- 历史浏览
“我的”页保留:
- 账号资料与身份卡
- 数据看板
- 常用功能
- 设置与账号安全
说明:
- 历史浏览本期直接从“我的”页移除,不再占据个人页首屏空间。
- 存档能力统一收口到平台一级“存档”Tab不再同时在“我的”页重复展示。
---
## 2. 存档定义
## 2.1 本期存档口径
本期“存档”Tab 展示的是:
- 当前账号在每个已游玩游戏 / 世界下保留的最近一个可恢复存档
不是:
- 同一游戏下的完整多槽位存档管理页
- 手动重命名 / 置顶 / 删除存档系统
## 2.2 世界唯一键
服务端必须按 `worldKey` 聚合最近存档:
- 自定义世界:`custom:<profileId>`
- 内建世界:`builtin:<worldType>`
同一账号、同一 `worldKey` 只保留最近一次成功保存的可恢复存档。
## 2.3 生命周期
1. 玩家每次成功写入运行时快照时,同步刷新该世界的最近存档记录。
2. 删除当前活动快照时,不删除历史存档归档。
3. 点击“继续游玩”时,从该世界最近存档恢复为当前活动快照,再进入游戏。
---
## 3. 界面设计
## 3.1 存档 Tab 首屏结构
页面由两部分组成:
1. 顶部摘要卡
2. 存档列表
顶部摘要卡用于表达:
- 当前共有多少个可恢复存档
- 最近一次更新的存档是谁
不要在 UI 中默认堆规则说明文案,只保留简洁的状态表达。
## 3.2 列表排序
列表按 `lastPlayedAt` 倒序。
最近更新的存档始终在最前面。
## 3.3 列表项字段
每个列表项必须展示:
- 游戏名称
- 最后游玩时间
- 游戏信息
其中“游戏信息”优先级如下:
1. `continueGameDigest`
2. 当前故事文本摘要
3. 世界简介 / 场景简介
4. 若都没有则给出简洁兜底文案
可附带展示封面,但封面不是必填验收项。
## 3.4 点击行为
点击列表项后:
1. 调用后端恢复接口
2. 将所选存档切换为当前活动快照
3. 直接进入游戏继续游玩
前端不允许自行拼装恢复上下文。
## 3.5 空状态
### 已登录但无存档
- 展示轻量空态
- 引导去首页开始游玩
### 未登录
- 展示登录态空壳
- 不请求受保护的云端存档列表接口
---
## 4. 默认进入逻辑
当满足以下条件时玩家进入网站后的平台首页默认进入“存档”Tab
1. 当前处于登录状态
2. 当前账号至少存在一个存档
否则:
- 仍默认进入“首页”Tab
注意:
- 这个默认进入逻辑只在平台首屏初始化时执行,不能覆盖用户手动切换后的选择。
---
## 5. 后端设计
## 5.1 新增数据表
建议新增 `profile_save_archives`
- `user_id`
- `world_key`
- `owner_user_id`
- `profile_id`
- `world_type`
- `world_name`
- `world_subtitle`
- `summary_text`
- `cover_image_src`
- `saved_at`
- `bottom_tab`
- `game_state_json`
- `current_story_json`
- `updated_at`
约束:
- 主键:`user_id + world_key`
- 排序索引:`user_id + saved_at desc`
## 5.2 写入规则
每次 `/api/runtime/save/snapshot` 成功写入后:
1. 正常更新当前活动快照
2. 同步 upsert 对应 `world_key` 的存档归档
3. 继续保留原有个人看板 / 已玩作品同步逻辑
## 5.3 列表接口
### `GET /api/runtime/profile/save-archives`
返回:
- 当前账号全部最近存档
字段至少包含:
- `worldKey`
- `worldName`
- `worldSubtitle`
- `summaryText`
- `coverImageSrc`
- `lastPlayedAt`
- `worldType`
- `profileId`
- `ownerUserId`
## 5.4 恢复接口
### `POST /api/runtime/profile/save-archives/:worldKey/resume`
用途:
- 将指定存档归档恢复为当前活动快照
- 返回恢复后的快照
限制:
- 恢复动作不能重复记账,不得再次累计个人资产流水
- 恢复动作不能重复累计已玩时长
- 恢复动作不能破坏现有快照水合逻辑
---
## 6. 前端实现要求
1. `PlatformHomeView` 新增 `存档` 主 Tab。
2. `PreGameSelectionFlow` 在平台数据加载时同时拉取存档列表。
3. 已登录且有存档时,平台首屏默认选中 `存档` Tab。
4. “我的”页删除“最近游玩 / 历史浏览”两个区块。
5. 点击存档列表项时必须经过后端恢复接口,恢复成功后直接进入游戏。
6. 移动端优先,列表项点击区域不能过小。
---
## 7. 验收标准
1. 已登录账号可以在“存档”Tab 看到所有已玩过世界的最近存档。
2. 列表按最近更新时间倒序。
3. 列表项可看到游戏名称、最后游玩时间和游戏信息。
4. 点击列表项后可直接继续对应游戏。
5. 已登录且至少有一个存档时进入网站默认打开“存档”Tab。
6. 未登录时不请求云端存档列表,也不会出现受保护接口报错。