Files
Genarrative/docs/technical/PUZZLE_RUNTIME_TIMER_AND_PROPS_2026-04-29.md
2026-04-29 20:56:59 +08:00

4.0 KiB
Raw Blame History

拼图运行时限时与道具系统设计 2026-04-29

背景

拼图运行时从纯粹的无压解谜升级为限时关卡,需要同时补齐三类体验:

  1. 不同难度有明确倒计时,超时即失败。
  2. 底部固定 3 个轻量道具:提示、查看原图、冻结时间。
  3. 道具使用必须经过确认弹窗并消耗 1 陶泥币,确认弹窗期间暂停关卡计时。

本设计只处理拼图运行时,不改拼图创作链、发布链和广场推荐链。

运行态字段

PuzzleRuntimeLevelSnapshot 增加以下字段:

  1. timeLimitMs:当前关卡限时。
  2. remainingMs:后端或本地运行态计算出的剩余时间。
  3. pausedAccumulatedMs:已累计暂停时长。
  4. pauseStartedAtMs:当前是否处于暂停中;有值表示暂停开始时间。
  5. freezeUntilMs:冻结时间道具生效截止时间;冻结期间倒计时不减少。

status 增加 failed。当 remainingMs <= 0 且关卡尚未通关时,状态进入 failed,后续交换、拖动、排行榜提交都拒绝。

难度限时

第一版按网格规模定义限时:

  1. 3x3180000ms
  2. 4x4300000ms

后续若扩展更多难度,只能通过同一个难度解析函数扩展,不允许在 UI 里写死另一套时间。

计时规则

有效消耗时间计算:

effectiveElapsedMs = nowMs - startedAtMs - pausedAccumulatedMs - activeFreezeElapsedMs
remainingMs = max(0, timeLimitMs - effectiveElapsedMs)

其中:

  1. 弹窗打开、设置面板打开、查看原图覆盖打开时,运行态需要暂停。
  2. 冻结时间生效时,画面播放冻结特效,并展示冻结剩余时长。
  3. 通关时 elapsedMs 使用有效消耗时间,不把确认弹窗、查看原图和冻结时间计入成绩。
  4. 失败后保留棋盘,不弹通关结算。
  5. 正式后端 run 的前端倒计时归零时,需要主动刷新一次 getPuzzleRun,让 SpacetimeDB 侧把 failed 状态写回快照,避免只停留在本地视觉失败。

道具规则

提示

提示道具只演示,不替玩家移动。

演示对象选择:

  1. 优先选当前棋盘中拼块数量最多、且尚未完全处于正确位置的合并块。
  2. 若没有合并块,选择一个不在正确格子的单块。
  3. 演示从当前所在格移动到该块锚点的正确格,结束后回到原位。

查看原图

查看原图是开关按钮:

  1. 打开后把原图以半透明方式覆盖在拼图棋盘上。
  2. 覆盖期间暂停倒计时;确认弹窗关闭到覆盖层显示之间不得恢复计时,正式后端 run 也需要保持 pauseStartedAtMs
  3. 再次点击关闭覆盖并恢复计时。

冻结时间

冻结时间确认后:

  1. 播放冻结视觉特效。
  2. 显示冻结剩余时长。
  3. 第一版冻结 10000ms

计费规则

每次确认使用道具消耗 1 陶泥币。

正式后端运行态复用现有资产操作钱包预扣链路,新增道具 asset_kind

  1. puzzle_prop_hint
  2. puzzle_prop_preview
  3. puzzle_prop_freeze_time

本地调试 run 没有真实用户钱包,不伪造扣费,只保留同样的确认交互与运行态效果。

若扣费或道具过程失败,确认弹窗保持打开并继续暂停倒计时,在弹窗内展示失败原因;只有成功确认后才关闭弹窗并播放对应反馈。

UI 规则

  1. 底部只放 3 个道具按钮,不写规则说明文案。
  2. 点击道具弹出独立确认窗口,不在底栏下方展开。
  3. 确认窗口打开期间暂停计时。
  4. 按钮使用图标和短标签;不可用时降低透明度。
  5. 失败状态使用简洁弹窗展示,可返回或重新开始,不与通关结算混用。

画布表现修正

本轮同步修正合并块视觉:

  1. 合并块之间不再使用额外 p-1 缝隙,拼图块需要贴合。
  2. 单块和大块使用同一套边界描边宽度与颜色。
  3. 外轮廓和凹入转角都需要圆角化。
  4. 新合并产生时,在新大块中心播放一次简洁闪光,不显示文字提示。