1
This commit is contained in:
@@ -82,7 +82,7 @@
|
||||
5. 玩家从广场进入某个作品时,第 1 关必须先显示当前作品本身。
|
||||
6. 第 2 关及以后必须按照“标签相似度权重 `70%` + 同作者权重 `30%`”选择下一关。
|
||||
7. 游戏运行时必须全屏展示拼图画布。
|
||||
8. 新游戏进入时难度必须从 `3*3` 开始,完成 `3` 关后切为 `4*4`,后续持续为 `4*4`。
|
||||
8. 新游戏进入时难度必须从第 `1` 关的 `3*3` 开始,并按关卡配置推进到 `4*4`、`5*5`、`6*6`、`7*7`;第 `11` 关起每 `6` 关循环复用第 `5~10` 关配置。
|
||||
9. 拼图运行时必须支持:
|
||||
- 点击选择两块并交换
|
||||
- 正确相邻后自动合并
|
||||
@@ -517,21 +517,35 @@ tagSimilarityScore =
|
||||
本次建议同时显示:
|
||||
|
||||
1. 当前关卡序号
|
||||
2. 当前网格规格,例如 `3x3` 或 `4x4`
|
||||
2. 当前网格规格,例如 `3x3`、`5x5` 或 `7x7`
|
||||
|
||||
## 9.3 难度与关卡推进规则
|
||||
|
||||
每次新 run 都必须从最低难度开始:
|
||||
每次新 run 都必须从第 `1` 关配置开始:
|
||||
|
||||
1. 第 `1~3` 关固定为 `3x3`
|
||||
2. 第 `4` 关开始固定为 `4x4`
|
||||
3. 后续全部关卡保持 `4x4`
|
||||
| 关卡 | 切割规格 | 限时 |
|
||||
| ---------- | -------- | -------------- |
|
||||
| 第 `1` 关 | `3x3` | `5` 分钟 |
|
||||
| 第 `2` 关 | `4x4` | `5` 分钟 |
|
||||
| 第 `3` 关 | `5x5` | `5` 分钟 |
|
||||
| 第 `4` 关 | `5x5` | `3` 分 `30` 秒 |
|
||||
| 第 `5` 关 | `5x5` | `3` 分 `30` 秒 |
|
||||
| 第 `6` 关 | `6x6` | `4` 分钟 |
|
||||
| 第 `7` 关 | `5x5` | `3` 分 `30` 秒 |
|
||||
| 第 `8` 关 | `7x7` | `4` 分 `30` 秒 |
|
||||
| 第 `9` 关 | `5x5` | `4` 分钟 |
|
||||
| 第 `10` 关 | `7x7` | `4` 分 `30` 秒 |
|
||||
|
||||
第 `11` 关开始,每 `6` 关循环复用第 `5~10` 关配置。
|
||||
|
||||
对应函数建议:
|
||||
|
||||
```ts
|
||||
function resolvePuzzleGridSize(clearedLevelCount: number): 3 | 4 {
|
||||
return clearedLevelCount >= 3 ? 4 : 3;
|
||||
function resolvePuzzleLevelConfig(levelIndex: number): {
|
||||
gridSize: 3 | 4 | 5 | 6 | 7;
|
||||
timeLimitMs: number;
|
||||
} {
|
||||
// 统一从关卡序号解析切割规格和倒计时。
|
||||
}
|
||||
```
|
||||
|
||||
@@ -646,8 +660,8 @@ V1 规则如下:
|
||||
|
||||
`2026-04-29` 起,拼图运行时加入倒计时:
|
||||
|
||||
1. `3x3` 关卡限时 `180` 秒。
|
||||
2. `4x4` 关卡限时 `300` 秒。
|
||||
1. 倒计时必须使用第 `9.3` 节的关卡配置函数,不允许在 UI 或本地兜底里按网格规模另写一套时间表。
|
||||
2. 第 `1~10` 关按配置表执行;第 `11` 关起每 `6` 关循环复用第 `5~10` 关配置。
|
||||
3. 规定时间内未完成拼图,关卡状态变为 `failed`。
|
||||
4. 弹窗、查看原图覆盖、冻结时间生效期间不消耗倒计时。
|
||||
5. 通关成绩只统计有效消耗时间,不统计暂停与冻结时间。
|
||||
@@ -693,7 +707,7 @@ interface PuzzleProfile {
|
||||
interface PuzzleRuntimeLevelSnapshot {
|
||||
runId: string;
|
||||
levelIndex: number;
|
||||
gridSize: 3 | 4;
|
||||
gridSize: 3 | 4 | 5 | 6 | 7;
|
||||
profileId: string;
|
||||
levelName: string;
|
||||
authorDisplayName: string;
|
||||
@@ -738,7 +752,7 @@ interface PuzzleRunSnapshot {
|
||||
entryProfileId: string;
|
||||
clearedLevelCount: number;
|
||||
currentLevelIndex: number;
|
||||
currentGridSize: 3 | 4;
|
||||
currentGridSize: 3 | 4 | 5 | 6 | 7;
|
||||
playedProfileIds: string[];
|
||||
previousLevelTags: string[];
|
||||
currentLevel: PuzzleRuntimeLevelSnapshot | null;
|
||||
@@ -1167,7 +1181,7 @@ interface PuzzleRunSnapshot {
|
||||
|
||||
先做:
|
||||
|
||||
1. `3x3 / 4x4` 切图
|
||||
1. `3x3 / 4x4 / 5x5 / 6x6 / 7x7` 切图
|
||||
2. 点击两块交换
|
||||
3. 正确连接自动合并
|
||||
4. 合并块整体拖动
|
||||
@@ -1202,7 +1216,7 @@ interface PuzzleRunSnapshot {
|
||||
4. 发布后的拼图作品能进入平台广场。
|
||||
5. 玩家从广场进入时,第 `1` 关必定是当前作品本身。
|
||||
6. 第 `2` 关及以后按照“标签相似度 `70%` + 同作者 `30%`”计算下一关。
|
||||
7. 新 run 前 `3` 关为 `3x3`,之后固定为 `4x4`。
|
||||
7. 新 run 的关卡切割和倒计时符合第 `9.3` 节配置,并且第 `11` 关起按第 `5~10` 关配置循环。
|
||||
8. 运行时支持点击两块交换。
|
||||
9. 交换后正确相邻的块会自动合并。
|
||||
10. 合并块可以整体拖动。
|
||||
|
||||
@@ -93,8 +93,9 @@
|
||||
|
||||
1. 数字过大时做单位缩略展示
|
||||
2. “游戏时长”卡固定以小时为单位展示,短时长不切换成分钟,长时长不切换成天
|
||||
3. 进入页面先展示骨架屏
|
||||
4. 数据请求失败时展示降级文案,不展示假数字
|
||||
3. “玩过”卡展示值始终带 `个` 单位,例如 `0个`、`1个`、`1.2万个`
|
||||
4. 进入页面先展示骨架屏
|
||||
5. 数据请求失败时展示降级文案,不展示假数字
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
1. 拼图生成图固定使用 `1024*1024`。
|
||||
2. 文生图和参考图生图共用同一个尺寸常量,禁止一条链路仍生成竖屏或横版图。
|
||||
3. 拼图图片提示词明确写入 `1:1 正方形画布`,继续保留 `3x3 或 4x4 拼图切块`、主体清晰、层次明确、无文字水印等约束。
|
||||
3. 拼图图片提示词明确写入 `1:1 正方形画布`,继续保留适配 `3x3 / 4x4 / 5x5 / 6x6 / 7x7` 拼图切块、主体清晰、层次明确、无文字水印等约束。
|
||||
4. 文生图正向 prompt 必须由后端压缩到 `500` 字符以内,优先保留玩家画面描述开头与固定拼图约束,避免 DashScope 旧 text2image 协议把超长 prompt 判为“请求参数不合法”。
|
||||
5. DashScope 上游失败时,api-server 必须在错误 details 中保留业务 message、`upstreamStatus` 和截断后的 `rawExcerpt`,日志也要记录同样的摘要,避免生成进度页只能看到通用 HTTP 文案。
|
||||
6. 图片生成仍由 `api-server` 执行。SpacetimeDB reducer 不做网络 I/O。
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
1. 点击拼图草稿生成或重新生成画面时,后端请求 DashScope 的 `size` 为 `1024*1024`。
|
||||
2. 图片提示词包含 `1:1 正方形拼图关卡`。
|
||||
3. 图片提示词长度不超过 `500` 字符,超长画面描述会被截断,但 `3x3 或 4x4`、`避免文字、水印、边框和 UI 元素` 等玩法约束不能丢。
|
||||
3. 图片提示词长度不超过 `500` 字符,超长画面描述会被截断,但适配 `3x3 / 4x4 / 5x5 / 6x6 / 7x7` 拼图切块、`避免文字、水印、边框和 UI 元素` 等玩法约束不能丢。
|
||||
4. DashScope 返回参数错误、任务失败或非 2xx 时,前端错误优先展示后端 details.message,后端日志能看到 `upstreamStatus` 和 `rawExcerpt`。
|
||||
5. 正式拼图 run 中拖动拼块后,前端立即更新棋盘、合并块和通关状态,不再等待 `/drag`。
|
||||
6. 移动端运行时棋盘为正方形,并尽量贴近屏幕两侧边缘。
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
1. 通关后默认点击“下一关”,优先加载当前拼图作品的下一关。
|
||||
2. 当前作品没有下一关时,后端按标签语义相似度选出相似度最高的三个已发布作品。
|
||||
3. 用户在通关弹窗里点击候选作品后,进入该作品并从第 1 关重新开始。
|
||||
3. 用户在通关弹窗里点击候选作品后,进入该作品并从第 `1` 关重新开始。
|
||||
4. 移动端优先,候选卡片要紧凑,不写玩法说明类文案。
|
||||
|
||||
## 数据契约
|
||||
@@ -51,8 +51,8 @@
|
||||
- 返回最高的 3 个候选
|
||||
4. `advance_puzzle_next_level`:
|
||||
- `nextLevelMode = sameWork` 时加载当前作品的下一关,并继续当前 run。
|
||||
- `nextLevelMode = similarWorks` 时默认加载候选第一项,并从该作品第 1 关重新开始。
|
||||
5. `local-next-level` 兼容接口同样优先找同作品下一关;没有时才返回相似作品候选或旧草稿兜底。
|
||||
- `nextLevelMode = similarWorks` 时默认加载候选第一项,并把 `entryProfileId / clearedLevelCount / currentLevelIndex` 重置到目标作品第 `1` 关。
|
||||
5. `local-next-level` 兼容接口同样优先找同作品下一关;没有时返回 `similarWorks` 候选并保持当前通关 run,只有候选池为空时才进入旧草稿兜底。
|
||||
|
||||
## 前端规则
|
||||
|
||||
@@ -64,11 +64,12 @@
|
||||
- `sameWork` 保留“下一关”。
|
||||
- `similarWorks` 显示“换个作品”,点击后打开结算弹窗供选择。
|
||||
3. 所有正式相似度计算只信任后端返回,不在 UI 里重新算。
|
||||
4. 本地/草稿 run 通关提交本地排行榜后,会异步调用 `local-next-level` 刷新 handoff;若拿到 `similarWorks`,只合并候选字段,不把已通关弹窗改成新的 playing 关卡。
|
||||
|
||||
## 验收
|
||||
|
||||
1. 当前作品有下一关时,点击“下一关”进入当前作品下一关。
|
||||
2. 当前作品没有下一关时,通关弹窗显示最多 3 个相似作品。
|
||||
3. 点击相似作品后进入该作品第 1 关。
|
||||
3. 点击相似作品后进入该作品第 `1` 关,HUD 关卡序号、切割规格和倒计时都按第 `1` 关显示。
|
||||
4. 旧 `recommendedNextProfileId` 为空时,只要 `nextLevelMode = sameWork`,按钮仍可用。
|
||||
5. 拼图 runtime 单测、Rust 拼图模块测试和编码检查通过。
|
||||
|
||||
@@ -24,12 +24,28 @@
|
||||
|
||||
## 难度限时
|
||||
|
||||
第一版按网格规模定义限时:
|
||||
拼图关卡切割规格和倒计时由统一关卡配置函数解析,不再按网格规模单独推导时间:
|
||||
|
||||
1. `3x3`:`180000ms`。
|
||||
2. `4x4`:`300000ms`。
|
||||
| 关卡 | 切割规格 | 限时 |
|
||||
| -------- | -------- | ---------- |
|
||||
| 第 1 关 | `3x3` | `300000ms` |
|
||||
| 第 2 关 | `4x4` | `300000ms` |
|
||||
| 第 3 关 | `5x5` | `300000ms` |
|
||||
| 第 4 关 | `5x5` | `210000ms` |
|
||||
| 第 5 关 | `5x5` | `210000ms` |
|
||||
| 第 6 关 | `6x6` | `240000ms` |
|
||||
| 第 7 关 | `5x5` | `210000ms` |
|
||||
| 第 8 关 | `7x7` | `270000ms` |
|
||||
| 第 9 关 | `5x5` | `240000ms` |
|
||||
| 第 10 关 | `7x7` | `270000ms` |
|
||||
|
||||
后续若扩展更多难度,只能通过同一个难度解析函数扩展,不允许在 UI 里写死另一套时间。
|
||||
第 11 关开始,每 6 关循环复用第 5 关到第 10 关的配置,即 `5x5/210000ms`、`6x6/240000ms`、`5x5/210000ms`、`7x7/270000ms`、`5x5/240000ms`、`7x7/270000ms`。
|
||||
|
||||
同作品下一关必须使用同一个运行时关卡序号继续推进。跨作品相似推荐代表进入新作品,必须从目标作品第 `1` 关重新开始。
|
||||
|
||||
失败状态点击“重新开始”时,不进入作品第 `1` 关,而是重开当前失败关卡:前端需要传当前关 `levelId`,服务端按该 `levelId` 在作品内的位置恢复 `currentLevelIndex`、切割规格和倒计时。
|
||||
|
||||
后续若扩展更多难度,只能通过同一个关卡配置解析函数扩展,不允许在 UI 里写死另一套时间。
|
||||
|
||||
## 计时规则
|
||||
|
||||
|
||||
59
docs/technical/PUZZLE_WORK_POINT_INCENTIVE_2026-05-01.md
Normal file
59
docs/technical/PUZZLE_WORK_POINT_INCENTIVE_2026-05-01.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# 拼图作品积分激励链路设计
|
||||
|
||||
更新时间:`2026-05-01`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
1. 拼图草稿页“新增关卡”按钮下方显示一行小字:“获得更多积分激励”。
|
||||
2. 创作页的已发布拼图作品卡展示当前作品的积分激励总数、待领取积分数和领取按钮。
|
||||
3. 用户在他人已发布拼图作品中消耗陶泥币时,作品作者获得消耗陶泥币数量的一半作为积分激励。
|
||||
4. 作者领取时只能领取整数个陶泥币,待领取值向下取整;未满 1 个陶泥币的半数余额继续保留。
|
||||
|
||||
## 2. 数据模型
|
||||
|
||||
拼图作品激励归属到 `puzzle_work_profile`。
|
||||
|
||||
1. `point_incentive_total_half_points: u64`
|
||||
- 记录该作品累计获得的激励,单位为“半个陶泥币”。
|
||||
- 每消耗 `N` 个陶泥币,增加 `N` 个 half points;当前拼图道具每次消耗 1 个陶泥币,因此每次为作者增加 0.5。
|
||||
2. `point_incentive_claimed_points: u64`
|
||||
- 记录作者已领取的整数陶泥币数量。
|
||||
3. 前端展示:
|
||||
- 激励总数 = `pointIncentiveTotalHalfPoints / 2`,允许展示一位小数。
|
||||
- 待领取积分 = `floor(pointIncentiveTotalHalfPoints / 2) - pointIncentiveClaimedPoints`。
|
||||
- 领取按钮仅在待领取积分大于 0 时可用。
|
||||
|
||||
## 3. 后端事务
|
||||
|
||||
1. 拼图运行道具扣费成功、道具效果成功落库后,后端根据 run 的当前作品 `profile_id` 查找作者。
|
||||
2. 若使用者不是作品作者,则给该作品累积 `consumed_points` 个 half points。
|
||||
3. 若使用者是作者本人,视为作者自测,不产生积分激励。
|
||||
4. 若后续业务操作失败并触发扣费退款,不写入激励。
|
||||
5. 领取接口:
|
||||
- 只允许作品作者领取。
|
||||
- 计算可领取整数 `claimable = total_half_points / 2 - claimed_points`。
|
||||
- `claimable <= 0` 时拒绝领取。
|
||||
- 同一事务内更新作品 `claimed_points += claimable`,并向作者钱包增加 `claimable` 陶泥币,钱包流水来源使用 `puzzle_author_incentive_claim`。
|
||||
|
||||
## 4. API 与前端
|
||||
|
||||
1. `PuzzleWorkSummary` / `PuzzleWorkProfile` 增加:
|
||||
- `pointIncentiveTotalHalfPoints`
|
||||
- `pointIncentiveClaimedPoints`
|
||||
- `pointIncentiveTotalPoints`
|
||||
- `pointIncentiveClaimablePoints`
|
||||
2. 新增领取接口:
|
||||
- `POST /api/runtime/puzzle/works/{profile_id}/point-incentive/claim`
|
||||
- 返回更新后的 `PuzzleWorkProfile`。
|
||||
3. 创作页仅对已发布拼图作品显示积分激励块;RPG、大鱼和草稿卡不显示。
|
||||
4. 领取成功后刷新对应拼图作品列表状态,按钮立即禁用或显示新的待领取数。
|
||||
5. `spacetime-client` 映射层继续兼容历史拼图运行快照:旧 `run_json` 若缺少 `started_at_ms`,API 记录回填为非 0 值,避免前端计时器拿到无效开始时间。
|
||||
|
||||
## 5. 验收点
|
||||
|
||||
1. 拼图草稿页新增关卡按钮下方显示“获得更多积分激励”。
|
||||
2. 已发布拼图作品卡展示“积分激励总数”和“待领取”两个数值。
|
||||
3. 待领取积分为 0 时领取按钮禁用。
|
||||
4. 非作者游玩他人拼图并使用付费道具后,该作品累计 half points 增加。
|
||||
5. 作者领取后钱包增加向下取整后的整数陶泥币,作品待领取数归零或保留不足 1 的小数余额。
|
||||
6. 修改后运行编码检查、SpacetimeDB 绑定生成、Rust 检查和必要前端测试。
|
||||
@@ -24,8 +24,9 @@
|
||||
- [PUZZLE_IMAGE_AND_FRONTEND_RULES_ALIGNMENT_2026-04-29.md](./PUZZLE_IMAGE_AND_FRONTEND_RULES_ALIGNMENT_2026-04-29.md):记录拼图生成图片回到 1:1,运行时拖动、交换、合并与拆分由前端即时裁决,以及移动端棋盘贴近屏幕边缘的落地边界。
|
||||
- [PUZZLE_FORM_CREATION_FLOW_2026-04-29.md](./PUZZLE_FORM_CREATION_FLOW_2026-04-29.md):冻结拼图填表式创作入口、初始表单自动保存草稿、生成前退出后的表单恢复,以及草稿编译/首图生成的前后端边界。
|
||||
- [PUZZLE_LEADERBOARD_FRONTEND_LEVEL_AND_RPG_COMING_SOON_2026-04-30.md](./PUZZLE_LEADERBOARD_FRONTEND_LEVEL_AND_RPG_COMING_SOON_2026-04-30.md):记录拼图第二关排行榜提交以前端当前关卡为准、不被 SpacetimeDB 旧 run 快照误杀,以及 RPG 创作入口改为敬请期待的落地边界。
|
||||
- [PUZZLE_NEXT_LEVEL_AND_SIMILAR_WORK_HANDOFF_2026-04-30.md](./PUZZLE_NEXT_LEVEL_AND_SIMILAR_WORK_HANDOFF_2026-04-30.md):记录拼图通关后优先同作品下一关、无下一关时按 RPG/build 标签语义相似度返回三个候选作品并从第 1 关接续的落地规则。
|
||||
- [PUZZLE_NEXT_LEVEL_AND_SIMILAR_WORK_HANDOFF_2026-04-30.md](./PUZZLE_NEXT_LEVEL_AND_SIMILAR_WORK_HANDOFF_2026-04-30.md):记录拼图通关后优先同作品下一关、无下一关时按 RPG/build 标签语义相似度返回三个候选作品,并在跨作品时只切换到候选作品第 1 张图、运行时关卡序号继续累进的落地规则。
|
||||
- [PUZZLE_FAILURE_EXTENSION_AND_SAVE_ARCHIVE_2026-05-01.md](./PUZZLE_FAILURE_EXTENSION_AND_SAVE_ARCHIVE_2026-05-01.md):记录拼图失败后重新开始/付费续时,以及进入作品与过关后同步存档页投影的落地规则。
|
||||
- [PUZZLE_RUNTIME_TIMER_AND_PROPS_2026-04-29.md](./PUZZLE_RUNTIME_TIMER_AND_PROPS_2026-04-29.md):记录拼图关卡切割、倒计时、失败态和三个运行时道具的统一规则;2026-05-01 起关卡切割与限时按第 1-10 关配置,并从第 11 关按第 5-10 关六关循环。
|
||||
- [RPG_SCENE_ACT_PREVIEW_BOOTSTRAP_FIX_2026-04-30.md](./RPG_SCENE_ACT_PREVIEW_BOOTSTRAP_FIX_2026-04-30.md):记录编辑器幕预览卡在“正在载入这一幕”时的启动态根因,收口预览本地运行态装配与禁持久化首段 story 注入。
|
||||
- [PUZZLE_RESULT_AUTOSAVE_AND_TAG_GATE_FIX_2026-04-28.md](./PUZZLE_RESULT_AUTOSAVE_AND_TAG_GATE_FIX_2026-04-28.md):记录拼图结果页名称与标签编辑自动保存、发布门槛统一到 `3~6` 标签,以及前端发布校验不再被旧 session blocker 卡死的修复口径。
|
||||
- [WORK_AUTHOR_ID_RESOLUTION_2026-04-30.md](./WORK_AUTHOR_ID_RESOLUTION_2026-04-30.md):记录作品作者以 `owner_user_id` 为真相源,API 按用户 ID 解析最新昵称与公开用户码,历史 `author_display_name` 仅作为兼容回退。
|
||||
|
||||
Reference in New Issue
Block a user